feat(input): route tab through overlays
- commit
- 5c6654fa400d203bfcff8fa021c1fa20ad41f122
- author
- brice · · 2026-07-14 11:26 UTC
- parent
- a50b4a9
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +21 -1
M internal/usecase/daemon/overlay.go +4 -0
| @@ -9,6 +9,7 @@ type overlayEvents struct { | |||
| 9 | 9 | rune func(rune) | |
| 10 | 10 | backspace func() | |
| 11 | 11 | enter func() | |
| 12 | + | tab func() | |
| 12 | 13 | cancel func() | |
| 13 | 14 | up func() | |
| 14 | 15 | down func() | |
| @@ -51,6 +52,9 @@ func routeOverlayBytes(data []byte, pending *[]byte, ev overlayEvents) { | |||
| 51 | 52 | case '\r', '\n': | |
| 52 | 53 | call(ev.enter) | |
| 53 | 54 | i++ | |
| 55 | + | case 0x09: | |
| 56 | + | call(ev.tab) | |
| 57 | + | i++ | |
| 54 | 58 | case 0x7f, 0x08: | |
| 55 | 59 | call(ev.backspace) | |
| 56 | 60 | i++ | |
| @@ -9,6 +9,7 @@ type overlayEvents struct { | |||||
| 9 | rune func(rune) | 9 | rune func(rune) | ||
| 10 | backspace func() | 10 | backspace func() | ||
| 11 | enter func() | 11 | enter func() | ||
| 12 | + | tab func() | |||
| 12 | cancel func() | 13 | cancel func() | ||
| 13 | up func() | 14 | up func() | ||
| 14 | down func() | 15 | down func() | ||
| @@ -51,6 +52,9 @@ func routeOverlayBytes(data []byte, pending *[]byte, ev overlayEvents) { | |||||
| 51 | case '\r', '\n': | 52 | case '\r', '\n': | ||
| 52 | call(ev.enter) | 53 | call(ev.enter) | ||
| 53 | i++ | 54 | i++ | ||
| 55 | + | case 0x09: | |||
| 56 | + | call(ev.tab) | |||
| 57 | + | i++ | |||
| 54 | case 0x7f, 0x08: | 58 | case 0x7f, 0x08: | ||
| 55 | call(ev.backspace) | 59 | call(ev.backspace) | ||
| 56 | i++ | 60 | i++ | ||
M internal/usecase/daemon/overlay_test.go +17 -1
| @@ -19,6 +19,8 @@ func TestRouteOverlayBytes(t *testing.T) { | |||
| 19 | 19 | wantCancel int | |
| 20 | 20 | wantUp int | |
| 21 | 21 | wantDown int | |
| 22 | + | wantTab int | |
| 23 | + | callback bool | |
| 22 | 24 | }{ | |
| 23 | 25 | { | |
| 24 | 26 | name: "text and split utf8", | |
| @@ -76,13 +78,23 @@ func TestRouteOverlayBytes(t *testing.T) { | |||
| 76 | 78 | chunks: [][]byte{{'a', 0x01, 0xff, 'b'}}, | |
| 77 | 79 | wantRunes: []rune{'a', 'b'}, | |
| 78 | 80 | }, | |
| 81 | + | { | |
| 82 | + | name: "tab routes to callback", | |
| 83 | + | chunks: [][]byte{{0x09}}, | |
| 84 | + | wantTab: 1, | |
| 85 | + | callback: true, | |
| 86 | + | }, | |
| 87 | + | { | |
| 88 | + | name: "tab without callback is consumed", | |
| 89 | + | chunks: [][]byte{{0x09}}, | |
| 90 | + | }, | |
| 79 | 91 | } | |
| 80 | 92 | ||
| 81 | 93 | for _, tt := range tests { | |
| 82 | 94 | t.Run(tt.name, func(t *testing.T) { | |
| 83 | 95 | var pending []byte | |
| 84 | 96 | var gotRunes []rune | |
| 85 | - | var gotBackspace, gotEnter, gotCancel, gotUp, gotDown int | |
| 97 | + | var gotBackspace, gotEnter, gotCancel, gotUp, gotDown, gotTab int | |
| 86 | 98 | ev := overlayEvents{ | |
| 87 | 99 | rune: func(r rune) { gotRunes = append(gotRunes, r) }, | |
| 88 | 100 | backspace: func() { gotBackspace++ }, | |
| @@ -91,6 +103,9 @@ func TestRouteOverlayBytes(t *testing.T) { | |||
| 91 | 103 | up: func() { gotUp++ }, | |
| 92 | 104 | down: func() { gotDown++ }, | |
| 93 | 105 | } | |
| 106 | + | if tt.callback { | |
| 107 | + | ev.tab = func() { gotTab++ } | |
| 108 | + | } | |
| 94 | 109 | ||
| 95 | 110 | for _, chunk := range tt.chunks { | |
| 96 | 111 | routeOverlayBytes(chunk, &pending, ev) | |
| @@ -103,6 +118,7 @@ func TestRouteOverlayBytes(t *testing.T) { | |||
| 103 | 118 | require.Equal(t, tt.wantCancel, gotCancel) | |
| 104 | 119 | require.Equal(t, tt.wantUp, gotUp) | |
| 105 | 120 | require.Equal(t, tt.wantDown, gotDown) | |
| 121 | + | require.Equal(t, tt.wantTab, gotTab) | |
| 106 | 122 | }) | |
| 107 | 123 | } | |
| 108 | 124 | } | |
| @@ -19,6 +19,8 @@ func TestRouteOverlayBytes(t *testing.T) { | |||||
| 19 | wantCancel int | 19 | wantCancel int | ||
| 20 | wantUp int | 20 | wantUp int | ||
| 21 | wantDown int | 21 | wantDown int | ||
| 22 | + | wantTab int | |||
| 23 | + | callback bool | |||
| 22 | }{ | 24 | }{ | ||
| 23 | { | 25 | { | ||
| 24 | name: "text and split utf8", | 26 | name: "text and split utf8", | ||
| @@ -76,13 +78,23 @@ func TestRouteOverlayBytes(t *testing.T) { | |||||
| 76 | chunks: [][]byte{{'a', 0x01, 0xff, 'b'}}, | 78 | chunks: [][]byte{{'a', 0x01, 0xff, 'b'}}, | ||
| 77 | wantRunes: []rune{'a', 'b'}, | 79 | wantRunes: []rune{'a', 'b'}, | ||
| 78 | }, | 80 | }, | ||
| 81 | + | { | |||
| 82 | + | name: "tab routes to callback", | |||
| 83 | + | chunks: [][]byte{{0x09}}, | |||
| 84 | + | wantTab: 1, | |||
| 85 | + | callback: true, | |||
| 86 | + | }, | |||
| 87 | + | { | |||
| 88 | + | name: "tab without callback is consumed", | |||
| 89 | + | chunks: [][]byte{{0x09}}, | |||
| 90 | + | }, | |||
| 79 | } | 91 | } | ||
| 80 | 92 | ||||
| 81 | for _, tt := range tests { | 93 | for _, tt := range tests { | ||
| 82 | t.Run(tt.name, func(t *testing.T) { | 94 | t.Run(tt.name, func(t *testing.T) { | ||
| 83 | var pending []byte | 95 | var pending []byte | ||
| 84 | var gotRunes []rune | 96 | var gotRunes []rune | ||
| 85 | - | var gotBackspace, gotEnter, gotCancel, gotUp, gotDown int | 97 | + | var gotBackspace, gotEnter, gotCancel, gotUp, gotDown, gotTab int |
| 86 | ev := overlayEvents{ | 98 | ev := overlayEvents{ | ||
| 87 | rune: func(r rune) { gotRunes = append(gotRunes, r) }, | 99 | rune: func(r rune) { gotRunes = append(gotRunes, r) }, | ||
| 88 | backspace: func() { gotBackspace++ }, | 100 | backspace: func() { gotBackspace++ }, | ||
| @@ -91,6 +103,9 @@ func TestRouteOverlayBytes(t *testing.T) { | |||||
| 91 | up: func() { gotUp++ }, | 103 | up: func() { gotUp++ }, | ||
| 92 | down: func() { gotDown++ }, | 104 | down: func() { gotDown++ }, | ||
| 93 | } | 105 | } | ||
| 106 | + | if tt.callback { | |||
| 107 | + | ev.tab = func() { gotTab++ } | |||
| 108 | + | } | |||
| 94 | 109 | ||||
| 95 | for _, chunk := range tt.chunks { | 110 | for _, chunk := range tt.chunks { | ||
| 96 | routeOverlayBytes(chunk, &pending, ev) | 111 | routeOverlayBytes(chunk, &pending, ev) | ||
| @@ -103,6 +118,7 @@ func TestRouteOverlayBytes(t *testing.T) { | |||||
| 103 | require.Equal(t, tt.wantCancel, gotCancel) | 118 | require.Equal(t, tt.wantCancel, gotCancel) | ||
| 104 | require.Equal(t, tt.wantUp, gotUp) | 119 | require.Equal(t, tt.wantUp, gotUp) | ||
| 105 | require.Equal(t, tt.wantDown, gotDown) | 120 | require.Equal(t, tt.wantDown, gotDown) | ||
| 121 | + | require.Equal(t, tt.wantTab, gotTab) | |||
| 106 | }) | 122 | }) | ||
| 107 | } | 123 | } | ||
| 108 | } | 124 | } | ||