From b5ca6a3add3b6d1fbf428dba84ee558e7cb16568 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 8 Oct 2023 19:52:54 +0200 Subject: When refreshing models, re-apply active filter for the corresponding view --- pkg/gui/context/filtered_list.go | 4 ++ pkg/gui/controllers.go | 4 +- pkg/gui/controllers/helpers/refresh_helper.go | 38 +++++++++------- pkg/gui/controllers/helpers/search_helper.go | 12 +++++ pkg/gui/types/context.go | 1 + .../filter_updates_when_model_changes.go | 52 ++++++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 7 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go diff --git a/pkg/gui/context/filtered_list.go b/pkg/gui/context/filtered_list.go index d2361ad53..82d9b81c8 100644 --- a/pkg/gui/context/filtered_list.go +++ b/pkg/gui/context/filtered_list.go @@ -41,6 +41,10 @@ func (self *FilteredList[T]) ClearFilter() { self.SetFilter("") } +func (self *FilteredList[T]) ReApplyFilter() { + self.applyFilter() +} + func (self *FilteredList[T]) IsFiltering() bool { return self.filter != "" } diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index 43b226b58..6a751e1ef 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -47,6 +47,7 @@ func (gui *Gui) resetHelpersAndControllers() { patchBuildingHelper := helpers.NewPatchBuildingHelper(helperCommon) stagingHelper := helpers.NewStagingHelper(helperCommon) mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon) + searchHelper := helpers.NewSearchHelper(helperCommon) refreshHelper := helpers.NewRefreshHelper( helperCommon, @@ -56,6 +57,7 @@ func (gui *Gui) resetHelpersAndControllers() { stagingHelper, mergeConflictsHelper, worktreeHelper, + searchHelper, ) diffHelper := helpers.NewDiffHelper(helperCommon) cherryPickHelper := helpers.NewCherryPickHelper( @@ -119,7 +121,7 @@ func (gui *Gui) resetHelpersAndControllers() { modeHelper, appStatusHelper, ), - Search: helpers.NewSearchHelper(helperCommon), + Search: searchHelper, Worktree: worktreeHelper, SubCommits: helpers.NewSubCommitsHelper(helperCommon, refreshHelper, setSubCommits), } diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index a299ea431..dc43844e2 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -28,6 +28,7 @@ type RefreshHelper struct { stagingHelper *StagingHelper mergeConflictsHelper *MergeConflictsHelper worktreeHelper *WorktreeHelper + searchHelper *SearchHelper } func NewRefreshHelper( @@ -38,6 +39,7 @@ func NewRefreshHelper( stagingHelper *StagingHelper, mergeConflictsHelper *MergeConflictsHelper, worktreeHelper *WorktreeHelper, + searchHelper *SearchHelper, ) *RefreshHelper { return &RefreshHelper{ c: c, @@ -47,6 +49,7 @@ func NewRefreshHelper( stagingHelper: stagingHelper, mergeConflictsHelper: mergeConflictsHelper, worktreeHelper: worktreeHelper, + searchHelper: searchHelper, } } @@ -328,7 +331,7 @@ func (self *RefreshHelper) refreshCommitsWithLimit() error { self.c.Model().WorkingTreeStateAtLastCommitRefresh = self.c.Git().Status.WorkingTreeState() self.c.Model().CheckedOutBranch = checkedOutBranchName - return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits) + return self.refreshView(self.c.Contexts().LocalCommits) } func (self *RefreshHelper) refreshSubCommitsWithLimit() error { @@ -351,7 +354,7 @@ func (self *RefreshHelper) refreshSubCommitsWithLimit() error { self.c.Model().SubCommits = commits self.RefreshAuthors(commits) - return self.c.PostRefreshUpdate(self.c.Contexts().SubCommits) + return self.refreshView(self.c.Contexts().SubCommits) } func (self *RefreshHelper) RefreshAuthors(commits []*models.Commit) { @@ -381,7 +384,7 @@ func (self *RefreshHelper) refreshCommitFilesContext() error { self.c.Model().CommitFiles = files self.c.Contexts().CommitFiles.CommitFileTreeViewModel.SetTree() - return self.c.PostRefreshUpdate(self.c.Contexts().CommitFiles) + return self.refreshView(self.c.Contexts().CommitFiles) } func (self *RefreshHelper) refreshRebaseCommits() error { @@ -395,7 +398,7 @@ func (self *RefreshHelper) refreshRebaseCommits() error { self.c.Model().Commits = updatedCommits self.c.Model().WorkingTreeStateAtLastCommitRefresh = self.c.Git().Status.WorkingTreeState() - return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits) + return self.refreshView(self.c.Contexts().LocalCommits) } func (self *RefreshHelper) refreshTags() error { @@ -406,7 +409,7 @@ func (self *RefreshHelper) refreshTags() error { self.c.Model().Tags = tags - return self.c.PostRefreshUpdate(self.c.Contexts().Tags) + return self.refreshView(self.c.Contexts().Tags) } func (self *RefreshHelper) refreshStateSubmoduleConfigs() error { @@ -448,12 +451,12 @@ func (self *RefreshHelper) refreshBranches(refreshWorktrees bool) { if refreshWorktrees { self.loadWorktrees() - if err := self.c.PostRefreshUpdate(self.c.Contexts().Worktrees); err != nil { + if err := self.refreshView(self.c.Contexts().Worktrees); err != nil { self.c.Log.Error(err) } } - if err := self.c.PostRefreshUpdate(self.c.Contexts().Branches); err != nil { + if err := self.refreshView(self.c.Contexts().Branches); err != nil { self.c.Log.Error(err) } @@ -485,11 +488,11 @@ func (self *RefreshHelper) refreshFilesAndSubmodules() error { } self.c.OnUIThread(func() error { - if err := self.c.PostRefreshUpdate(self.c.Contexts().Submodules); err != nil { + if err := self.refreshView(self.c.Contexts().Submodules); err != nil { self.c.Log.Error(err) } - if err := self.c.PostRefreshUpdate(self.c.Contexts().Files); err != nil { + if err := self.refreshView(self.c.Contexts().Files); err != nil { self.c.Log.Error(err) } @@ -611,7 +614,7 @@ func (self *RefreshHelper) refreshReflogCommits() error { model.FilteredReflogCommits = model.ReflogCommits } - return self.c.PostRefreshUpdate(self.c.Contexts().ReflogCommits) + return self.refreshView(self.c.Contexts().ReflogCommits) } func (self *RefreshHelper) refreshRemotes() error { @@ -635,11 +638,11 @@ func (self *RefreshHelper) refreshRemotes() error { } } - if err := self.c.PostRefreshUpdate(self.c.Contexts().Remotes); err != nil { + if err := self.refreshView(self.c.Contexts().Remotes); err != nil { return err } - if err := self.c.PostRefreshUpdate(self.c.Contexts().RemoteBranches); err != nil { + if err := self.refreshView(self.c.Contexts().RemoteBranches); err != nil { return err } @@ -661,18 +664,18 @@ func (self *RefreshHelper) refreshWorktrees() error { // need to refresh branches because the branches view shows worktrees against // branches - if err := self.c.PostRefreshUpdate(self.c.Contexts().Branches); err != nil { + if err := self.refreshView(self.c.Contexts().Branches); err != nil { return err } - return self.c.PostRefreshUpdate(self.c.Contexts().Worktrees) + return self.refreshView(self.c.Contexts().Worktrees) } func (self *RefreshHelper) refreshStashEntries() error { self.c.Model().StashEntries = self.c.Git().Loaders.StashLoader. GetStashEntries(self.c.Modes().Filtering.GetPath()) - return self.c.PostRefreshUpdate(self.c.Contexts().Stash) + return self.refreshView(self.c.Contexts().Stash) } // never call this on its own, it should only be called from within refreshCommits() @@ -711,3 +714,8 @@ func (self *RefreshHelper) refForLog() string { return bisectInfo.GetStartSha() } + +func (self *RefreshHelper) refreshView(context types.Context) error { + self.searchHelper.ReApplyFilter(context) + return self.c.PostRefreshUpdate(context) +} diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index c036bda3d..4c4b6918c 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -227,6 +227,18 @@ func (self *SearchHelper) OnPromptContentChanged(searchString string) { } } +func (self *SearchHelper) ReApplyFilter(context types.Context) { + state := self.searchState() + if context == state.Context { + filterableContext, ok := context.(types.IFilterableContext) + if ok { + filterableContext.SetSelectedLineIdx(0) + _ = filterableContext.GetView().SetOriginY(0) + filterableContext.ReApplyFilter() + } + } +} + func (self *SearchHelper) RenderSearchStatus(c types.Context) { if c.GetKey() == context.SEARCH_CONTEXT_KEY { return diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index df16cf2bd..c47945aee 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -102,6 +102,7 @@ type IFilterableContext interface { SetFilter(string) GetFilter() string ClearFilter() + ReApplyFilter() IsFiltering() bool IsFilterableContext() } diff --git a/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go b/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go new file mode 100644 index 000000000..ae3c862c0 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go @@ -0,0 +1,52 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FilterUpdatesWhenModelChanges = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Verify that after deleting a branch the filter is reapplied to show only the remaining branches", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("first commit") + shell.NewBranch("branch-to-delete") + shell.NewBranch("other") + shell.NewBranch("checked-out-branch") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + Lines( + Contains("checked-out-branch").IsSelected(), + Contains("other"), + Contains("branch-to-delete"), + Contains("master"), + ). + FilterOrSearch("branch"). + Lines( + Contains("branch-to-delete").IsSelected(), + Contains("checked-out-branch"), + ). + Press(keys.Universal.Remove). + Tap(func() { + t.ExpectPopup(). + Menu(). + Title(Equals("Delete branch 'branch-to-delete'?")). + Select(Contains("Delete local branch")). + Confirm() + }). + Lines( + Contains("checked-out-branch").IsSelected(), + ). + // cancel the filter + PressEscape(). + Lines( + Contains("checked-out-branch").IsSelected(), + Contains("other"), + Contains("master"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 521656d10..cea838380 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -133,6 +133,7 @@ var tests = []*components.IntegrationTest{ filter_and_search.FilterRemoteBranches, filter_and_search.FilterRemotes, filter_and_search.FilterSearchHistory, + filter_and_search.FilterUpdatesWhenModelChanges, filter_and_search.NestedFilter, filter_and_search.NestedFilterTransient, filter_and_search.NewSearch, -- cgit v1.2.3