summaryrefslogtreecommitdiffhomepage
path: root/packages/tui/input/kitty.go
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-11-02 18:43:17 -0500
committerDax Raad <[email protected]>2025-11-02 18:43:33 -0500
commitf68374ad2223ddc213bdea9519ca6a699819ee0e (patch)
tree04f0fe21b8e12cd62d7274961bb0cff64f966f40 /packages/tui/input/kitty.go
parent5e86c9b7916f75c7ad227b80eab18c7c54fc8ffe (diff)
downloadopencode-f68374ad2223ddc213bdea9519ca6a699819ee0e.tar.gz
opencode-f68374ad2223ddc213bdea9519ca6a699819ee0e.zip
DELETE GO BUBBLETEA CRAP HOORAY
Diffstat (limited to 'packages/tui/input/kitty.go')
-rw-r--r--packages/tui/input/kitty.go353
1 files changed, 0 insertions, 353 deletions
diff --git a/packages/tui/input/kitty.go b/packages/tui/input/kitty.go
deleted file mode 100644
index 4da00b502..000000000
--- a/packages/tui/input/kitty.go
+++ /dev/null
@@ -1,353 +0,0 @@
-package input
-
-import (
- "unicode"
- "unicode/utf8"
-
- "github.com/charmbracelet/x/ansi"
- "github.com/charmbracelet/x/ansi/kitty"
-)
-
-// KittyGraphicsEvent represents a Kitty Graphics response event.
-//
-// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
-type KittyGraphicsEvent struct {
- Options kitty.Options
- Payload []byte
-}
-
-// KittyEnhancementsEvent represents a Kitty enhancements event.
-type KittyEnhancementsEvent int
-
-// Kitty keyboard enhancement constants.
-// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
-const (
- KittyDisambiguateEscapeCodes KittyEnhancementsEvent = 1 << iota
- KittyReportEventTypes
- KittyReportAlternateKeys
- KittyReportAllKeysAsEscapeCodes
- KittyReportAssociatedText
-)
-
-// Contains reports whether m contains the given enhancements.
-func (e KittyEnhancementsEvent) Contains(enhancements KittyEnhancementsEvent) bool {
- return e&enhancements == enhancements
-}
-
-// Kitty Clipboard Control Sequences.
-var kittyKeyMap = map[int]Key{
- ansi.BS: {Code: KeyBackspace},
- ansi.HT: {Code: KeyTab},
- ansi.CR: {Code: KeyEnter},
- ansi.ESC: {Code: KeyEscape},
- ansi.DEL: {Code: KeyBackspace},
-
- 57344: {Code: KeyEscape},
- 57345: {Code: KeyEnter},
- 57346: {Code: KeyTab},
- 57347: {Code: KeyBackspace},
- 57348: {Code: KeyInsert},
- 57349: {Code: KeyDelete},
- 57350: {Code: KeyLeft},
- 57351: {Code: KeyRight},
- 57352: {Code: KeyUp},
- 57353: {Code: KeyDown},
- 57354: {Code: KeyPgUp},
- 57355: {Code: KeyPgDown},
- 57356: {Code: KeyHome},
- 57357: {Code: KeyEnd},
- 57358: {Code: KeyCapsLock},
- 57359: {Code: KeyScrollLock},
- 57360: {Code: KeyNumLock},
- 57361: {Code: KeyPrintScreen},
- 57362: {Code: KeyPause},
- 57363: {Code: KeyMenu},
- 57364: {Code: KeyF1},
- 57365: {Code: KeyF2},
- 57366: {Code: KeyF3},
- 57367: {Code: KeyF4},
- 57368: {Code: KeyF5},
- 57369: {Code: KeyF6},
- 57370: {Code: KeyF7},
- 57371: {Code: KeyF8},
- 57372: {Code: KeyF9},
- 57373: {Code: KeyF10},
- 57374: {Code: KeyF11},
- 57375: {Code: KeyF12},
- 57376: {Code: KeyF13},
- 57377: {Code: KeyF14},
- 57378: {Code: KeyF15},
- 57379: {Code: KeyF16},
- 57380: {Code: KeyF17},
- 57381: {Code: KeyF18},
- 57382: {Code: KeyF19},
- 57383: {Code: KeyF20},
- 57384: {Code: KeyF21},
- 57385: {Code: KeyF22},
- 57386: {Code: KeyF23},
- 57387: {Code: KeyF24},
- 57388: {Code: KeyF25},
- 57389: {Code: KeyF26},
- 57390: {Code: KeyF27},
- 57391: {Code: KeyF28},
- 57392: {Code: KeyF29},
- 57393: {Code: KeyF30},
- 57394: {Code: KeyF31},
- 57395: {Code: KeyF32},
- 57396: {Code: KeyF33},
- 57397: {Code: KeyF34},
- 57398: {Code: KeyF35},
- 57399: {Code: KeyKp0},
- 57400: {Code: KeyKp1},
- 57401: {Code: KeyKp2},
- 57402: {Code: KeyKp3},
- 57403: {Code: KeyKp4},
- 57404: {Code: KeyKp5},
- 57405: {Code: KeyKp6},
- 57406: {Code: KeyKp7},
- 57407: {Code: KeyKp8},
- 57408: {Code: KeyKp9},
- 57409: {Code: KeyKpDecimal},
- 57410: {Code: KeyKpDivide},
- 57411: {Code: KeyKpMultiply},
- 57412: {Code: KeyKpMinus},
- 57413: {Code: KeyKpPlus},
- 57414: {Code: KeyKpEnter},
- 57415: {Code: KeyKpEqual},
- 57416: {Code: KeyKpSep},
- 57417: {Code: KeyKpLeft},
- 57418: {Code: KeyKpRight},
- 57419: {Code: KeyKpUp},
- 57420: {Code: KeyKpDown},
- 57421: {Code: KeyKpPgUp},
- 57422: {Code: KeyKpPgDown},
- 57423: {Code: KeyKpHome},
- 57424: {Code: KeyKpEnd},
- 57425: {Code: KeyKpInsert},
- 57426: {Code: KeyKpDelete},
- 57427: {Code: KeyKpBegin},
- 57428: {Code: KeyMediaPlay},
- 57429: {Code: KeyMediaPause},
- 57430: {Code: KeyMediaPlayPause},
- 57431: {Code: KeyMediaReverse},
- 57432: {Code: KeyMediaStop},
- 57433: {Code: KeyMediaFastForward},
- 57434: {Code: KeyMediaRewind},
- 57435: {Code: KeyMediaNext},
- 57436: {Code: KeyMediaPrev},
- 57437: {Code: KeyMediaRecord},
- 57438: {Code: KeyLowerVol},
- 57439: {Code: KeyRaiseVol},
- 57440: {Code: KeyMute},
- 57441: {Code: KeyLeftShift},
- 57442: {Code: KeyLeftCtrl},
- 57443: {Code: KeyLeftAlt},
- 57444: {Code: KeyLeftSuper},
- 57445: {Code: KeyLeftHyper},
- 57446: {Code: KeyLeftMeta},
- 57447: {Code: KeyRightShift},
- 57448: {Code: KeyRightCtrl},
- 57449: {Code: KeyRightAlt},
- 57450: {Code: KeyRightSuper},
- 57451: {Code: KeyRightHyper},
- 57452: {Code: KeyRightMeta},
- 57453: {Code: KeyIsoLevel3Shift},
- 57454: {Code: KeyIsoLevel5Shift},
-}
-
-func init() {
- // These are some faulty C0 mappings some terminals such as WezTerm have
- // and doesn't follow the specs.
- kittyKeyMap[ansi.NUL] = Key{Code: KeySpace, Mod: ModCtrl}
- for i := ansi.SOH; i <= ansi.SUB; i++ {
- if _, ok := kittyKeyMap[i]; !ok {
- kittyKeyMap[i] = Key{Code: rune(i + 0x60), Mod: ModCtrl}
- }
- }
- for i := ansi.FS; i <= ansi.US; i++ {
- if _, ok := kittyKeyMap[i]; !ok {
- kittyKeyMap[i] = Key{Code: rune(i + 0x40), Mod: ModCtrl}
- }
- }
-}
-
-const (
- kittyShift = 1 << iota
- kittyAlt
- kittyCtrl
- kittySuper
- kittyHyper
- kittyMeta
- kittyCapsLock
- kittyNumLock
-)
-
-func fromKittyMod(mod int) KeyMod {
- var m KeyMod
- if mod&kittyShift != 0 {
- m |= ModShift
- }
- if mod&kittyAlt != 0 {
- m |= ModAlt
- }
- if mod&kittyCtrl != 0 {
- m |= ModCtrl
- }
- if mod&kittySuper != 0 {
- m |= ModSuper
- }
- if mod&kittyHyper != 0 {
- m |= ModHyper
- }
- if mod&kittyMeta != 0 {
- m |= ModMeta
- }
- if mod&kittyCapsLock != 0 {
- m |= ModCapsLock
- }
- if mod&kittyNumLock != 0 {
- m |= ModNumLock
- }
- return m
-}
-
-// parseKittyKeyboard parses a Kitty Keyboard Protocol sequence.
-//
-// In `CSI u`, this is parsed as:
-//
-// CSI codepoint ; modifiers u
-// codepoint: ASCII Dec value
-//
-// The Kitty Keyboard Protocol extends this with optional components that can be
-// enabled progressively. The full sequence is parsed as:
-//
-// CSI unicode-key-code:alternate-key-codes ; modifiers:event-type ; text-as-codepoints u
-//
-// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/
-func parseKittyKeyboard(params ansi.Params) (Event Event) {
- var isRelease bool
- var key Key
-
- // The index of parameters separated by semicolons ';'. Sub parameters are
- // separated by colons ':'.
- var paramIdx int
- var sudIdx int // The sub parameter index
- for _, p := range params {
- // Kitty Keyboard Protocol has 3 optional components.
- switch paramIdx {
- case 0:
- switch sudIdx {
- case 0:
- var foundKey bool
- code := p.Param(1) // CSI u has a default value of 1
- key, foundKey = kittyKeyMap[code]
- if !foundKey {
- r := rune(code)
- if !utf8.ValidRune(r) {
- r = utf8.RuneError
- }
-
- key.Code = r
- }
-
- case 2:
- // shifted key + base key
- if b := rune(p.Param(1)); unicode.IsPrint(b) {
- // XXX: When alternate key reporting is enabled, the protocol
- // can return 3 things, the unicode codepoint of the key,
- // the shifted codepoint of the key, and the standard
- // PC-101 key layout codepoint.
- // This is useful to create an unambiguous mapping of keys
- // when using a different language layout.
- key.BaseCode = b
- }
- fallthrough
-
- case 1:
- // shifted key
- if s := rune(p.Param(1)); unicode.IsPrint(s) {
- // XXX: We swap keys here because we want the shifted key
- // to be the Rune that is returned by the event.
- // For example, shift+a should produce "A" not "a".
- // In such a case, we set AltRune to the original key "a"
- // and Rune to "A".
- key.ShiftedCode = s
- }
- }
- case 1:
- switch sudIdx {
- case 0:
- mod := p.Param(1)
- if mod > 1 {
- key.Mod = fromKittyMod(mod - 1)
- if key.Mod > ModShift {
- // XXX: We need to clear the text if we have a modifier key
- // other than a [ModShift] key.
- key.Text = ""
- }
- }
-
- case 1:
- switch p.Param(1) {
- case 2:
- key.IsRepeat = true
- case 3:
- isRelease = true
- }
- case 2:
- }
- case 2:
- if code := p.Param(0); code != 0 {
- key.Text += string(rune(code))
- }
- }
-
- sudIdx++
- if !p.HasMore() {
- paramIdx++
- sudIdx = 0
- }
- }
-
- //nolint:nestif
- if len(key.Text) == 0 && unicode.IsPrint(key.Code) &&
- (key.Mod <= ModShift || key.Mod == ModCapsLock || key.Mod == ModShift|ModCapsLock) {
- if key.Mod == 0 {
- key.Text = string(key.Code)
- } else {
- desiredCase := unicode.ToLower
- if key.Mod.Contains(ModShift) || key.Mod.Contains(ModCapsLock) {
- desiredCase = unicode.ToUpper
- }
- if key.ShiftedCode != 0 {
- key.Text = string(key.ShiftedCode)
- } else {
- key.Text = string(desiredCase(key.Code))
- }
- }
- }
-
- if isRelease {
- return KeyReleaseEvent(key)
- }
-
- return KeyPressEvent(key)
-}
-
-// parseKittyKeyboardExt parses a Kitty Keyboard Protocol sequence extensions
-// for non CSI u sequences. This includes things like CSI A, SS3 A and others,
-// and CSI ~.
-func parseKittyKeyboardExt(params ansi.Params, k KeyPressEvent) Event {
- // Handle Kitty keyboard protocol
- if len(params) > 2 && // We have at least 3 parameters
- params[0].Param(1) == 1 && // The first parameter is 1 (defaults to 1)
- params[1].HasMore() { // The second parameter is a subparameter (separated by a ":")
- switch params[2].Param(1) { // The third parameter is the event type (defaults to 1)
- case 2:
- k.IsRepeat = true
- case 3:
- return KeyReleaseEvent(k)
- }
- }
- return k
-}