Reworking Keymaps
This commit is contained in:
160
keymap.go
160
keymap.go
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user