summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2023-06-03 12:12:32 +1000
committerJesse Duffield <jessedduffield@gmail.com>2023-07-03 12:54:14 +1000
commitb8bee4de5158a6f285127eff018c442bf45ae970 (patch)
tree04f5a1fc634e7d8e5cf02f653e47e4d9c23113c5 /pkg
parentd67b209e62f8254d5f17ecdb8fe7ff810f000566 (diff)
Scroll to top when filtering and retain selection when cancelling filter
Diffstat (limited to 'pkg')
-rw-r--r--pkg/gui/context/filtered_list.go14
-rw-r--r--pkg/gui/context/filtered_list_view_model.go10
-rw-r--r--pkg/gui/controllers/helpers/search_helper.go7
-rw-r--r--pkg/gui/types/context.go1
4 files changed, 29 insertions, 3 deletions
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