From 1996eddd9124709431ced14b1650ae5a50963be7 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sun, 21 Nov 2021 12:48:49 +1100 Subject: more efficient context diff size changing --- pkg/gui/basic_context.go | 82 +++++++++++++++++++++++++-------------- pkg/gui/branches_panel.go | 2 +- pkg/gui/commit_files_panel.go | 20 +++++----- pkg/gui/commits_panel.go | 6 ++- pkg/gui/context.go | 26 +++++++++---- pkg/gui/context_config.go | 60 ++++++++++++++++------------ pkg/gui/diff_context_size.go | 24 +++++++++++- pkg/gui/diff_context_size_test.go | 36 ++++++++++++++--- pkg/gui/files_panel.go | 31 +++++++-------- pkg/gui/global_handlers.go | 6 +-- pkg/gui/list_context.go | 31 ++++++++++----- pkg/gui/list_context_config.go | 27 ++++++------- pkg/gui/menu_panel.go | 12 +----- pkg/gui/reflog_panel.go | 2 +- pkg/gui/remote_branches_panel.go | 2 +- pkg/gui/remotes_panel.go | 2 +- pkg/gui/stash_panel.go | 2 +- pkg/gui/status_panel.go | 4 +- pkg/gui/sub_commits_panel.go | 2 +- pkg/gui/submodules_panel.go | 2 +- pkg/gui/tags_panel.go | 6 +-- 21 files changed, 239 insertions(+), 146 deletions(-) (limited to 'pkg/gui') diff --git a/pkg/gui/basic_context.go b/pkg/gui/basic_context.go index 78cf85144..1db80ee4a 100644 --- a/pkg/gui/basic_context.go +++ b/pkg/gui/basic_context.go @@ -1,9 +1,11 @@ package gui type BasicContext struct { - OnFocus func() error - OnFocusLost func() error - OnRender func() error + OnFocus func(opts ...OnFocusOpts) error + OnFocusLost func() error + OnRender func() error + // this is for pushing some content to the main view + OnRenderToMain func(opts ...OnFocusOpts) error Kind ContextKind Key ContextKey ViewName string @@ -15,63 +17,83 @@ type BasicContext struct { hasParent bool } -func (c *BasicContext) GetOptionsMap() map[string]string { - if c.OnGetOptionsMap != nil { - return c.OnGetOptionsMap() +func (self *BasicContext) GetOptionsMap() map[string]string { + if self.OnGetOptionsMap != nil { + return self.OnGetOptionsMap() } return nil } -func (c *BasicContext) SetParentContext(context Context) { - c.ParentContext = context - c.hasParent = true +func (self *BasicContext) SetParentContext(context Context) { + self.ParentContext = context + self.hasParent = true } -func (c *BasicContext) GetParentContext() (Context, bool) { - return c.ParentContext, c.hasParent +func (self *BasicContext) GetParentContext() (Context, bool) { + return self.ParentContext, self.hasParent } -func (c *BasicContext) SetWindowName(windowName string) { - c.WindowName = windowName +func (self *BasicContext) SetWindowName(windowName string) { + self.WindowName = windowName } -func (c *BasicContext) GetWindowName() string { - windowName := c.WindowName +func (self *BasicContext) GetWindowName() string { + windowName := self.WindowName if windowName != "" { return windowName } // TODO: actually set this for everything so we don't default to the view name - return c.ViewName + return self.ViewName } -func (c *BasicContext) HandleRender() error { - if c.OnRender != nil { - return c.OnRender() +func (self *BasicContext) HandleRender() error { + if self.OnRender != nil { + return self.OnRender() } return nil } -func (c *BasicContext) GetViewName() string { - return c.ViewName +func (self *BasicContext) GetViewName() string { + return self.ViewName } -func (c *BasicContext) HandleFocus() error { - return c.OnFocus() +func (self *BasicContext) HandleFocus(opts ...OnFocusOpts) error { + 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 (c *BasicContext) HandleFocusLost() error { - if c.OnFocusLost != nil { - return c.OnFocusLost() +func (self *BasicContext) HandleFocusLost() error { + if self.OnFocusLost != nil { + return self.OnFocusLost() } return nil } -func (c *BasicContext) GetKind() ContextKind { - return c.Kind +func (self *BasicContext) HandleRenderToMain() error { + if self.OnRenderToMain != nil { + return self.OnRenderToMain() + } + + return nil +} + +func (self *BasicContext) GetKind() ContextKind { + return self.Kind } -func (c *BasicContext) GetKey() ContextKey { - return c.Key +func (self *BasicContext) GetKey() ContextKey { + return self.Key } diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index e913f6f8d..487084e97 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -25,7 +25,7 @@ func (gui *Gui) getSelectedBranch() *models.Branch { return gui.State.Branches[selectedLine] } -func (gui *Gui) handleBranchSelect() error { +func (gui *Gui) branchesRenderToMain() error { var task updateTask branch := gui.getSelectedBranch() if branch == nil { diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index a01551e8d..e89108e46 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -31,9 +31,12 @@ func (gui *Gui) getSelectedCommitFilePath() string { return node.GetPath() } -func (gui *Gui) handleCommitFileSelect() error { +func (gui *Gui) onCommitFileFocus() error { gui.escapeLineByLinePanel() + return nil +} +func (gui *Gui) commitFilesRenderToMain() error { node := gui.getSelectedCommitFileNode() if node == nil { return nil @@ -198,10 +201,10 @@ func (gui *Gui) startPatchManager() error { } func (gui *Gui) handleEnterCommitFile() error { - return gui.enterCommitFile(-1) + return gui.enterCommitFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1}) } -func (gui *Gui) enterCommitFile(selectedLineIdx int) error { +func (gui *Gui) enterCommitFile(opts OnFocusOpts) error { node := gui.getSelectedCommitFileNode() if node == nil { return nil @@ -211,17 +214,14 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { return gui.handleToggleCommitFileDirCollapsed() } - enterTheFile := func(selectedLineIdx int) error { + enterTheFile := func() error { if !gui.GitCommand.PatchManager.Active() { if err := gui.startPatchManager(); err != nil { return err } } - if err := gui.pushContext(gui.State.Contexts.PatchBuilding); err != nil { - return err - } - return gui.handleRefreshPatchBuildingPanel(selectedLineIdx) + return gui.pushContext(gui.State.Contexts.PatchBuilding, opts) } if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileManager.GetParent() { @@ -231,7 +231,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { handlersManageFocus: true, handleConfirm: func() error { gui.GitCommand.PatchManager.Reset() - return enterTheFile(selectedLineIdx) + return enterTheFile() }, handleClose: func() error { return gui.pushContext(gui.State.Contexts.CommitFiles) @@ -239,7 +239,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { }) } - return enterTheFile(selectedLineIdx) + return enterTheFile() } func (gui *Gui) handleToggleCommitFileDirCollapsed() error { diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 77558ab8e..395b8bf9f 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -24,7 +24,7 @@ func (gui *Gui) getSelectedLocalCommit() *models.Commit { return gui.State.Commits[selectedLine] } -func (gui *Gui) handleCommitSelect() error { +func (gui *Gui) onCommitFocus() error { state := gui.State.Panels.Commits if state.SelectedLineIdx > COMMIT_THRESHOLD && state.LimitCommits { state.LimitCommits = false @@ -37,6 +37,10 @@ func (gui *Gui) handleCommitSelect() error { gui.escapeLineByLinePanel() + return nil +} + +func (gui *Gui) branchCommitsRenderToMain() error { var task updateTask commit := gui.getSelectedLocalCommit() if commit == nil { diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 61c7e60a3..2c9d20f7e 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -1,6 +1,7 @@ package gui import ( + "errors" "fmt" "github.com/jesseduffield/gocui" @@ -16,10 +17,16 @@ const ( EXTRAS_CONTEXT ) +type OnFocusOpts struct { + ClickedViewName string + ClickedViewLineIdx int +} + type Context interface { - HandleFocus() error + HandleFocus(opts ...OnFocusOpts) error HandleFocusLost() error HandleRender() error + HandleRenderToMain() error GetKind() ContextKind GetViewName() string GetWindowName() string @@ -81,15 +88,20 @@ func (gui *Gui) replaceContext(c Context) error { return nil } -func (gui *Gui) pushContext(c Context) error { +func (gui *Gui) pushContext(c Context, opts ...OnFocusOpts) error { + // using triple dot but you should only ever pass one of these opt structs + if len(opts) > 1 { + return errors.New("cannot pass multiple opts to pushContext") + } + gui.g.Update(func(*gocui.Gui) error { - return gui.pushContextDirect(c) + return gui.pushContextDirect(c, opts...) }) return nil } -func (gui *Gui) pushContextDirect(c Context) error { +func (gui *Gui) pushContextDirect(c Context, opts ...OnFocusOpts) error { gui.State.ContextManager.Lock() // push onto stack @@ -114,7 +126,7 @@ func (gui *Gui) pushContextDirect(c Context) error { gui.State.ContextManager.Unlock() - return gui.activateContext(c) + return gui.activateContext(c, opts...) } // asynchronous code idea: functions return an error via a channel, when done @@ -206,7 +218,7 @@ func (gui *Gui) postRefreshUpdate(c Context) error { return nil } -func (gui *Gui) activateContext(c Context) error { +func (gui *Gui) activateContext(c Context, opts ...OnFocusOpts) error { viewName := c.GetViewName() v, err := gui.g.View(viewName) if err != nil { @@ -249,7 +261,7 @@ func (gui *Gui) activateContext(c Context) error { } gui.renderOptionsMap(optionsMap) - if err := c.HandleFocus(); err != nil { + if err := c.HandleFocus(opts...); err != nil { return err } diff --git a/pkg/gui/context_config.go b/pkg/gui/context_config.go index d2459ccb5..9e12a1896 100644 --- a/pkg/gui/context_config.go +++ b/pkg/gui/context_config.go @@ -110,10 +110,10 @@ func (gui *Gui) allContexts() []Context { func (gui *Gui) contextTree() ContextTree { return ContextTree{ Status: &BasicContext{ - OnFocus: gui.handleStatusSelect, - Kind: SIDE_CONTEXT, - ViewName: "status", - Key: STATUS_CONTEXT_KEY, + OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain), + Kind: SIDE_CONTEXT, + ViewName: "status", + Key: STATUS_CONTEXT_KEY, }, Files: gui.filesListContext(), Submodules: gui.submodulesListContext(), @@ -128,7 +128,7 @@ func (gui *Gui) contextTree() ContextTree { Tags: gui.tagsListContext(), Stash: gui.stashListContext(), Normal: &BasicContext{ - OnFocus: func() error { + OnFocus: func(opts ...OnFocusOpts) error { return nil // TODO: should we do something here? We should allow for scrolling the panel }, Kind: MAIN_CONTEXT, @@ -136,65 +136,67 @@ func (gui *Gui) contextTree() ContextTree { Key: MAIN_NORMAL_CONTEXT_KEY, }, Staging: &BasicContext{ - OnFocus: func() error { - return nil - // TODO: centralise the code here - // return gui.refreshStagingPanel(false, -1) - }, - OnRender: func() error { - return gui.handleRefreshStagingPanel(false, -1) + OnRenderToMain: func(opts ...OnFocusOpts) error { + forceSecondaryFocused := false + selectedLineIdx := -1 + if len(opts) > 0 && opts[0].ClickedViewName != "" { + if opts[0].ClickedViewName == "main" || opts[0].ClickedViewName == "secondary" { + selectedLineIdx = opts[0].ClickedViewLineIdx + } + if opts[0].ClickedViewName == "secondary" { + forceSecondaryFocused = true + } + } + return gui.handleRefreshStagingPanel(forceSecondaryFocused, selectedLineIdx) }, Kind: MAIN_CONTEXT, ViewName: "main", Key: MAIN_STAGING_CONTEXT_KEY, }, PatchBuilding: &BasicContext{ - OnFocus: func() error { - return nil - // TODO: centralise the code here - // return gui.refreshPatchBuildingPanel(-1) - }, - OnRender: func() error { - return gui.handleRefreshPatchBuildingPanel(-1) + OnRenderToMain: func(opts ...OnFocusOpts) error { + selectedLineIdx := -1 + if len(opts) > 0 && (opts[0].ClickedViewName == "main" || opts[0].ClickedViewName == "secondary") { + selectedLineIdx = opts[0].ClickedViewLineIdx + } + + return gui.handleRefreshPatchBuildingPanel(selectedLineIdx) }, Kind: MAIN_CONTEXT, ViewName: "main", Key: MAIN_PATCH_BUILDING_CONTEXT_KEY, }, Merging: &BasicContext{ - OnFocus: gui.refreshMergePanelWithLock, + OnFocus: OnFocusWrapper(gui.refreshMergePanelWithLock), Kind: MAIN_CONTEXT, ViewName: "main", Key: MAIN_MERGING_CONTEXT_KEY, OnGetOptionsMap: gui.getMergingOptions, }, Credentials: &BasicContext{ - OnFocus: gui.handleCredentialsViewFocused, + OnFocus: OnFocusWrapper(gui.handleCredentialsViewFocused), Kind: PERSISTENT_POPUP, ViewName: "credentials", Key: CREDENTIALS_CONTEXT_KEY, }, Confirmation: &BasicContext{ - OnFocus: func() error { return nil }, Kind: TEMPORARY_POPUP, ViewName: "confirmation", Key: CONFIRMATION_CONTEXT_KEY, }, Suggestions: gui.suggestionsListContext(), CommitMessage: &BasicContext{ - OnFocus: gui.handleCommitMessageFocused, + OnFocus: OnFocusWrapper(gui.handleCommitMessageFocused), Kind: PERSISTENT_POPUP, ViewName: "commitMessage", Key: COMMIT_MESSAGE_CONTEXT_KEY, }, Search: &BasicContext{ - OnFocus: func() error { return nil }, Kind: PERSISTENT_POPUP, ViewName: "search", Key: SEARCH_CONTEXT_KEY, }, CommandLog: &BasicContext{ - OnFocus: func() error { return nil }, Kind: EXTRAS_CONTEXT, ViewName: "extras", Key: COMMAND_LOG_CONTEXT_KEY, @@ -207,6 +209,14 @@ func (gui *Gui) contextTree() ContextTree { } } +// using this wrapper for when an onFocus function doesn't care about any potential +// props that could be passed +func OnFocusWrapper(f func() error) func(opts ...OnFocusOpts) error { + return func(opts ...OnFocusOpts) error { + return f() + } +} + func (tree ContextTree) initialViewContextMap() map[string]Context { return map[string]Context{ "status": tree.Status, diff --git a/pkg/gui/diff_context_size.go b/pkg/gui/diff_context_size.go index a54a9c418..fdf147496 100644 --- a/pkg/gui/diff_context_size.go +++ b/pkg/gui/diff_context_size.go @@ -1,5 +1,9 @@ package gui +import ( + "errors" +) + func isShowingDiff(gui *Gui) bool { key := gui.currentStaticContext().GetKey() @@ -8,8 +12,12 @@ func isShowingDiff(gui *Gui) bool { func (gui *Gui) IncreaseContextInDiffView() error { if isShowingDiff(gui) { + if err := gui.CheckCanChangeContext(); err != nil { + return gui.surfaceError(err) + } + gui.Config.GetUserConfig().Git.DiffContextSize = gui.Config.GetUserConfig().Git.DiffContextSize + 1 - return gui.postRefreshUpdate(gui.currentStaticContext()) + return gui.currentStaticContext().HandleRenderToMain() } return nil @@ -19,8 +27,20 @@ func (gui *Gui) DecreaseContextInDiffView() error { old_size := gui.Config.GetUserConfig().Git.DiffContextSize if isShowingDiff(gui) && old_size > 1 { + if err := gui.CheckCanChangeContext(); err != nil { + return gui.surfaceError(err) + } + gui.Config.GetUserConfig().Git.DiffContextSize = old_size - 1 - return gui.postRefreshUpdate(gui.currentStaticContext()) + return gui.currentStaticContext().HandleRenderToMain() + } + + return nil +} + +func (gui *Gui) CheckCanChangeContext() error { + if gui.GitCommand.PatchManager.Active() { + return errors.New(gui.Tr.CantChangeContextSizeError) } return nil diff --git a/pkg/gui/diff_context_size_test.go b/pkg/gui/diff_context_size_test.go index 3725a81a6..bd5758bf7 100644 --- a/pkg/gui/diff_context_size_test.go +++ b/pkg/gui/diff_context_size_test.go @@ -28,11 +28,11 @@ func setupGuiForTest(gui *Gui) { gui.Views.Main, _ = gui.prepareView("main") gui.Views.Secondary, _ = gui.prepareView("secondary") gui.GitCommand.PatchManager = &patch.PatchManager{} - gui.refreshLineByLinePanel(diffForTest, "", false, 11) + gui.refreshLineByLinePanel(diffForTest, "", false, 11) } func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) { - contexts := []func(gui *Gui) Context { + contexts := []func(gui *Gui) Context{ func(gui *Gui) Context { return gui.State.Contexts.Files }, func(gui *Gui) Context { return gui.State.Contexts.BranchCommits }, func(gui *Gui) Context { return gui.State.Contexts.CommitFiles }, @@ -56,7 +56,7 @@ func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) { } func TestDoesntIncreaseContextInDiffViewInContextWithoutDiff(t *testing.T) { - contexts := []func(gui *Gui) Context { + contexts := []func(gui *Gui) Context{ func(gui *Gui) Context { return gui.State.Contexts.Status }, func(gui *Gui) Context { return gui.State.Contexts.Submodules }, func(gui *Gui) Context { return gui.State.Contexts.Remotes }, @@ -82,7 +82,7 @@ func TestDoesntIncreaseContextInDiffViewInContextWithoutDiff(t *testing.T) { } func TestDecreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) { - contexts := []func(gui *Gui) Context { + contexts := []func(gui *Gui) Context{ func(gui *Gui) Context { return gui.State.Contexts.Files }, func(gui *Gui) Context { return gui.State.Contexts.BranchCommits }, func(gui *Gui) Context { return gui.State.Contexts.CommitFiles }, @@ -106,7 +106,7 @@ func TestDecreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) { } func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) { - contexts := []func(gui *Gui) Context { + contexts := []func(gui *Gui) Context{ func(gui *Gui) Context { return gui.State.Contexts.Status }, func(gui *Gui) Context { return gui.State.Contexts.Submodules }, func(gui *Gui) Context { return gui.State.Contexts.Remotes }, @@ -119,7 +119,7 @@ func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) { } for _, c := range contexts { - gui := NewDummyGui() + gui := NewDummyGui() context := c(gui) setupGuiForTest(gui) gui.Config.GetUserConfig().Git.DiffContextSize = 2 @@ -131,6 +131,30 @@ func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) { } } +func TestDoesntIncreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *testing.T) { + gui := NewDummyGui() + setupGuiForTest(gui) + gui.Config.GetUserConfig().Git.DiffContextSize = 2 + gui.pushContextDirect(gui.State.Contexts.CommitFiles) + gui.GitCommand.PatchManager.Start("from", "to", false, false) + + gui.IncreaseContextInDiffView() + + assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize) +} + +func TestDoesntDecreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *testing.T) { + gui := NewDummyGui() + setupGuiForTest(gui) + gui.Config.GetUserConfig().Git.DiffContextSize = 2 + gui.pushContextDirect(gui.State.Contexts.CommitFiles) + gui.GitCommand.PatchManager.Start("from", "to", false, false) + + gui.DecreaseContextInDiffView() + + assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize) +} + func TestDecreasesContextInDiffViewNoFurtherThanOne(t *testing.T) { gui := NewDummyGui() setupGuiForTest(gui) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 6b5d0dd5d..a6f6a9f08 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -42,9 +42,7 @@ func (gui *Gui) getSelectedPath() string { return node.GetPath() } -func (gui *Gui) selectFile(alreadySelected bool) error { - gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx) - +func (gui *Gui) filesRenderToMain() error { node := gui.getSelectedFileNode() if node == nil { @@ -56,10 +54,6 @@ func (gui *Gui) selectFile(alreadySelected bool) error { }) } - if !alreadySelected { - gui.takeOverMergeConflictScrolling() - } - if node.File != nil && node.File.HasInlineMergeConflicts { return gui.refreshMergePanelWithLock() } @@ -121,9 +115,12 @@ func (gui *Gui) refreshFilesAndSubmodules() error { if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (g.CurrentView() == gui.Views.Main && ContextKey(g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) { newSelectedPath := gui.getSelectedPath() alreadySelected := selectedPath != "" && newSelectedPath == selectedPath - if err := gui.selectFile(alreadySelected); err != nil { - return err + if !alreadySelected { + gui.takeOverMergeConflictScrolling() } + + gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx) + return gui.filesRenderToMain() } return nil @@ -166,10 +163,10 @@ func (gui *Gui) stageSelectedFile() error { } func (gui *Gui) handleEnterFile() error { - return gui.enterFile(false, -1) + return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1}) } -func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error { +func (gui *Gui) enterFile(opts OnFocusOpts) error { node := gui.getSelectedFileNode() if node == nil { return nil @@ -193,9 +190,8 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error if file.HasMergeConflicts { return gui.createErrorPanel(gui.Tr.FileStagingRequirements) } - _ = gui.pushContext(gui.State.Contexts.Staging) - return gui.handleRefreshStagingPanel(forceSecondaryFocused, selectedLineIdx) // TODO: check if this is broken, try moving into context code + return gui.pushContext(gui.State.Contexts.Staging, opts) } func (gui *Gui) handleFilePress() error { @@ -243,7 +239,7 @@ func (gui *Gui) handleFilePress() error { return err } - return gui.selectFile(true) + return gui.State.Contexts.Files.HandleFocus() } func (gui *Gui) allFilesStaged() bool { @@ -255,8 +251,9 @@ func (gui *Gui) allFilesStaged() bool { return true } -func (gui *Gui) focusAndSelectFile() error { - return gui.selectFile(false) +func (gui *Gui) onFocusFile() error { + gui.takeOverMergeConflictScrolling() + return nil } func (gui *Gui) handleStageAll() error { @@ -274,7 +271,7 @@ func (gui *Gui) handleStageAll() error { return err } - return gui.selectFile(false) + return gui.State.Contexts.Files.HandleFocus() } func (gui *Gui) handleIgnoreFile() error { diff --git a/pkg/gui/global_handlers.go b/pkg/gui/global_handlers.go index c104c1664..e0f05ca44 100644 --- a/pkg/gui/global_handlers.go +++ b/pkg/gui/global_handlers.go @@ -189,9 +189,9 @@ func (gui *Gui) handleMouseDownMain() error { // set filename, set primary/secondary selected, set line number, then switch context // I'll need to know it was changed though. // Could I pass something along to the context change? - return gui.enterFile(false, gui.Views.Main.SelectedLineIdx()) + return gui.enterFile(OnFocusOpts{ClickedViewName: "main", ClickedViewLineIdx: gui.Views.Main.SelectedLineIdx()}) case gui.State.Contexts.CommitFiles: - return gui.enterCommitFile(gui.Views.Main.SelectedLineIdx()) + return gui.enterCommitFile(OnFocusOpts{ClickedViewName: "main", ClickedViewLineIdx: gui.Views.Main.SelectedLineIdx()}) } return nil @@ -204,7 +204,7 @@ func (gui *Gui) handleMouseDownSecondary() error { switch gui.g.CurrentView() { case gui.Views.Files: - return gui.enterFile(true, gui.Views.Secondary.SelectedLineIdx()) + return gui.enterFile(OnFocusOpts{ClickedViewName: "secondary", ClickedViewLineIdx: gui.Views.Secondary.SelectedLineIdx()}) } return nil diff --git a/pkg/gui/list_context.go b/pkg/gui/list_context.go index a7c47e480..445b0f3d0 100644 --- a/pkg/gui/list_context.go +++ b/pkg/gui/list_context.go @@ -9,7 +9,8 @@ import ( type ListContext struct { GetItemsLength func() int GetDisplayStrings func(startIdx int, length int) [][]string - OnFocus func() error + OnFocus func(...OnFocusOpts) error + OnRenderToMain func(...OnFocusOpts) error OnFocusLost func() error OnClickSelectedItem func() error @@ -29,7 +30,6 @@ type ListContext struct { type IListContext interface { GetSelectedItem() (ListItem, bool) GetSelectedItemId() string - OnRender() error handlePrevLine() error handleNextLine() error handleScrollLeft() error @@ -42,6 +42,7 @@ type IListContext interface { handleClick() error onSearchSelect(selectedLineIdx int) error FocusLine() + HandleRenderToMain() error GetPanelState() IListPanelState @@ -101,7 +102,7 @@ func (self *ListContext) GetSelectedItemId() string { } // 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) OnRender() error { +func (self *ListContext) HandleRender() error { view, err := self.Gui.g.View(self.ViewName) if err != nil { return nil @@ -131,7 +132,7 @@ func (self *ListContext) HandleFocusLost() error { return nil } -func (self *ListContext) HandleFocus() error { +func (self *ListContext) HandleFocus(opts ...OnFocusOpts) error { if self.Gui.popupPanelFocused() { return nil } @@ -143,14 +144,18 @@ func (self *ListContext) HandleFocus() error { } if self.OnFocus != nil { - return self.OnFocus() + if err := self.OnFocus(opts...); err != nil { + return err + } } - return nil -} + if self.OnRenderToMain != nil { + if err := self.OnRenderToMain(opts...); err != nil { + return err + } + } -func (self *ListContext) HandleRender() error { - return self.OnRender() + return nil } func (self *ListContext) handlePrevLine() error { @@ -268,3 +273,11 @@ 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 +} diff --git a/pkg/gui/list_context_config.go b/pkg/gui/list_context_config.go index 48b08f492..48399e667 100644 --- a/pkg/gui/list_context_config.go +++ b/pkg/gui/list_context_config.go @@ -18,7 +18,6 @@ func (gui *Gui) menuListContext() IListContext { }, GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Menu }, - OnFocus: gui.handleMenuSelect, OnClickSelectedItem: gui.onMenuPress, Gui: gui, @@ -36,7 +35,8 @@ func (gui *Gui) filesListContext() IListContext { }, GetItemsLength: func() int { return gui.State.FileManager.GetItemsLength() }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Files }, - OnFocus: gui.focusAndSelectFile, + OnFocus: OnFocusWrapper(gui.onFocusFile), + OnRenderToMain: OnFocusWrapper(gui.filesRenderToMain), OnClickSelectedItem: gui.handleFilePress, Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { @@ -65,7 +65,7 @@ func (gui *Gui) branchesListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Branches) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Branches }, - OnFocus: gui.handleBranchSelect, + OnRenderToMain: OnFocusWrapper(gui.branchesRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref) @@ -87,7 +87,7 @@ func (gui *Gui) remotesListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Remotes) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Remotes }, - OnFocus: gui.handleRemoteSelect, + OnRenderToMain: OnFocusWrapper(gui.remotesRenderToMain), OnClickSelectedItem: gui.handleRemoteEnter, Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { @@ -110,7 +110,7 @@ func (gui *Gui) remoteBranchesListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.RemoteBranches) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.RemoteBranches }, - OnFocus: gui.handleRemoteBranchSelect, + OnRenderToMain: OnFocusWrapper(gui.remoteBranchesRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Modes.Diffing.Ref) @@ -132,7 +132,7 @@ func (gui *Gui) tagsListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Tags) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Tags }, - OnFocus: gui.handleTagSelect, + OnRenderToMain: OnFocusWrapper(gui.tagsRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Modes.Diffing.Ref) @@ -155,7 +155,8 @@ func (gui *Gui) branchCommitsListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Commits) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Commits }, - OnFocus: gui.handleCommitSelect, + OnFocus: OnFocusWrapper(gui.onCommitFocus), + OnRenderToMain: OnFocusWrapper(gui.branchCommitsRenderToMain), OnClickSelectedItem: gui.handleViewCommitFiles, Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { @@ -197,7 +198,7 @@ func (gui *Gui) subCommitsListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.SubCommits) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.SubCommits }, - OnFocus: gui.handleSubCommitSelect, + OnRenderToMain: OnFocusWrapper(gui.subCommitsRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { selectedCommitSha := "" @@ -253,7 +254,7 @@ func (gui *Gui) reflogCommitsListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.ReflogCommits }, - OnFocus: gui.handleReflogCommitSelect, + OnRenderToMain: OnFocusWrapper(gui.reflogCommitsRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetReflogCommitListDisplayStrings( @@ -281,7 +282,7 @@ func (gui *Gui) stashListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.StashEntries) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Stash }, - OnFocus: gui.handleStashEntrySelect, + OnRenderToMain: OnFocusWrapper(gui.stashRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Modes.Diffing.Ref) @@ -303,7 +304,8 @@ func (gui *Gui) commitFilesListContext() IListContext { }, GetItemsLength: func() int { return gui.State.CommitFileManager.GetItemsLength() }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.CommitFiles }, - OnFocus: gui.handleCommitFileSelect, + OnFocus: OnFocusWrapper(gui.onCommitFileFocus), + OnRenderToMain: OnFocusWrapper(gui.commitFilesRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { if gui.State.CommitFileManager.GetItemsLength() == 0 { @@ -335,7 +337,7 @@ func (gui *Gui) submodulesListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Submodules) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Submodules }, - OnFocus: gui.handleSubmoduleSelect, + OnRenderToMain: OnFocusWrapper(gui.submodulesRenderToMain), Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetSubmoduleListDisplayStrings(gui.State.Submodules) @@ -357,7 +359,6 @@ func (gui *Gui) suggestionsListContext() IListContext { }, GetItemsLength: func() int { return len(gui.State.Suggestions) }, OnGetPanelState: func() IListPanelState { return gui.State.Panels.Suggestions }, - OnFocus: func() error { return nil }, Gui: gui, GetDisplayStrings: func(startIdx int, length int) [][]string { return presentation.GetSuggestionListDisplayStrings(gui.State.Suggestions) diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go index 23c6d91cb..45b5cbf50 100644 --- a/pkg/gui/menu_panel.go +++ b/pkg/gui/menu_panel.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" - "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -27,12 +26,6 @@ func (i *menuItem) ID() string { return strings.Join(i.displayStrings, "-") } -// list panel functions - -func (gui *Gui) handleMenuSelect() error { - return nil -} - // specific functions func (gui *Gui) getMenuOptions() map[string]string { @@ -95,10 +88,7 @@ func (gui *Gui) createMenu(title string, items []*menuItem, createMenuOptions cr menuView.SetContent(list) gui.State.Panels.Menu.SelectedLineIdx = 0 - gui.g.Update(func(g *gocui.Gui) error { - return gui.pushContext(gui.State.Contexts.Menu) - }) - return nil + return gui.pushContext(gui.State.Contexts.Menu) } func (gui *Gui) onMenuPress() error { diff --git a/pkg/gui/reflog_panel.go b/pkg/gui/reflog_panel.go index e00d7c223..a5f1d2614 100644 --- a/pkg/gui/reflog_panel.go +++ b/pkg/gui/reflog_panel.go @@ -16,7 +16,7 @@ func (gui *Gui) getSelectedReflogCommit() *models.Commit { return reflogComits[selectedLine] } -func (gui *Gui) handleReflogCommitSelect() error { +func (gui *Gui) reflogCommitsRenderToMain() error { commit := gui.getSelectedReflogCommit() var task updateTask if commit == nil { diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go index a53a7470c..eba2e5d2b 100644 --- a/pkg/gui/remote_branches_panel.go +++ b/pkg/gui/remote_branches_panel.go @@ -18,7 +18,7 @@ func (gui *Gui) getSelectedRemoteBranch() *models.RemoteBranch { return gui.State.RemoteBranches[selectedLine] } -func (gui *Gui) handleRemoteBranchSelect() error { +func (gui *Gui) remoteBranchesRenderToMain() error { var task updateTask remoteBranch := gui.getSelectedRemoteBranch() if remoteBranch == nil { diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go index 29e723e38..1731aacba 100644 --- a/pkg/gui/remotes_panel.go +++ b/pkg/gui/remotes_panel.go @@ -20,7 +20,7 @@ func (gui *Gui) getSelectedRemote() *models.Remote { return gui.State.Remotes[selectedLine] } -func (gui *Gui) handleRemoteSelect() error { +func (gui *Gui) remotesRenderToMain() error { var task updateTask remote := gui.getSelectedRemote() if remote == nil { diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index d72b32451..61dd6afd8 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -16,7 +16,7 @@ func (gui *Gui) getSelectedStashEntry() *models.StashEntry { return gui.State.StashEntries[selectedLine] } -func (gui *Gui) handleStashEntrySelect() error { +func (gui *Gui) stashRenderToMain() error { var task updateTask stashEntry := gui.getSelectedStashEntry() if stashEntry == nil { diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index 0adc4d383..6072db38c 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -86,10 +86,10 @@ func (gui *Gui) handleStatusClick() error { } } - return gui.handleStatusSelect() + return nil } -func (gui *Gui) handleStatusSelect() error { +func (gui *Gui) statusRenderToMain() error { // TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives) if gui.popupPanelFocused() { return nil diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go index f1c27388a..a60767eea 100644 --- a/pkg/gui/sub_commits_panel.go +++ b/pkg/gui/sub_commits_panel.go @@ -17,7 +17,7 @@ func (gui *Gui) getSelectedSubCommit() *models.Commit { return commits[selectedLine] } -func (gui *Gui) handleSubCommitSelect() error { +func (gui *Gui) subCommitsRenderToMain() error { commit := gui.getSelectedSubCommit() var task updateTask if commit == nil { diff --git a/pkg/gui/submodules_panel.go b/pkg/gui/submodules_panel.go index ff1cb0aeb..4dd6aa628 100644 --- a/pkg/gui/submodules_panel.go +++ b/pkg/gui/submodules_panel.go @@ -19,7 +19,7 @@ func (gui *Gui) getSelectedSubmodule() *models.SubmoduleConfig { return gui.State.Submodules[selectedLine] } -func (gui *Gui) handleSubmoduleSelect() error { +func (gui *Gui) submodulesRenderToMain() error { var task updateTask submodule := gui.getSelectedSubmodule() if submodule == nil { diff --git a/pkg/gui/tags_panel.go b/pkg/gui/tags_panel.go index 2ce52d54a..7ea810e09 100644 --- a/pkg/gui/tags_panel.go +++ b/pkg/gui/tags_panel.go @@ -40,9 +40,7 @@ func (gui *Gui) handleCreateTag() error { }) } -// tag-specific handlers -// view model would need to raise an event called 'tag selected', perhaps containing a tag. The listener would _be_ the main view, or the main context, and it would be able to render to itself. -func (gui *Gui) handleTagSelect() error { +func (gui *Gui) tagsRenderToMain() error { var task updateTask tag := gui.getSelectedTag() if tag == nil { @@ -85,6 +83,8 @@ func (gui *Gui) withSelectedTag(f func(tag *models.Tag) error) func() error { } } +// tag-specific handlers + func (gui *Gui) handleCheckoutTag(tag *models.Tag) error { if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{span: gui.Tr.Spans.CheckoutTag}); err != nil { return err -- cgit v1.2.3