summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-03-23 10:03:08 +0100
committerStefan Haller <stefan@haller-berlin.de>2024-03-23 11:46:10 +0100
commitbef8620d4fb39ea4ec5e659c1fd1a89123d2fe67 (patch)
tree8cb091aa0f7ab541c7ba05b09c978e52a93c072e
parente1c3ef66295bf949de5e7781c0a60ac7f79c47ce (diff)
Keep the same commit selected when exiting filtering modeselect-same-commit-again-on-exit-filter-mode
When exiting filtering mode, we currently keep the selection index the same in the commits panel. This doesn't make sense at all, since the index in the filtered view has no relation to the index in the unfiltered view. I often use filtering mode (either by path or by author) to find a given commit faster than I would otherwise be able to. When exiting filtering mode, it's useful to keep the same commit selected, so that I can look at the surrounding commits, see which branch it was a part of, etc. So reselect the commit again after exiting filtering mode. Sometimes this is not possible, most likely when the commit is so long ago that it's outside of the initial 300 range. In that case, at least select the commit again that was selected before I entered filtering; this is still better than arbitrarily keeping the same selection index.
-rw-r--r--pkg/gui/context/local_commits_context.go22
-rw-r--r--pkg/gui/controllers/filtering_menu_action.go2
-rw-r--r--pkg/gui/controllers/helpers/mode_helper.go15
-rw-r--r--pkg/gui/modes/filtering/filtering.go13
-rw-r--r--pkg/integration/tests/filter_by_path/keep_same_commit_selected_on_exit.go51
-rw-r--r--pkg/integration/tests/test_list.go1
6 files changed, 101 insertions, 3 deletions
diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go
index 604d51205..784bab0c1 100644
--- a/pkg/gui/context/local_commits_context.go
+++ b/pkg/gui/context/local_commits_context.go
@@ -8,6 +8,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/samber/lo"
)
type LocalCommitsContext struct {
@@ -125,6 +126,27 @@ func (self *LocalCommitsContext) GetSelectedRef() types.Ref {
return commit
}
+// Returns the commit hash of the selected commit, or an empty string if no
+// commit is selected
+func (self *LocalCommitsContext) GetSelectedCommitHash() string {
+ commit := self.GetSelected()
+ if commit == nil {
+ return ""
+ }
+ return commit.Sha
+}
+
+func (self *LocalCommitsContext) SelectCommitByHash(hash string) bool {
+ if hash != "" {
+ if _, idx, found := lo.FindIndexOf(self.GetItems(), func(c *models.Commit) bool { return c.Sha == hash }); found {
+ self.SetSelection(idx)
+ return true
+ }
+ }
+
+ return false
+}
+
func (self *LocalCommitsContext) GetDiffTerminals() []string {
itemId := self.GetSelectedItemId()
diff --git a/pkg/gui/controllers/filtering_menu_action.go b/pkg/gui/controllers/filtering_menu_action.go
index 9af0276e5..3771cdabd 100644
--- a/pkg/gui/controllers/filtering_menu_action.go
+++ b/pkg/gui/controllers/filtering_menu_action.go
@@ -109,6 +109,8 @@ func (self *FilteringMenuAction) setFilteringAuthor(author string) error {
}
func (self *FilteringMenuAction) setFiltering() error {
+ self.c.Modes().Filtering.SetSelectedCommitHash(self.c.Contexts().LocalCommits.GetSelectedCommitHash())
+
repoState := self.c.State().GetRepoState()
if repoState.GetScreenMode() == types.SCREEN_NORMAL {
repoState.SetScreenMode(types.SCREEN_HALF)
diff --git a/pkg/gui/controllers/helpers/mode_helper.go b/pkg/gui/controllers/helpers/mode_helper.go
index a25862252..0745c2288 100644
--- a/pkg/gui/controllers/helpers/mode_helper.go
+++ b/pkg/gui/controllers/helpers/mode_helper.go
@@ -163,12 +163,25 @@ func (self *ModeHelper) ExitFilterMode() error {
}
func (self *ModeHelper) ClearFiltering() error {
+ selectedCommitHash := self.c.Contexts().LocalCommits.GetSelectedCommitHash()
self.c.Modes().Filtering.Reset()
if self.c.State().GetRepoState().GetScreenMode() == types.SCREEN_HALF {
self.c.State().GetRepoState().SetScreenMode(types.SCREEN_NORMAL)
}
- return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.COMMITS}})
+ return self.c.Refresh(types.RefreshOptions{
+ Scope: []types.RefreshableView{types.COMMITS},
+ Then: func() {
+ // Find the commit that was last selected in filtering mode, and select it again after refreshing
+ if !self.c.Contexts().LocalCommits.SelectCommitByHash(selectedCommitHash) {
+ // If we couldn't find it (either because no commit was selected
+ // in filtering mode, or because the commit is outside the
+ // initial 300 range), go back to the commit that was selected
+ // before we entered filtering
+ self.c.Contexts().LocalCommits.SelectCommitByHash(self.c.Modes().Filtering.GetSelectedCommitHash())
+ }
+ },
+ })
}
func (self *ModeHelper) SetSuppressRebasingMode(value bool) {
diff --git a/pkg/gui/modes/filtering/filtering.go b/pkg/gui/modes/filtering/filtering.go
index 368df31f2..acdb94e53 100644
--- a/pkg/gui/modes/filtering/filtering.go
+++ b/pkg/gui/modes/filtering/filtering.go
@@ -1,8 +1,9 @@
package filtering
type Filtering struct {
- path string // the filename that gets passed to git log
- author string // the author that gets passed to git log
+ path string // the filename that gets passed to git log
+ author string // the author that gets passed to git log
+ selectedCommitHash string // the commit that was selected before we entered filtering mode
}
func New(path string, author string) Filtering {
@@ -33,3 +34,11 @@ func (m *Filtering) SetAuthor(author string) {
func (m *Filtering) GetAuthor() string {
return m.author
}
+
+func (m *Filtering) SetSelectedCommitHash(hash string) {
+ m.selectedCommitHash = hash
+}
+
+func (m *Filtering) GetSelectedCommitHash() string {
+ return m.selectedCommitHash
+}
diff --git a/pkg/integration/tests/filter_by_path/keep_same_commit_selected_on_exit.go b/pkg/integration/tests/filter_by_path/keep_same_commit_selected_on_exit.go
new file mode 100644
index 000000000..728a5aedf
--- /dev/null
+++ b/pkg/integration/tests/filter_by_path/keep_same_commit_selected_on_exit.go
@@ -0,0 +1,51 @@
+package filter_by_path
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var KeepSameCommitSelectedOnExit = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "When exiting filtering mode, keep the same commit selected if possible",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {
+ },
+ SetupRepo: func(shell *Shell) {
+ commonSetup(shell)
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Commits().
+ Focus().
+ Lines(
+ Contains(`none of the two`).IsSelected(),
+ Contains(`only filterFile`),
+ Contains(`only otherFile`),
+ Contains(`both files`),
+ ).Press(keys.Universal.FilteringMenu).
+ Tap(func() {
+ t.ExpectPopup().Menu().
+ Title(Equals("Filtering")).
+ Select(Contains("Enter path to filter by")).
+ Confirm()
+
+ t.ExpectPopup().Prompt().
+ Title(Equals("Enter path:")).
+ Type("filterF").
+ SuggestionLines(Equals("filterFile")).
+ ConfirmFirstSuggestion()
+ }).
+ Lines(
+ Contains(`only filterFile`).IsSelected(),
+ Contains(`both files`),
+ ).
+ SelectNextItem().
+ PressEscape().
+ Lines(
+ Contains(`none of the two`),
+ Contains(`only filterFile`),
+ Contains(`only otherFile`),
+ Contains(`both files`).IsSelected(),
+ )
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 1dbfe95fb..26d4f4b78 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -156,6 +156,7 @@ var tests = []*components.IntegrationTest{
filter_by_author.SelectAuthor,
filter_by_author.TypeAuthor,
filter_by_path.CliArg,
+ filter_by_path.KeepSameCommitSelectedOnExit,
filter_by_path.SelectFile,
filter_by_path.TypeFile,
interactive_rebase.AdvancedInteractiveRebase,