mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 04:45:47 +02:00
refactor contexts
This commit is contained in:
parent
145c69d9ae
commit
d82f175e79
54 changed files with 1562 additions and 1248 deletions
|
@ -13,22 +13,9 @@ import (
|
|||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedBranch() *models.Branch {
|
||||
if len(gui.State.Model.Branches) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
selectedLine := gui.State.Panels.Branches.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.Branches[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) branchesRenderToMain() error {
|
||||
var task updateTask
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
task = NewRenderStringTask(gui.c.Tr.NoBranchesThisRepo)
|
||||
} else {
|
||||
|
@ -48,24 +35,26 @@ func (gui *Gui) branchesRenderToMain() error {
|
|||
// specific functions
|
||||
|
||||
func (gui *Gui) handleBranchPress() error {
|
||||
if gui.State.Panels.Branches.SelectedLineIdx == -1 {
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
return nil
|
||||
}
|
||||
if gui.State.Panels.Branches.SelectedLineIdx == 0 {
|
||||
|
||||
if branch == gui.getCheckedOutBranch() {
|
||||
return gui.c.ErrorMsg(gui.c.Tr.AlreadyCheckedOutBranch)
|
||||
}
|
||||
branch := gui.getSelectedBranch()
|
||||
|
||||
gui.c.LogAction(gui.c.Tr.Actions.CheckoutBranch)
|
||||
return gui.helpers.Refs.CheckoutRef(branch.Name, types.CheckoutRefOptions{})
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreatePullRequestPress() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
return gui.createPullRequest(branch.Name, "")
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreatePullRequestMenu() error {
|
||||
selectedBranch := gui.getSelectedBranch()
|
||||
selectedBranch := gui.State.Contexts.Branches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -77,7 +66,7 @@ func (gui *Gui) handleCreatePullRequestMenu() error {
|
|||
func (gui *Gui) handleCopyPullRequestURLPress() error {
|
||||
hostingServiceMgr := gui.getHostingServiceMgr()
|
||||
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
|
||||
branchExistsOnRemote := gui.git.Remote.CheckRemoteBranchExists(branch.Name)
|
||||
|
||||
|
@ -109,7 +98,7 @@ func (gui *Gui) handleGitFetch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleForceCheckout() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
message := gui.c.Tr.SureForceCheckout
|
||||
title := gui.c.Tr.ForceCheckoutBranch
|
||||
|
||||
|
@ -156,7 +145,7 @@ func (gui *Gui) getCheckedOutBranch() *models.Branch {
|
|||
}
|
||||
|
||||
func (gui *Gui) createNewBranchWithName(newBranchName string) error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -165,7 +154,7 @@ func (gui *Gui) createNewBranchWithName(newBranchName string) error {
|
|||
return gui.c.Error(err)
|
||||
}
|
||||
|
||||
gui.State.Panels.Branches.SelectedLineIdx = 0
|
||||
gui.State.Contexts.Branches.SetSelectedLineIdx(0)
|
||||
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||
}
|
||||
|
||||
|
@ -174,7 +163,7 @@ func (gui *Gui) handleDeleteBranch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) deleteBranch(force bool) error {
|
||||
selectedBranch := gui.getSelectedBranch()
|
||||
selectedBranch := gui.State.Contexts.Branches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -245,12 +234,12 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleMerge() error {
|
||||
selectedBranchName := gui.getSelectedBranch().Name
|
||||
selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name
|
||||
return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleRebaseOntoLocalBranch() error {
|
||||
selectedBranchName := gui.getSelectedBranch().Name
|
||||
selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name
|
||||
return gui.handleRebaseOntoBranch(selectedBranchName)
|
||||
}
|
||||
|
||||
|
@ -279,7 +268,7 @@ func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleFastForward() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil || !branch.IsRealBranch() {
|
||||
return nil
|
||||
}
|
||||
|
@ -305,7 +294,7 @@ func (gui *Gui) handleFastForward() error {
|
|||
)
|
||||
|
||||
return gui.c.WithLoaderPanel(message, func() error {
|
||||
if gui.State.Panels.Branches.SelectedLineIdx == 0 {
|
||||
if branch == gui.getCheckedOutBranch() {
|
||||
gui.c.LogAction(action)
|
||||
|
||||
err := gui.git.Sync.Pull(
|
||||
|
@ -334,7 +323,7 @@ func (gui *Gui) handleFastForward() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCreateResetToBranchMenu() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -343,7 +332,7 @@ func (gui *Gui) handleCreateResetToBranchMenu() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleRenameBranch() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil || !branch.IsRealBranch() {
|
||||
return nil
|
||||
}
|
||||
|
@ -364,7 +353,7 @@ func (gui *Gui) handleRenameBranch() error {
|
|||
// now that we've got our stuff again we need to find that branch and reselect it.
|
||||
for i, newBranch := range gui.State.Model.Branches {
|
||||
if newBranch.Name == newBranchName {
|
||||
gui.State.Panels.Branches.SetSelectedLineIdx(i)
|
||||
gui.State.Contexts.Branches.SetSelectedLineIdx(i)
|
||||
if err := gui.State.Contexts.Branches.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -391,7 +380,7 @@ func (gui *Gui) handleRenameBranch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleEnterBranch() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -400,7 +389,7 @@ func (gui *Gui) handleEnterBranch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleNewBranchOffBranch() error {
|
||||
selectedBranch := gui.getSelectedBranch()
|
||||
selectedBranch := gui.State.Contexts.Branches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,16 +5,11 @@ import (
|
|||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/controllers"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
func (gui *Gui) getSelectedCommitFileNode() *filetree.CommitFileNode {
|
||||
return gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedCommitFile() *models.CommitFile {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -22,20 +17,21 @@ func (gui *Gui) getSelectedCommitFile() *models.CommitFile {
|
|||
}
|
||||
|
||||
func (gui *Gui) getSelectedCommitFilePath() string {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return ""
|
||||
}
|
||||
return node.GetPath()
|
||||
}
|
||||
|
||||
// TODO: do we need this?
|
||||
func (gui *Gui) onCommitFileFocus() error {
|
||||
gui.escapeLineByLinePanel()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) commitFilesRenderToMain() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -62,7 +58,7 @@ func (gui *Gui) commitFilesRenderToMain() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCheckoutCommitFile() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -88,7 +84,7 @@ func (gui *Gui) handleDiscardOldFileChange() error {
|
|||
HandleConfirm: func() error {
|
||||
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
||||
gui.c.LogAction(gui.c.Tr.Actions.DiscardOldFileChange)
|
||||
if err := gui.git.Rebase.DiscardOldFileChanges(gui.State.Model.Commits, gui.State.Panels.Commits.SelectedLineIdx, fileName); err != nil {
|
||||
if err := gui.git.Rebase.DiscardOldFileChanges(gui.State.Model.Commits, gui.State.Contexts.BranchCommits.GetSelectedLineIdx(), fileName); err != nil {
|
||||
if err := gui.helpers.Rebase.CheckMergeOrRebase(err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -122,7 +118,7 @@ func (gui *Gui) refreshCommitFilesView() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleOpenOldCommitFile() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -131,7 +127,7 @@ func (gui *Gui) handleOpenOldCommitFile() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleEditCommitFile() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -144,7 +140,7 @@ func (gui *Gui) handleEditCommitFile() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleToggleFileForPatch() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -212,7 +208,7 @@ func (gui *Gui) handleEnterCommitFile() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) enterCommitFile(opts types.OnFocusOpts) error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -246,7 +242,7 @@ func (gui *Gui) enterCommitFile(opts types.OnFocusOpts) error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleToggleCommitFileDirCollapsed() error {
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -11,18 +11,12 @@ const COMMIT_THRESHOLD = 200
|
|||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedLocalCommit() *models.Commit {
|
||||
selectedLine := gui.State.Panels.Commits.SelectedLineIdx
|
||||
if selectedLine == -1 || selectedLine > len(gui.State.Model.Commits)-1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.Commits[selectedLine]
|
||||
return gui.State.Contexts.BranchCommits.GetSelected()
|
||||
}
|
||||
|
||||
func (gui *Gui) onCommitFocus() error {
|
||||
state := gui.State.Panels.Commits
|
||||
if state.SelectedLineIdx > COMMIT_THRESHOLD && state.LimitCommits {
|
||||
state.LimitCommits = false
|
||||
if gui.State.Contexts.BranchCommits.GetSelectedLineIdx() > COMMIT_THRESHOLD && gui.State.LimitCommits {
|
||||
gui.State.LimitCommits = false
|
||||
go utils.Safe(func() {
|
||||
if err := gui.refreshCommitsWithLimit(); err != nil {
|
||||
_ = gui.c.Error(err)
|
||||
|
@ -37,7 +31,7 @@ func (gui *Gui) onCommitFocus() error {
|
|||
|
||||
func (gui *Gui) branchCommitsRenderToMain() error {
|
||||
var task updateTask
|
||||
commit := gui.getSelectedLocalCommit()
|
||||
commit := gui.State.Contexts.BranchCommits.GetSelected()
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask(gui.c.Tr.NoCommitsThisBranch)
|
||||
} else {
|
||||
|
|
|
@ -77,7 +77,29 @@ func (gui *Gui) getMessageHeight(wrap bool, message string, width int) int {
|
|||
}
|
||||
|
||||
func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, int, int, int) {
|
||||
panelWidth := gui.getConfirmationPanelWidth()
|
||||
panelHeight := gui.getMessageHeight(wrap, prompt, panelWidth)
|
||||
return gui.getConfirmationPanelDimensionsAux(panelWidth, panelHeight)
|
||||
}
|
||||
|
||||
func (gui *Gui) getConfirmationPanelDimensionsForContentHeight(contentHeight int) (int, int, int, int) {
|
||||
panelWidth := gui.getConfirmationPanelWidth()
|
||||
return gui.getConfirmationPanelDimensionsAux(panelWidth, contentHeight)
|
||||
}
|
||||
|
||||
func (gui *Gui) getConfirmationPanelDimensionsAux(panelWidth int, panelHeight int) (int, int, int, int) {
|
||||
width, height := gui.g.Size()
|
||||
if panelHeight > height*3/4 {
|
||||
panelHeight = height * 3 / 4
|
||||
}
|
||||
return width/2 - panelWidth/2,
|
||||
height/2 - panelHeight/2 - panelHeight%2 - 1,
|
||||
width/2 + panelWidth/2,
|
||||
height/2 + panelHeight/2
|
||||
}
|
||||
|
||||
func (gui *Gui) getConfirmationPanelWidth() int {
|
||||
width, _ := gui.g.Size()
|
||||
// we want a minimum width up to a point, then we do it based on ratio.
|
||||
panelWidth := 4 * width / 7
|
||||
minWidth := 80
|
||||
|
@ -88,14 +110,8 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i
|
|||
panelWidth = minWidth
|
||||
}
|
||||
}
|
||||
panelHeight := gui.getMessageHeight(wrap, prompt, panelWidth)
|
||||
if panelHeight > height*3/4 {
|
||||
panelHeight = height * 3 / 4
|
||||
}
|
||||
return width/2 - panelWidth/2,
|
||||
height/2 - panelHeight/2 - panelHeight%2 - 1,
|
||||
width/2 + panelWidth/2,
|
||||
height/2 + panelHeight/2
|
||||
|
||||
return panelWidth
|
||||
}
|
||||
|
||||
func (gui *Gui) prepareConfirmationPanel(
|
||||
|
|
|
@ -65,7 +65,6 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
|
|||
}
|
||||
|
||||
if !c.IsFocusable() {
|
||||
panic(c.GetKey())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
86
pkg/gui/context/branches_context.go
Normal file
86
pkg/gui/context/branches_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type BranchesContext struct {
|
||||
*BranchesViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*BranchesContext)(nil)
|
||||
|
||||
func NewBranchesContext(
|
||||
getModel func() []*models.Branch,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *BranchesContext {
|
||||
viewModel := NewBranchesViewModel(getModel)
|
||||
|
||||
return &BranchesContext{
|
||||
BranchesViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *BranchesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type BranchesViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.Branch
|
||||
}
|
||||
|
||||
func NewBranchesViewModel(getModel func() []*models.Branch) *BranchesViewModel {
|
||||
self := &BranchesViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *BranchesViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *BranchesViewModel) GetSelected() *models.Branch {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
type CommitFilesContext struct {
|
||||
*filetree.CommitFileTreeViewModel
|
||||
*BaseContext
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
|
@ -17,7 +16,7 @@ var _ types.IListContext = (*CommitFilesContext)(nil)
|
|||
|
||||
func NewCommitFilesContext(
|
||||
getModel func() []*models.CommitFile,
|
||||
getView func() *gocui.View,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
|
@ -26,43 +25,30 @@ func NewCommitFilesContext(
|
|||
|
||||
c *types.ControllerCommon,
|
||||
) *CommitFilesContext {
|
||||
baseContext := NewBaseContext(NewBaseContextOpts{
|
||||
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
|
||||
return &CommitFilesContext{
|
||||
CommitFileTreeViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(
|
||||
NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "commitFiles",
|
||||
WindowName: "commits",
|
||||
Key: COMMIT_FILES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &CommitFilesContext{}
|
||||
takeFocus := func() error { return c.PushContext(self) }
|
||||
|
||||
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
viewTrait := NewViewTrait(getView)
|
||||
listContextTrait := &ListContextTrait{
|
||||
base: baseContext,
|
||||
list: viewModel,
|
||||
viewTrait: viewTrait,
|
||||
|
||||
GetDisplayStrings: getDisplayStrings,
|
||||
}),
|
||||
ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
OnFocusLost: onFocusLost,
|
||||
takeFocus: takeFocus,
|
||||
|
||||
// TODO: handle this in a trait
|
||||
RenderSelection: false,
|
||||
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
|
||||
baseContext.AddKeybindingsFn(listContextTrait.keybindings)
|
||||
|
||||
self.BaseContext = baseContext
|
||||
self.ListContextTrait = listContextTrait
|
||||
self.CommitFileTreeViewModel = viewModel
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *CommitFilesContext) GetSelectedItemId() string {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package context
|
||||
|
||||
import "github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
const (
|
||||
GLOBAL_CONTEXT_KEY types.ContextKey = "global"
|
||||
|
@ -60,18 +64,18 @@ type ContextTree struct {
|
|||
Global types.Context
|
||||
Status types.Context
|
||||
Files *WorkingTreeContext
|
||||
Submodules types.IListContext
|
||||
Menu types.IListContext
|
||||
Branches types.IListContext
|
||||
Remotes types.IListContext
|
||||
RemoteBranches types.IListContext
|
||||
Menu *MenuContext
|
||||
Branches *BranchesContext
|
||||
Tags *TagsContext
|
||||
BranchCommits types.IListContext
|
||||
BranchCommits *LocalCommitsContext
|
||||
CommitFiles *CommitFilesContext
|
||||
ReflogCommits types.IListContext
|
||||
SubCommits types.IListContext
|
||||
Stash types.IListContext
|
||||
Suggestions types.IListContext
|
||||
Remotes *RemotesContext
|
||||
Submodules *SubmodulesContext
|
||||
RemoteBranches *RemoteBranchesContext
|
||||
ReflogCommits *ReflogCommitsContext
|
||||
SubCommits *SubCommitsContext
|
||||
Stash *StashContext
|
||||
Suggestions *SuggestionsContext
|
||||
Normal types.Context
|
||||
Staging types.Context
|
||||
PatchBuilding types.Context
|
||||
|
@ -113,6 +117,7 @@ func (self *ContextTree) Flatten() []types.Context {
|
|||
|
||||
type ViewContextMap struct {
|
||||
content map[string]types.Context
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewViewContextMap() *ViewContextMap {
|
||||
|
@ -120,10 +125,15 @@ func NewViewContextMap() *ViewContextMap {
|
|||
}
|
||||
|
||||
func (self *ViewContextMap) Get(viewName string) types.Context {
|
||||
self.RLock()
|
||||
defer self.RUnlock()
|
||||
|
||||
return self.content[viewName]
|
||||
}
|
||||
|
||||
func (self *ViewContextMap) Set(viewName string, context types.Context) {
|
||||
self.Lock()
|
||||
defer self.Unlock()
|
||||
self.content[viewName] = context
|
||||
}
|
||||
|
||||
|
|
|
@ -3,44 +3,35 @@ package context
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
type ListContextTrait struct {
|
||||
base types.IBaseContext
|
||||
list types.IList
|
||||
viewTrait *ViewTrait
|
||||
|
||||
takeFocus func() error
|
||||
|
||||
GetDisplayStrings func(startIdx int, length int) [][]string
|
||||
OnFocus func(...types.OnFocusOpts) error
|
||||
OnRenderToMain func(...types.OnFocusOpts) error
|
||||
OnFocusLost func() error
|
||||
|
||||
// if this is true, we'll call GetDisplayStrings for just the visible part of the
|
||||
// view and re-render that. This is useful when you need to render different
|
||||
// content based on the selection (e.g. for showing the selected commit)
|
||||
RenderSelection bool
|
||||
types.Context
|
||||
|
||||
c *types.ControllerCommon
|
||||
list types.IList
|
||||
viewTrait *ViewTrait
|
||||
getDisplayStrings func(startIdx int, length int) [][]string
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) GetList() types.IList {
|
||||
return self.list
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
func (self *ListContextTrait) GetPanelState() types.IListPanelState {
|
||||
return self.list
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) GetViewTrait() types.IViewTrait {
|
||||
return self.viewTrait
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) FocusLine() {
|
||||
// we need a way of knowing whether we've rendered to the view yet.
|
||||
self.viewTrait.FocusPoint(self.list.GetSelectedLineIdx())
|
||||
if self.RenderSelection {
|
||||
min, max := self.viewTrait.ViewPortYBounds()
|
||||
displayStrings := self.GetDisplayStrings(min, max)
|
||||
content := utils.RenderDisplayStrings(displayStrings)
|
||||
self.viewTrait.SetViewPortContent(content)
|
||||
}
|
||||
self.viewTrait.SetFooter(formatListFooter(self.list.GetSelectedLineIdx(), self.list.GetItemsLength()))
|
||||
}
|
||||
|
||||
|
@ -48,164 +39,29 @@ func formatListFooter(selectedLineIdx int, length int) string {
|
|||
return fmt.Sprintf("%d of %d", selectedLineIdx+1, length)
|
||||
}
|
||||
|
||||
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
|
||||
func (self *ListContextTrait) HandleRender() error {
|
||||
if self.GetDisplayStrings != nil {
|
||||
self.list.RefreshSelectedIdx()
|
||||
content := utils.RenderDisplayStrings(self.GetDisplayStrings(0, self.list.GetItemsLength()))
|
||||
self.viewTrait.SetContent(content)
|
||||
self.c.Render()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleFocusLost() error {
|
||||
if self.OnFocusLost != nil {
|
||||
return self.OnFocusLost()
|
||||
}
|
||||
|
||||
self.viewTrait.SetOriginX(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleFocus(opts ...types.OnFocusOpts) error {
|
||||
self.FocusLine()
|
||||
|
||||
if self.OnFocus != nil {
|
||||
if err := self.OnFocus(opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
return self.Context.HandleFocus(opts...)
|
||||
}
|
||||
|
||||
if self.OnRenderToMain != nil {
|
||||
if err := self.OnRenderToMain(opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
func (self *ListContextTrait) HandleFocusLost() error {
|
||||
self.viewTrait.SetOriginX(0)
|
||||
|
||||
return self.Context.HandleFocus()
|
||||
}
|
||||
|
||||
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
|
||||
func (self *ListContextTrait) HandleRender() error {
|
||||
self.list.RefreshSelectedIdx()
|
||||
content := utils.RenderDisplayStrings(self.getDisplayStrings(0, self.list.GetItemsLength()))
|
||||
self.viewTrait.SetContent(content)
|
||||
self.c.Render()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandlePrevLine() error {
|
||||
return self.handleLineChange(-1)
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleNextLine() error {
|
||||
return self.handleLineChange(1)
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleScrollLeft() error {
|
||||
return self.scroll(self.viewTrait.ScrollLeft)
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleScrollRight() error {
|
||||
return self.scroll(self.viewTrait.ScrollRight)
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) scroll(scrollFunc func()) error {
|
||||
scrollFunc()
|
||||
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) handleLineChange(change int) error {
|
||||
before := self.list.GetSelectedLineIdx()
|
||||
self.list.MoveSelectedLine(change)
|
||||
after := self.list.GetSelectedLineIdx()
|
||||
|
||||
// doing this check so that if we're holding the up key at the start of the list
|
||||
// we're not constantly re-rendering the main view.
|
||||
if before != after {
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandlePrevPage() error {
|
||||
return self.handleLineChange(-self.viewTrait.PageDelta())
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleNextPage() error {
|
||||
return self.handleLineChange(self.viewTrait.PageDelta())
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleGotoTop() error {
|
||||
return self.handleLineChange(-self.list.GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleGotoBottom() error {
|
||||
return self.handleLineChange(self.list.GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleClick(onClick func() error) error {
|
||||
prevSelectedLineIdx := self.list.GetSelectedLineIdx()
|
||||
// because we're handling a click, we need to determine the new line idx based
|
||||
// on the view itself.
|
||||
newSelectedLineIdx := self.viewTrait.SelectedLineIdx()
|
||||
|
||||
currentContextKey := self.c.CurrentContext().GetKey()
|
||||
alreadyFocused := currentContextKey == self.base.GetKey()
|
||||
|
||||
// we need to focus the view
|
||||
if !alreadyFocused {
|
||||
if err := self.takeFocus(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newSelectedLineIdx > self.list.GetItemsLength()-1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.list.SetSelectedLineIdx(newSelectedLineIdx)
|
||||
|
||||
if prevSelectedLineIdx == newSelectedLineIdx && alreadyFocused && onClick != nil {
|
||||
return onClick()
|
||||
}
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) OnSearchSelect(selectedLineIdx int) error {
|
||||
self.list.SetSelectedLineIdx(selectedLineIdx)
|
||||
self.GetList().SetSelectedLineIdx(selectedLineIdx)
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleRenderToMain() error {
|
||||
if self.OnRenderToMain != nil {
|
||||
return self.OnRenderToMain()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) keybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||
return []*types.Binding{
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevPage), Modifier: gocui.ModNone, Handler: self.HandlePrevPage, Description: self.c.Tr.LcPrevPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextPage), Modifier: gocui.ModNone, Handler: self.HandleNextPage, Description: self.c.Tr.LcNextPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoTop), Modifier: gocui.ModNone, Handler: self.HandleGotoTop, Description: self.c.Tr.LcGotoTop},
|
||||
{Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: func() error { return self.HandleClick(nil) }},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: self.HandleScrollLeft},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: self.HandleScrollRight},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.StartSearch),
|
||||
Handler: func() error { self.c.OpenSearch(); return nil },
|
||||
Description: self.c.Tr.LcStartSearch,
|
||||
Tag: "navigation",
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.GotoBottom),
|
||||
Description: self.c.Tr.LcGotoBottom,
|
||||
Handler: self.HandleGotoBottom,
|
||||
Tag: "navigation",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
87
pkg/gui/context/local_commits_context.go
Normal file
87
pkg/gui/context/local_commits_context.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type LocalCommitsContext struct {
|
||||
*LocalCommitsViewModel
|
||||
*ViewportListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*LocalCommitsContext)(nil)
|
||||
|
||||
func NewLocalCommitsContext(
|
||||
getModel func() []*models.Commit,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *LocalCommitsContext {
|
||||
viewModel := NewLocalCommitsViewModel(getModel)
|
||||
|
||||
return &LocalCommitsContext{
|
||||
LocalCommitsViewModel: viewModel,
|
||||
ViewportListContextTrait: &ViewportListContextTrait{
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "commits",
|
||||
WindowName: "commits",
|
||||
Key: BRANCH_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *LocalCommitsContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type LocalCommitsViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.Commit
|
||||
}
|
||||
|
||||
func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel {
|
||||
self := &LocalCommitsViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) GetSelected() *models.Commit {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
108
pkg/gui/context/menu_context.go
Normal file
108
pkg/gui/context/menu_context.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type MenuContext struct {
|
||||
*MenuViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*MenuContext)(nil)
|
||||
|
||||
func NewMenuContext(
|
||||
view *gocui.View,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
getOptionsMap func() map[string]string,
|
||||
) *MenuContext {
|
||||
viewModel := NewMenuViewModel()
|
||||
|
||||
return &MenuContext{
|
||||
MenuViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "menu",
|
||||
Key: "menu",
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
OnGetOptionsMap: getOptionsMap,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
getDisplayStrings: viewModel.GetDisplayStrings,
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove this thing.
|
||||
func (self *MenuContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.DisplayString
|
||||
}
|
||||
|
||||
type MenuViewModel struct {
|
||||
*traits.ListCursor
|
||||
menuItems []*types.MenuItem
|
||||
}
|
||||
|
||||
func NewMenuViewModel() *MenuViewModel {
|
||||
self := &MenuViewModel{
|
||||
menuItems: nil,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *MenuViewModel) GetItemsLength() int {
|
||||
return len(self.menuItems)
|
||||
}
|
||||
|
||||
func (self *MenuViewModel) GetSelected() *types.MenuItem {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.menuItems[self.GetSelectedLineIdx()]
|
||||
}
|
||||
|
||||
func (self *MenuViewModel) SetMenuItems(items []*types.MenuItem) {
|
||||
self.menuItems = items
|
||||
}
|
||||
|
||||
// TODO: move into presentation package
|
||||
func (self *MenuViewModel) GetDisplayStrings(startIdx int, length int) [][]string {
|
||||
stringArrays := make([][]string, len(self.menuItems))
|
||||
for i, item := range self.menuItems {
|
||||
if item.DisplayStrings == nil {
|
||||
styledStr := item.DisplayString
|
||||
if item.OpensMenu {
|
||||
styledStr = presentation.OpensMenuStyle(styledStr)
|
||||
}
|
||||
stringArrays[i] = []string{styledStr}
|
||||
} else {
|
||||
stringArrays[i] = item.DisplayStrings
|
||||
}
|
||||
}
|
||||
|
||||
return stringArrays
|
||||
}
|
86
pkg/gui/context/reflog_commits_context.go
Normal file
86
pkg/gui/context/reflog_commits_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type ReflogCommitsContext struct {
|
||||
*ReflogCommitsViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*ReflogCommitsContext)(nil)
|
||||
|
||||
func NewReflogCommitsContext(
|
||||
getModel func() []*models.Commit,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *ReflogCommitsContext {
|
||||
viewModel := NewReflogCommitsViewModel(getModel)
|
||||
|
||||
return &ReflogCommitsContext{
|
||||
ReflogCommitsViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "commits",
|
||||
WindowName: "commits",
|
||||
Key: REFLOG_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ReflogCommitsContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type ReflogCommitsViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.Commit
|
||||
}
|
||||
|
||||
func NewReflogCommitsViewModel(getModel func() []*models.Commit) *ReflogCommitsViewModel {
|
||||
self := &ReflogCommitsViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *ReflogCommitsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *ReflogCommitsViewModel) GetSelected() *models.Commit {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
86
pkg/gui/context/remote_branches_context.go
Normal file
86
pkg/gui/context/remote_branches_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type RemoteBranchesContext struct {
|
||||
*RemoteBranchesViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*RemoteBranchesContext)(nil)
|
||||
|
||||
func NewRemoteBranchesContext(
|
||||
getModel func() []*models.RemoteBranch,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *RemoteBranchesContext {
|
||||
viewModel := NewRemoteBranchesViewModel(getModel)
|
||||
|
||||
return &RemoteBranchesContext{
|
||||
RemoteBranchesViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: REMOTE_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *RemoteBranchesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type RemoteBranchesViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.RemoteBranch
|
||||
}
|
||||
|
||||
func NewRemoteBranchesViewModel(getModel func() []*models.RemoteBranch) *RemoteBranchesViewModel {
|
||||
self := &RemoteBranchesViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *RemoteBranchesViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *RemoteBranchesViewModel) GetSelected() *models.RemoteBranch {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
86
pkg/gui/context/remotes_context.go
Normal file
86
pkg/gui/context/remotes_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type RemotesContext struct {
|
||||
*RemotesViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*RemotesContext)(nil)
|
||||
|
||||
func NewRemotesContext(
|
||||
getModel func() []*models.Remote,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *RemotesContext {
|
||||
viewModel := NewRemotesViewModel(getModel)
|
||||
|
||||
return &RemotesContext{
|
||||
RemotesViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: REMOTES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *RemotesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type RemotesViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.Remote
|
||||
}
|
||||
|
||||
func NewRemotesViewModel(getModel func() []*models.Remote) *RemotesViewModel {
|
||||
self := &RemotesViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *RemotesViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *RemotesViewModel) GetSelected() *models.Remote {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package gui
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
|
@ -12,10 +11,10 @@ type SimpleContext struct {
|
|||
// this is for pushing some content to the main view
|
||||
OnRenderToMain func(opts ...types.OnFocusOpts) error
|
||||
|
||||
*context.BaseContext
|
||||
*BaseContext
|
||||
}
|
||||
|
||||
type NewSimpleContextOpts struct {
|
||||
type ContextCallbackOpts struct {
|
||||
OnFocus func(opts ...types.OnFocusOpts) error
|
||||
OnFocusLost func() error
|
||||
OnRender func() error
|
||||
|
@ -23,7 +22,7 @@ type NewSimpleContextOpts struct {
|
|||
OnRenderToMain func(opts ...types.OnFocusOpts) error
|
||||
}
|
||||
|
||||
func NewSimpleContext(baseContext *context.BaseContext, opts NewSimpleContextOpts) *SimpleContext {
|
||||
func NewSimpleContext(baseContext *BaseContext, opts ContextCallbackOpts) *SimpleContext {
|
||||
return &SimpleContext{
|
||||
OnFocus: opts.OnFocus,
|
||||
OnFocusLost: opts.OnFocusLost,
|
||||
|
@ -35,13 +34,6 @@ func NewSimpleContext(baseContext *context.BaseContext, opts NewSimpleContextOpt
|
|||
|
||||
var _ types.Context = &SimpleContext{}
|
||||
|
||||
func (self *SimpleContext) HandleRender() error {
|
||||
if self.OnRender != nil {
|
||||
return self.OnRender()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SimpleContext) HandleFocus(opts ...types.OnFocusOpts) error {
|
||||
if self.OnFocus != nil {
|
||||
if err := self.OnFocus(opts...); err != nil {
|
||||
|
@ -65,6 +57,13 @@ func (self *SimpleContext) HandleFocusLost() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (self *SimpleContext) HandleRender() error {
|
||||
if self.OnRender != nil {
|
||||
return self.OnRender()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SimpleContext) HandleRenderToMain() error {
|
||||
if self.OnRenderToMain != nil {
|
||||
return self.OnRenderToMain()
|
86
pkg/gui/context/stash_context.go
Normal file
86
pkg/gui/context/stash_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type StashContext struct {
|
||||
*StashViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*StashContext)(nil)
|
||||
|
||||
func NewStashContext(
|
||||
getModel func() []*models.StashEntry,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *StashContext {
|
||||
viewModel := NewStashViewModel(getModel)
|
||||
|
||||
return &StashContext{
|
||||
StashViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "stash",
|
||||
WindowName: "stash",
|
||||
Key: STASH_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StashContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type StashViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.StashEntry
|
||||
}
|
||||
|
||||
func NewStashViewModel(getModel func() []*models.StashEntry) *StashViewModel {
|
||||
self := &StashViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *StashViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *StashViewModel) GetSelected() *models.StashEntry {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
87
pkg/gui/context/sub_commits_context.go
Normal file
87
pkg/gui/context/sub_commits_context.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type SubCommitsContext struct {
|
||||
*SubCommitsViewModel
|
||||
*ViewportListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*SubCommitsContext)(nil)
|
||||
|
||||
func NewSubCommitsContext(
|
||||
getModel func() []*models.Commit,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *SubCommitsContext {
|
||||
viewModel := NewSubCommitsViewModel(getModel)
|
||||
|
||||
return &SubCommitsContext{
|
||||
SubCommitsViewModel: viewModel,
|
||||
ViewportListContextTrait: &ViewportListContextTrait{
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: SUB_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SubCommitsContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type SubCommitsViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.Commit
|
||||
}
|
||||
|
||||
func NewSubCommitsViewModel(getModel func() []*models.Commit) *SubCommitsViewModel {
|
||||
self := &SubCommitsViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *SubCommitsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *SubCommitsViewModel) GetSelected() *models.Commit {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
86
pkg/gui/context/submodules_context.go
Normal file
86
pkg/gui/context/submodules_context.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type SubmodulesContext struct {
|
||||
*SubmodulesViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*SubmodulesContext)(nil)
|
||||
|
||||
func NewSubmodulesContext(
|
||||
getModel func() []*models.SubmoduleConfig,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *SubmodulesContext {
|
||||
viewModel := NewSubmodulesViewModel(getModel)
|
||||
|
||||
return &SubmodulesContext{
|
||||
SubmodulesViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "files",
|
||||
WindowName: "files",
|
||||
Key: SUBMODULES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SubmodulesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
type SubmodulesViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*models.SubmoduleConfig
|
||||
}
|
||||
|
||||
func NewSubmodulesViewModel(getModel func() []*models.SubmoduleConfig) *SubmodulesViewModel {
|
||||
self := &SubmodulesViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *SubmodulesViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *SubmodulesViewModel) GetSelected() *models.SubmoduleConfig {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
85
pkg/gui/context/suggestions_context.go
Normal file
85
pkg/gui/context/suggestions_context.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type SuggestionsContext struct {
|
||||
*SuggestionsViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*SuggestionsContext)(nil)
|
||||
|
||||
func NewSuggestionsContext(
|
||||
getModel func() []*types.Suggestion,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
) *SuggestionsContext {
|
||||
viewModel := NewSuggestionsViewModel(getModel)
|
||||
|
||||
return &SuggestionsContext{
|
||||
SuggestionsViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "suggestions",
|
||||
WindowName: "suggestions",
|
||||
Key: SUGGESTIONS_CONTEXT_KEY,
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
Focusable: true,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnFocusLost: onFocusLost,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SuggestionsContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.Value
|
||||
}
|
||||
|
||||
type SuggestionsViewModel struct {
|
||||
*traits.ListCursor
|
||||
getModel func() []*types.Suggestion
|
||||
}
|
||||
|
||||
func NewSuggestionsViewModel(getModel func() []*types.Suggestion) *SuggestionsViewModel {
|
||||
self := &SuggestionsViewModel{
|
||||
getModel: getModel,
|
||||
}
|
||||
|
||||
self.ListCursor = traits.NewListCursor(self)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *SuggestionsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *SuggestionsViewModel) GetSelected() *types.Suggestion {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
type TagsContext struct {
|
||||
*TagsViewModel
|
||||
*BaseContext
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
|
@ -17,7 +16,7 @@ var _ types.IListContext = (*TagsContext)(nil)
|
|||
|
||||
func NewTagsContext(
|
||||
getModel func() []*models.Tag,
|
||||
getView func() *gocui.View,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
|
@ -26,47 +25,32 @@ func NewTagsContext(
|
|||
|
||||
c *types.ControllerCommon,
|
||||
) *TagsContext {
|
||||
baseContext := NewBaseContext(NewBaseContextOpts{
|
||||
viewModel := NewTagsViewModel(getModel)
|
||||
|
||||
return &TagsContext{
|
||||
TagsViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: TAGS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &TagsContext{}
|
||||
takeFocus := func() error { return c.PushContext(self) }
|
||||
|
||||
list := NewTagsViewModel(getModel)
|
||||
viewTrait := NewViewTrait(getView)
|
||||
listContextTrait := &ListContextTrait{
|
||||
base: baseContext,
|
||||
list: list,
|
||||
viewTrait: viewTrait,
|
||||
|
||||
GetDisplayStrings: getDisplayStrings,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
OnFocusLost: onFocusLost,
|
||||
takeFocus: takeFocus,
|
||||
|
||||
// TODO: handle this in a trait
|
||||
RenderSelection: false,
|
||||
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
|
||||
baseContext.AddKeybindingsFn(listContextTrait.keybindings)
|
||||
|
||||
self.BaseContext = baseContext
|
||||
self.ListContextTrait = listContextTrait
|
||||
self.TagsViewModel = list
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *TagsContext) GetSelectedItemId() string {
|
||||
item := self.GetSelectedTag()
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -79,18 +63,6 @@ type TagsViewModel struct {
|
|||
getModel func() []*models.Tag
|
||||
}
|
||||
|
||||
func (self *TagsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *TagsViewModel) GetSelectedTag() *models.Tag {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
||||
|
||||
func NewTagsViewModel(getModel func() []*models.Tag) *TagsViewModel {
|
||||
self := &TagsViewModel{
|
||||
getModel: getModel,
|
||||
|
@ -100,3 +72,15 @@ func NewTagsViewModel(getModel func() []*models.Tag) *TagsViewModel {
|
|||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *TagsViewModel) GetItemsLength() int {
|
||||
return len(self.getModel())
|
||||
}
|
||||
|
||||
func (self *TagsViewModel) GetSelected() *models.Tag {
|
||||
if self.GetItemsLength() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.getModel()[self.GetSelectedLineIdx()]
|
||||
}
|
||||
|
|
|
@ -2,70 +2,62 @@ package context
|
|||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
const HORIZONTAL_SCROLL_FACTOR = 3
|
||||
|
||||
type ViewTrait struct {
|
||||
getView func() *gocui.View
|
||||
view *gocui.View
|
||||
}
|
||||
|
||||
func NewViewTrait(getView func() *gocui.View) *ViewTrait {
|
||||
return &ViewTrait{getView: getView}
|
||||
var _ types.IViewTrait = &ViewTrait{}
|
||||
|
||||
func NewViewTrait(view *gocui.View) *ViewTrait {
|
||||
return &ViewTrait{view: view}
|
||||
}
|
||||
|
||||
func (self *ViewTrait) FocusPoint(yIdx int) {
|
||||
view := self.getView()
|
||||
view.FocusPoint(view.OriginX(), yIdx)
|
||||
self.view.FocusPoint(self.view.OriginX(), yIdx)
|
||||
}
|
||||
|
||||
func (self *ViewTrait) SetViewPortContent(content string) {
|
||||
view := self.getView()
|
||||
|
||||
_, y := view.Origin()
|
||||
view.OverwriteLines(y, content)
|
||||
_, y := self.view.Origin()
|
||||
self.view.OverwriteLines(y, content)
|
||||
}
|
||||
|
||||
func (self *ViewTrait) SetContent(content string) {
|
||||
self.getView().SetContent(content)
|
||||
self.view.SetContent(content)
|
||||
}
|
||||
|
||||
func (self *ViewTrait) SetFooter(value string) {
|
||||
self.getView().Footer = value
|
||||
self.view.Footer = value
|
||||
}
|
||||
|
||||
func (self *ViewTrait) SetOriginX(value int) {
|
||||
_ = self.getView().SetOriginX(value)
|
||||
_ = self.view.SetOriginX(value)
|
||||
}
|
||||
|
||||
// tells us the bounds of line indexes shown in the view currently
|
||||
func (self *ViewTrait) ViewPortYBounds() (int, int) {
|
||||
view := self.getView()
|
||||
|
||||
_, min := view.Origin()
|
||||
max := view.InnerHeight() + 1
|
||||
_, min := self.view.Origin()
|
||||
max := self.view.InnerHeight() + 1
|
||||
return min, max
|
||||
}
|
||||
|
||||
func (self *ViewTrait) ScrollLeft() {
|
||||
view := self.getView()
|
||||
|
||||
newOriginX := utils.Max(view.OriginX()-view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR, 0)
|
||||
_ = view.SetOriginX(newOriginX)
|
||||
newOriginX := utils.Max(self.view.OriginX()-self.view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR, 0)
|
||||
_ = self.view.SetOriginX(newOriginX)
|
||||
}
|
||||
|
||||
func (self *ViewTrait) ScrollRight() {
|
||||
view := self.getView()
|
||||
|
||||
_ = view.SetOriginX(view.OriginX() + view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR)
|
||||
_ = self.view.SetOriginX(self.view.OriginX() + self.view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR)
|
||||
}
|
||||
|
||||
// this returns the amount we'll scroll if we want to scroll by a page.
|
||||
func (self *ViewTrait) PageDelta() int {
|
||||
view := self.getView()
|
||||
|
||||
_, height := view.Size()
|
||||
_, height := self.view.Size()
|
||||
|
||||
delta := height - 1
|
||||
if delta == 0 {
|
||||
|
@ -76,5 +68,5 @@ func (self *ViewTrait) PageDelta() int {
|
|||
}
|
||||
|
||||
func (self *ViewTrait) SelectedLineIdx() int {
|
||||
return self.getView().SelectedLineIdx()
|
||||
return self.view.SelectedLineIdx()
|
||||
}
|
||||
|
|
22
pkg/gui/context/viewport_list_context_trait.go
Normal file
22
pkg/gui/context/viewport_list_context_trait.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// This embeds a list context trait and adds logic to re-render the viewport
|
||||
// whenever a line is focused. We use this in the commits panel because different
|
||||
// sections of the log graph need to be highlighted depending on the currently selected line
|
||||
|
||||
type ViewportListContextTrait struct {
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
func (self *ViewportListContextTrait) FocusLine() {
|
||||
self.ListContextTrait.FocusLine()
|
||||
|
||||
min, max := self.GetViewTrait().ViewPortYBounds()
|
||||
displayStrings := self.ListContextTrait.getDisplayStrings(min, max)
|
||||
content := utils.RenderDisplayStrings(displayStrings)
|
||||
self.GetViewTrait().SetViewPortContent(content)
|
||||
}
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
type WorkingTreeContext struct {
|
||||
*filetree.FileTreeViewModel
|
||||
*BaseContext
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
|
@ -17,7 +16,7 @@ var _ types.IListContext = (*WorkingTreeContext)(nil)
|
|||
|
||||
func NewWorkingTreeContext(
|
||||
getModel func() []*models.File,
|
||||
getView func() *gocui.View,
|
||||
view *gocui.View,
|
||||
getDisplayStrings func(startIdx int, length int) [][]string,
|
||||
|
||||
onFocus func(...types.OnFocusOpts) error,
|
||||
|
@ -26,43 +25,28 @@ func NewWorkingTreeContext(
|
|||
|
||||
c *types.ControllerCommon,
|
||||
) *WorkingTreeContext {
|
||||
baseContext := NewBaseContext(NewBaseContextOpts{
|
||||
viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
|
||||
return &WorkingTreeContext{
|
||||
FileTreeViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
ViewName: "files",
|
||||
WindowName: "files",
|
||||
Key: FILES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &WorkingTreeContext{}
|
||||
takeFocus := func() error { return c.PushContext(self) }
|
||||
|
||||
viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
viewTrait := NewViewTrait(getView)
|
||||
listContextTrait := &ListContextTrait{
|
||||
base: baseContext,
|
||||
list: viewModel,
|
||||
viewTrait: viewTrait,
|
||||
|
||||
GetDisplayStrings: getDisplayStrings,
|
||||
}), ContextCallbackOpts{
|
||||
OnFocus: onFocus,
|
||||
OnRenderToMain: onRenderToMain,
|
||||
OnFocusLost: onFocusLost,
|
||||
takeFocus: takeFocus,
|
||||
|
||||
// TODO: handle this in a trait
|
||||
RenderSelection: false,
|
||||
|
||||
OnRenderToMain: onRenderToMain,
|
||||
}),
|
||||
list: viewModel,
|
||||
viewTrait: NewViewTrait(view),
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
|
||||
baseContext.AddKeybindingsFn(listContextTrait.keybindings)
|
||||
|
||||
self.BaseContext = baseContext
|
||||
self.ListContextTrait = listContextTrait
|
||||
self.FileTreeViewModel = viewModel
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *WorkingTreeContext) GetSelectedItemId() string {
|
||||
|
|
|
@ -35,7 +35,7 @@ func (gui *Gui) allContexts2() []types.Context {
|
|||
|
||||
func (gui *Gui) contextTree() *context.ContextTree {
|
||||
return &context.ContextTree{
|
||||
Global: NewSimpleContext(
|
||||
Global: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.GLOBAL_CONTEXT,
|
||||
ViewName: "",
|
||||
|
@ -43,11 +43,11 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.GLOBAL_CONTEXT_KEY,
|
||||
Focusable: false,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain),
|
||||
},
|
||||
),
|
||||
Status: NewSimpleContext(
|
||||
Status: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
ViewName: "status",
|
||||
|
@ -55,7 +55,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.STATUS_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain),
|
||||
},
|
||||
),
|
||||
|
@ -72,7 +72,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Tags: gui.tagsListContext(),
|
||||
Stash: gui.stashListContext(),
|
||||
Suggestions: gui.suggestionsListContext(),
|
||||
Normal: NewSimpleContext(
|
||||
Normal: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
ViewName: "main",
|
||||
|
@ -80,13 +80,13 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.MAIN_NORMAL_CONTEXT_KEY,
|
||||
Focusable: false,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
return nil // TODO: should we do something here? We should allow for scrolling the panel
|
||||
},
|
||||
},
|
||||
),
|
||||
Staging: NewSimpleContext(
|
||||
Staging: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
ViewName: "main",
|
||||
|
@ -94,7 +94,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.MAIN_STAGING_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
forceSecondaryFocused := false
|
||||
selectedLineIdx := -1
|
||||
|
@ -110,7 +110,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
},
|
||||
},
|
||||
),
|
||||
PatchBuilding: NewSimpleContext(
|
||||
PatchBuilding: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
ViewName: "main",
|
||||
|
@ -118,7 +118,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.MAIN_PATCH_BUILDING_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
selectedLineIdx := -1
|
||||
if len(opts) > 0 && (opts[0].ClickedViewName == "main" || opts[0].ClickedViewName == "secondary") {
|
||||
|
@ -129,7 +129,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
},
|
||||
},
|
||||
),
|
||||
Merging: NewSimpleContext(
|
||||
Merging: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.MAIN_CONTEXT,
|
||||
ViewName: "main",
|
||||
|
@ -138,11 +138,11 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
OnGetOptionsMap: gui.getMergingOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: OnFocusWrapper(func() error { return gui.renderConflictsWithLock(true) }),
|
||||
},
|
||||
),
|
||||
Credentials: NewSimpleContext(
|
||||
Credentials: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
ViewName: "credentials",
|
||||
|
@ -150,11 +150,11 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.CREDENTIALS_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleAskFocused),
|
||||
},
|
||||
),
|
||||
Confirmation: NewSimpleContext(
|
||||
Confirmation: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.TEMPORARY_POPUP,
|
||||
ViewName: "confirmation",
|
||||
|
@ -162,11 +162,11 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.CONFIRMATION_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleAskFocused),
|
||||
},
|
||||
),
|
||||
CommitMessage: NewSimpleContext(
|
||||
CommitMessage: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
ViewName: "commitMessage",
|
||||
|
@ -174,11 +174,11 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.COMMIT_MESSAGE_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleCommitMessageFocused),
|
||||
},
|
||||
),
|
||||
Search: NewSimpleContext(
|
||||
Search: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
ViewName: "search",
|
||||
|
@ -186,9 +186,9 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
Key: context.SEARCH_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{},
|
||||
context.ContextCallbackOpts{},
|
||||
),
|
||||
CommandLog: NewSimpleContext(
|
||||
CommandLog: context.NewSimpleContext(
|
||||
context.NewBaseContext(context.NewBaseContextOpts{
|
||||
Kind: types.EXTRAS_CONTEXT,
|
||||
ViewName: "extras",
|
||||
|
@ -197,7 +197,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||
OnGetOptionsMap: gui.getMergingOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
context.ContextCallbackOpts{
|
||||
OnFocusLost: func() error {
|
||||
gui.Views.Extras.Autoscroll = true
|
||||
return nil
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
|
@ -14,11 +15,10 @@ type BisectController struct {
|
|||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context types.IListContext
|
||||
context *context.LocalCommitsContext
|
||||
git *commands.GitCommand
|
||||
bisectHelper *BisectHelper
|
||||
|
||||
getSelectedLocalCommit func() *models.Commit
|
||||
getCommits func() []*models.Commit
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,10 @@ var _ types.IController = &BisectController{}
|
|||
|
||||
func NewBisectController(
|
||||
c *types.ControllerCommon,
|
||||
context types.IListContext,
|
||||
context *context.LocalCommitsContext,
|
||||
git *commands.GitCommand,
|
||||
bisectHelper *BisectHelper,
|
||||
|
||||
getSelectedLocalCommit func() *models.Commit,
|
||||
getCommits func() []*models.Commit,
|
||||
) *BisectController {
|
||||
return &BisectController{
|
||||
|
@ -40,7 +39,6 @@ func NewBisectController(
|
|||
git: git,
|
||||
bisectHelper: bisectHelper,
|
||||
|
||||
getSelectedLocalCommit: getSelectedLocalCommit,
|
||||
getCommits: getCommits,
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +232,7 @@ func (self *BisectController) selectCurrentBisectCommit() {
|
|||
// find index of commit with that sha, move cursor to that.
|
||||
for i, commit := range self.getCommits() {
|
||||
if commit.Sha == info.GetCurrentSha() {
|
||||
self.context.GetPanelState().SetSelectedLineIdx(i)
|
||||
self.context.SetSelectedLineIdx(i)
|
||||
_ = self.context.HandleFocus()
|
||||
break
|
||||
}
|
||||
|
@ -244,7 +242,7 @@ func (self *BisectController) selectCurrentBisectCommit() {
|
|||
|
||||
func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error {
|
||||
return func() error {
|
||||
commit := self.getSelectedLocalCommit()
|
||||
commit := self.context.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -94,10 +94,10 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||
Handler: self.checkSelectedFileNode(self.press),
|
||||
Description: self.c.Tr.LcToggleStaged,
|
||||
},
|
||||
{
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func() error { return self.context.HandleClick(self.checkSelectedFileNode(self.press)) },
|
||||
},
|
||||
// {
|
||||
// Key: gocui.MouseLeft,
|
||||
// Handler: func() error { return self.context.HandleClick(self.checkSelectedFileNode(self.press)) },
|
||||
// },
|
||||
{
|
||||
Key: opts.GetKey("<c-b>"), // TODO: softcode
|
||||
Handler: self.handleStatusFilterPressed,
|
||||
|
|
144
pkg/gui/controllers/list_controller.go
Normal file
144
pkg/gui/controllers/list_controller.go
Normal file
|
@ -0,0 +1,144 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type ListControllerFactory struct {
|
||||
c *types.ControllerCommon
|
||||
}
|
||||
|
||||
func NewListControllerFactory(c *types.ControllerCommon) *ListControllerFactory {
|
||||
return &ListControllerFactory{
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ListControllerFactory) Create(context types.IListContext) *ListController {
|
||||
return &ListController{
|
||||
baseController: baseController{},
|
||||
c: self.c,
|
||||
context: context,
|
||||
}
|
||||
}
|
||||
|
||||
type ListController struct {
|
||||
baseController
|
||||
c *types.ControllerCommon
|
||||
|
||||
context types.IListContext
|
||||
}
|
||||
|
||||
func (self *ListController) Context() types.Context {
|
||||
return self.context
|
||||
}
|
||||
|
||||
func (self *ListController) HandlePrevLine() error {
|
||||
return self.handleLineChange(-1)
|
||||
}
|
||||
|
||||
func (self *ListController) HandleNextLine() error {
|
||||
return self.handleLineChange(1)
|
||||
}
|
||||
|
||||
func (self *ListController) HandleScrollLeft() error {
|
||||
return self.scroll(self.context.GetViewTrait().ScrollLeft)
|
||||
}
|
||||
|
||||
func (self *ListController) HandleScrollRight() error {
|
||||
return self.scroll(self.context.GetViewTrait().ScrollRight)
|
||||
}
|
||||
|
||||
func (self *ListController) scroll(scrollFunc func()) error {
|
||||
scrollFunc()
|
||||
|
||||
return self.context.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListController) handleLineChange(change int) error {
|
||||
before := self.context.GetList().GetSelectedLineIdx()
|
||||
self.context.GetList().MoveSelectedLine(change)
|
||||
after := self.context.GetList().GetSelectedLineIdx()
|
||||
|
||||
// doing this check so that if we're holding the up key at the start of the list
|
||||
// we're not constantly re-rendering the main view.
|
||||
if before != after {
|
||||
return self.context.HandleFocus()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListController) HandlePrevPage() error {
|
||||
return self.handleLineChange(-self.context.GetViewTrait().PageDelta())
|
||||
}
|
||||
|
||||
func (self *ListController) HandleNextPage() error {
|
||||
return self.handleLineChange(self.context.GetViewTrait().PageDelta())
|
||||
}
|
||||
|
||||
func (self *ListController) HandleGotoTop() error {
|
||||
return self.handleLineChange(-self.context.GetList().GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListController) HandleGotoBottom() error {
|
||||
return self.handleLineChange(self.context.GetList().GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListController) HandleClick(onClick func() error) error {
|
||||
prevSelectedLineIdx := self.context.GetList().GetSelectedLineIdx()
|
||||
// because we're handling a click, we need to determine the new line idx based
|
||||
// on the view itself.
|
||||
newSelectedLineIdx := self.context.GetViewTrait().SelectedLineIdx()
|
||||
|
||||
currentContextKey := self.c.CurrentContext().GetKey()
|
||||
alreadyFocused := currentContextKey == self.context.GetKey()
|
||||
|
||||
// we need to focus the view
|
||||
if !alreadyFocused {
|
||||
if err := self.c.PushContext(self.context); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newSelectedLineIdx > self.context.GetList().GetItemsLength()-1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.context.GetList().SetSelectedLineIdx(newSelectedLineIdx)
|
||||
|
||||
if prevSelectedLineIdx == newSelectedLineIdx && alreadyFocused && onClick != nil {
|
||||
return onClick()
|
||||
}
|
||||
return self.context.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||
return []*types.Binding{
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevPage), Modifier: gocui.ModNone, Handler: self.HandlePrevPage, Description: self.c.Tr.LcPrevPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextPage), Modifier: gocui.ModNone, Handler: self.HandleNextPage, Description: self.c.Tr.LcNextPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoTop), Modifier: gocui.ModNone, Handler: self.HandleGotoTop, Description: self.c.Tr.LcGotoTop},
|
||||
{Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: func() error { return self.HandleClick(nil) }},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: self.HandleScrollLeft},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: self.HandleScrollRight},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.StartSearch),
|
||||
Handler: func() error { self.c.OpenSearch(); return nil },
|
||||
Description: self.c.Tr.LcStartSearch,
|
||||
Tag: "navigation",
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.GotoBottom),
|
||||
Description: self.c.Tr.LcGotoBottom,
|
||||
Handler: self.HandleGotoBottom,
|
||||
Tag: "navigation",
|
||||
},
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
@ -24,7 +25,7 @@ type (
|
|||
type LocalCommitsController struct {
|
||||
baseController
|
||||
c *types.ControllerCommon
|
||||
context types.IListContext
|
||||
context *context.LocalCommitsContext
|
||||
os *oscommands.OSCommand
|
||||
git *commands.GitCommand
|
||||
tagsHelper *TagsHelper
|
||||
|
@ -32,9 +33,7 @@ type LocalCommitsController struct {
|
|||
cherryPickHelper *CherryPickHelper
|
||||
rebaseHelper *RebaseHelper
|
||||
|
||||
getSelectedLocalCommit func() *models.Commit
|
||||
model *types.Model
|
||||
getSelectedLocalCommitIdx func() int
|
||||
CheckMergeOrRebase CheckMergeOrRebase
|
||||
pullFiles PullFilesFn
|
||||
getHostingServiceMgr GetHostingServiceMgrFn
|
||||
|
@ -49,16 +48,14 @@ var _ types.IController = &LocalCommitsController{}
|
|||
|
||||
func NewLocalCommitsController(
|
||||
c *types.ControllerCommon,
|
||||
context types.IListContext,
|
||||
context *context.LocalCommitsContext,
|
||||
os *oscommands.OSCommand,
|
||||
git *commands.GitCommand,
|
||||
tagsHelper *TagsHelper,
|
||||
refsHelper IRefsHelper,
|
||||
cherryPickHelper *CherryPickHelper,
|
||||
rebaseHelper *RebaseHelper,
|
||||
getSelectedLocalCommit func() *models.Commit,
|
||||
model *types.Model,
|
||||
getSelectedLocalCommitIdx func() int,
|
||||
CheckMergeOrRebase CheckMergeOrRebase,
|
||||
pullFiles PullFilesFn,
|
||||
getHostingServiceMgr GetHostingServiceMgrFn,
|
||||
|
@ -78,9 +75,7 @@ func NewLocalCommitsController(
|
|||
refsHelper: refsHelper,
|
||||
cherryPickHelper: cherryPickHelper,
|
||||
rebaseHelper: rebaseHelper,
|
||||
getSelectedLocalCommit: getSelectedLocalCommit,
|
||||
model: model,
|
||||
getSelectedLocalCommitIdx: getSelectedLocalCommitIdx,
|
||||
CheckMergeOrRebase: CheckMergeOrRebase,
|
||||
pullFiles: pullFiles,
|
||||
getHostingServiceMgr: getHostingServiceMgr,
|
||||
|
@ -194,10 +189,10 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||
Description: self.c.Tr.LcGotoBottom,
|
||||
Tag: "navigation",
|
||||
},
|
||||
{
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
},
|
||||
// {
|
||||
// Key: gocui.MouseLeft,
|
||||
// Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
// },
|
||||
}
|
||||
|
||||
for _, binding := range outsideFilterModeBindings {
|
||||
|
@ -316,7 +311,7 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error {
|
|||
InitialContent: message,
|
||||
HandleConfirm: func(response string) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.RewordCommit)
|
||||
if err := self.git.Rebase.RewordCommit(self.model.Commits, self.getSelectedLocalCommitIdx(), response); err != nil {
|
||||
if err := self.git.Rebase.RewordCommit(self.model.Commits, self.context.GetSelectedLineIdx(), response); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
|
||||
|
@ -336,7 +331,7 @@ func (self *LocalCommitsController) rewordEditor() error {
|
|||
|
||||
self.c.LogAction(self.c.Tr.Actions.RewordCommit)
|
||||
subProcess, err := self.git.Rebase.RewordCommitInEditor(
|
||||
self.model.Commits, self.getSelectedLocalCommitIdx(),
|
||||
self.model.Commits, self.context.GetSelectedLineIdx(),
|
||||
)
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
|
@ -399,7 +394,7 @@ func (self *LocalCommitsController) pick() error {
|
|||
}
|
||||
|
||||
func (self *LocalCommitsController) interactiveRebase(action string) error {
|
||||
err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.getSelectedLocalCommitIdx(), action)
|
||||
err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context.GetSelectedLineIdx(), action)
|
||||
return self.CheckMergeOrRebase(err)
|
||||
}
|
||||
|
||||
|
@ -407,7 +402,7 @@ func (self *LocalCommitsController) interactiveRebase(action string) error {
|
|||
// commit meaning you are trying to edit the todo file rather than actually
|
||||
// begin a rebase. It then updates the todo file with that action
|
||||
func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, error) {
|
||||
selectedCommit := self.getSelectedLocalCommit()
|
||||
selectedCommit := self.context.GetSelected()
|
||||
if selectedCommit.Status != "rebasing" {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -427,7 +422,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
|
|||
)
|
||||
|
||||
if err := self.git.Rebase.EditRebaseTodo(
|
||||
self.getSelectedLocalCommitIdx(), action,
|
||||
self.context.GetSelectedLineIdx(), action,
|
||||
); err != nil {
|
||||
return false, self.c.Error(err)
|
||||
}
|
||||
|
@ -438,7 +433,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
|
|||
}
|
||||
|
||||
func (self *LocalCommitsController) handleCommitMoveDown() error {
|
||||
index := self.context.GetPanelState().GetSelectedLineIdx()
|
||||
index := self.context.GetSelectedLineIdx()
|
||||
commits := self.model.Commits
|
||||
selectedCommit := self.model.Commits[index]
|
||||
if selectedCommit.Status == "rebasing" {
|
||||
|
@ -454,8 +449,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
|
|||
if err := self.git.Rebase.MoveTodoDown(index); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
// TODO: use MoveSelectedLine
|
||||
_ = self.context.HandleNextLine()
|
||||
self.context.MoveSelectedLine(1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
|
||||
})
|
||||
|
@ -465,8 +459,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
|
|||
self.c.LogAction(self.c.Tr.Actions.MoveCommitDown)
|
||||
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index)
|
||||
if err == nil {
|
||||
// TODO: use MoveSelectedLine
|
||||
_ = self.context.HandleNextLine()
|
||||
self.context.MoveSelectedLine(1)
|
||||
}
|
||||
return self.CheckMergeOrRebase(err)
|
||||
})
|
||||
|
@ -491,7 +484,7 @@ func (self *LocalCommitsController) handleCommitMoveUp() error {
|
|||
if err := self.git.Rebase.MoveTodoDown(index - 1); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
_ = self.context.HandlePrevLine()
|
||||
self.context.MoveSelectedLine(-1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
|
||||
})
|
||||
|
@ -501,7 +494,7 @@ func (self *LocalCommitsController) handleCommitMoveUp() error {
|
|||
self.c.LogAction(self.c.Tr.Actions.MoveCommitUp)
|
||||
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index-1)
|
||||
if err == nil {
|
||||
_ = self.context.HandlePrevLine()
|
||||
self.context.MoveSelectedLine(-1)
|
||||
}
|
||||
return self.CheckMergeOrRebase(err)
|
||||
})
|
||||
|
@ -514,7 +507,7 @@ func (self *LocalCommitsController) handleCommitAmendTo() error {
|
|||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.AmendCommit)
|
||||
err := self.git.Rebase.AmendTo(self.getSelectedLocalCommit().Sha)
|
||||
err := self.git.Rebase.AmendTo(self.context.GetSelected().Sha)
|
||||
return self.CheckMergeOrRebase(err)
|
||||
})
|
||||
},
|
||||
|
@ -569,7 +562,7 @@ func (self *LocalCommitsController) createRevertMergeCommitMenu(commit *models.C
|
|||
}
|
||||
|
||||
func (self *LocalCommitsController) afterRevertCommit() error {
|
||||
_ = self.context.HandleNextLine()
|
||||
self.context.MoveSelectedLine(1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
Mode: types.BLOCK_UI, Scope: []types.RefreshableView{types.COMMITS, types.BRANCHES},
|
||||
})
|
||||
|
@ -669,7 +662,7 @@ func (self *LocalCommitsController) gotoBottom() error {
|
|||
}
|
||||
}
|
||||
|
||||
_ = self.context.HandleGotoBottom()
|
||||
self.context.SetSelectedLineIdx(self.context.GetItemsLength() - 1)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -791,7 +784,7 @@ func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Com
|
|||
|
||||
func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) error) func() error {
|
||||
return func() error {
|
||||
commit := self.getSelectedLocalCommit()
|
||||
commit := self.context.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -813,7 +806,7 @@ func (self *LocalCommitsController) copy(commit *models.Commit) error {
|
|||
}
|
||||
|
||||
func (self *LocalCommitsController) copyRange(*models.Commit) error {
|
||||
return self.cherryPickHelper.CopyRange(self.context.GetPanelState().GetSelectedLineIdx(), self.model.Commits, self.context)
|
||||
return self.cherryPickHelper.CopyRange(self.context.GetSelectedLineIdx(), self.model.Commits, self.context)
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) paste() error {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
|
@ -9,24 +9,20 @@ type MenuController struct {
|
|||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context types.IListContext
|
||||
|
||||
getSelectedMenuItem func() *types.MenuItem
|
||||
context *context.MenuContext
|
||||
}
|
||||
|
||||
var _ types.IController = &MenuController{}
|
||||
|
||||
func NewMenuController(
|
||||
c *types.ControllerCommon,
|
||||
context types.IListContext,
|
||||
getSelectedMenuItem func() *types.MenuItem,
|
||||
context *context.MenuContext,
|
||||
) *MenuController {
|
||||
return &MenuController{
|
||||
baseController: baseController{},
|
||||
|
||||
c: c,
|
||||
context: context,
|
||||
getSelectedMenuItem: getSelectedMenuItem,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,17 +40,17 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||
Key: opts.GetKey(opts.Config.Universal.ConfirmAlt1),
|
||||
Handler: self.press,
|
||||
},
|
||||
{
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func() error { return self.context.HandleClick(self.press) },
|
||||
},
|
||||
// {
|
||||
// Key: gocui.MouseLeft,
|
||||
// Handler: func() error { return self.context.HandleClick(self.press) },
|
||||
// },
|
||||
}
|
||||
|
||||
return bindings
|
||||
}
|
||||
|
||||
func (self *MenuController) press() error {
|
||||
selectedItem := self.getSelectedMenuItem()
|
||||
selectedItem := self.context.GetSelected()
|
||||
|
||||
if err := self.c.PopContext(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
|
@ -13,10 +12,9 @@ type RemotesController struct {
|
|||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context types.IListContext
|
||||
context *context.RemotesContext
|
||||
git *commands.GitCommand
|
||||
|
||||
getSelectedRemote func() *models.Remote
|
||||
setRemoteBranches func([]*models.RemoteBranch)
|
||||
contexts *context.ContextTree
|
||||
}
|
||||
|
@ -25,10 +23,9 @@ var _ types.IController = &RemotesController{}
|
|||
|
||||
func NewRemotesController(
|
||||
c *types.ControllerCommon,
|
||||
context types.IListContext,
|
||||
context *context.RemotesContext,
|
||||
git *commands.GitCommand,
|
||||
contexts *context.ContextTree,
|
||||
getSelectedRemote func() *models.Remote,
|
||||
setRemoteBranches func([]*models.RemoteBranch),
|
||||
) *RemotesController {
|
||||
return &RemotesController{
|
||||
|
@ -37,7 +34,6 @@ func NewRemotesController(
|
|||
git: git,
|
||||
contexts: contexts,
|
||||
context: context,
|
||||
getSelectedRemote: getSelectedRemote,
|
||||
setRemoteBranches: setRemoteBranches,
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +44,10 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||
Handler: self.checkSelected(self.enter),
|
||||
},
|
||||
{
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
},
|
||||
// {
|
||||
// Key: gocui.MouseLeft,
|
||||
// Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
// },
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.FetchRemote),
|
||||
Handler: self.checkSelected(self.fetch),
|
||||
|
@ -183,7 +179,7 @@ func (self *RemotesController) fetch(remote *models.Remote) error {
|
|||
|
||||
func (self *RemotesController) checkSelected(callback func(*models.Remote) error) func() error {
|
||||
return func() error {
|
||||
file := self.getSelectedRemote()
|
||||
file := self.context.GetSelected()
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
@ -16,21 +16,19 @@ type SubmodulesController struct {
|
|||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context types.IListContext
|
||||
context *context.SubmodulesContext
|
||||
git *commands.GitCommand
|
||||
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error
|
||||
getSelectedSubmodule func() *models.SubmoduleConfig
|
||||
}
|
||||
|
||||
var _ types.IController = &SubmodulesController{}
|
||||
|
||||
func NewSubmodulesController(
|
||||
c *types.ControllerCommon,
|
||||
context types.IListContext,
|
||||
context *context.SubmodulesContext,
|
||||
git *commands.GitCommand,
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error,
|
||||
getSelectedSubmodule func() *models.SubmoduleConfig,
|
||||
) *SubmodulesController {
|
||||
return &SubmodulesController{
|
||||
baseController: baseController{},
|
||||
|
@ -38,7 +36,6 @@ func NewSubmodulesController(
|
|||
context: context,
|
||||
git: git,
|
||||
enterSubmodule: enterSubmodule,
|
||||
getSelectedSubmodule: getSelectedSubmodule,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,10 +77,10 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||
Description: self.c.Tr.LcViewBulkSubmoduleOptions,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
},
|
||||
// {
|
||||
// Key: gocui.MouseLeft,
|
||||
// Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) },
|
||||
// },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +227,7 @@ func (self *SubmodulesController) remove(submodule *models.SubmoduleConfig) erro
|
|||
|
||||
func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleConfig) error) func() error {
|
||||
return func() error {
|
||||
submodule := self.getSelectedSubmodule()
|
||||
submodule := self.context.GetSelected()
|
||||
if submodule == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ func (self *TagsController) create() error {
|
|||
|
||||
func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {
|
||||
return func() error {
|
||||
tag := self.context.GetSelectedTag()
|
||||
tag := self.context.GetSelected()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -44,16 +44,16 @@ func (gui *Gui) resolveTemplate(templateStr string, promptResponses []string) (s
|
|||
objects := CustomCommandObjects{
|
||||
SelectedFile: gui.getSelectedFile(),
|
||||
SelectedPath: gui.getSelectedPath(),
|
||||
SelectedLocalCommit: gui.getSelectedLocalCommit(),
|
||||
SelectedReflogCommit: gui.getSelectedReflogCommit(),
|
||||
SelectedLocalBranch: gui.getSelectedBranch(),
|
||||
SelectedRemoteBranch: gui.getSelectedRemoteBranch(),
|
||||
SelectedRemote: gui.getSelectedRemote(),
|
||||
SelectedTag: gui.State.Contexts.Tags.GetSelectedTag(),
|
||||
SelectedStashEntry: gui.getSelectedStashEntry(),
|
||||
SelectedLocalCommit: gui.State.Contexts.BranchCommits.GetSelected(),
|
||||
SelectedReflogCommit: gui.State.Contexts.ReflogCommits.GetSelected(),
|
||||
SelectedLocalBranch: gui.State.Contexts.Branches.GetSelected(),
|
||||
SelectedRemoteBranch: gui.State.Contexts.RemoteBranches.GetSelected(),
|
||||
SelectedRemote: gui.State.Contexts.Remotes.GetSelected(),
|
||||
SelectedTag: gui.State.Contexts.Tags.GetSelected(),
|
||||
SelectedStashEntry: gui.State.Contexts.Stash.GetSelected(),
|
||||
SelectedCommitFile: gui.getSelectedCommitFile(),
|
||||
SelectedCommitFilePath: gui.getSelectedCommitFilePath(),
|
||||
SelectedSubCommit: gui.getSelectedSubCommit(),
|
||||
SelectedSubCommit: gui.State.Contexts.SubCommits.GetSelected(),
|
||||
CheckedOutBranch: gui.getCheckedOutBranch(),
|
||||
PromptResponses: promptResponses,
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func (gui *Gui) currentDiffTerminals() []string {
|
|||
return []string{gui.State.Contexts.CommitFiles.GetRefName()}
|
||||
case context.LOCAL_BRANCHES_CONTEXT_KEY:
|
||||
// for our local branches we want to include both the branch and its upstream
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch != nil {
|
||||
names := []string{branch.ID()}
|
||||
if branch.IsTrackingRemote() {
|
||||
|
|
|
@ -16,7 +16,7 @@ func (gui *Gui) handleCreateFilteringMenuPanel() error {
|
|||
fileName = node.GetPath()
|
||||
}
|
||||
case gui.State.Contexts.CommitFiles:
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node != nil {
|
||||
fileName = node.GetPath()
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
func (gui *Gui) handleCreateGitFlowMenu() error {
|
||||
branch := gui.getSelectedBranch()
|
||||
branch := gui.State.Contexts.Branches.GetSelected()
|
||||
if branch == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -179,11 +179,11 @@ type GuiRepoState struct {
|
|||
|
||||
// Suggestions will sometimes appear when typing into a prompt
|
||||
Suggestions []*types.Suggestion
|
||||
MenuItems []*types.MenuItem
|
||||
|
||||
Updating bool
|
||||
Panels *panelStates
|
||||
SplitMainPanel bool
|
||||
LimitCommits bool
|
||||
|
||||
IsRefreshingFiles bool
|
||||
Searching searchingState
|
||||
|
@ -253,68 +253,11 @@ type MergingPanelState struct {
|
|||
UserVerticalScrolling bool
|
||||
}
|
||||
|
||||
// TODO: consider splitting this out into the window and the branches view
|
||||
type branchPanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type remotePanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type remoteBranchesState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type commitPanelState struct {
|
||||
listPanelState
|
||||
|
||||
LimitCommits bool
|
||||
}
|
||||
|
||||
type reflogCommitPanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type subCommitPanelState struct {
|
||||
listPanelState
|
||||
|
||||
// e.g. name of branch whose commits we're looking at
|
||||
refName string
|
||||
}
|
||||
|
||||
type stashPanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type menuPanelState struct {
|
||||
listPanelState
|
||||
OnPress func() error
|
||||
}
|
||||
|
||||
type submodulePanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
type suggestionsPanelState struct {
|
||||
listPanelState
|
||||
}
|
||||
|
||||
// as we move things to the new context approach we're going to eventually
|
||||
// remove this struct altogether and store this state on the contexts.
|
||||
type panelStates struct {
|
||||
Branches *branchPanelState
|
||||
Remotes *remotePanelState
|
||||
RemoteBranches *remoteBranchesState
|
||||
Commits *commitPanelState
|
||||
ReflogCommits *reflogCommitPanelState
|
||||
SubCommits *subCommitPanelState
|
||||
Stash *stashPanelState
|
||||
Menu *menuPanelState
|
||||
LineByLine *LblPanelState
|
||||
Merging *MergingPanelState
|
||||
Submodules *submodulePanelState
|
||||
Suggestions *suggestionsPanelState
|
||||
}
|
||||
|
||||
type Views struct {
|
||||
|
@ -449,22 +392,12 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
|||
},
|
||||
|
||||
Panels: &panelStates{
|
||||
// TODO: work out why some of these are -1 and some are 0. Last time I checked there was a good reason but I'm less certain now
|
||||
Submodules: &submodulePanelState{listPanelState{SelectedLineIdx: -1}},
|
||||
Branches: &branchPanelState{listPanelState{SelectedLineIdx: 0}},
|
||||
Remotes: &remotePanelState{listPanelState{SelectedLineIdx: 0}},
|
||||
RemoteBranches: &remoteBranchesState{listPanelState{SelectedLineIdx: -1}},
|
||||
Commits: &commitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, LimitCommits: true},
|
||||
ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}},
|
||||
SubCommits: &subCommitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, refName: ""},
|
||||
Stash: &stashPanelState{listPanelState{SelectedLineIdx: -1}},
|
||||
Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil},
|
||||
Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}},
|
||||
Merging: &MergingPanelState{
|
||||
State: mergeconflicts.NewState(),
|
||||
UserVerticalScrolling: false,
|
||||
},
|
||||
},
|
||||
LimitCommits: true,
|
||||
Ptmx: nil,
|
||||
Modes: Modes{
|
||||
Filtering: filtering.New(filterPath),
|
||||
|
@ -584,7 +517,7 @@ func (gui *Gui) resetControllers() {
|
|||
controllerCommon,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
func() { gui.State.Panels.Commits.LimitCommits = true },
|
||||
func() { gui.State.LimitCommits = true },
|
||||
),
|
||||
Bisect: controllers.NewBisectHelper(controllerCommon, gui.git),
|
||||
Suggestions: controllers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions),
|
||||
|
@ -615,7 +548,6 @@ func (gui *Gui) resetControllers() {
|
|||
gui.State.Contexts.Submodules,
|
||||
gui.git,
|
||||
gui.enterSubmodule,
|
||||
gui.getSelectedSubmodule,
|
||||
)
|
||||
|
||||
bisectController := controllers.NewBisectController(
|
||||
|
@ -623,7 +555,6 @@ func (gui *Gui) resetControllers() {
|
|||
gui.State.Contexts.BranchCommits,
|
||||
gui.git,
|
||||
gui.helpers.Bisect,
|
||||
gui.getSelectedLocalCommit,
|
||||
func() []*models.Commit { return gui.State.Model.Commits },
|
||||
)
|
||||
|
||||
|
@ -672,15 +603,13 @@ func (gui *Gui) resetControllers() {
|
|||
gui.helpers.Refs,
|
||||
gui.helpers.CherryPick,
|
||||
gui.helpers.Rebase,
|
||||
gui.getSelectedLocalCommit,
|
||||
model,
|
||||
func() int { return gui.State.Panels.Commits.SelectedLineIdx },
|
||||
gui.helpers.Rebase.CheckMergeOrRebase,
|
||||
syncController.HandlePull,
|
||||
gui.getHostingServiceMgr,
|
||||
gui.SwitchToCommitFilesContext,
|
||||
func() bool { return gui.State.Panels.Commits.LimitCommits },
|
||||
func(value bool) { gui.State.Panels.Commits.LimitCommits = value },
|
||||
func() bool { return gui.State.LimitCommits },
|
||||
func(value bool) { gui.State.LimitCommits = value },
|
||||
func() bool { return gui.ShowWholeGitGraph },
|
||||
func(value bool) { gui.ShowWholeGitGraph = value },
|
||||
),
|
||||
|
@ -689,13 +618,11 @@ func (gui *Gui) resetControllers() {
|
|||
gui.State.Contexts.Remotes,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
gui.getSelectedRemote,
|
||||
func(branches []*models.RemoteBranch) { gui.State.Model.RemoteBranches = branches },
|
||||
),
|
||||
Menu: controllers.NewMenuController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.Menu,
|
||||
gui.getSelectedMenuItem,
|
||||
),
|
||||
Undo: controllers.NewUndoController(
|
||||
controllerCommon,
|
||||
|
@ -714,6 +641,11 @@ func (gui *Gui) resetControllers() {
|
|||
controllers.AttachControllers(gui.State.Contexts.Remotes, gui.Controllers.Remotes)
|
||||
controllers.AttachControllers(gui.State.Contexts.Menu, gui.Controllers.Menu)
|
||||
controllers.AttachControllers(gui.State.Contexts.Global, gui.Controllers.Sync, gui.Controllers.Undo, gui.Controllers.Global)
|
||||
|
||||
listControllerFactory := controllers.NewListControllerFactory(gui.c)
|
||||
for _, context := range gui.getListContexts() {
|
||||
controllers.AttachControllers(context, listControllerFactory.Create(context))
|
||||
}
|
||||
}
|
||||
|
||||
var RuneReplacements = map[rune]string{
|
||||
|
|
|
@ -1,267 +0,0 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type ListContext struct {
|
||||
GetItemsLength func() int
|
||||
GetDisplayStrings func(startIdx int, length int) [][]string
|
||||
OnFocus func(...types.OnFocusOpts) error
|
||||
OnRenderToMain func(...types.OnFocusOpts) error
|
||||
OnFocusLost func() error
|
||||
|
||||
OnGetSelectedItemId func() string
|
||||
OnGetPanelState func() types.IListPanelState
|
||||
// if this is true, we'll call GetDisplayStrings for just the visible part of the
|
||||
// view and re-render that. This is useful when you need to render different
|
||||
// content based on the selection (e.g. for showing the selected commit)
|
||||
RenderSelection bool
|
||||
|
||||
Gui *Gui
|
||||
|
||||
*context.BaseContext
|
||||
}
|
||||
|
||||
var _ types.IListContext = &ListContext{}
|
||||
|
||||
func (self *ListContext) GetPanelState() types.IListPanelState {
|
||||
return self.OnGetPanelState()
|
||||
}
|
||||
|
||||
func (self *ListContext) FocusLine() {
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
// ignoring error for now
|
||||
return
|
||||
}
|
||||
|
||||
// we need a way of knowing whether we've rendered to the view yet.
|
||||
view.FocusPoint(view.OriginX(), self.GetPanelState().GetSelectedLineIdx())
|
||||
if self.RenderSelection {
|
||||
_, originY := view.Origin()
|
||||
displayStrings := self.GetDisplayStrings(originY, view.InnerHeight()+1)
|
||||
self.Gui.renderDisplayStringsInViewPort(view, displayStrings)
|
||||
}
|
||||
view.Footer = formatListFooter(self.GetPanelState().GetSelectedLineIdx(), self.GetItemsLength())
|
||||
}
|
||||
|
||||
func formatListFooter(selectedLineIdx int, length int) string {
|
||||
return fmt.Sprintf("%d of %d", selectedLineIdx+1, length)
|
||||
}
|
||||
|
||||
func (self *ListContext) GetSelectedItemId() string {
|
||||
return self.OnGetSelectedItemId()
|
||||
}
|
||||
|
||||
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
|
||||
func (self *ListContext) HandleRender() error {
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if self.GetDisplayStrings != nil {
|
||||
self.Gui.refreshSelectedLine(self.GetPanelState(), self.GetItemsLength())
|
||||
self.Gui.renderDisplayStrings(view, self.GetDisplayStrings(0, self.GetItemsLength()))
|
||||
self.Gui.render()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleFocusLost() error {
|
||||
if self.OnFocusLost != nil {
|
||||
return self.OnFocusLost()
|
||||
}
|
||||
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
_ = view.SetOriginX(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleFocus(opts ...types.OnFocusOpts) error {
|
||||
self.FocusLine()
|
||||
|
||||
if self.OnFocus != nil {
|
||||
if err := self.OnFocus(opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if self.OnRenderToMain != nil {
|
||||
if err := self.OnRenderToMain(opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContext) HandlePrevLine() error {
|
||||
return self.handleLineChange(-1)
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleNextLine() error {
|
||||
return self.handleLineChange(1)
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleScrollLeft() error {
|
||||
return self.scroll(self.Gui.scrollLeft)
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleScrollRight() error {
|
||||
return self.scroll(self.Gui.scrollRight)
|
||||
}
|
||||
|
||||
func (self *ListContext) scroll(scrollFunc func(*gocui.View)) error {
|
||||
if self.ignoreKeybinding() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// get the view, move the origin
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
scrollFunc(view)
|
||||
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContext) ignoreKeybinding() bool {
|
||||
return !self.Gui.isPopupPanel(self.ViewName) && self.Gui.popupPanelFocused()
|
||||
}
|
||||
|
||||
func (self *ListContext) handleLineChange(change int) error {
|
||||
if self.ignoreKeybinding() {
|
||||
return nil
|
||||
}
|
||||
|
||||
selectedLineIdx := self.GetPanelState().GetSelectedLineIdx()
|
||||
if (change < 0 && selectedLineIdx == 0) || (change > 0 && selectedLineIdx == self.GetItemsLength()-1) {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.Gui.changeSelectedLine(self.GetPanelState(), self.GetItemsLength(), change)
|
||||
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleNextPage() error {
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
delta := self.Gui.pageDelta(view)
|
||||
|
||||
return self.handleLineChange(delta)
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleGotoTop() error {
|
||||
return self.handleLineChange(-self.GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleGotoBottom() error {
|
||||
return self.handleLineChange(self.GetItemsLength())
|
||||
}
|
||||
|
||||
func (self *ListContext) HandlePrevPage() error {
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
delta := self.Gui.pageDelta(view)
|
||||
|
||||
return self.handleLineChange(-delta)
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleClick(onClick func() error) error {
|
||||
if self.ignoreKeybinding() {
|
||||
return nil
|
||||
}
|
||||
|
||||
view, err := self.Gui.g.View(self.ViewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
prevSelectedLineIdx := self.GetPanelState().GetSelectedLineIdx()
|
||||
newSelectedLineIdx := view.SelectedLineIdx()
|
||||
|
||||
// we need to focus the view
|
||||
if err := self.Gui.c.PushContext(self); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if newSelectedLineIdx > self.GetItemsLength()-1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.GetPanelState().SetSelectedLineIdx(newSelectedLineIdx)
|
||||
|
||||
prevViewName := self.Gui.currentViewName()
|
||||
if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == self.ViewName && onClick != nil {
|
||||
return onClick()
|
||||
}
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContext) OnSearchSelect(selectedLineIdx int) error {
|
||||
self.GetPanelState().SetSelectedLineIdx(selectedLineIdx)
|
||||
return self.HandleFocus()
|
||||
}
|
||||
|
||||
func (self *ListContext) HandleRenderToMain() error {
|
||||
if self.OnRenderToMain != nil {
|
||||
return self.OnRenderToMain()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ListContext) attachKeybindings() *ListContext {
|
||||
self.BaseContext.AddKeybindingsFn(self.keybindings)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *ListContext) keybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||
return []*types.Binding{
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevPage), Modifier: gocui.ModNone, Handler: self.HandlePrevPage, Description: self.Gui.c.Tr.LcPrevPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextPage), Modifier: gocui.ModNone, Handler: self.HandleNextPage, Description: self.Gui.c.Tr.LcNextPage},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoTop), Modifier: gocui.ModNone, Handler: self.HandleGotoTop, Description: self.Gui.c.Tr.LcGotoTop},
|
||||
{Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: func() error { return self.HandleClick(nil) }},
|
||||
{Tag: "navigation", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: self.HandleNextLine},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: self.HandleScrollLeft},
|
||||
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: self.HandleScrollRight},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.StartSearch),
|
||||
Handler: func() error { return self.Gui.handleOpenSearch(self.GetViewName()) },
|
||||
Description: self.Gui.c.Tr.LcStartSearch,
|
||||
Tag: "navigation",
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.GotoBottom),
|
||||
Description: self.Gui.c.Tr.LcGotoBottom,
|
||||
Handler: self.HandleGotoBottom,
|
||||
Tag: "navigation",
|
||||
},
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package gui
|
|||
import (
|
||||
"log"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
|
@ -12,27 +11,21 @@ import (
|
|||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
func (gui *Gui) menuListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "menu",
|
||||
Key: "menu",
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
OnGetOptionsMap: gui.getMenuOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Menu },
|
||||
Gui: gui,
|
||||
|
||||
// no GetDisplayStrings field because we do a custom render on menu creation
|
||||
}).attachKeybindings()
|
||||
func (gui *Gui) menuListContext() *context.MenuContext {
|
||||
return context.NewMenuContext(
|
||||
gui.Views.Menu,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
gui.c,
|
||||
gui.getMenuOptions,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) filesListContext() *context.WorkingTreeContext {
|
||||
return context.NewWorkingTreeContext(
|
||||
func() []*models.File { return gui.State.Model.Files },
|
||||
func() *gocui.View { return gui.Views.Files },
|
||||
gui.Views.Files,
|
||||
func(startIdx int, length int) [][]string {
|
||||
lines := presentation.RenderFileTree(gui.State.Contexts.Files.FileTreeViewModel, gui.State.Modes.Diffing.Ref, gui.State.Model.Submodules)
|
||||
mappedLines := make([][]string, len(lines))
|
||||
|
@ -49,82 +42,46 @@ func (gui *Gui) filesListContext() *context.WorkingTreeContext {
|
|||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) branchesListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: context.LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Branches) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Branches },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.branchesRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) branchesListContext() *context.BranchesContext {
|
||||
return context.NewBranchesContext(
|
||||
func() []*models.Branch { return gui.State.Model.Branches },
|
||||
gui.Views.Branches,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetBranchListDisplayStrings(gui.State.Model.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedBranch()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.branchesRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) remotesListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: context.REMOTES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Remotes) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Remotes },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.remotesRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) remotesListContext() *context.RemotesContext {
|
||||
return context.NewRemotesContext(
|
||||
func() []*models.Remote { return gui.State.Model.Remotes },
|
||||
gui.Views.Branches,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetRemoteListDisplayStrings(gui.State.Model.Remotes, gui.State.Modes.Diffing.Ref)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedRemote()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.remotesRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) remoteBranchesListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: context.REMOTE_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.RemoteBranches) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.RemoteBranches },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.remoteBranchesRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) remoteBranchesListContext() *context.RemoteBranchesContext {
|
||||
return context.NewRemoteBranchesContext(
|
||||
func() []*models.RemoteBranch { return gui.State.Model.RemoteBranches },
|
||||
gui.Views.Branches,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetRemoteBranchListDisplayStrings(gui.State.Model.RemoteBranches, gui.State.Modes.Diffing.Ref)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedRemoteBranch()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.remoteBranchesRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) withDiffModeCheck(f func() error) func() error {
|
||||
|
@ -140,7 +97,7 @@ func (gui *Gui) withDiffModeCheck(f func() error) func() error {
|
|||
func (gui *Gui) tagsListContext() *context.TagsContext {
|
||||
return context.NewTagsContext(
|
||||
func() []*models.Tag { return gui.State.Model.Tags },
|
||||
func() *gocui.View { return gui.Views.Branches },
|
||||
gui.Views.Branches,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetTagListDisplayStrings(gui.State.Model.Tags, gui.State.Modes.Diffing.Ref)
|
||||
},
|
||||
|
@ -151,25 +108,14 @@ func (gui *Gui) tagsListContext() *context.TagsContext {
|
|||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) branchCommitsListContext() types.IListContext {
|
||||
parseEmoji := gui.c.UserConfig.Git.ParseEmoji
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "commits",
|
||||
WindowName: "commits",
|
||||
Key: context.BRANCH_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Commits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Commits },
|
||||
OnFocus: OnFocusWrapper(gui.onCommitFocus),
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.branchCommitsRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) branchCommitsListContext() *context.LocalCommitsContext {
|
||||
return context.NewLocalCommitsContext(
|
||||
func() []*models.Commit { return gui.State.Model.Commits },
|
||||
gui.Views.Commits,
|
||||
func(startIdx int, length int) [][]string {
|
||||
selectedCommitSha := ""
|
||||
if gui.currentContext().GetKey() == context.BRANCH_COMMITS_CONTEXT_KEY {
|
||||
selectedCommit := gui.getSelectedLocalCommit()
|
||||
selectedCommit := gui.State.Contexts.BranchCommits.GetSelected()
|
||||
if selectedCommit != nil {
|
||||
selectedCommitSha = selectedCommit.Sha
|
||||
}
|
||||
|
@ -179,7 +125,7 @@ func (gui *Gui) branchCommitsListContext() types.IListContext {
|
|||
gui.State.ScreenMode != SCREEN_NORMAL,
|
||||
gui.helpers.CherryPick.CherryPickedCommitShaMap(),
|
||||
gui.State.Modes.Diffing.Ref,
|
||||
parseEmoji,
|
||||
gui.c.UserConfig.Git.ParseEmoji,
|
||||
selectedCommitSha,
|
||||
startIdx,
|
||||
length,
|
||||
|
@ -187,35 +133,21 @@ func (gui *Gui) branchCommitsListContext() types.IListContext {
|
|||
gui.State.Model.BisectInfo,
|
||||
)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedLocalCommit()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
RenderSelection: true,
|
||||
}).attachKeybindings()
|
||||
OnFocusWrapper(gui.onCommitFocus),
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.branchCommitsRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) subCommitsListContext() types.IListContext {
|
||||
parseEmoji := gui.c.UserConfig.Git.ParseEmoji
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "branches",
|
||||
WindowName: "branches",
|
||||
Key: context.SUB_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.SubCommits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.SubCommits },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.subCommitsRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) subCommitsListContext() *context.SubCommitsContext {
|
||||
return context.NewSubCommitsContext(
|
||||
func() []*models.Commit { return gui.State.Model.SubCommits },
|
||||
gui.Views.Branches,
|
||||
func(startIdx int, length int) [][]string {
|
||||
selectedCommitSha := ""
|
||||
if gui.currentContext().GetKey() == context.SUB_COMMITS_CONTEXT_KEY {
|
||||
selectedCommit := gui.getSelectedSubCommit()
|
||||
selectedCommit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if selectedCommit != nil {
|
||||
selectedCommitSha = selectedCommit.Sha
|
||||
}
|
||||
|
@ -225,7 +157,7 @@ func (gui *Gui) subCommitsListContext() types.IListContext {
|
|||
gui.State.ScreenMode != SCREEN_NORMAL,
|
||||
gui.helpers.CherryPick.CherryPickedCommitShaMap(),
|
||||
gui.State.Modes.Diffing.Ref,
|
||||
parseEmoji,
|
||||
gui.c.UserConfig.Git.ParseEmoji,
|
||||
selectedCommitSha,
|
||||
startIdx,
|
||||
length,
|
||||
|
@ -233,15 +165,11 @@ func (gui *Gui) subCommitsListContext() types.IListContext {
|
|||
git_commands.NewNullBisectInfo(),
|
||||
)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedSubCommit()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
RenderSelection: true,
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.subCommitsRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) shouldShowGraph() bool {
|
||||
|
@ -263,69 +191,44 @@ func (gui *Gui) shouldShowGraph() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (gui *Gui) reflogCommitsListContext() types.IListContext {
|
||||
parseEmoji := gui.c.UserConfig.Git.ParseEmoji
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "commits",
|
||||
WindowName: "commits",
|
||||
Key: context.REFLOG_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.FilteredReflogCommits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.ReflogCommits },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.reflogCommitsRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) reflogCommitsListContext() *context.ReflogCommitsContext {
|
||||
return context.NewReflogCommitsContext(
|
||||
func() []*models.Commit { return gui.State.Model.FilteredReflogCommits },
|
||||
gui.Views.Commits,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetReflogCommitListDisplayStrings(
|
||||
gui.State.Model.FilteredReflogCommits,
|
||||
gui.State.ScreenMode != SCREEN_NORMAL,
|
||||
gui.helpers.CherryPick.CherryPickedCommitShaMap(),
|
||||
gui.State.Modes.Diffing.Ref,
|
||||
parseEmoji,
|
||||
gui.c.UserConfig.Git.ParseEmoji,
|
||||
)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedReflogCommit()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.reflogCommitsRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) stashListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "stash",
|
||||
WindowName: "stash",
|
||||
Key: context.STASH_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.StashEntries) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Stash },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.stashRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) stashListContext() *context.StashContext {
|
||||
return context.NewStashContext(
|
||||
func() []*models.StashEntry { return gui.State.Model.StashEntries },
|
||||
gui.Views.Stash,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetStashEntryListDisplayStrings(gui.State.Model.StashEntries, gui.State.Modes.Diffing.Ref)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedStashEntry()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.stashRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) commitFilesListContext() *context.CommitFilesContext {
|
||||
return context.NewCommitFilesContext(
|
||||
func() []*models.CommitFile { return gui.State.Model.CommitFiles },
|
||||
func() *gocui.View { return gui.Views.CommitFiles },
|
||||
gui.Views.CommitFiles,
|
||||
func(startIdx int, length int) [][]string {
|
||||
if gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetItemsLength() == 0 {
|
||||
return [][]string{{style.FgRed.Sprint("(none)")}}
|
||||
|
@ -346,48 +249,32 @@ func (gui *Gui) commitFilesListContext() *context.CommitFilesContext {
|
|||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) submodulesListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "files",
|
||||
WindowName: "files",
|
||||
Key: context.SUBMODULES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Submodules) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Submodules },
|
||||
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.submodulesRenderToMain)),
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) submodulesListContext() *context.SubmodulesContext {
|
||||
return context.NewSubmodulesContext(
|
||||
func() []*models.SubmoduleConfig { return gui.State.Model.Submodules },
|
||||
gui.Views.Files,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetSubmoduleListDisplayStrings(gui.State.Model.Submodules)
|
||||
},
|
||||
OnGetSelectedItemId: func() string {
|
||||
item := gui.getSelectedSubmodule()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
return item.ID()
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
OnFocusWrapper(gui.withDiffModeCheck(gui.submodulesRenderToMain)),
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) suggestionsListContext() types.IListContext {
|
||||
return (&ListContext{
|
||||
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{
|
||||
ViewName: "suggestions",
|
||||
WindowName: "suggestions",
|
||||
Key: context.SUGGESTIONS_CONTEXT_KEY,
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Suggestions) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Suggestions },
|
||||
Gui: gui,
|
||||
GetDisplayStrings: func(startIdx int, length int) [][]string {
|
||||
func (gui *Gui) suggestionsListContext() *context.SuggestionsContext {
|
||||
return context.NewSuggestionsContext(
|
||||
func() []*types.Suggestion { return gui.State.Suggestions },
|
||||
gui.Views.Files,
|
||||
func(startIdx int, length int) [][]string {
|
||||
return presentation.GetSuggestionListDisplayStrings(gui.State.Suggestions)
|
||||
},
|
||||
}).attachKeybindings()
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
gui.c,
|
||||
)
|
||||
}
|
||||
|
||||
func (gui *Gui) getListContexts() []types.IListContext {
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
func (gui *Gui) getMenuOptions() map[string]string {
|
||||
|
@ -35,44 +34,24 @@ func (gui *Gui) createMenu(opts types.CreateMenuOptions) error {
|
|||
})
|
||||
}
|
||||
|
||||
gui.State.MenuItems = opts.Items
|
||||
|
||||
stringArrays := make([][]string, len(opts.Items))
|
||||
for i, item := range opts.Items {
|
||||
for _, item := range opts.Items {
|
||||
if item.OpensMenu && item.DisplayStrings != nil {
|
||||
return errors.New("Message for the developer of this app: you've set opensMenu with displaystrings on the menu panel. Bad developer!. Apologies, user")
|
||||
}
|
||||
|
||||
if item.DisplayStrings == nil {
|
||||
styledStr := item.DisplayString
|
||||
if item.OpensMenu {
|
||||
styledStr = opensMenuStyle(styledStr)
|
||||
}
|
||||
stringArrays[i] = []string{styledStr}
|
||||
} else {
|
||||
stringArrays[i] = item.DisplayStrings
|
||||
}
|
||||
}
|
||||
|
||||
list := utils.RenderDisplayStrings(stringArrays)
|
||||
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(false, list)
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensionsForContentHeight(len(opts.Items))
|
||||
menuView, _ := gui.g.SetView("menu", x0, y0, x1, y1, 0)
|
||||
menuView.Title = opts.Title
|
||||
menuView.FgColor = theme.GocuiDefaultTextColor
|
||||
menuView.SetOnSelectItem(gui.onSelectItemWrapper(func(selectedLine int) error {
|
||||
return nil
|
||||
}))
|
||||
menuView.SetContent(list)
|
||||
gui.State.Panels.Menu.SelectedLineIdx = 0
|
||||
|
||||
gui.State.Contexts.Menu.SetMenuItems(opts.Items)
|
||||
gui.State.Contexts.Menu.GetPanelState().SetSelectedLineIdx(0)
|
||||
_ = gui.c.PostRefreshUpdate(gui.State.Contexts.Menu)
|
||||
|
||||
// TODO: ensure that if we're opened a menu from within a menu that it renders correctly
|
||||
return gui.c.PushContext(gui.State.Contexts.Menu)
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedMenuItem() *types.MenuItem {
|
||||
if len(gui.State.MenuItems) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.MenuItems[gui.State.Panels.Menu.SelectedLineIdx]
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package gui
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
|
@ -34,16 +35,12 @@ func (gui *Gui) getBindings(context types.Context) []*types.Binding {
|
|||
|
||||
func (gui *Gui) displayDescription(binding *types.Binding) string {
|
||||
if binding.OpensMenu {
|
||||
return opensMenuStyle(binding.Description)
|
||||
return presentation.OpensMenuStyle(binding.Description)
|
||||
}
|
||||
|
||||
return style.FgCyan.Sprint(binding.Description)
|
||||
}
|
||||
|
||||
func opensMenuStyle(str string) string {
|
||||
return style.FgMagenta.Sprintf("%s...", str)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreateOptionsMenu() error {
|
||||
context := gui.currentContext()
|
||||
bindings := gui.getBindings(context)
|
||||
|
|
|
@ -26,7 +26,7 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
|||
gui.Views.Secondary.Title = "Custom Patch"
|
||||
|
||||
// get diff from commit file that's currently selected
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func (gui *Gui) handleToggleSelectionForPatch() error {
|
|||
}
|
||||
|
||||
// add range of lines to those set for the file
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ func (gui *Gui) handleMovePatchToSelectedCommit() error {
|
|||
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
||||
commitIndex := gui.getPatchCommitIndex()
|
||||
gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit)
|
||||
err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Panels.Commits.SelectedLineIdx)
|
||||
err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Contexts.BranchCommits.GetSelectedLineIdx())
|
||||
return gui.helpers.Rebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
}
|
||||
|
|
7
pkg/gui/presentation/menu.go
Normal file
7
pkg/gui/presentation/menu.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package presentation
|
||||
|
||||
import "github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
|
||||
func OpensMenuStyle(str string) string {
|
||||
return style.FgMagenta.Sprintf("%s...", str)
|
||||
}
|
|
@ -9,17 +9,11 @@ import (
|
|||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedReflogCommit() *models.Commit {
|
||||
selectedLine := gui.State.Panels.ReflogCommits.SelectedLineIdx
|
||||
reflogComits := gui.State.Model.FilteredReflogCommits
|
||||
if selectedLine == -1 || len(reflogComits) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return reflogComits[selectedLine]
|
||||
return gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
}
|
||||
|
||||
func (gui *Gui) reflogCommitsRenderToMain() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
var task updateTask
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask("No reflog history")
|
||||
|
@ -38,7 +32,7 @@ func (gui *Gui) reflogCommitsRenderToMain() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) CheckoutReflogCommit() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -55,19 +49,17 @@ func (gui *Gui) CheckoutReflogCommit() error {
|
|||
return err
|
||||
}
|
||||
|
||||
gui.State.Panels.ReflogCommits.SelectedLineIdx = 0
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreateReflogResetMenu() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
|
||||
return gui.helpers.Refs.CreateGitResetMenu(commit.Sha)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleViewReflogCommitFiles() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -81,7 +73,7 @@ func (gui *Gui) handleViewReflogCommitFiles() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCopyReflogCommit() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -91,7 +83,7 @@ func (gui *Gui) handleCopyReflogCommit() error {
|
|||
|
||||
func (gui *Gui) handleCopyReflogCommitRange() error {
|
||||
// just doing this to ensure something is selected
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
commit := gui.State.Contexts.ReflogCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
|
|||
|
||||
commits, err := gui.git.Loaders.Commits.GetCommits(
|
||||
loaders.GetCommitsOptions{
|
||||
Limit: gui.State.Panels.Commits.LimitCommits,
|
||||
Limit: gui.State.LimitCommits,
|
||||
FilterPath: gui.State.Modes.Filtering.GetPath(),
|
||||
IncludeRebaseCommits: true,
|
||||
RefName: gui.refForLog(),
|
||||
|
@ -484,7 +484,7 @@ func (gui *Gui) refreshReflogCommits() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) refreshRemotes() error {
|
||||
prevSelectedRemote := gui.getSelectedRemote()
|
||||
prevSelectedRemote := gui.State.Contexts.Remotes.GetSelected()
|
||||
|
||||
remotes, err := gui.git.Loaders.Remotes.GetRemotes()
|
||||
if err != nil {
|
||||
|
|
|
@ -4,25 +4,15 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedRemoteBranch() *models.RemoteBranch {
|
||||
selectedLine := gui.State.Panels.RemoteBranches.SelectedLineIdx
|
||||
if selectedLine == -1 || len(gui.State.Model.RemoteBranches) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.RemoteBranches[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) remoteBranchesRenderToMain() error {
|
||||
var task updateTask
|
||||
remoteBranch := gui.getSelectedRemoteBranch()
|
||||
remoteBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if remoteBranch == nil {
|
||||
task = NewRenderStringTask("No branches for this remote")
|
||||
} else {
|
||||
|
@ -43,12 +33,12 @@ func (gui *Gui) handleRemoteBranchesEscape() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleMergeRemoteBranch() error {
|
||||
selectedBranchName := gui.getSelectedRemoteBranch().FullName()
|
||||
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
|
||||
return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDeleteRemoteBranch() error {
|
||||
remoteBranch := gui.getSelectedRemoteBranch()
|
||||
remoteBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if remoteBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -72,12 +62,12 @@ func (gui *Gui) handleDeleteRemoteBranch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleRebaseOntoRemoteBranch() error {
|
||||
selectedBranchName := gui.getSelectedRemoteBranch().FullName()
|
||||
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
|
||||
return gui.handleRebaseOntoBranch(selectedBranchName)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSetBranchUpstream() error {
|
||||
selectedBranch := gui.getSelectedRemoteBranch()
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
checkedOutBranch := gui.getCheckedOutBranch()
|
||||
|
||||
message := utils.ResolvePlaceholderString(
|
||||
|
@ -103,7 +93,7 @@ func (gui *Gui) handleSetBranchUpstream() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCreateResetToRemoteBranchMenu() error {
|
||||
selectedBranch := gui.getSelectedRemoteBranch()
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -112,7 +102,7 @@ func (gui *Gui) handleCreateResetToRemoteBranchMenu() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleEnterRemoteBranch() error {
|
||||
selectedBranch := gui.getSelectedRemoteBranch()
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -121,7 +111,7 @@ func (gui *Gui) handleEnterRemoteBranch() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleNewBranchOffRemoteBranch() error {
|
||||
selectedBranch := gui.getSelectedRemoteBranch()
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,24 +4,14 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedRemote() *models.Remote {
|
||||
selectedLine := gui.State.Panels.Remotes.SelectedLineIdx
|
||||
if selectedLine == -1 || len(gui.State.Model.Remotes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.Remotes[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) remotesRenderToMain() error {
|
||||
var task updateTask
|
||||
remote := gui.getSelectedRemote()
|
||||
remote := gui.State.Contexts.Remotes.GetSelected()
|
||||
if remote == nil {
|
||||
task = NewRenderStringTask("No remotes")
|
||||
} else {
|
||||
|
|
|
@ -9,12 +9,7 @@ import (
|
|||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedStashEntry() *models.StashEntry {
|
||||
selectedLine := gui.State.Panels.Stash.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.StashEntries[selectedLine]
|
||||
return gui.State.Contexts.Stash.GetSelected()
|
||||
}
|
||||
|
||||
func (gui *Gui) stashRenderToMain() error {
|
||||
|
|
|
@ -2,25 +2,14 @@ package gui
|
|||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/controllers"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedSubCommit() *models.Commit {
|
||||
selectedLine := gui.State.Panels.SubCommits.SelectedLineIdx
|
||||
commits := gui.State.Model.SubCommits
|
||||
if selectedLine == -1 || len(commits) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return commits[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) subCommitsRenderToMain() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
var task updateTask
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask("No commits")
|
||||
|
@ -39,7 +28,7 @@ func (gui *Gui) subCommitsRenderToMain() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCheckoutSubCommit() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -62,13 +51,13 @@ func (gui *Gui) handleCheckoutSubCommit() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCreateSubCommitResetMenu() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
|
||||
return gui.helpers.Refs.CreateGitResetMenu(commit.Sha)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleViewSubCommitFiles() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -85,7 +74,7 @@ func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
|||
// need to populate my sub commits
|
||||
commits, err := gui.git.Loaders.Commits.GetCommits(
|
||||
loaders.GetCommitsOptions{
|
||||
Limit: gui.State.Panels.Commits.LimitCommits,
|
||||
Limit: gui.State.LimitCommits,
|
||||
FilterPath: gui.State.Modes.Filtering.GetPath(),
|
||||
IncludeRebaseCommits: false,
|
||||
RefName: refName,
|
||||
|
@ -96,7 +85,6 @@ func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
|||
}
|
||||
|
||||
gui.State.Model.SubCommits = commits
|
||||
gui.State.Panels.SubCommits.refName = refName
|
||||
gui.State.Contexts.SubCommits.GetPanelState().SetSelectedLineIdx(0)
|
||||
gui.State.Contexts.SubCommits.SetParentContext(gui.currentSideListContext())
|
||||
|
||||
|
@ -104,7 +92,7 @@ func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleNewBranchOffSubCommit() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -113,7 +101,7 @@ func (gui *Gui) handleNewBranchOffSubCommit() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) handleCopySubCommit() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -123,7 +111,7 @@ func (gui *Gui) handleCopySubCommit() error {
|
|||
|
||||
func (gui *Gui) handleCopySubCommitRange() error {
|
||||
// just doing this to ensure something is selected
|
||||
commit := gui.getSelectedSubCommit()
|
||||
commit := gui.State.Contexts.SubCommits.GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -8,18 +8,9 @@ import (
|
|||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
)
|
||||
|
||||
func (gui *Gui) getSelectedSubmodule() *models.SubmoduleConfig {
|
||||
selectedLine := gui.State.Panels.Submodules.SelectedLineIdx
|
||||
if selectedLine == -1 || len(gui.State.Model.Submodules) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Model.Submodules[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) submodulesRenderToMain() error {
|
||||
var task updateTask
|
||||
submodule := gui.getSelectedSubmodule()
|
||||
submodule := gui.State.Contexts.Submodules.GetSelected()
|
||||
if submodule == nil {
|
||||
task = NewRenderStringTask("No submodules")
|
||||
} else {
|
||||
|
|
|
@ -15,17 +15,12 @@ func (gui *Gui) getSelectedSuggestionValue() string {
|
|||
}
|
||||
|
||||
func (gui *Gui) getSelectedSuggestion() *types.Suggestion {
|
||||
selectedLine := gui.State.Panels.Suggestions.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.Suggestions[selectedLine]
|
||||
return gui.State.Contexts.Suggestions.GetSelected()
|
||||
}
|
||||
|
||||
func (gui *Gui) setSuggestions(suggestions []*types.Suggestion) {
|
||||
gui.State.Suggestions = suggestions
|
||||
gui.State.Panels.Suggestions.SelectedLineIdx = 0
|
||||
gui.State.Contexts.Suggestions.SetSelectedLineIdx(0)
|
||||
_ = gui.resetOrigin(gui.Views.Suggestions)
|
||||
_ = gui.State.Contexts.Suggestions.HandleRender()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package gui
|
|||
|
||||
func (self *Gui) tagsRenderToMain() error {
|
||||
var task updateTask
|
||||
tag := self.State.Contexts.Tags.GetSelectedTag()
|
||||
tag := self.State.Contexts.Tags.GetSelected()
|
||||
if tag == nil {
|
||||
task = NewRenderStringTask("No tags")
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,7 @@ type ParentContexter interface {
|
|||
}
|
||||
|
||||
type IBaseContext interface {
|
||||
HasKeybindings
|
||||
ParentContexter
|
||||
|
||||
GetKind() ContextKind
|
||||
|
@ -35,9 +36,7 @@ type IBaseContext interface {
|
|||
|
||||
GetOptionsMap() map[string]string
|
||||
|
||||
GetKeybindings(opts KeybindingsOpts) []*Binding
|
||||
AddKeybindingsFn(KeybindingsFn)
|
||||
GetMouseKeybindings(opts KeybindingsOpts) []*gocui.ViewMouseBinding
|
||||
AddMouseKeybindingsFn(MouseKeybindingsFn)
|
||||
}
|
||||
|
||||
|
@ -50,6 +49,33 @@ type Context interface {
|
|||
HandleRenderToMain() error
|
||||
}
|
||||
|
||||
type IListContext interface {
|
||||
Context
|
||||
|
||||
GetSelectedItemId() string
|
||||
|
||||
GetList() IList
|
||||
|
||||
OnSearchSelect(selectedLineIdx int) error
|
||||
FocusLine()
|
||||
|
||||
GetPanelState() IListPanelState
|
||||
GetViewTrait() IViewTrait
|
||||
}
|
||||
|
||||
type IViewTrait interface {
|
||||
FocusPoint(yIdx int)
|
||||
SetViewPortContent(content string)
|
||||
SetContent(content string)
|
||||
SetFooter(value string)
|
||||
SetOriginX(value int)
|
||||
ViewPortYBounds() (int, int)
|
||||
ScrollLeft()
|
||||
ScrollRight()
|
||||
PageDelta() int
|
||||
SelectedLineIdx() int
|
||||
}
|
||||
|
||||
type OnFocusOpts struct {
|
||||
ClickedViewName string
|
||||
ClickedViewLineIdx int
|
||||
|
@ -76,28 +102,6 @@ type IController interface {
|
|||
Context() Context
|
||||
}
|
||||
|
||||
type IListContext interface {
|
||||
HasKeybindings
|
||||
|
||||
GetSelectedItemId() string
|
||||
HandlePrevLine() error
|
||||
HandleNextLine() error
|
||||
HandleScrollLeft() error
|
||||
HandleScrollRight() error
|
||||
HandlePrevPage() error
|
||||
HandleNextPage() error
|
||||
HandleGotoTop() error
|
||||
HandleGotoBottom() error
|
||||
HandleClick(onClick func() error) error
|
||||
|
||||
OnSearchSelect(selectedLineIdx int) error
|
||||
FocusLine()
|
||||
|
||||
GetPanelState() IListPanelState
|
||||
|
||||
Context
|
||||
}
|
||||
|
||||
type IList interface {
|
||||
IListCursor
|
||||
GetItemsLength() int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue