From 80a614d330eff81bd48552525bc6fb6fdf65d7bf Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 4 Jul 2025 10:58:47 +0200 Subject: [PATCH 1/3] Fix collapsing the range selection after deleting branches We had code already that was supposed to do this, but it didn't work. It should have used SetSelection() instead of SetSelectedLineIdx(); the latter doesn't actually cancel a range selection. Introduce a new function specifically for collapsing the range after deleting multiple items, so that clients don't need two calls (we'll add a bunch more in this branch). --- pkg/gui/context/traits/list_cursor.go | 9 +++++++++ pkg/gui/controllers/helpers/branches_helper.go | 8 +++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/gui/context/traits/list_cursor.go b/pkg/gui/context/traits/list_cursor.go index c471d9a0f..3b3e58639 100644 --- a/pkg/gui/context/traits/list_cursor.go +++ b/pkg/gui/context/traits/list_cursor.go @@ -133,10 +133,19 @@ func (self *ListCursor) GetRangeStartIdx() (int, bool) { return 0, false } +// Cancel range select mode, but keep the "moving end" of the range selected. +// Used when pressing 'v' or escape to toggle range select mode, for example. func (self *ListCursor) CancelRangeSelect() { self.rangeSelectMode = RangeSelectModeNone } +// Cancel range select mode, but keep the top of the range selected. Note that +// this is different from CancelRangeSelect. Useful after deleting a range of items. +func (self *ListCursor) CollapseRangeSelectionToTop() { + start, _ := self.GetSelectionRange() + self.SetSelection(start) +} + // Returns true if we are in range select mode. Note that we may be in range select // mode and still only selecting a single item. See AreMultipleItemsSelected below. func (self *ListCursor) IsSelectingRange() bool { diff --git a/pkg/gui/controllers/helpers/branches_helper.go b/pkg/gui/controllers/helpers/branches_helper.go index 2478dee58..4bb390b3e 100644 --- a/pkg/gui/controllers/helpers/branches_helper.go +++ b/pkg/gui/controllers/helpers/branches_helper.go @@ -47,8 +47,8 @@ func (self *BranchesHelper) ConfirmLocalDelete(branches []*models.Branch) error if err := self.c.Git().Branch.LocalDelete(branchNames, true); err != nil { return err } - selectionStart, _ := self.c.Contexts().Branches.GetSelectionRange() - self.c.Contexts().Branches.SetSelectedLineIdx(selectionStart) + + self.c.Contexts().Branches.CollapseRangeSelectionToTop() self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) return nil }) @@ -180,9 +180,7 @@ func (self *BranchesHelper) ConfirmLocalAndRemoteDelete(branches []*models.Branc return err } - selectionStart, _ := self.c.Contexts().Branches.GetSelectionRange() - self.c.Contexts().Branches.SetSelectedLineIdx(selectionStart) - + self.c.Contexts().Branches.CollapseRangeSelectionToTop() self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}}) return nil }) From 4b33efffbe53c6a58b75c88d336674feac95b72c Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 4 Jul 2025 17:04:00 +0200 Subject: [PATCH 2/3] Collapse selection after deleting a range of remote branches We only want to do this when the function is called from the remote branches panel. It can also be called with a selection of local branches in order to delete their remote branches, but in this case the selection shouldn't be collapsed because the local branches stay around. --- pkg/gui/controllers/branches_controller.go | 2 +- pkg/gui/controllers/helpers/branches_helper.go | 5 ++++- pkg/gui/controllers/remote_branches_controller.go | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 47520a653..77e22f1c3 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -535,7 +535,7 @@ func (self *BranchesController) remoteDelete(branches []*models.Branch) error { remoteBranches := lo.Map(branches, func(branch *models.Branch, _ int) *models.RemoteBranch { return &models.RemoteBranch{Name: branch.UpstreamBranch, RemoteName: branch.UpstreamRemote} }) - return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(remoteBranches) + return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(remoteBranches, false) } func (self *BranchesController) localAndRemoteDelete(branches []*models.Branch) error { diff --git a/pkg/gui/controllers/helpers/branches_helper.go b/pkg/gui/controllers/helpers/branches_helper.go index 4bb390b3e..8760c4366 100644 --- a/pkg/gui/controllers/helpers/branches_helper.go +++ b/pkg/gui/controllers/helpers/branches_helper.go @@ -82,7 +82,7 @@ func (self *BranchesHelper) ConfirmLocalDelete(branches []*models.Branch) error return nil } -func (self *BranchesHelper) ConfirmDeleteRemote(remoteBranches []*models.RemoteBranch) error { +func (self *BranchesHelper) ConfirmDeleteRemote(remoteBranches []*models.RemoteBranch, resetRemoteBranchesSelection bool) error { var title string if len(remoteBranches) == 1 { title = utils.ResolvePlaceholderString( @@ -115,6 +115,9 @@ func (self *BranchesHelper) ConfirmDeleteRemote(remoteBranches []*models.RemoteB return err } self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}}) + if resetRemoteBranchesSelection { + self.c.Contexts().RemoteBranches.CollapseRangeSelectionToTop() + } return nil }) }, diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go index 304baa125..629bbbaa3 100644 --- a/pkg/gui/controllers/remote_branches_controller.go +++ b/pkg/gui/controllers/remote_branches_controller.go @@ -133,7 +133,7 @@ func (self *RemoteBranchesController) context() *context.RemoteBranchesContext { } func (self *RemoteBranchesController) delete(selectedBranches []*models.RemoteBranch) error { - return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(selectedBranches) + return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(selectedBranches, true) } func (self *RemoteBranchesController) merge(selectedBranch *models.RemoteBranch) error { From bc0cddf03d2570f7ae6ce42ec3a7b96a85ec222d Mon Sep 17 00:00:00 2001 From: nileric Date: Tue, 24 Jun 2025 18:31:34 +0700 Subject: [PATCH 3/3] Collapse selection after deleting a range of stashes --- pkg/gui/controllers/stash_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/gui/controllers/stash_controller.go b/pkg/gui/controllers/stash_controller.go index c6ec419dc..cd9a613ff 100644 --- a/pkg/gui/controllers/stash_controller.go +++ b/pkg/gui/controllers/stash_controller.go @@ -178,6 +178,7 @@ func (self *StashController) handleStashDrop(stashEntries []*models.StashEntry) return err } } + self.context().CollapseRangeSelectionToTop() return nil }, })