mirror of
https://github.com/jixishi/SerialTerminalForWindowsTerminal.git
synced 2026-08-02 18:22:18 +00:00
fix: insert CSI u handler into model.go + add tui tests
The previous commit defined parseCSIuBytes but failed to insert the handler into Update(). Now properly inserted before the textinput fallback. Add 10 test cases for parseCSIuBytes covering ctrl+alt+f/c/ m/p/h, ctrl+shift+c, alt+c, and invalid sequences. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b1c499b340
commit
e9a58dc363
@@ -240,6 +240,28 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Handle CSI u sequences that bubbletea does not parse into KeyMsg
|
||||||
|
if b, ok := msg.([]byte); ok {
|
||||||
|
if key, ok2 := parseCSIuBytes(b); ok2 {
|
||||||
|
keyStr := strings.ToLower(key)
|
||||||
|
if m.showModal {
|
||||||
|
last := rune(key[len(key)-1])
|
||||||
|
fake := tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{last}, Alt: strings.Contains(key, "alt+")}
|
||||||
|
if handled, _ := m.handleModalKey(fake); handled {
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if keyStr == normalizeHotkeyPrefix(m.App.Cfg().HotkeyMod)+"+c" {
|
||||||
|
m.App.Close()
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
if handleLocalHotkey(m, keyStr) {
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
m.input, cmd = m.input.Update(msg)
|
m.input, cmd = m.input.Update(msg)
|
||||||
return m, cmd
|
return m, cmd
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package tui
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestParseCSIuBytes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
seq []byte
|
||||||
|
want string
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{name: "ctrl+alt+f", seq: []byte{0x1b, '[', '1', '0', '2', ';', '6', 'u'}, want: "ctrl+alt+f", ok: true},
|
||||||
|
{name: "ctrl+alt+c", seq: []byte{0x1b, '[', '9', '9', ';', '6', 'u'}, want: "ctrl+alt+c", ok: true},
|
||||||
|
{name: "ctrl+alt+m", seq: []byte{0x1b, '[', '1', '0', '9', ';', '6', 'u'}, want: "ctrl+alt+m", ok: true},
|
||||||
|
{name: "ctrl+alt+p", seq: []byte{0x1b, '[', '1', '1', '2', ';', '6', 'u'}, want: "ctrl+alt+p", ok: true},
|
||||||
|
{name: "ctrl+alt+h", seq: []byte{0x1b, '[', '1', '0', '4', ';', '6', 'u'}, want: "ctrl+alt+h", ok: true},
|
||||||
|
{name: "ctrl+shift+c", seq: []byte{0x1b, '[', '9', '9', ';', '5', 'u'}, want: "ctrl+shift+c", ok: true},
|
||||||
|
{name: "alt+c (no ctrl)", seq: []byte{0x1b, '[', '9', '9', ';', '2', 'u'}, want: "alt+c", ok: true},
|
||||||
|
{name: "plain c", seq: []byte{0x1b, '[', '9', '9', ';', '0', 'u'}, want: "c", ok: true},
|
||||||
|
{name: "not CSI u", seq: []byte{0x1b, '[', 'A'}, want: "", ok: false},
|
||||||
|
{name: "empty", seq: []byte{}, want: "", ok: false},
|
||||||
|
{name: "no escape", seq: []byte("hello"), want: "", ok: false},
|
||||||
|
{name: "ESC [ A (arrow up)", seq: []byte{0x1b, '[', 'A'}, want: "", ok: false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, ok := parseCSIuBytes(tt.seq)
|
||||||
|
if ok != tt.ok || got != tt.want {
|
||||||
|
t.Fatalf("parseCSIuBytes(%v): got=(%q,%v) want=(%q,%v)", tt.seq, got, ok, tt.want, tt.ok)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user