From b8bee4de5158a6f285127eff018c442bf45ae970 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 3 Jun 2023 12:12:32 +1000 Subject: Scroll to top when filtering and retain selection when cancelling filter --- pkg/gui/context/filtered_list.go | 14 ++++++++++++++ pkg/gui/context/filtered_list_view_model.go | 10 ++++++++++ pkg/gui/controllers/helpers/search_helper.go | 7 ++++--- pkg/gui/types/context.go | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) (limited to 'pkg') diff --git a/pkg/gui/context/filtered_list.go b/pkg/gui/context/filtered_list.go index b848b96d4..bffd0eddb 100644 --- a/pkg/gui/context/filtered_list.go +++ b/pkg/gui/context/filtered_list.go @@ -68,3 +68,17 @@ func (self *FilteredList[T]) applyFilter() { func (self *FilteredList[T]) match(haystack string, needle string) bool { return utils.CaseInsensitiveContains(haystack, needle) } + +func (self *FilteredList[T]) UnfilteredIndex(index int) int { + if self.filteredIndices == nil { + return index + } + + // we use -1 when there are no items + if index == -1 { + return -1 + } + + // TODO: mutex + return self.filteredIndices[index] +} diff --git a/pkg/gui/context/filtered_list_view_model.go b/pkg/gui/context/filtered_list_view_model.go index 6196ed180..77f6e1174 100644 --- a/pkg/gui/context/filtered_list_view_model.go +++ b/pkg/gui/context/filtered_list_view_model.go @@ -21,3 +21,13 @@ func NewFilteredListViewModel[T any](getList func() []T, getFilterFields func(T) // used for type switch func (self *FilteredListViewModel[T]) IsFilterableContext() {} + +func (self *FilteredListViewModel[T]) ClearFilter() { + // Set the selected line index to the unfiltered index of the currently selected line, + // so that the current item is still selected after the filter is cleared. + unfilteredIndex := self.FilteredList.UnfilteredIndex(self.GetSelectedLineIdx()) + + self.FilteredList.ClearFilter() + + self.SetSelectedLineIdx(unfilteredIndex) +} diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index f8bfcbd9c..68af20b35 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -123,14 +123,13 @@ func (self *SearchHelper) ConfirmFilter() error { // We also do this on each keypress but we do it here again just in case state := self.searchState() - context, ok := state.Context.(types.IFilterableContext) + _, ok := state.Context.(types.IFilterableContext) if !ok { self.c.Log.Warnf("Context %s is not filterable", state.Context.GetKey()) return nil } - context.SetFilter(self.promptContent()) - _ = self.c.PostRefreshUpdate(state.Context) + self.OnPromptContentChanged(self.promptContent()) return self.c.PopContext() } @@ -187,6 +186,8 @@ func (self *SearchHelper) OnPromptContentChanged(searchString string) { state := self.searchState() switch context := state.Context.(type) { case types.IFilterableContext: + context.SetSelectedLineIdx(0) + _ = context.GetView().SetOriginY(0) context.SetFilter(searchString) _ = self.c.PostRefreshUpdate(context) case types.ISearchableContext: diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index 9da9ad2b1..dca5b042c 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -89,6 +89,7 @@ type Context interface { type IFilterableContext interface { Context + IListPanelState SetFilter(string) GetFilter() string -- cgit v1.2.3