d6155691c8
#295 — include narration_llm tokens in changes-panel aggregate count #296 — execution plan overlay (Ctrl+P in-session) #298 — surface reasoning/CoT on tool-call turns in output view #265 — dismiss clarification modal when answered externally (session.resumed)
127 lines
2.5 KiB
Go
127 lines
2.5 KiB
Go
package app
|
|
|
|
import tea "charm.land/bubbletea/v2"
|
|
|
|
// bubbletea v2 collapsed key events into a single (Code rune, Mod KeyMod) form
|
|
// and dropped the v1 KeyType enum the handlers were written against. Rather than
|
|
// rewrite ~190 key-match sites, this shim adapts a v2 key press into the same
|
|
// v1-shaped struct (Type + Runes + modifier flags), so all the matching logic
|
|
// downstream stays untouched. The only place that ever touches the raw v2 key
|
|
// is toKeyMsg below, called once at the Update boundary.
|
|
|
|
type keyType int
|
|
|
|
const (
|
|
keyRunes keyType = iota
|
|
keyEnter
|
|
keyUp
|
|
keyDown
|
|
keyLeft
|
|
keyRight
|
|
keySpace
|
|
keyEsc
|
|
keyBackspace
|
|
keyTab
|
|
keyPgUp
|
|
keyPgDown
|
|
keyCtrlA
|
|
keyCtrlC
|
|
keyCtrlD
|
|
keyCtrlJ
|
|
keyCtrlR
|
|
keyCtrlU
|
|
keyCtrlX
|
|
keyCtrlP
|
|
keyCtrlUp
|
|
keyCtrlDown
|
|
keyOther
|
|
)
|
|
|
|
// keyMsg is the v1-shaped key event the handlers consume: a Type plus the typed
|
|
// Runes and modifier flags. Shift is newly meaningful under v2's kitty key
|
|
// disambiguation — it powers Shift+Enter newlines (see handleInsertKey).
|
|
type keyMsg struct {
|
|
Type keyType
|
|
Runes []rune
|
|
Alt bool
|
|
Shift bool
|
|
str string
|
|
}
|
|
|
|
func (k keyMsg) String() string { return k.str }
|
|
|
|
// toKeyMsg converts a bubbletea v2 key press into the shim's v1-shaped form.
|
|
func toKeyMsg(p tea.KeyPressMsg) keyMsg {
|
|
k := p.Key()
|
|
out := keyMsg{
|
|
Alt: k.Mod.Contains(tea.ModAlt),
|
|
Shift: k.Mod.Contains(tea.ModShift),
|
|
str: k.Keystroke(),
|
|
}
|
|
ctrl := k.Mod.Contains(tea.ModCtrl)
|
|
switch k.Code {
|
|
case tea.KeyEnter:
|
|
out.Type = keyEnter
|
|
case tea.KeyEscape:
|
|
out.Type = keyEsc
|
|
case tea.KeyTab:
|
|
out.Type = keyTab
|
|
case tea.KeyBackspace:
|
|
out.Type = keyBackspace
|
|
case tea.KeySpace:
|
|
out.Type = keySpace
|
|
out.Runes = []rune{' '}
|
|
case tea.KeyUp:
|
|
if ctrl {
|
|
out.Type = keyCtrlUp
|
|
} else {
|
|
out.Type = keyUp
|
|
}
|
|
case tea.KeyDown:
|
|
if ctrl {
|
|
out.Type = keyCtrlDown
|
|
} else {
|
|
out.Type = keyDown
|
|
}
|
|
case tea.KeyLeft:
|
|
out.Type = keyLeft
|
|
case tea.KeyRight:
|
|
out.Type = keyRight
|
|
case tea.KeyPgUp:
|
|
out.Type = keyPgUp
|
|
case tea.KeyPgDown:
|
|
out.Type = keyPgDown
|
|
default:
|
|
if ctrl {
|
|
switch k.Code {
|
|
case 'a':
|
|
out.Type = keyCtrlA
|
|
case 'c':
|
|
out.Type = keyCtrlC
|
|
case 'd':
|
|
out.Type = keyCtrlD
|
|
case 'p':
|
|
out.Type = keyCtrlP
|
|
case 'j':
|
|
out.Type = keyCtrlJ
|
|
case 'r':
|
|
out.Type = keyCtrlR
|
|
case 'u':
|
|
out.Type = keyCtrlU
|
|
case 'x':
|
|
out.Type = keyCtrlX
|
|
default:
|
|
out.Type = keyOther
|
|
}
|
|
return out
|
|
}
|
|
if k.Text != "" {
|
|
out.Type = keyRunes
|
|
out.Runes = []rune(k.Text)
|
|
} else {
|
|
out.Type = keyOther
|
|
}
|
|
}
|
|
return out
|
|
}
|