vcom/internal/ui/keymap.go
vrubelroman 08c095e74f feat: add interactive file search/filter (feature #1)
Pressing / opens a filter bar at the bottom of the screen. As the user
types, the active pane's entries are filtered in real-time using
case-insensitive substring matching. The .. entry is always preserved.

Key bindings:
  /       - open filter input (re-opens with previous query if active)
  Esc     - clear filter and restore full list
  Enter   - commit filter (keeps filtering active, closes input bar)
  Up/Down - navigate the filtered list while typing
  PgUp/Dn - scroll the filtered list

Filter is automatically cleared when navigating to a different directory
(Enter on a folder, Backspace to parent, opening an archive).

Modified files:
  - internal/ui/keymap.go: added Filter key binding (/)
  - internal/ui/model.go: filterMode, filterQuery, filterInput fields;
    filteredPane() helper for View rendering; filter handling in Update();
    renderFilterBar() for the bottom bar UI; clearFilter() helper;
    adjustCursorForFilter() to keep cursor in bounds

Created files:
  - plans/feature-roadmap.md
2026-04-27 17:14:48 +03:00

89 lines
4.4 KiB
Go

package ui
import "github.com/charmbracelet/bubbles/key"
type KeyMap struct {
Help key.Binding
Visual key.Binding
Caret key.Binding
View key.Binding
Edit key.Binding
Rename key.Binding
Info key.Binding
Archive key.Binding
SelectText key.Binding
ToggleHidden key.Binding
CycleTheme key.Binding
CycleSort key.Binding
Up key.Binding
Down key.Binding
SelectUp key.Binding
SelectDown key.Binding
PageUp key.Binding
PageDown key.Binding
Open key.Binding
Back key.Binding
Switch key.Binding
Filter key.Binding
Refresh key.Binding
DirSize key.Binding
Copy key.Binding
Move key.Binding
Mkdir key.Binding
Delete key.Binding
Confirm key.Binding
Background key.Binding
ProgressCancel key.Binding
Cancel key.Binding
Quit key.Binding
}
func DefaultKeyMap() KeyMap {
return KeyMap{
Help: key.NewBinding(key.WithKeys("f1", "?"), key.WithHelp("F1/?", "help")),
Rename: key.NewBinding(key.WithKeys("f2", "r"), key.WithHelp("F2/r", "rename")),
View: key.NewBinding(key.WithKeys("f3", "v"), key.WithHelp("F3/v", "view")),
Visual: key.NewBinding(key.WithKeys("v"), key.WithHelp("v", "visual")),
Caret: key.NewBinding(key.WithKeys("i"), key.WithHelp("i", "caret")),
Edit: key.NewBinding(key.WithKeys("e"), key.WithHelp("e", "edit")),
Archive: key.NewBinding(key.WithKeys("f4", "a"), key.WithHelp("F4/a", "archive")),
Info: key.NewBinding(key.WithKeys("f9", "o"), key.WithHelp("F9/o", "info")),
SelectText: key.NewBinding(key.WithKeys("ctrl+t"), key.WithHelp("C-t", "text select")),
ToggleHidden: key.NewBinding(key.WithKeys("."), key.WithHelp(".", "hidden")),
CycleTheme: key.NewBinding(key.WithKeys("t"), key.WithHelp("t", "theme")),
CycleSort: key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "sort")),
Up: key.NewBinding(key.WithKeys("up", "k"), key.WithHelp("↑/k", "up")),
Down: key.NewBinding(key.WithKeys("down", "j"), key.WithHelp("↓/j", "down")),
SelectUp: key.NewBinding(key.WithKeys("shift+up", "K"), key.WithHelp("S-↑/K", "select up")),
SelectDown: key.NewBinding(key.WithKeys("shift+down", "J"), key.WithHelp("S-↓/J", "select down")),
PageUp: key.NewBinding(key.WithKeys("pgup"), key.WithHelp("PgUp", "page up")),
PageDown: key.NewBinding(),
Filter: key.NewBinding(key.WithKeys("/"), key.WithHelp("/", "filter")),
Open: key.NewBinding(key.WithKeys("enter", "right"), key.WithHelp("Enter", "open")),
Back: key.NewBinding(key.WithKeys("backspace", "left"), key.WithHelp("←", "parent")),
Switch: key.NewBinding(key.WithKeys("tab", "h", "l"), key.WithHelp("Tab/h/l", "switch pane")),
Refresh: key.NewBinding(key.WithKeys("ctrl+r"), key.WithHelp("C-r", "refresh")),
DirSize: key.NewBinding(key.WithKeys(" "), key.WithHelp("Space", "dir size")),
Copy: key.NewBinding(key.WithKeys("f5", "c"), key.WithHelp("F5/c", "copy")),
Move: key.NewBinding(key.WithKeys("f6", "m"), key.WithHelp("F6/m", "move")),
Mkdir: key.NewBinding(key.WithKeys("f7", "n"), key.WithHelp("F7/n", "mkdir")),
Delete: key.NewBinding(key.WithKeys("f8", "delete", "x"), key.WithHelp("F8/x", "delete")),
Confirm: key.NewBinding(key.WithKeys("enter", "y"), key.WithHelp("Enter/y", "confirm")),
Background: key.NewBinding(key.WithKeys("b"), key.WithHelp("b", "background")),
ProgressCancel: key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "cancel transfer")),
Cancel: key.NewBinding(key.WithKeys("esc"), key.WithHelp("Esc", "cancel")),
Quit: key.NewBinding(key.WithKeys("f10", "q", "ctrl+c"), key.WithHelp("F10/q", "quit")),
}
}
func (k KeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Help, k.Rename, k.View, k.Archive, k.Copy, k.Move, k.Mkdir, k.Delete, k.Info, k.Quit}
}
func (k KeyMap) FullHelp() [][]key.Binding {
return [][]key.Binding{
{k.Help, k.Up, k.Down, k.SelectUp, k.SelectDown, k.Open, k.Back},
{k.Rename, k.View, k.Caret, k.Edit, k.Archive, k.Copy, k.Move, k.Delete},
{k.SelectText, k.DirSize, k.Refresh, k.ToggleHidden, k.CycleSort, k.CycleTheme, k.Quit},
}
}