diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2022-03-24 22:07:30 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-03-26 18:00:46 +1100 |
commit | 13b90ac37f40baa648c25fab6d299ae0fa59118b (patch) | |
tree | 61dd23273a4b32c3c8d191759cc0ce3ae9d7c08a /pkg | |
parent | e039429885996f1335430a856b846d8dc6279325 (diff) |
support viewing commits of reflog entry and show better view title
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/gui/commit_files_panel.go | 8 | ||||
-rw-r--r-- | pkg/gui/context.go | 33 | ||||
-rw-r--r-- | pkg/gui/context/base_context.go | 11 | ||||
-rw-r--r-- | pkg/gui/context/commit_files_context.go | 8 | ||||
-rw-r--r-- | pkg/gui/context/sub_commits_context.go | 31 | ||||
-rw-r--r-- | pkg/gui/controllers.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/switch_to_sub_commits_controller.go | 8 | ||||
-rw-r--r-- | pkg/gui/gui.go | 5 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 5 | ||||
-rw-r--r-- | pkg/gui/layout.go | 12 | ||||
-rw-r--r-- | pkg/gui/list_context_config.go | 2 | ||||
-rw-r--r-- | pkg/gui/patch_building_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/patch_options_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/refresh.go | 2 | ||||
-rw-r--r-- | pkg/gui/types/context.go | 7 | ||||
-rw-r--r-- | pkg/gui/window.go | 4 | ||||
-rw-r--r-- | pkg/i18n/english.go | 4 |
17 files changed, 119 insertions, 27 deletions
diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 21afc54f4..4f292d3eb 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -39,24 +39,20 @@ func (gui *Gui) commitFilesRenderToMain() error { } func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesContextOpts) error { - // sometimes the commitFiles view is already shown in another window, so we need to ensure that window - // no longer considers the commitFiles view as its main view. - gui.resetWindowContext(gui.State.Contexts.CommitFiles) - gui.State.Contexts.CommitFiles.SetSelectedLineIdx(0) gui.State.Contexts.CommitFiles.SetRefName(opts.RefName) gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase) gui.State.Contexts.CommitFiles.SetParentContext(opts.Context) gui.State.Contexts.CommitFiles.SetWindowName(opts.Context.GetWindowName()) - if err := gui.refreshCommitFilesView(); err != nil { + if err := gui.refreshCommitFilesContext(); err != nil { return err } return gui.c.PushContext(gui.State.Contexts.CommitFiles) } -func (gui *Gui) refreshCommitFilesView() error { +func (gui *Gui) refreshCommitFilesContext() error { currentSideContext := gui.currentSideContext() if currentSideContext.GetKey() == context.COMMIT_FILES_CONTEXT_KEY || currentSideContext.GetKey() == context.LOCAL_COMMITS_CONTEXT_KEY { if err := gui.handleRefreshPatchBuildingPanel(-1); err != nil { diff --git a/pkg/gui/context.go b/pkg/gui/context.go index e75eb0a05..c02411640 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -11,6 +11,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) func (gui *Gui) popupViewNames() []string { @@ -99,8 +100,6 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error { return gui.activateContext(c, opts...) } -// asynchronous code idea: functions return an error via a channel, when done - // pushContextWithView is to be used when you don't know which context you // want to switch to: you only know the view that you want to switch to. It will // look up the context currently active for that view and switch to that context @@ -136,6 +135,10 @@ func (gui *Gui) returnFromContext() error { } func (gui *Gui) deactivateContext(c types.Context) error { + if c.IsTransient() { + gui.resetWindowContext(c) + } + view, _ := gui.g.View(c.GetViewName()) if view != nil && view.IsSearching() { @@ -145,7 +148,11 @@ func (gui *Gui) deactivateContext(c types.Context) error { } // if we are the kind of context that is sent to back upon deactivation, we should do that - if view != nil && (c.GetKind() == types.TEMPORARY_POPUP || c.GetKind() == types.PERSISTENT_POPUP || c.GetKey() == context.COMMIT_FILES_CONTEXT_KEY) { + if view != nil && + (c.GetKind() == types.TEMPORARY_POPUP || + c.GetKind() == types.PERSISTENT_POPUP || + c.GetKey() == context.COMMIT_FILES_CONTEXT_KEY || + c.GetKey() == context.SUB_COMMITS_CONTEXT_KEY) { view.Visible = false } @@ -204,6 +211,11 @@ func (gui *Gui) activateContext(c types.Context, opts ...types.OnFocusOpts) erro return err } + desiredTitle := c.Title() + if desiredTitle != "" { + v.Title = desiredTitle + } + v.Visible = true // if the new context's view was previously displaying another context, render the new context @@ -380,10 +392,17 @@ func (gui *Gui) onViewFocusLost(oldView *gocui.View, newView *gocui.View) error _ = oldView.SetOriginX(0) - if oldView == gui.Views.CommitFiles && newView != gui.Views.Main && newView != gui.Views.Secondary && newView != gui.Views.Search { - gui.resetWindowContext(gui.State.Contexts.CommitFiles) - if err := gui.deactivateContext(gui.State.Contexts.CommitFiles); err != nil { - return err + if !lo.Contains([]*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Search}, newView) { + transientContexts := slices.Filter(gui.State.Contexts.Flatten(), func(context types.Context) bool { + return context.IsTransient() + }) + + for _, context := range transientContexts { + if oldView.Name() == context.GetViewName() { + if err := gui.deactivateContext(context); err != nil { + return err + } + } } } diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go index 9b006662f..4e73aa0ff 100644 --- a/pkg/gui/context/base_context.go +++ b/pkg/gui/context/base_context.go @@ -17,6 +17,7 @@ type BaseContext struct { onClickFn func() error focusable bool + transient bool *ParentContextMgr } @@ -29,6 +30,7 @@ type NewBaseContextOpts struct { ViewName string WindowName string Focusable bool + Transient bool OnGetOptionsMap func() map[string]string } @@ -41,6 +43,7 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext { windowName: opts.WindowName, onGetOptionsMap: opts.OnGetOptionsMap, focusable: opts.Focusable, + transient: opts.Transient, ParentContextMgr: &ParentContextMgr{}, } } @@ -115,3 +118,11 @@ func (self *BaseContext) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocu func (self *BaseContext) IsFocusable() bool { return self.focusable } + +func (self *BaseContext) IsTransient() bool { + return self.transient +} + +func (self *BaseContext) Title() string { + return "" +} diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go index 0576be102..5ad7144dc 100644 --- a/pkg/gui/context/commit_files_context.go +++ b/pkg/gui/context/commit_files_context.go @@ -1,10 +1,13 @@ package context import ( + "fmt" + "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) type CommitFilesContext struct { @@ -37,6 +40,7 @@ func NewCommitFilesContext( Key: COMMIT_FILES_CONTEXT_KEY, Kind: types.SIDE_CONTEXT, Focusable: true, + Transient: true, }), ContextCallbackOpts{ OnFocus: onFocus, @@ -59,3 +63,7 @@ func (self *CommitFilesContext) GetSelectedItemId() string { return item.ID() } + +func (self *CommitFilesContext) Title() string { + return fmt.Sprintf(self.c.Tr.CommitFilesDynamicTitle, utils.TruncateWithEllipsis(self.GetRefName(), 50)) +} diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 315093f8f..6c1d5910f 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -1,13 +1,16 @@ package context import ( + "fmt" + "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) type SubCommitsContext struct { - *BasicViewModel[*models.Commit] + *SubCommitsViewModel *ViewportListContextTrait } @@ -24,18 +27,22 @@ func NewSubCommitsContext( c *types.HelperCommon, ) *SubCommitsContext { - viewModel := NewBasicViewModel(getModel) + viewModel := &SubCommitsViewModel{ + BasicViewModel: NewBasicViewModel(getModel), + refName: "", + } return &SubCommitsContext{ - BasicViewModel: viewModel, + SubCommitsViewModel: viewModel, ViewportListContextTrait: &ViewportListContextTrait{ ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - ViewName: "branches", + ViewName: "subCommits", WindowName: "branches", Key: SUB_COMMITS_CONTEXT_KEY, Kind: types.SIDE_CONTEXT, Focusable: true, + Transient: true, }), ContextCallbackOpts{ OnFocus: onFocus, OnFocusLost: onFocusLost, @@ -50,6 +57,16 @@ func NewSubCommitsContext( } } +type SubCommitsViewModel struct { + // name of the ref that the sub-commits are shown for + refName string + *BasicViewModel[*models.Commit] +} + +func (self *SubCommitsViewModel) SetRefName(refName string) { + self.refName = refName +} + func (self *SubCommitsContext) GetSelectedItemId() string { item := self.GetSelected() if item == nil { @@ -63,6 +80,8 @@ func (self *SubCommitsContext) CanRebase() bool { return false } +// not to be confused with the refName in the view model. This is the ref name of +// the selected commit func (self *SubCommitsContext) GetSelectedRefName() string { item := self.GetSelected() @@ -76,3 +95,7 @@ func (self *SubCommitsContext) GetSelectedRefName() string { func (self *SubCommitsContext) GetCommits() []*models.Commit { return self.getModel() } + +func (self *SubCommitsContext) Title() string { + return fmt.Sprintf(self.c.Tr.SubCommitsDynamicTitle, utils.TruncateWithEllipsis(self.refName, 50)) +} diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index 8e28e7f6e..9d55625ea 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -135,6 +135,7 @@ func (gui *Gui) resetControllers() { gui.State.Contexts.Branches, gui.State.Contexts.RemoteBranches, gui.State.Contexts.Tags, + gui.State.Contexts.ReflogCommits, } { controllers.AttachControllers(context, controllers.NewSwitchToSubCommitsController( common, setSubCommits, context, @@ -143,7 +144,6 @@ func (gui *Gui) resetControllers() { for _, context := range []controllers.CanSwitchToDiffFiles{ gui.State.Contexts.LocalCommits, - gui.State.Contexts.ReflogCommits, gui.State.Contexts.SubCommits, gui.State.Contexts.Stash, } { diff --git a/pkg/gui/controllers/switch_to_sub_commits_controller.go b/pkg/gui/controllers/switch_to_sub_commits_controller.go index abd8642d3..82b52509b 100644 --- a/pkg/gui/controllers/switch_to_sub_commits_controller.go +++ b/pkg/gui/controllers/switch_to_sub_commits_controller.go @@ -70,8 +70,16 @@ func (self *SwitchToSubCommitsController) viewCommits() error { } self.setSubCommits(commits) + self.contexts.SubCommits.SetSelectedLineIdx(0) self.contexts.SubCommits.SetParentContext(self.context) + self.contexts.SubCommits.SetWindowName(self.context.GetWindowName()) + self.contexts.SubCommits.SetRefName(refName) + + err = self.c.PostRefreshUpdate(self.contexts.SubCommits) + if err != nil { + return err + } return self.c.PushContext(self.contexts.SubCommits) } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 144be8df5..334133487 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -252,6 +252,7 @@ type Views struct { Menu *gocui.View CommitMessage *gocui.View CommitFiles *gocui.View + SubCommits *gocui.View Information *gocui.View AppStatus *gocui.View Search *gocui.View @@ -410,6 +411,7 @@ func initialViewContextMapping(contextTree *context.ContextTree) map[string]type "branches": contextTree.Branches, "commits": contextTree.LocalCommits, "commitFiles": contextTree.CommitFiles, + "subCommits": contextTree.SubCommits, "stash": contextTree.Stash, "menu": contextTree.Menu, "confirmation": contextTree.Confirmation, @@ -601,6 +603,7 @@ func (gui *Gui) createAllViews() error { {viewPtr: &gui.Views.Commits, name: "commits"}, {viewPtr: &gui.Views.Stash, name: "stash"}, {viewPtr: &gui.Views.CommitFiles, name: "commitFiles"}, + {viewPtr: &gui.Views.SubCommits, name: "subCommits"}, {viewPtr: &gui.Views.Main, name: "main"}, {viewPtr: &gui.Views.Secondary, name: "secondary"}, {viewPtr: &gui.Views.Options, name: "options"}, @@ -641,6 +644,8 @@ func (gui *Gui) createAllViews() error { gui.Views.CommitFiles.Title = gui.c.Tr.CommitFiles gui.Views.CommitFiles.FgColor = theme.GocuiDefaultTextColor + gui.Views.SubCommits.FgColor = theme.GocuiDefaultTextColor + gui.Views.Branches.Title = gui.c.Tr.BranchesTitle gui.Views.Branches.FgColor = theme.GocuiDefaultTextColor diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 13fdf7d26..122fbfd04 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -406,7 +406,7 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi Description: self.c.Tr.LcCopyCommitShaToClipboard, }, { - ViewName: "branches", + ViewName: "subCommits", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), Handler: self.handleCopySelectedSideContextItemToClipboard, @@ -426,6 +426,7 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi }, { ViewName: "commitFiles", + Contexts: []string{string(context.COMMIT_FILES_CONTEXT_KEY)}, Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), Handler: self.handleCopySelectedSideContextItemToClipboard, Description: self.c.Tr.LcCopyCommitFileNameToClipboard, @@ -998,7 +999,7 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi mouseKeybindings = append(mouseKeybindings, c.GetMouseKeybindings(opts)...) } - for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} { + for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "subCommits", "stash", "menu"} { bindings = append(bindings, []*types.Binding{ {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.PrevBlock), Modifier: gocui.ModNone, Handler: self.previousSideWindow}, {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.NextBlock), Modifier: gocui.ModNone, Handler: self.nextSideWindow}, diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 350549311..c77c9030d 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -2,6 +2,7 @@ package gui import ( "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/theme" ) @@ -96,6 +97,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { {viewName: "files", windowName: "files", frame: true}, {viewName: "branches", windowName: "branches", frame: true}, {viewName: "commitFiles", windowName: gui.State.Contexts.CommitFiles.GetWindowName(), frame: true}, + {viewName: "subCommits", windowName: gui.State.Contexts.SubCommits.GetWindowName(), frame: true}, {viewName: "commits", windowName: "commits", frame: true}, {viewName: "stash", windowName: "stash", frame: true}, {viewName: "options", windowName: "options", frame: false}, @@ -113,8 +115,13 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } - // if the commit files view is the view to be displayed for its window, we'll display it - gui.Views.CommitFiles.Visible = gui.getViewNameForWindow(gui.State.Contexts.CommitFiles.GetWindowName()) == "commitFiles" + for _, context := range []types.Context{gui.State.Contexts.SubCommits, gui.State.Contexts.CommitFiles} { + view, err := gui.g.View(context.GetViewName()) + if err != nil && err.Error() != UNKNOWN_VIEW_ERROR_MSG { + return err + } + view.Visible = gui.getViewNameForWindow(context.GetWindowName()) == context.GetViewName() + } if gui.PrevLayout.Information != informationStr { gui.setViewContent(gui.Views.Information, informationStr) @@ -206,6 +213,7 @@ func (gui *Gui) onInitialViewsCreation() error { gui.Views.Branches, gui.Views.Commits, gui.Views.Stash, + gui.Views.SubCommits, gui.Views.CommitFiles, gui.Views.Main, gui.Views.Secondary, diff --git a/pkg/gui/list_context_config.go b/pkg/gui/list_context_config.go index 5a3f172f0..b2f267a6a 100644 --- a/pkg/gui/list_context_config.go +++ b/pkg/gui/list_context_config.go @@ -141,7 +141,7 @@ func (gui *Gui) branchCommitsListContext() *context.LocalCommitsContext { func (gui *Gui) subCommitsListContext() *context.SubCommitsContext { return context.NewSubCommitsContext( func() []*models.Commit { return gui.State.Model.SubCommits }, - gui.Views.Branches, + gui.Views.SubCommits, func(startIdx int, length int) [][]string { selectedCommitSha := "" if gui.currentContext().GetKey() == context.SUB_COMMITS_CONTEXT_KEY { diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index cae6167a4..b2c3c4ab2 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -90,7 +90,7 @@ func (gui *Gui) handleToggleSelectionForPatch() error { return err } - if err := gui.refreshCommitFilesView(); err != nil { + if err := gui.refreshCommitFilesContext(); err != nil { return err } diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index 14de524a5..439b726cb 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -194,5 +194,5 @@ func (gui *Gui) handleResetPatch() error { return err } } - return gui.refreshCommitFilesView() + return gui.refreshCommitFilesContext() } diff --git a/pkg/gui/refresh.go b/pkg/gui/refresh.go index 602eb37e9..f56cb55d7 100644 --- a/pkg/gui/refresh.go +++ b/pkg/gui/refresh.go @@ -187,7 +187,7 @@ func (gui *Gui) refreshCommits() { commit := gui.getSelectedLocalCommit() if commit != nil { gui.State.Contexts.CommitFiles.SetRefName(commit.RefName()) - _ = gui.refreshCommitFilesView() + _ = gui.refreshCommitFilesContext() } } wg.Done() diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index 58dee1c0e..bf4051538 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -33,6 +33,13 @@ type IBaseContext interface { SetWindowName(string) GetKey() ContextKey IsFocusable() bool + // if a context is transient, then when it loses focus, its corresponding view + // returns control of the window to the default view for that window + IsTransient() bool + + // returns the desired title for the view upon activation. If there is no desired title (returns empty string), then + // no title will be set + Title() string GetOptionsMap() map[string]string diff --git a/pkg/gui/window.go b/pkg/gui/window.go index 4ea33292a..88d93d5ae 100644 --- a/pkg/gui/window.go +++ b/pkg/gui/window.go @@ -35,5 +35,7 @@ func (gui *Gui) currentWindow() string { func (gui *Gui) resetWindowContext(c types.Context) { // we assume here that the window contains as its default view a view with the same name as the window windowName := c.GetWindowName() - gui.State.WindowViewNameMap[windowName] = windowName + if gui.State.WindowViewNameMap[windowName] == c.GetViewName() { + gui.State.WindowViewNameMap[windowName] = windowName + } } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index b09b6550c..a5cadb47d 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -230,6 +230,8 @@ type TranslationSet struct { CheckingOutStatus string CommittingStatus string CommitFiles string + SubCommitsDynamicTitle string + CommitFilesDynamicTitle string LcViewItemFiles string CommitFilesTitle string LcCheckoutCommitFile string @@ -819,6 +821,8 @@ func EnglishTranslationSet() TranslationSet { CheckingOutStatus: "checking out", CommittingStatus: "committing", CommitFiles: "Commit files", + SubCommitsDynamicTitle: "Commits for %s", + CommitFilesDynamicTitle: "Diff files for %s", LcViewItemFiles: "view selected item's files", CommitFilesTitle: "Commit Files", LcCheckoutCommitFile: "checkout file", |