diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go index 037554c91..ad1ffa031 100644 --- a/pkg/gui/context/commit_files_context.go +++ b/pkg/gui/context/commit_files_context.go @@ -63,7 +63,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext { } ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error { - ctx.GetList().SetSelectedLineIdx(selectedLineIdx) + ctx.GetList().SetSelection(selectedLineIdx) return ctx.HandleFocus(types.OnFocusOpts{}) })) diff --git a/pkg/gui/context/filtered_list_view_model.go b/pkg/gui/context/filtered_list_view_model.go index 1e649550a..c8abbe4a1 100644 --- a/pkg/gui/context/filtered_list_view_model.go +++ b/pkg/gui/context/filtered_list_view_model.go @@ -31,5 +31,5 @@ func (self *FilteredListViewModel[T]) ClearFilter() { self.FilteredList.ClearFilter() - self.SetSelectedLineIdx(unfilteredIndex) + self.SetSelection(unfilteredIndex) } diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go index c4f0e2549..d7315c9ec 100644 --- a/pkg/gui/context/list_context_trait.go +++ b/pkg/gui/context/list_context_trait.go @@ -102,7 +102,7 @@ func (self *ListContextTrait) HandleRender() error { } func (self *ListContextTrait) OnSearchSelect(selectedLineIdx int) error { - self.GetList().SetSelectedLineIdx(selectedLineIdx) + self.GetList().SetSelection(selectedLineIdx) return self.HandleFocus(types.OnFocusOpts{}) } diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index e0172638d..61a40b30b 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -85,7 +85,7 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext { } ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error { - ctx.GetList().SetSelectedLineIdx(selectedLineIdx) + ctx.GetList().SetSelection(selectedLineIdx) return ctx.HandleFocus(types.OnFocusOpts{}) })) diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 79b0d9781..1f795b44d 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -134,7 +134,7 @@ func NewSubCommitsContext( } ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error { - ctx.GetList().SetSelectedLineIdx(selectedLineIdx) + ctx.GetList().SetSelection(selectedLineIdx) return ctx.HandleFocus(types.OnFocusOpts{}) })) diff --git a/pkg/gui/context/suggestions_context.go b/pkg/gui/context/suggestions_context.go index e3c1f5f26..0921a7329 100644 --- a/pkg/gui/context/suggestions_context.go +++ b/pkg/gui/context/suggestions_context.go @@ -74,7 +74,7 @@ func (self *SuggestionsContext) GetSelectedItemId() string { func (self *SuggestionsContext) SetSuggestions(suggestions []*types.Suggestion) { self.State.Suggestions = suggestions - self.SetSelectedLineIdx(0) + self.SetSelection(0) self.c.ResetViewOrigin(self.GetView()) _ = self.HandleRender() } diff --git a/pkg/gui/context/traits/list_cursor.go b/pkg/gui/context/traits/list_cursor.go index 647f2a36b..85cf22e30 100644 --- a/pkg/gui/context/traits/list_cursor.go +++ b/pkg/gui/context/traits/list_cursor.go @@ -45,10 +45,25 @@ func (self *ListCursor) GetSelectedLineIdx() int { return self.selectedIdx } +// Sets the selected line index. Note, you probably don't want to use this directly, +// because it doesn't affect the range select mode or range start index. You should only +// use this for navigation situations where e.g. the user wants to jump to the top of +// a list while in range select mode so that the selection ends up being between +// the top of the list and the previous selection func (self *ListCursor) SetSelectedLineIdx(value int) { self.selectedIdx = self.clampValue(value) } +// Sets the selected index and cancels the range. You almost always want to use +// this instead of SetSelectedLineIdx. For example, if you want to jump the cursor +// to the top of a list after checking out a branch, you should use this method, +// or you may end up with a large range selection from the previous cursor position +// to the top of the list. +func (self *ListCursor) SetSelection(value int) { + self.selectedIdx = self.clampValue(value) + self.CancelRangeSelect() +} + func (self *ListCursor) clampValue(value int) int { clampedValue := -1 if self.list.Len() > 0 { diff --git a/pkg/gui/context/working_tree_context.go b/pkg/gui/context/working_tree_context.go index 0e0b8d72b..72a991f76 100644 --- a/pkg/gui/context/working_tree_context.go +++ b/pkg/gui/context/working_tree_context.go @@ -50,7 +50,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext { } ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error { - ctx.GetList().SetSelectedLineIdx(selectedLineIdx) + ctx.GetList().SetSelection(selectedLineIdx) return ctx.HandleFocus(types.OnFocusOpts{}) })) diff --git a/pkg/gui/controllers/bisect_controller.go b/pkg/gui/controllers/bisect_controller.go index 7cb36ef26..bff603afb 100644 --- a/pkg/gui/controllers/bisect_controller.go +++ b/pkg/gui/controllers/bisect_controller.go @@ -265,7 +265,7 @@ func (self *BisectController) selectCurrentBisectCommit() { // find index of commit with that sha, move cursor to that. for i, commit := range self.c.Model().Commits { if commit.Sha == info.GetCurrentSha() { - self.context().SetSelectedLineIdx(i) + self.context().SetSelection(i) _ = self.context().HandleFocus(types.OnFocusOpts{}) break } diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 866f3eae3..8e762d78b 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -424,7 +424,7 @@ func (self *BranchesController) createNewBranchWithName(newBranchName string) er return self.c.Error(err) } - self.context().SetSelectedLineIdx(0) + self.context().SetSelection(0) return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) } @@ -627,7 +627,7 @@ func (self *BranchesController) createSortMenu() error { if self.c.GetAppState().LocalBranchSortOrder != sortOrder { self.c.GetAppState().LocalBranchSortOrder = sortOrder self.c.SaveAppStateAndLogError() - self.c.Contexts().Branches.SetSelectedLineIdx(0) + self.c.Contexts().Branches.SetSelection(0) return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) } return nil @@ -658,7 +658,7 @@ func (self *BranchesController) rename(branch *models.Branch) error { // now that we've got our stuff again we need to find that branch and reselect it. for i, newBranch := range self.c.Model().Branches { if newBranch.Name == newBranchName { - self.context().SetSelectedLineIdx(i) + self.context().SetSelection(i) if err := self.context().HandleRender(); err != nil { return err } diff --git a/pkg/gui/controllers/filtering_menu_action.go b/pkg/gui/controllers/filtering_menu_action.go index 6a0f3b2db..d8525b99d 100644 --- a/pkg/gui/controllers/filtering_menu_action.go +++ b/pkg/gui/controllers/filtering_menu_action.go @@ -73,7 +73,7 @@ func (self *FilteringMenuAction) setFiltering(path string) error { } return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.COMMITS}, Then: func() { - self.c.Contexts().LocalCommits.SetSelectedLineIdx(0) + self.c.Contexts().LocalCommits.SetSelection(0) self.c.Contexts().LocalCommits.FocusLine() }}) } diff --git a/pkg/gui/controllers/helpers/fixup_helper.go b/pkg/gui/controllers/helpers/fixup_helper.go index 35c8233b8..0a1bc713e 100644 --- a/pkg/gui/controllers/helpers/fixup_helper.go +++ b/pkg/gui/controllers/helpers/fixup_helper.go @@ -87,7 +87,7 @@ func (self *FixupHelper) HandleFindBaseCommitForFixupPress() error { _ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}}) } - self.c.Contexts().LocalCommits.SetSelectedLineIdx(index) + self.c.Contexts().LocalCommits.SetSelection(index) return self.c.PushContext(self.c.Contexts().LocalCommits) } diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go index 6d0d64983..4e4461526 100644 --- a/pkg/gui/controllers/helpers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -44,9 +44,9 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions cmdOptions := git_commands.CheckoutOptions{Force: false, EnvVars: options.EnvVars} onSuccess := func() { - self.c.Contexts().Branches.SetSelectedLineIdx(0) - self.c.Contexts().ReflogCommits.SetSelectedLineIdx(0) - self.c.Contexts().LocalCommits.SetSelectedLineIdx(0) + self.c.Contexts().Branches.SetSelection(0) + self.c.Contexts().ReflogCommits.SetSelection(0) + self.c.Contexts().LocalCommits.SetSelection(0) // loading a heap of commits is slow so we limit them whenever doing a reset self.c.Contexts().LocalCommits.SetLimitCommits(true) } @@ -107,8 +107,8 @@ func (self *RefsHelper) ResetToRef(ref string, strength string, envVars []string return self.c.Error(err) } - self.c.Contexts().LocalCommits.SetSelectedLineIdx(0) - self.c.Contexts().ReflogCommits.SetSelectedLineIdx(0) + self.c.Contexts().LocalCommits.SetSelection(0) + self.c.Contexts().ReflogCommits.SetSelection(0) // loading a heap of commits is slow so we limit them whenever doing a reset self.c.Contexts().LocalCommits.SetLimitCommits(true) @@ -215,8 +215,8 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest } } - self.c.Contexts().LocalCommits.SetSelectedLineIdx(0) - self.c.Contexts().Branches.SetSelectedLineIdx(0) + self.c.Contexts().LocalCommits.SetSelection(0) + self.c.Contexts().Branches.SetSelection(0) return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) }, diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index 4c4b6918c..9ceea2f90 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -216,7 +216,7 @@ func (self *SearchHelper) OnPromptContentChanged(searchString string) { state := self.searchState() switch context := state.Context.(type) { case types.IFilterableContext: - context.SetSelectedLineIdx(0) + context.SetSelection(0) _ = context.GetView().SetOriginY(0) context.SetFilter(searchString) _ = self.c.PostRefreshUpdate(context) @@ -232,7 +232,7 @@ func (self *SearchHelper) ReApplyFilter(context types.Context) { if context == state.Context { filterableContext, ok := context.(types.IFilterableContext) if ok { - filterableContext.SetSelectedLineIdx(0) + filterableContext.SetSelection(0) _ = filterableContext.GetView().SetOriginY(0) filterableContext.ReApplyFilter() } diff --git a/pkg/gui/controllers/helpers/sub_commits_helper.go b/pkg/gui/controllers/helpers/sub_commits_helper.go index 7f5417cc3..b572aa45b 100644 --- a/pkg/gui/controllers/helpers/sub_commits_helper.go +++ b/pkg/gui/controllers/helpers/sub_commits_helper.go @@ -53,7 +53,7 @@ func (self *SubCommitsHelper) ViewSubCommits(opts ViewSubCommitsOpts) error { self.refreshHelper.RefreshAuthors(commits) subCommitsContext := self.c.Contexts().SubCommits - subCommitsContext.SetSelectedLineIdx(0) + subCommitsContext.SetSelection(0) subCommitsContext.SetParentContext(opts.Context) subCommitsContext.SetWindowName(opts.Context.GetWindowName()) subCommitsContext.SetTitleRef(utils.TruncateWithEllipsis(opts.TitleRef, 50)) diff --git a/pkg/gui/controllers/list_controller.go b/pkg/gui/controllers/list_controller.go index 1f3c743bc..9b7a740b5 100644 --- a/pkg/gui/controllers/list_controller.go +++ b/pkg/gui/controllers/list_controller.go @@ -160,7 +160,7 @@ func (self *ListController) HandleClick(opts gocui.ViewMouseBindingOpts) error { return nil } - self.context.GetList().SetSelectedLineIdx(newSelectedLineIdx) + self.context.GetList().SetSelection(newSelectedLineIdx) if prevSelectedLineIdx == newSelectedLineIdx && alreadyFocused && self.context.GetOnClick() != nil { return self.context.GetOnClick()() diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 97151f4fe..c484d2487 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -459,7 +459,7 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit( return c.Sha == selectedCommit.Sha }) if ok { - self.context().SetSelectedLineIdx(index) + self.context().SetSelection(index) } }}) }) diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go index 04afd6415..d6f9e9036 100644 --- a/pkg/gui/controllers/remote_branches_controller.go +++ b/pkg/gui/controllers/remote_branches_controller.go @@ -132,7 +132,7 @@ func (self *RemoteBranchesController) createSortMenu() error { if self.c.GetAppState().RemoteBranchSortOrder != sortOrder { self.c.GetAppState().RemoteBranchSortOrder = sortOrder self.c.SaveAppStateAndLogError() - self.c.Contexts().RemoteBranches.SetSelectedLineIdx(0) + self.c.Contexts().RemoteBranches.SetSelection(0) return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.REMOTES}}) } return nil diff --git a/pkg/gui/controllers/remotes_controller.go b/pkg/gui/controllers/remotes_controller.go index d0f643eec..47f14417e 100644 --- a/pkg/gui/controllers/remotes_controller.go +++ b/pkg/gui/controllers/remotes_controller.go @@ -106,7 +106,7 @@ func (self *RemotesController) enter(remote *models.Remote) error { newSelectedLine = -1 } remoteBranchesContext := self.c.Contexts().RemoteBranches - remoteBranchesContext.SetSelectedLineIdx(newSelectedLine) + remoteBranchesContext.SetSelection(newSelectedLine) remoteBranchesContext.SetTitleRef(remote.Name) remoteBranchesContext.SetParentContext(self.Context()) remoteBranchesContext.GetView().TitlePrefix = self.Context().GetView().TitlePrefix diff --git a/pkg/gui/controllers/stash_controller.go b/pkg/gui/controllers/stash_controller.go index 5d74e10af..acd66cd31 100644 --- a/pkg/gui/controllers/stash_controller.go +++ b/pkg/gui/controllers/stash_controller.go @@ -189,7 +189,7 @@ func (self *StashController) handleRenameStashEntry(stashEntry *models.StashEntr if err != nil { return err } - self.context().SetSelectedLineIdx(0) // Select the renamed stash + self.context().SetSelection(0) // Select the renamed stash self.context().FocusLine() return nil }, diff --git a/pkg/gui/controllers/switch_to_diff_files_controller.go b/pkg/gui/controllers/switch_to_diff_files_controller.go index 7143a8805..af2b38984 100644 --- a/pkg/gui/controllers/switch_to_diff_files_controller.go +++ b/pkg/gui/controllers/switch_to_diff_files_controller.go @@ -77,7 +77,7 @@ func (self *SwitchToDiffFilesController) Context() types.Context { func (self *SwitchToDiffFilesController) viewFiles(opts SwitchToCommitFilesContextOpts) error { diffFilesContext := self.diffFilesContext - diffFilesContext.SetSelectedLineIdx(0) + diffFilesContext.SetSelection(0) diffFilesContext.SetRef(opts.Ref) diffFilesContext.SetTitleRef(opts.Ref.Description()) diffFilesContext.SetCanRebase(opts.CanRebase) diff --git a/pkg/gui/controllers/tags_controller.go b/pkg/gui/controllers/tags_controller.go index dcbef4d2c..e96dde2e4 100644 --- a/pkg/gui/controllers/tags_controller.go +++ b/pkg/gui/controllers/tags_controller.go @@ -210,7 +210,9 @@ func (self *TagsController) createResetMenu(tag *models.Tag) error { func (self *TagsController) create() error { // leaving commit SHA blank so that we're just creating the tag for the current commit - return self.c.Helpers().Tags.OpenCreateTagPrompt("", func() { self.context().SetSelectedLineIdx(0) }) + return self.c.Helpers().Tags.OpenCreateTagPrompt("", func() { + self.context().SetSelection(0) + }) } func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error { diff --git a/pkg/gui/filetree/commit_file_tree_view_model.go b/pkg/gui/filetree/commit_file_tree_view_model.go index a022bc25e..d7bc447a1 100644 --- a/pkg/gui/filetree/commit_file_tree_view_model.go +++ b/pkg/gui/filetree/commit_file_tree_view_model.go @@ -106,6 +106,6 @@ func (self *CommitFileTreeViewModel) ToggleShowTree() { index, found := self.GetIndexForPath(path) if found { - self.SetSelectedLineIdx(index) + self.SetSelection(index) } } diff --git a/pkg/gui/filetree/file_tree_view_model.go b/pkg/gui/filetree/file_tree_view_model.go index f19f74fbc..2364087d3 100644 --- a/pkg/gui/filetree/file_tree_view_model.go +++ b/pkg/gui/filetree/file_tree_view_model.go @@ -81,7 +81,7 @@ func (self *FileTreeViewModel) SetTree() { newNodes := self.GetAllItems() newIdx := self.findNewSelectedIdx(prevNodes[prevSelectedLineIdx:], newNodes) if newIdx != -1 && newIdx != prevSelectedLineIdx { - self.SetSelectedLineIdx(newIdx) + self.SetSelection(newIdx) } } @@ -128,7 +128,7 @@ func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNod func (self *FileTreeViewModel) SetStatusFilter(filter FileTreeDisplayFilter) { self.IFileTree.SetStatusFilter(filter) - self.IListCursor.SetSelectedLineIdx(0) + self.IListCursor.SetSelection(0) } // If we're going from flat to tree we want to select the same file. diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 6acdc804c..66ef453da 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -329,7 +329,7 @@ func (gui *Gui) onNewRepo(startArgs appTypes.StartArgs, contextKey types.Context // because e.g. with worktrees, we'll show the current worktree at the top of the list. listContext, ok := contextToPush.(types.IListContext) if ok { - listContext.GetList().SetSelectedLineIdx(0) + listContext.GetList().SetSelection(0) } } diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go index 88095584d..fe05e7e32 100644 --- a/pkg/gui/menu_panel.go +++ b/pkg/gui/menu_panel.go @@ -43,7 +43,7 @@ func (gui *Gui) createMenu(opts types.CreateMenuOptions) error { } gui.State.Contexts.Menu.SetMenuItems(opts.Items, opts.ColumnAlignment) - gui.State.Contexts.Menu.SetSelectedLineIdx(0) + gui.State.Contexts.Menu.SetSelection(0) gui.Views.Menu.Title = opts.Title gui.Views.Menu.FgColor = theme.GocuiDefaultTextColor diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index b20d70beb..3557cf5aa 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -224,6 +224,7 @@ type IList interface { type IListCursor interface { GetSelectedLineIdx() int SetSelectedLineIdx(value int) + SetSelection(value int) MoveSelectedLine(delta int) ClampSelection() CancelRangeSelect() @@ -236,6 +237,7 @@ type IListCursor interface { type IListPanelState interface { SetSelectedLineIdx(int) + SetSelection(int) GetSelectedLineIdx() int }