diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index b40055025..a5ad2aff4 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -329,6 +329,10 @@ func (self *MainViewController) onDragInFocusedView(opts gocui.ViewMouseBindingO func (self *MainViewController) onDragRelease(gocui.ViewMouseBindingOpts) error { self.draggingWithMouse = false self.dragAutoscroller.Cancel() + + // The drag moved the selection without going through showSelectionAtLine: gocui + // moves the cursor for it. Let the search catch up with where it ended. + self.context.GetView().SetNearestSearchPosition() return nil } @@ -489,6 +493,11 @@ func hunkModeApplies(c *ControllerCommon, view *gocui.View, changeViewLine int) // screen already. func showSelectionAtLine(view *gocui.View, lineIdx int, scrollIntoView bool) { view.FocusPoint(0, lo.Clamp(lineIdx, 0, max(0, view.ViewLinesHeight()-1)), scrollIntoView) + + // A search carries on from where the selection now is, so that stepping to the + // next match goes to the one after it rather than the one after the match the + // user last stepped to. + view.SetNearestSearchPosition() } func (self *MainViewController) selectHunkAround(changeViewLine int, scrollIntoView bool) { diff --git a/pkg/integration/tests/main_view/search_follows_the_selection.go b/pkg/integration/tests/main_view/search_follows_the_selection.go new file mode 100644 index 000000000..55048cf0f --- /dev/null +++ b/pkg/integration/tests/main_view/search_follows_the_selection.go @@ -0,0 +1,44 @@ +package main_view + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var SearchFollowsTheSelection = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Stepping to the next match in the focused main view carries on from the selection", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "") + shell.Commit("one") + + shell.UpdateFile("file1", "NEEDLE a\ntwo\nNEEDLE b\nfour\nNEEDLE c\n") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Press(keys.Universal.FocusMainView) + + t.Views().Main(). + IsFocused(). + FilterOrSearch("NEEDLE"). + SelectedLines(Contains("+NEEDLE a")). + Tap(func() { + t.Views().Search().Content(Contains("matches for 'NEEDLE' (1 of 3)")) + }). + // Move the selection past the second match by hand. + SelectNextItem(). + SelectNextItem(). + SelectNextItem(). + SelectedLines(Contains("+four")). + Tap(func() { + t.Views().Search().Content(Contains("matches for 'NEEDLE' (2 of 3)")) + }). + // So the next match is the one after where the selection is, not the one + // after the match it was last on. + Press(keys.Universal.NextMatch). + SelectedLines(Contains("+NEEDLE c")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 363c3a265..e4df6b23f 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -378,6 +378,7 @@ var tests = []*components.IntegrationTest{ main_view.NoSelectionWhenNoChanges, main_view.RangeSelectDiffLines, main_view.SearchCollapsesTheSelection, + main_view.SearchFollowsTheSelection, main_view.SelectBelowALongCommitMessage, main_view.SelectBelowALongDiffstat, main_view.SelectDiffLines,