From 74c1079c9db696ec96d6d20037dbb9a3c3e5e2bf Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 12 Dec 2024 10:12:28 -0300 Subject: [PATCH] feat(filter): ctrl+a to toggle select all (#770) closes #388 --- filter/command.go | 1 + filter/filter.go | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/filter/command.go b/filter/command.go index 1c5a6ca5b..dfc827465 100644 --- a/filter/command.go +++ b/filter/command.go @@ -83,6 +83,7 @@ func (o Options) Run() error { km.Toggle.SetEnabled(true) km.ToggleAndPrevious.SetEnabled(true) km.ToggleAndNext.SetEnabled(true) + km.ToggleAll.SetEnabled(true) } p := tea.NewProgram(model{ diff --git a/filter/filter.go b/filter/filter.go index 77c609bd1..23c0006eb 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -45,6 +45,11 @@ func defaultKeymap() keymap { key.WithHelp("ctrl+@", "toggle"), key.WithDisabled(), ), + ToggleAll: key.NewBinding( + key.WithKeys("ctrl+a"), + key.WithHelp("ctrl+a", "select all"), + key.WithDisabled(), + ), Quit: key.NewBinding( key.WithKeys("esc"), key.WithHelp("esc", "quit"), @@ -65,6 +70,7 @@ type keymap struct { Up, ToggleAndNext, ToggleAndPrevious, + ToggleAll, Toggle, Abort, Quit, @@ -77,11 +83,12 @@ func (k keymap) FullHelp() [][]key.Binding { return nil } // ShortHelp implements help.KeyMap. func (k keymap) ShortHelp() []key.Binding { return []key.Binding{ - k.ToggleAndNext, key.NewBinding( key.WithKeys("up", "down"), key.WithHelp("↓↑", "navigate"), ), + k.ToggleAndNext, + k.ToggleAll, k.Submit, } } @@ -286,6 +293,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { break // no op } m.ToggleSelection() + case key.Matches(msg, km.ToggleAll): + if m.limit <= 1 { + break + } + if m.numSelected < len(m.matches) && m.numSelected < m.limit { + m = m.selectAll() + } else { + m = m.deselectAll() + } default: // yOffsetFromBottom is the number of lines from the bottom of the // list to the top of the viewport. This is used to keep the viewport @@ -390,6 +406,26 @@ func (m *model) ToggleSelection() { } } +func (m model) selectAll() model { + for i := range m.matches { + if m.numSelected >= m.limit { + break // do not exceed given limit + } + if _, ok := m.selected[m.matches[i].Str]; ok { + continue + } + m.selected[m.matches[i].Str] = struct{}{} + m.numSelected++ + } + return m +} + +func (m model) deselectAll() model { + m.selected = make(map[string]struct{}) + m.numSelected = 0 + return m +} + func matchAll(options []string) []fuzzy.Match { matches := make([]fuzzy.Match, len(options)) for i, option := range options {