Skip to content

Commit 643515d

Browse files
wesmclaude
andauthored
fix(tui): allow j/k/q to be typed in filter search (#654) (#655)
## Summary - The filter modal bound `j`/`k` to navigate up/down and `q` to close, which swallowed those characters before they could reach the search input (issue #654). - Help text only advertises arrow keys and `esc`, so drop the vim-style aliases to match the documented UX. - Added regression test for typing `j`/`k`/`q`; updated existing nav tests to use arrow keys. Closes #654 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 60a4c77 commit 643515d

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

cmd/roborev/tui/filter_queue_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ import (
1111
func TestTUIFilterNavigation(t *testing.T) {
1212
cases := []struct {
1313
startIdx int
14-
key rune
14+
key tea.KeyType
1515
expectedIdx int
1616
description string
1717
}{
18-
{0, 'j', 1, "Navigate down from 0"},
19-
{1, 'j', 2, "Navigate down from 1"},
20-
{2, 'j', 2, "Navigate down at boundary"},
21-
{2, 'k', 1, "Navigate up from 2"},
18+
{0, tea.KeyDown, 1, "Navigate down from 0"},
19+
{1, tea.KeyDown, 2, "Navigate down from 1"},
20+
{2, tea.KeyDown, 2, "Navigate down at boundary"},
21+
{2, tea.KeyUp, 1, "Navigate up from 2"},
2222
}
2323

2424
for _, tc := range cases {
@@ -29,7 +29,7 @@ func TestTUIFilterNavigation(t *testing.T) {
2929
})
3030
m.filterSelectedIdx = tc.startIdx
3131

32-
m2, _ := pressKey(m, tc.key)
32+
m2, _ := pressSpecial(m, tc.key)
3333
assert.Equal(t, tc.expectedIdx, m2.filterSelectedIdx)
3434
})
3535
}
@@ -42,11 +42,11 @@ func TestTUIFilterNavigationSequential(t *testing.T) {
4242
makeNode("repo-c", 1),
4343
})
4444

45-
keys := []rune{'j', 'j', 'j', 'k'}
45+
keys := []tea.KeyType{tea.KeyDown, tea.KeyDown, tea.KeyDown, tea.KeyUp}
4646

4747
m2 := m
4848
for _, k := range keys {
49-
m2, _ = pressKey(m2, k)
49+
m2, _ = pressSpecial(m2, k)
5050
}
5151

5252
assert.Equal(t, 2, m2.filterSelectedIdx)

cmd/roborev/tui/filter_search_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,28 @@ func TestTUIFilterTypingHAndL(t *testing.T) {
119119
assert.Equal(t, "hl", m3.filterSearch)
120120
}
121121

122+
// Regression test for issue #654: j, k, and q were swallowed by
123+
// vim-style navigation/quit shortcuts instead of being appended to
124+
// the search text.
125+
func TestTUIFilterTypingJKQ(t *testing.T) {
126+
for _, r := range []rune{'j', 'k', 'q'} {
127+
t.Run(string(r), func(t *testing.T) {
128+
m := initFilterModel([]treeFilterNode{
129+
makeNode("kubernetes", 3),
130+
makeNode("jenkins", 2),
131+
makeNode("queue-worker", 1),
132+
})
133+
m.filterSelectedIdx = 1
134+
135+
m2, _ := pressKey(m, r)
136+
assert.Equal(t, string(r), m2.filterSearch,
137+
"key %q should be appended to search", r)
138+
assert.Equal(t, viewFilter, m2.currentView,
139+
"key %q must not close the filter modal", r)
140+
})
141+
}
142+
}
143+
122144
func TestTUIFilterSearchByRepoPath(t *testing.T) {
123145
m := initFilterModel([]treeFilterNode{
124146
{name: "backend", rootPaths: []string{"/path/to/backend-dev", "/path/to/backend-prod"}, count: 2},

cmd/roborev/tui/handlers_modal.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ func (m model) handleFilterKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
5555
switch msg.String() {
5656
case "ctrl+c":
5757
return m, tea.Quit
58-
case "esc", "q":
58+
case "esc":
5959
m.currentView = viewQueue
6060
m.filterSearch = ""
6161
m.filterBranchMode = false
6262
return m, nil
63-
case "up", "k":
63+
case "up":
6464
m.filterNavigateUp()
6565
return m, nil
66-
case "down", "j":
66+
case "down":
6767
m.filterNavigateDown()
6868
return m, nil
6969
case "right":

0 commit comments

Comments
 (0)