278 lines
8.9 KiB
Go
278 lines
8.9 KiB
Go
package input
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/xo/terminfo"
|
|
)
|
|
|
|
func buildTerminfoKeys(flags int, term string) map[string]Key {
|
|
table := make(map[string]Key)
|
|
ti, _ := terminfo.Load(term)
|
|
if ti == nil {
|
|
return table
|
|
}
|
|
|
|
tiTable := defaultTerminfoKeys(flags)
|
|
|
|
// Default keys
|
|
for name, seq := range ti.StringCapsShort() {
|
|
if !strings.HasPrefix(name, "k") || len(seq) == 0 {
|
|
continue
|
|
}
|
|
|
|
if k, ok := tiTable[name]; ok {
|
|
table[string(seq)] = k
|
|
}
|
|
}
|
|
|
|
// Extended keys
|
|
for name, seq := range ti.ExtStringCapsShort() {
|
|
if !strings.HasPrefix(name, "k") || len(seq) == 0 {
|
|
continue
|
|
}
|
|
|
|
if k, ok := tiTable[name]; ok {
|
|
table[string(seq)] = k
|
|
}
|
|
}
|
|
|
|
return table
|
|
}
|
|
|
|
// This returns a map of terminfo keys to key events. It's a mix of ncurses
|
|
// terminfo default and user-defined key capabilities.
|
|
// Upper-case caps that are defined in the default terminfo database are
|
|
// - kNXT
|
|
// - kPRV
|
|
// - kHOM
|
|
// - kEND
|
|
// - kDC
|
|
// - kIC
|
|
// - kLFT
|
|
// - kRIT
|
|
//
|
|
// See https://man7.org/linux/man-pages/man5/terminfo.5.html
|
|
// See https://github.com/mirror/ncurses/blob/master/include/Caps-ncurses
|
|
func defaultTerminfoKeys(flags int) map[string]Key {
|
|
keys := map[string]Key{
|
|
"kcuu1": {Sym: KeyUp},
|
|
"kUP": {Sym: KeyUp, Mod: Shift},
|
|
"kUP3": {Sym: KeyUp, Mod: Alt},
|
|
"kUP4": {Sym: KeyUp, Mod: Shift | Alt},
|
|
"kUP5": {Sym: KeyUp, Mod: Ctrl},
|
|
"kUP6": {Sym: KeyUp, Mod: Shift | Ctrl},
|
|
"kUP7": {Sym: KeyUp, Mod: Alt | Ctrl},
|
|
"kUP8": {Sym: KeyUp, Mod: Shift | Alt | Ctrl},
|
|
"kcud1": {Sym: KeyDown},
|
|
"kDN": {Sym: KeyDown, Mod: Shift},
|
|
"kDN3": {Sym: KeyDown, Mod: Alt},
|
|
"kDN4": {Sym: KeyDown, Mod: Shift | Alt},
|
|
"kDN5": {Sym: KeyDown, Mod: Ctrl},
|
|
"kDN7": {Sym: KeyDown, Mod: Alt | Ctrl},
|
|
"kDN6": {Sym: KeyDown, Mod: Shift | Ctrl},
|
|
"kDN8": {Sym: KeyDown, Mod: Shift | Alt | Ctrl},
|
|
"kcub1": {Sym: KeyLeft},
|
|
"kLFT": {Sym: KeyLeft, Mod: Shift},
|
|
"kLFT3": {Sym: KeyLeft, Mod: Alt},
|
|
"kLFT4": {Sym: KeyLeft, Mod: Shift | Alt},
|
|
"kLFT5": {Sym: KeyLeft, Mod: Ctrl},
|
|
"kLFT6": {Sym: KeyLeft, Mod: Shift | Ctrl},
|
|
"kLFT7": {Sym: KeyLeft, Mod: Alt | Ctrl},
|
|
"kLFT8": {Sym: KeyLeft, Mod: Shift | Alt | Ctrl},
|
|
"kcuf1": {Sym: KeyRight},
|
|
"kRIT": {Sym: KeyRight, Mod: Shift},
|
|
"kRIT3": {Sym: KeyRight, Mod: Alt},
|
|
"kRIT4": {Sym: KeyRight, Mod: Shift | Alt},
|
|
"kRIT5": {Sym: KeyRight, Mod: Ctrl},
|
|
"kRIT6": {Sym: KeyRight, Mod: Shift | Ctrl},
|
|
"kRIT7": {Sym: KeyRight, Mod: Alt | Ctrl},
|
|
"kRIT8": {Sym: KeyRight, Mod: Shift | Alt | Ctrl},
|
|
"kich1": {Sym: KeyInsert},
|
|
"kIC": {Sym: KeyInsert, Mod: Shift},
|
|
"kIC3": {Sym: KeyInsert, Mod: Alt},
|
|
"kIC4": {Sym: KeyInsert, Mod: Shift | Alt},
|
|
"kIC5": {Sym: KeyInsert, Mod: Ctrl},
|
|
"kIC6": {Sym: KeyInsert, Mod: Shift | Ctrl},
|
|
"kIC7": {Sym: KeyInsert, Mod: Alt | Ctrl},
|
|
"kIC8": {Sym: KeyInsert, Mod: Shift | Alt | Ctrl},
|
|
"kdch1": {Sym: KeyDelete},
|
|
"kDC": {Sym: KeyDelete, Mod: Shift},
|
|
"kDC3": {Sym: KeyDelete, Mod: Alt},
|
|
"kDC4": {Sym: KeyDelete, Mod: Shift | Alt},
|
|
"kDC5": {Sym: KeyDelete, Mod: Ctrl},
|
|
"kDC6": {Sym: KeyDelete, Mod: Shift | Ctrl},
|
|
"kDC7": {Sym: KeyDelete, Mod: Alt | Ctrl},
|
|
"kDC8": {Sym: KeyDelete, Mod: Shift | Alt | Ctrl},
|
|
"khome": {Sym: KeyHome},
|
|
"kHOM": {Sym: KeyHome, Mod: Shift},
|
|
"kHOM3": {Sym: KeyHome, Mod: Alt},
|
|
"kHOM4": {Sym: KeyHome, Mod: Shift | Alt},
|
|
"kHOM5": {Sym: KeyHome, Mod: Ctrl},
|
|
"kHOM6": {Sym: KeyHome, Mod: Shift | Ctrl},
|
|
"kHOM7": {Sym: KeyHome, Mod: Alt | Ctrl},
|
|
"kHOM8": {Sym: KeyHome, Mod: Shift | Alt | Ctrl},
|
|
"kend": {Sym: KeyEnd},
|
|
"kEND": {Sym: KeyEnd, Mod: Shift},
|
|
"kEND3": {Sym: KeyEnd, Mod: Alt},
|
|
"kEND4": {Sym: KeyEnd, Mod: Shift | Alt},
|
|
"kEND5": {Sym: KeyEnd, Mod: Ctrl},
|
|
"kEND6": {Sym: KeyEnd, Mod: Shift | Ctrl},
|
|
"kEND7": {Sym: KeyEnd, Mod: Alt | Ctrl},
|
|
"kEND8": {Sym: KeyEnd, Mod: Shift | Alt | Ctrl},
|
|
"kpp": {Sym: KeyPgUp},
|
|
"kprv": {Sym: KeyPgUp},
|
|
"kPRV": {Sym: KeyPgUp, Mod: Shift},
|
|
"kPRV3": {Sym: KeyPgUp, Mod: Alt},
|
|
"kPRV4": {Sym: KeyPgUp, Mod: Shift | Alt},
|
|
"kPRV5": {Sym: KeyPgUp, Mod: Ctrl},
|
|
"kPRV6": {Sym: KeyPgUp, Mod: Shift | Ctrl},
|
|
"kPRV7": {Sym: KeyPgUp, Mod: Alt | Ctrl},
|
|
"kPRV8": {Sym: KeyPgUp, Mod: Shift | Alt | Ctrl},
|
|
"knp": {Sym: KeyPgDown},
|
|
"knxt": {Sym: KeyPgDown},
|
|
"kNXT": {Sym: KeyPgDown, Mod: Shift},
|
|
"kNXT3": {Sym: KeyPgDown, Mod: Alt},
|
|
"kNXT4": {Sym: KeyPgDown, Mod: Shift | Alt},
|
|
"kNXT5": {Sym: KeyPgDown, Mod: Ctrl},
|
|
"kNXT6": {Sym: KeyPgDown, Mod: Shift | Ctrl},
|
|
"kNXT7": {Sym: KeyPgDown, Mod: Alt | Ctrl},
|
|
"kNXT8": {Sym: KeyPgDown, Mod: Shift | Alt | Ctrl},
|
|
|
|
"kbs": {Sym: KeyBackspace},
|
|
"kcbt": {Sym: KeyTab, Mod: Shift},
|
|
|
|
// Function keys
|
|
// This only includes the first 12 function keys. The rest are treated
|
|
// as modifiers of the first 12.
|
|
// Take a look at XTerm modifyFunctionKeys
|
|
//
|
|
// XXX: To use unambiguous function keys, use fixterms or kitty clipboard.
|
|
//
|
|
// See https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyFunctionKeys
|
|
// See https://invisible-island.net/xterm/terminfo.html
|
|
|
|
"kf1": {Sym: KeyF1},
|
|
"kf2": {Sym: KeyF2},
|
|
"kf3": {Sym: KeyF3},
|
|
"kf4": {Sym: KeyF4},
|
|
"kf5": {Sym: KeyF5},
|
|
"kf6": {Sym: KeyF6},
|
|
"kf7": {Sym: KeyF7},
|
|
"kf8": {Sym: KeyF8},
|
|
"kf9": {Sym: KeyF9},
|
|
"kf10": {Sym: KeyF10},
|
|
"kf11": {Sym: KeyF11},
|
|
"kf12": {Sym: KeyF12},
|
|
"kf13": {Sym: KeyF1, Mod: Shift},
|
|
"kf14": {Sym: KeyF2, Mod: Shift},
|
|
"kf15": {Sym: KeyF3, Mod: Shift},
|
|
"kf16": {Sym: KeyF4, Mod: Shift},
|
|
"kf17": {Sym: KeyF5, Mod: Shift},
|
|
"kf18": {Sym: KeyF6, Mod: Shift},
|
|
"kf19": {Sym: KeyF7, Mod: Shift},
|
|
"kf20": {Sym: KeyF8, Mod: Shift},
|
|
"kf21": {Sym: KeyF9, Mod: Shift},
|
|
"kf22": {Sym: KeyF10, Mod: Shift},
|
|
"kf23": {Sym: KeyF11, Mod: Shift},
|
|
"kf24": {Sym: KeyF12, Mod: Shift},
|
|
"kf25": {Sym: KeyF1, Mod: Ctrl},
|
|
"kf26": {Sym: KeyF2, Mod: Ctrl},
|
|
"kf27": {Sym: KeyF3, Mod: Ctrl},
|
|
"kf28": {Sym: KeyF4, Mod: Ctrl},
|
|
"kf29": {Sym: KeyF5, Mod: Ctrl},
|
|
"kf30": {Sym: KeyF6, Mod: Ctrl},
|
|
"kf31": {Sym: KeyF7, Mod: Ctrl},
|
|
"kf32": {Sym: KeyF8, Mod: Ctrl},
|
|
"kf33": {Sym: KeyF9, Mod: Ctrl},
|
|
"kf34": {Sym: KeyF10, Mod: Ctrl},
|
|
"kf35": {Sym: KeyF11, Mod: Ctrl},
|
|
"kf36": {Sym: KeyF12, Mod: Ctrl},
|
|
"kf37": {Sym: KeyF1, Mod: Shift | Ctrl},
|
|
"kf38": {Sym: KeyF2, Mod: Shift | Ctrl},
|
|
"kf39": {Sym: KeyF3, Mod: Shift | Ctrl},
|
|
"kf40": {Sym: KeyF4, Mod: Shift | Ctrl},
|
|
"kf41": {Sym: KeyF5, Mod: Shift | Ctrl},
|
|
"kf42": {Sym: KeyF6, Mod: Shift | Ctrl},
|
|
"kf43": {Sym: KeyF7, Mod: Shift | Ctrl},
|
|
"kf44": {Sym: KeyF8, Mod: Shift | Ctrl},
|
|
"kf45": {Sym: KeyF9, Mod: Shift | Ctrl},
|
|
"kf46": {Sym: KeyF10, Mod: Shift | Ctrl},
|
|
"kf47": {Sym: KeyF11, Mod: Shift | Ctrl},
|
|
"kf48": {Sym: KeyF12, Mod: Shift | Ctrl},
|
|
"kf49": {Sym: KeyF1, Mod: Alt},
|
|
"kf50": {Sym: KeyF2, Mod: Alt},
|
|
"kf51": {Sym: KeyF3, Mod: Alt},
|
|
"kf52": {Sym: KeyF4, Mod: Alt},
|
|
"kf53": {Sym: KeyF5, Mod: Alt},
|
|
"kf54": {Sym: KeyF6, Mod: Alt},
|
|
"kf55": {Sym: KeyF7, Mod: Alt},
|
|
"kf56": {Sym: KeyF8, Mod: Alt},
|
|
"kf57": {Sym: KeyF9, Mod: Alt},
|
|
"kf58": {Sym: KeyF10, Mod: Alt},
|
|
"kf59": {Sym: KeyF11, Mod: Alt},
|
|
"kf60": {Sym: KeyF12, Mod: Alt},
|
|
"kf61": {Sym: KeyF1, Mod: Shift | Alt},
|
|
"kf62": {Sym: KeyF2, Mod: Shift | Alt},
|
|
"kf63": {Sym: KeyF3, Mod: Shift | Alt},
|
|
}
|
|
|
|
// Preserve F keys from F13 to F63 instead of using them for F-keys
|
|
// modifiers.
|
|
if flags&FlagFKeys != 0 {
|
|
keys["kf13"] = Key{Sym: KeyF13}
|
|
keys["kf14"] = Key{Sym: KeyF14}
|
|
keys["kf15"] = Key{Sym: KeyF15}
|
|
keys["kf16"] = Key{Sym: KeyF16}
|
|
keys["kf17"] = Key{Sym: KeyF17}
|
|
keys["kf18"] = Key{Sym: KeyF18}
|
|
keys["kf19"] = Key{Sym: KeyF19}
|
|
keys["kf20"] = Key{Sym: KeyF20}
|
|
keys["kf21"] = Key{Sym: KeyF21}
|
|
keys["kf22"] = Key{Sym: KeyF22}
|
|
keys["kf23"] = Key{Sym: KeyF23}
|
|
keys["kf24"] = Key{Sym: KeyF24}
|
|
keys["kf25"] = Key{Sym: KeyF25}
|
|
keys["kf26"] = Key{Sym: KeyF26}
|
|
keys["kf27"] = Key{Sym: KeyF27}
|
|
keys["kf28"] = Key{Sym: KeyF28}
|
|
keys["kf29"] = Key{Sym: KeyF29}
|
|
keys["kf30"] = Key{Sym: KeyF30}
|
|
keys["kf31"] = Key{Sym: KeyF31}
|
|
keys["kf32"] = Key{Sym: KeyF32}
|
|
keys["kf33"] = Key{Sym: KeyF33}
|
|
keys["kf34"] = Key{Sym: KeyF34}
|
|
keys["kf35"] = Key{Sym: KeyF35}
|
|
keys["kf36"] = Key{Sym: KeyF36}
|
|
keys["kf37"] = Key{Sym: KeyF37}
|
|
keys["kf38"] = Key{Sym: KeyF38}
|
|
keys["kf39"] = Key{Sym: KeyF39}
|
|
keys["kf40"] = Key{Sym: KeyF40}
|
|
keys["kf41"] = Key{Sym: KeyF41}
|
|
keys["kf42"] = Key{Sym: KeyF42}
|
|
keys["kf43"] = Key{Sym: KeyF43}
|
|
keys["kf44"] = Key{Sym: KeyF44}
|
|
keys["kf45"] = Key{Sym: KeyF45}
|
|
keys["kf46"] = Key{Sym: KeyF46}
|
|
keys["kf47"] = Key{Sym: KeyF47}
|
|
keys["kf48"] = Key{Sym: KeyF48}
|
|
keys["kf49"] = Key{Sym: KeyF49}
|
|
keys["kf50"] = Key{Sym: KeyF50}
|
|
keys["kf51"] = Key{Sym: KeyF51}
|
|
keys["kf52"] = Key{Sym: KeyF52}
|
|
keys["kf53"] = Key{Sym: KeyF53}
|
|
keys["kf54"] = Key{Sym: KeyF54}
|
|
keys["kf55"] = Key{Sym: KeyF55}
|
|
keys["kf56"] = Key{Sym: KeyF56}
|
|
keys["kf57"] = Key{Sym: KeyF57}
|
|
keys["kf58"] = Key{Sym: KeyF58}
|
|
keys["kf59"] = Key{Sym: KeyF59}
|
|
keys["kf60"] = Key{Sym: KeyF60}
|
|
keys["kf61"] = Key{Sym: KeyF61}
|
|
keys["kf62"] = Key{Sym: KeyF62}
|
|
keys["kf63"] = Key{Sym: KeyF63}
|
|
}
|
|
|
|
return keys
|
|
}
|