1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-11-28 09:08:41 +02:00

Keep the same commit selected when exiting filtering mode (#3416)

- **PR Description**

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.
This commit is contained in:
Stefan Haller 2024-03-28 12:27:02 +01:00 committed by GitHub
commit 04fcb78c0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 103 additions and 3 deletions

View File

@ -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,29 @@ 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 == "" {
return false
}
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()

View File

@ -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)

View File

@ -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) {

View File

@ -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
}

View File

@ -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(),
)
},
})

View File

@ -157,6 +157,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,