summaryrefslogtreecommitdiffstats
path: root/pkg/gui
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-03-24 22:07:30 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-26 18:00:46 +1100
commit13b90ac37f40baa648c25fab6d299ae0fa59118b (patch)
tree61dd23273a4b32c3c8d191759cc0ce3ae9d7c08a /pkg/gui
parente039429885996f1335430a856b846d8dc6279325 (diff)
support viewing commits of reflog entry and show better view title
Diffstat (limited to 'pkg/gui')
-rw-r--r--pkg/gui/commit_files_panel.go8
-rw-r--r--pkg/gui/context.go33
-rw-r--r--pkg/gui/context/base_context.go11
-rw-r--r--pkg/gui/context/commit_files_context.go8
-rw-r--r--pkg/gui/context/sub_commits_context.go31
-rw-r--r--pkg/gui/controllers.go2
-rw-r--r--pkg/gui/controllers/switch_to_sub_commits_controller.go8
-rw-r--r--pkg/gui/gui.go5
-rw-r--r--pkg/gui/keybindings.go5
-rw-r--r--pkg/gui/layout.go12
-rw-r--r--pkg/gui/list_context_config.go2
-rw-r--r--pkg/gui/patch_building_panel.go2
-rw-r--r--pkg/gui/patch_options_panel.go2
-rw-r--r--pkg/gui/refresh.go2
-rw-r--r--pkg/gui/types/context.go7
-rw-r--r--pkg/gui/window.go4
16 files changed, 115 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
+ }
}