feat(frame): add KeyMap with default bindings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-02-22 21:03:50 +00:00
parent aa5cfc312d
commit 02e8343ee5
No known key found for this signature in database
GPG key ID: AF404715446AEB41
2 changed files with 41 additions and 0 deletions

View file

@ -29,3 +29,30 @@ type modelAdapter struct {
func (a *modelAdapter) View(w, h int) string { return a.m.View(w, h) }
func (a *modelAdapter) Init() tea.Cmd { return nil }
func (a *modelAdapter) Update(tea.Msg) (FrameModel, tea.Cmd) { return a, nil }
// KeyMap defines key bindings for Frame navigation.
// Use DefaultKeyMap() for sensible defaults, or build your own.
type KeyMap struct {
FocusNext tea.KeyType // Tab — cycle focus forward
FocusPrev tea.KeyType // Shift-Tab — cycle focus backward
FocusUp tea.KeyType // Up — spatial: move to Header
FocusDown tea.KeyType // Down — spatial: move to Footer
FocusLeft tea.KeyType // Left — spatial: move to Left sidebar
FocusRight tea.KeyType // Right — spatial: move to Right sidebar
Back tea.KeyType // Esc — Navigate back
Quit tea.KeyType // Ctrl-C — quit
}
// DefaultKeyMap returns the standard Frame key bindings.
func DefaultKeyMap() KeyMap {
return KeyMap{
FocusNext: tea.KeyTab,
FocusPrev: tea.KeyShiftTab,
FocusUp: tea.KeyUp,
FocusDown: tea.KeyDown,
FocusLeft: tea.KeyLeft,
FocusRight: tea.KeyRight,
Back: tea.KeyEsc,
Quit: tea.KeyCtrlC,
}
}

View file

@ -247,6 +247,20 @@ func (m *testFrameModel) Update(msg tea.Msg) (FrameModel, tea.Cmd) {
return m, nil
}
func TestKeyMap_Good(t *testing.T) {
t.Run("default keymap has expected bindings", func(t *testing.T) {
km := DefaultKeyMap()
assert.Equal(t, tea.KeyTab, km.FocusNext)
assert.Equal(t, tea.KeyShiftTab, km.FocusPrev)
assert.Equal(t, tea.KeyUp, km.FocusUp)
assert.Equal(t, tea.KeyDown, km.FocusDown)
assert.Equal(t, tea.KeyLeft, km.FocusLeft)
assert.Equal(t, tea.KeyRight, km.FocusRight)
assert.Equal(t, tea.KeyEsc, km.Back)
assert.Equal(t, tea.KeyCtrlC, km.Quit)
})
}
// indexOf returns the position of substr in s, or -1 if not found.
func indexOf(s, substr string) int {
for i := range len(s) - len(substr) + 1 {