diff --git a/go.mod b/go.mod index 2c609288d..b082b968b 100644 --- a/go.mod +++ b/go.mod @@ -9,13 +9,13 @@ require ( github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 github.com/creack/pty v1.1.11 github.com/fsmiamoto/git-todo-parser v0.0.5 - github.com/go-errors/errors v1.5.0 + github.com/go-errors/errors v1.5.1 github.com/gookit/color v1.4.2 github.com/imdario/mergo v0.3.11 github.com/integrii/flaggy v1.4.0 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d - github.com/jesseduffield/gocui v0.3.1-0.20230909074155-fc7119a39341 + github.com/jesseduffield/gocui v0.3.1-0.20230925062444-7cd0d7e2a70a github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e diff --git a/go.sum b/go.sum index 5b4853b2c..deff61581 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs= -github.com/go-errors/errors v1.5.0 h1:/EuijeGOu7ckFxzhkj4CXJ8JaenxK7bKUxpPYqeLHqQ= -github.com/go-errors/errors v1.5.0/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= @@ -179,8 +179,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= -github.com/jesseduffield/gocui v0.3.1-0.20230909074155-fc7119a39341 h1:COQ5uU+gFCQuE878cw0HcTSpKX+xLTu0/6lNTPJStG4= -github.com/jesseduffield/gocui v0.3.1-0.20230909074155-fc7119a39341/go.mod h1:trXE7RRGL2hTsv+Ntk+SHLtRobg9JE138n3Ug/X2Cf4= +github.com/jesseduffield/gocui v0.3.1-0.20230925062444-7cd0d7e2a70a h1:/Ifbvq4BWY5VKoyPnHIW5oRLiy00S3ebFtVIY2MlJm0= +github.com/jesseduffield/gocui v0.3.1-0.20230925062444-7cd0d7e2a70a/go.mod h1:trXE7RRGL2hTsv+Ntk+SHLtRobg9JE138n3Ug/X2Cf4= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo= github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY= diff --git a/pkg/gui/context/search_trait.go b/pkg/gui/context/search_trait.go index 264c8217d..b8faf0757 100644 --- a/pkg/gui/context/search_trait.go +++ b/pkg/gui/context/search_trait.go @@ -37,20 +37,32 @@ func (self *SearchTrait) ClearSearchString() { func (self *SearchTrait) IsSearchableContext() {} func (self *SearchTrait) onSelectItemWrapper(innerFunc func(int) error) func(int, int, int) error { + return func(selectedLineIdx int, index int, total int) error { + self.RenderSearchStatus(index, total) + + if total != 0 { + if err := innerFunc(selectedLineIdx); err != nil { + return err + } + } + + return nil + } +} + +func (self *SearchTrait) RenderSearchStatus(index int, total int) { keybindingConfig := self.c.UserConfig.Keybinding - return func(y int, index int, total int) error { - if total == 0 { - self.c.SetViewContent( - self.c.Views().Search, - fmt.Sprintf( - self.c.Tr.NoMatchesFor, - self.searchString, - theme.OptionsFgColor.Sprintf(self.c.Tr.ExitSearchMode, keybindings.Label(keybindingConfig.Universal.Return)), - ), - ) - return nil - } + if total == 0 { + self.c.SetViewContent( + self.c.Views().Search, + fmt.Sprintf( + self.c.Tr.NoMatchesFor, + self.searchString, + theme.OptionsFgColor.Sprintf(self.c.Tr.ExitSearchMode, keybindings.Label(keybindingConfig.Universal.Return)), + ), + ) + } else { self.c.SetViewContent( self.c.Views().Search, fmt.Sprintf( @@ -66,10 +78,6 @@ func (self *SearchTrait) onSelectItemWrapper(innerFunc func(int) error) func(int ), ), ) - if err := innerFunc(y); err != nil { - return err - } - return nil } } diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index 8764337b1..c036bda3d 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -84,7 +84,8 @@ func (self *SearchHelper) DisplaySearchStatus(context types.ISearchableContext) state.Context = context self.searchPrefixView().SetContent(self.c.Tr.SearchPrefix) - _ = context.GetView().SelectCurrentSearchResult() + index, totalCount := context.GetView().GetSearchStatus() + context.RenderSearchStatus(index, totalCount) } func (self *SearchHelper) searchState() *types.SearchState { diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index fbc38df82..df16cf2bd 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -115,6 +115,7 @@ type ISearchableContext interface { ClearSearchString() IsSearching() bool IsSearchableContext() + RenderSearchStatus(int, int) } type DiffableContext interface { diff --git a/pkg/integration/tests/filter_and_search/new_search.go b/pkg/integration/tests/filter_and_search/new_search.go new file mode 100644 index 000000000..9186dc085 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/new_search.go @@ -0,0 +1,39 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +// This is a regression test to ensure https://github.com/jesseduffield/lazygit/issues/2971 +// doesn't happen again + +var NewSearch = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Start a new search and verify the search begins from the current cursor position, not from the current search match", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // need to create some branches, each with their own commits + shell.EmptyCommit("Add foo") + shell.EmptyCommit("Remove foo") + shell.EmptyCommit("Add bar") + shell.EmptyCommit("Remove bar") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains(`Remove bar`).IsSelected(), + Contains(`Add bar`), + Contains(`Remove foo`), + Contains(`Add foo`), + ). + FilterOrSearch("Add"). + SelectedLine(Contains(`Add bar`)). + SelectPreviousItem(). + SelectedLine(Contains(`Remove bar`)). + FilterOrSearch("Remove"). + SelectedLine(Contains(`Remove bar`)) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index f3b57a5dd..89019719a 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -134,6 +134,7 @@ var tests = []*components.IntegrationTest{ filter_and_search.FilterSearchHistory, filter_and_search.NestedFilter, filter_and_search.NestedFilterTransient, + filter_and_search.NewSearch, filter_by_path.CliArg, filter_by_path.SelectFile, filter_by_path.TypeFile, diff --git a/vendor/github.com/go-errors/errors/README.md b/vendor/github.com/go-errors/errors/README.md index 1ec92329e..558bc883e 100644 --- a/vendor/github.com/go-errors/errors/README.md +++ b/vendor/github.com/go-errors/errors/README.md @@ -81,3 +81,4 @@ This package is licensed under the MIT license, see LICENSE.MIT for details. * v1.4.1 no code change, but now without an unnecessary cover.out file. * v1.4.2 performance improvement to ErrorStack() to avoid unnecessary work https://github.com/go-errors/errors/pull/40 * v1.5.0 add errors.Join() and errors.Unwrap() copying the stdlib https://github.com/go-errors/errors/pull/40 +* v1.5.1 fix build on go1.13..go1.19 (broken by adding Join and Unwrap with wrong build constraints) diff --git a/vendor/github.com/go-errors/errors/error_1_13.go b/vendor/github.com/go-errors/errors/error_1_13.go index 91e709caa..34ab3e00e 100644 --- a/vendor/github.com/go-errors/errors/error_1_13.go +++ b/vendor/github.com/go-errors/errors/error_1_13.go @@ -33,29 +33,3 @@ func Is(e error, original error) bool { return false } - -// Join returns an error that wraps the given errors. -// Any nil error values are discarded. -// Join returns nil if every value in errs is nil. -// The error formats as the concatenation of the strings obtained -// by calling the Error method of each element of errs, with a newline -// between each string. -// -// A non-nil error returned by Join implements the Unwrap() []error method. -// -// For more information see stdlib errors.Join. -func Join(errs ...error) error { - return baseErrors.Join(errs...) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's -// type contains an Unwrap method returning error. -// Otherwise, Unwrap returns nil. -// -// Unwrap only calls a method of the form "Unwrap() error". -// In particular Unwrap does not unwrap errors returned by [Join]. -// -// For more information see stdlib errors.Unwrap. -func Unwrap(err error) error { - return baseErrors.Unwrap(err) -} diff --git a/vendor/github.com/go-errors/errors/join_unwrap_1_20.go b/vendor/github.com/go-errors/errors/join_unwrap_1_20.go new file mode 100644 index 000000000..44df35ece --- /dev/null +++ b/vendor/github.com/go-errors/errors/join_unwrap_1_20.go @@ -0,0 +1,32 @@ +//go:build go1.20 +// +build go1.20 + +package errors + +import baseErrors "errors" + +// Join returns an error that wraps the given errors. +// Any nil error values are discarded. +// Join returns nil if every value in errs is nil. +// The error formats as the concatenation of the strings obtained +// by calling the Error method of each element of errs, with a newline +// between each string. +// +// A non-nil error returned by Join implements the Unwrap() []error method. +// +// For more information see stdlib errors.Join. +func Join(errs ...error) error { + return baseErrors.Join(errs...) +} + +// Unwrap returns the result of calling the Unwrap method on err, if err's +// type contains an Unwrap method returning error. +// Otherwise, Unwrap returns nil. +// +// Unwrap only calls a method of the form "Unwrap() error". +// In particular Unwrap does not unwrap errors returned by [Join]. +// +// For more information see stdlib errors.Unwrap. +func Unwrap(err error) error { + return baseErrors.Unwrap(err) +} diff --git a/vendor/github.com/go-errors/errors/join_unwrap_backward.go b/vendor/github.com/go-errors/errors/join_unwrap_backward.go new file mode 100644 index 000000000..50c766976 --- /dev/null +++ b/vendor/github.com/go-errors/errors/join_unwrap_backward.go @@ -0,0 +1,71 @@ +//go:build !go1.20 +// +build !go1.20 + +package errors + +// Disclaimer: functions Join and Unwrap are copied from the stdlib errors +// package v1.21.0. + +// Join returns an error that wraps the given errors. +// Any nil error values are discarded. +// Join returns nil if every value in errs is nil. +// The error formats as the concatenation of the strings obtained +// by calling the Error method of each element of errs, with a newline +// between each string. +// +// A non-nil error returned by Join implements the Unwrap() []error method. +func Join(errs ...error) error { + n := 0 + for _, err := range errs { + if err != nil { + n++ + } + } + if n == 0 { + return nil + } + e := &joinError{ + errs: make([]error, 0, n), + } + for _, err := range errs { + if err != nil { + e.errs = append(e.errs, err) + } + } + return e +} + +type joinError struct { + errs []error +} + +func (e *joinError) Error() string { + var b []byte + for i, err := range e.errs { + if i > 0 { + b = append(b, '\n') + } + b = append(b, err.Error()...) + } + return string(b) +} + +func (e *joinError) Unwrap() []error { + return e.errs +} + +// Unwrap returns the result of calling the Unwrap method on err, if err's +// type contains an Unwrap method returning error. +// Otherwise, Unwrap returns nil. +// +// Unwrap only calls a method of the form "Unwrap() error". +// In particular Unwrap does not unwrap errors returned by [Join]. +func Unwrap(err error) error { + u, ok := err.(interface { + Unwrap() error + }) + if !ok { + return nil + } + return u.Unwrap() +} diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 707c32137..c907c1732 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -211,10 +211,6 @@ func (v *View) gotoPreviousMatch() error { return v.SelectSearchResult(v.searcher.currentSearchIndex) } -func (v *View) SelectCurrentSearchResult() error { - return v.SelectSearchResult(v.searcher.currentSearchIndex) -} - func (v *View) SelectSearchResult(index int) error { itemCount := len(v.searcher.searchPositions) if itemCount == 0 { @@ -225,6 +221,7 @@ func (v *View) SelectSearchResult(index int) error { } y := v.searcher.searchPositions[index].y + v.FocusPoint(v.ox, y) if v.searcher.onSelectItem != nil { return v.searcher.onSelectItem(y, index, itemCount) @@ -232,6 +229,11 @@ func (v *View) SelectSearchResult(index int) error { return nil } +// Returns , +func (v *View) GetSearchStatus() (int, int) { + return v.searcher.currentSearchIndex, len(v.searcher.searchPositions) +} + func (v *View) Search(str string) error { v.writeMutex.Lock() v.searcher.search(str) diff --git a/vendor/modules.txt b/vendor/modules.txt index 82ad517a3..fe2248d26 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -33,7 +33,7 @@ github.com/fsmiamoto/git-todo-parser/todo # github.com/gdamore/encoding v1.0.0 ## explicit; go 1.9 github.com/gdamore/encoding -# github.com/go-errors/errors v1.5.0 +# github.com/go-errors/errors v1.5.1 ## explicit; go 1.14 github.com/go-errors/errors # github.com/go-git/gcfg v1.5.0 @@ -124,7 +124,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem github.com/jesseduffield/go-git/v5/utils/merkletrie/index github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame github.com/jesseduffield/go-git/v5/utils/merkletrie/noder -# github.com/jesseduffield/gocui v0.3.1-0.20230909074155-fc7119a39341 +# github.com/jesseduffield/gocui v0.3.1-0.20230925062444-7cd0d7e2a70a ## explicit; go 1.12 github.com/jesseduffield/gocui # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10