Reworking Keymaps

This commit is contained in:
2025-10-26 08:47:07 -05:00
parent cf47b5a4e4
commit d63e3a414a
30 changed files with 384 additions and 715 deletions

160
keymap.go
View File

@@ -23,71 +23,119 @@ package widgets
import "github.com/gdamore/tcell"
type Key struct {
ev *tcell.EventKey
do []func(*tcell.EventKey) bool
desc string
}
func BuildEK(k tcell.Key) *tcell.EventKey { return tcell.NewEventKey(k, 0, 0) }
func BuildEKr(r rune) *tcell.EventKey { return tcell.NewEventKey(tcell.KeyRune, r, 0) }
func NewKey(ev *tcell.EventKey, do func(*tcell.EventKey) bool) *Key {
return &Key{
ev: ev,
do: []func(*tcell.EventKey) bool{do},
}
}
func (k *Key) AddBinding(do func(*tcell.EventKey) bool) *Key {
k.do = append(k.do, do)
return k
}
func (k *Key) SetDescription(d string) *Key {
k.desc = d
return k
}
func (k *Key) Matches(ev *tcell.EventKey) bool {
return k.ev.Key() == ev.Key() &&
k.ev.Rune() == ev.Rune() &&
k.ev.Modifiers() == ev.Modifiers()
}
func (k *Key) Handle(ev *tcell.EventKey) bool {
if !k.Matches(ev) {
return false
}
var cons bool
for _, d := range k.do {
cons = cons || d(ev)
}
return cons
}
type KeyMap struct {
Keys map[tcell.Key]func(*tcell.EventKey) bool
Runes map[rune]func(*tcell.EventKey) bool
Keys []*Key
}
func BlankKeyMap() KeyMap {
return KeyMap{
Keys: make(map[tcell.Key]func(*tcell.EventKey) bool),
Runes: make(map[rune]func(*tcell.EventKey) bool),
func BlankKeyMap() *KeyMap { return &KeyMap{} }
func NewKeyMap(k *Key, rest ...*Key) *KeyMap {
ret := &KeyMap{}
return ret
}
// Search through 'Keys', and return all that matches
func (m *KeyMap) Get(k *Key) *Key {
for _, key := range m.Keys {
if k.Matches(key.ev) {
return key
}
}
return nil
}
func (m *KeyMap) Merge(n *KeyMap) {
switch len(n.Keys) {
case 0:
return
case 1:
m.Add(n.Keys[0])
default:
m.Add(n.Keys[0], n.Keys[1:]...)
}
}
func NewKeyMap(m map[tcell.Key]func(*tcell.EventKey) bool) KeyMap {
return KeyMap{
Keys: m,
Runes: make(map[rune]func(*tcell.EventKey) bool),
}
}
func NewRuneMap(m map[rune]func(*tcell.EventKey) bool) KeyMap {
return KeyMap{
Keys: make(map[tcell.Key]func(*tcell.EventKey) bool),
Runes: m,
}
}
func (m KeyMap) Merge(km KeyMap) {
for k, v := range km.Keys {
m.Keys[k] = v
}
for r, v := range km.Runes {
m.Runes[r] = v
}
}
func (m KeyMap) Add(k tcell.Key, do func(*tcell.EventKey) bool) { m.Keys[k] = do }
func (m KeyMap) Remove(k tcell.Key) { delete(m.Keys, k) }
func (m KeyMap) AddAll(all map[tcell.Key]func(*tcell.EventKey) bool) {
for k, v := range all {
m.Add(k, v)
}
}
func (m KeyMap) AddRune(k rune, do func(*tcell.EventKey) bool) { m.Runes[k] = do }
func (m KeyMap) RemoveRune(k rune) { delete(m.Runes, k) }
func (m KeyMap) AddRunes(all map[rune]func(*tcell.EventKey) bool) {
for k, v := range all {
m.AddRune(k, v)
}
}
func (m KeyMap) Handle(ev *tcell.EventKey) bool {
if ev.Key() == tcell.KeyRune {
for k, v := range m.Runes {
if ev.Rune() == k {
return v(ev)
}
func (m *KeyMap) Add(k *Key, rest ...*Key) {
p := m.Get(k)
if p != nil {
for dIdx := range k.do {
p.AddBinding(k.do[dIdx])
}
if k.desc != "" {
p.SetDescription(k.desc)
}
} else {
for k, v := range m.Keys {
if ev.Key() == k {
return v(ev)
m.Keys = append(m.Keys, k)
}
}
func (m *KeyMap) Remove(k *Key, rest ...*Key) {
do := func(k *Key) {
idx := -1
for i := range m.Keys {
if m.Keys[i].Matches(k.ev) {
idx = i
break
}
}
if idx == -1 {
return
}
m.Keys = append(m.Keys[:idx], m.Keys[idx+1:]...)
}
do(k)
for i := range rest {
do(rest[i])
}
return false
}
func (m *KeyMap) Handle(ev *tcell.EventKey) bool {
var cons bool
for _, k := range m.Keys {
cons = cons || k.Handle(ev)
}
return cons
}