diff options
author | Karim Khaleel <code.karim@gmail.com> | 2023-08-04 14:01:30 +0300 |
---|---|---|
committer | Karim Khaleel <code.karim@gmail.com> | 2023-09-20 08:35:41 +0300 |
commit | edec116cebe6dde1f8e7ce375fabc407c84d92b5 (patch) | |
tree | bbc27be98cc27ad51fe8d55df23bf9d66a2698ab /pkg/gui | |
parent | ab5875c78fcd7fc2f0cdbc867dc84ef4331a5de3 (diff) |
Add search history
Add search history for filterable and searchable views.
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/context/filtered_list_view_model.go | 4 | ||||
-rw-r--r-- | pkg/gui/context/history_trait.go | 20 | ||||
-rw-r--r-- | pkg/gui/context/remotes_context.go | 1 | ||||
-rw-r--r-- | pkg/gui/context/search_trait.go | 6 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/search_helper.go | 35 | ||||
-rw-r--r-- | pkg/gui/controllers/search_prompt_controller.go | 20 | ||||
-rw-r--r-- | pkg/gui/types/context.go | 9 | ||||
-rw-r--r-- | pkg/gui/types/search_state.go | 5 |
8 files changed, 92 insertions, 8 deletions
diff --git a/pkg/gui/context/filtered_list_view_model.go b/pkg/gui/context/filtered_list_view_model.go index 77f6e1174..1e649550a 100644 --- a/pkg/gui/context/filtered_list_view_model.go +++ b/pkg/gui/context/filtered_list_view_model.go @@ -3,13 +3,15 @@ package context type FilteredListViewModel[T any] struct { *FilteredList[T] *ListViewModel[T] + *SearchHistory } func NewFilteredListViewModel[T any](getList func() []T, getFilterFields func(T) []string) *FilteredListViewModel[T] { filteredList := NewFilteredList(getList, getFilterFields) self := &FilteredListViewModel[T]{ - FilteredList: filteredList, + FilteredList: filteredList, + SearchHistory: NewSearchHistory(), } listViewModel := NewListViewModel(filteredList.GetFilteredList) diff --git a/pkg/gui/context/history_trait.go b/pkg/gui/context/history_trait.go new file mode 100644 index 000000000..f850a3b77 --- /dev/null +++ b/pkg/gui/context/history_trait.go @@ -0,0 +1,20 @@ +package context + +import ( + "github.com/jesseduffield/lazygit/pkg/utils" +) + +// Maintains a list of strings that have previously been searched/filtered for +type SearchHistory struct { + history *utils.HistoryBuffer[string] +} + +func NewSearchHistory() *SearchHistory { + return &SearchHistory{ + history: utils.NewHistoryBuffer[string](1000), + } +} + +func (self *SearchHistory) GetSearchHistory() *utils.HistoryBuffer[string] { + return self.history +} diff --git a/pkg/gui/context/remotes_context.go b/pkg/gui/context/remotes_context.go index f5e2a97ab..43da46576 100644 --- a/pkg/gui/context/remotes_context.go +++ b/pkg/gui/context/remotes_context.go @@ -9,6 +9,7 @@ import ( type RemotesContext struct { *FilteredListViewModel[*models.Remote] *ListContextTrait + *SearchHistory } var ( diff --git a/pkg/gui/context/search_trait.go b/pkg/gui/context/search_trait.go index fad68d794..264c8217d 100644 --- a/pkg/gui/context/search_trait.go +++ b/pkg/gui/context/search_trait.go @@ -9,12 +9,16 @@ import ( type SearchTrait struct { c *ContextCommon + *SearchHistory searchString string } func NewSearchTrait(c *ContextCommon) *SearchTrait { - return &SearchTrait{c: c} + return &SearchTrait{ + c: c, + SearchHistory: NewSearchHistory(), + } } func (self *SearchTrait) GetSearchString() string { diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index b244f20e4..8764337b1 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -36,7 +36,7 @@ func (self *SearchHelper) OpenFilterPrompt(context types.IFilterableContext) err self.searchPrefixView().SetContent(self.c.Tr.FilterPrefix) promptView := self.promptView() promptView.ClearTextArea() - promptView.TextArea.TypeString(context.GetFilter()) + self.OnPromptContentChanged("") promptView.RenderTextArea() if err := self.c.PushContext(self.c.Contexts().Search); err != nil { @@ -49,13 +49,13 @@ func (self *SearchHelper) OpenFilterPrompt(context types.IFilterableContext) err func (self *SearchHelper) OpenSearchPrompt(context types.ISearchableContext) error { state := self.searchState() + state.PrevSearchIndex = -1 + state.Context = context - searchString := context.GetSearchString() self.searchPrefixView().SetContent(self.c.Tr.SearchPrefix) promptView := self.promptView() promptView.ClearTextArea() - promptView.TextArea.TypeString(searchString) promptView.RenderTextArea() if err := self.c.PushContext(self.c.Contexts().Search); err != nil { @@ -125,13 +125,17 @@ func (self *SearchHelper) ConfirmFilter() error { // We also do this on each keypress but we do it here again just in case state := self.searchState() - _, ok := state.Context.(types.IFilterableContext) + context, ok := state.Context.(types.IFilterableContext) if !ok { self.c.Log.Warnf("Context %s is not filterable", state.Context.GetKey()) return nil } self.OnPromptContentChanged(self.promptContent()) + filterString := self.promptContent() + if filterString != "" { + context.GetSearchHistory().Push(filterString) + } return self.c.PopContext() } @@ -147,6 +151,9 @@ func (self *SearchHelper) ConfirmSearch() error { searchString := self.promptContent() context.SetSearchString(searchString) + if searchString != "" { + context.GetSearchHistory().Push(searchString) + } view := context.GetView() @@ -167,6 +174,26 @@ func (self *SearchHelper) CancelPrompt() error { return self.c.PopContext() } +func (self *SearchHelper) ScrollHistory(scrollIncrement int) { + state := self.searchState() + + context, ok := state.Context.(types.ISearchHistoryContext) + if !ok { + return + } + + states := context.GetSearchHistory() + + if val, err := states.PeekAt(state.PrevSearchIndex + scrollIncrement); err == nil { + state.PrevSearchIndex += scrollIncrement + promptView := self.promptView() + promptView.ClearTextArea() + promptView.TextArea.TypeString(val) + promptView.RenderTextArea() + self.OnPromptContentChanged(val) + } +} + func (self *SearchHelper) Cancel() { state := self.searchState() diff --git a/pkg/gui/controllers/search_prompt_controller.go b/pkg/gui/controllers/search_prompt_controller.go index 2326ed1c1..014edd094 100644 --- a/pkg/gui/controllers/search_prompt_controller.go +++ b/pkg/gui/controllers/search_prompt_controller.go @@ -33,6 +33,16 @@ func (self *SearchPromptController) GetKeybindings(opts types.KeybindingsOpts) [ Modifier: gocui.ModNone, Handler: self.cancel, }, + { + Key: opts.GetKey(opts.Config.Universal.PrevItem), + Modifier: gocui.ModNone, + Handler: self.prevHistory, + }, + { + Key: opts.GetKey(opts.Config.Universal.NextItem), + Modifier: gocui.ModNone, + Handler: self.nextHistory, + }, } } @@ -51,3 +61,13 @@ func (self *SearchPromptController) confirm() error { func (self *SearchPromptController) cancel() error { return self.c.Helpers().Search.CancelPrompt() } + +func (self *SearchPromptController) prevHistory() error { + self.c.Helpers().Search.ScrollHistory(1) + return nil +} + +func (self *SearchPromptController) nextHistory() error { + self.c.Helpers().Search.ScrollHistory(-1) + return nil +} diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index dca5b042c..e06138a99 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -4,6 +4,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/patch_exploring" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/sasha-s/go-deadlock" ) @@ -87,9 +88,16 @@ type Context interface { HandleRenderToMain() error } +type ISearchHistoryContext interface { + Context + + GetSearchHistory() *utils.HistoryBuffer[string] +} + type IFilterableContext interface { Context IListPanelState + ISearchHistoryContext SetFilter(string) GetFilter() string @@ -100,6 +108,7 @@ type IFilterableContext interface { type ISearchableContext interface { Context + ISearchHistoryContext SetSearchString(string) GetSearchString() string diff --git a/pkg/gui/types/search_state.go b/pkg/gui/types/search_state.go index 9b24af095..af806f2c3 100644 --- a/pkg/gui/types/search_state.go +++ b/pkg/gui/types/search_state.go @@ -12,11 +12,12 @@ const ( // TODO: could we remove this entirely? type SearchState struct { - Context Context + Context Context + PrevSearchIndex int } func NewSearchState() *SearchState { - return &SearchState{} + return &SearchState{PrevSearchIndex: -1} } func (self *SearchState) SearchType() SearchType { |