...
1 package cbind
2
3 import (
4 "fmt"
5 "sync"
6 "unicode"
7
8 "github.com/gdamore/tcell/v2"
9 )
10
11 type eventHandler func(ev *tcell.EventKey) *tcell.EventKey
12
13
14 type Configuration struct {
15 handlers map[string]eventHandler
16 mutex *sync.RWMutex
17 }
18
19
20 func NewConfiguration() *Configuration {
21 c := Configuration{
22 handlers: make(map[string]eventHandler),
23 mutex: new(sync.RWMutex),
24 }
25
26 return &c
27 }
28
29
30 func (c *Configuration) Set(s string, handler func(ev *tcell.EventKey) *tcell.EventKey) error {
31 mod, key, ch, err := Decode(s)
32 if err != nil {
33 return err
34 }
35
36 if key == tcell.KeyRune {
37 c.SetRune(mod, ch, handler)
38 } else {
39 c.SetKey(mod, key, handler)
40 }
41 return nil
42 }
43
44
45 func (c *Configuration) SetKey(mod tcell.ModMask, key tcell.Key, handler func(ev *tcell.EventKey) *tcell.EventKey) {
46 c.mutex.Lock()
47 defer c.mutex.Unlock()
48
49 if mod&tcell.ModShift != 0 && key == tcell.KeyTab {
50 mod ^= tcell.ModShift
51 key = tcell.KeyBacktab
52 }
53
54 if mod&tcell.ModCtrl == 0 && key != tcell.KeyBackspace && key != tcell.KeyTab && key != tcell.KeyEnter {
55 for _, ctrlKey := range ctrlKeys {
56 if key == ctrlKey {
57 mod |= tcell.ModCtrl
58 break
59 }
60 }
61 }
62
63 c.handlers[fmt.Sprintf("%d-%d", mod, key)] = handler
64 }
65
66
67 func (c *Configuration) SetRune(mod tcell.ModMask, ch rune, handler func(ev *tcell.EventKey) *tcell.EventKey) {
68
69
70 switch ch {
71 case '\t':
72 c.SetKey(mod, tcell.KeyTab, handler)
73 return
74 case '\n':
75 c.SetKey(mod, tcell.KeyEnter, handler)
76 return
77 }
78
79 if mod&tcell.ModCtrl != 0 {
80 k, ok := ctrlKeys[unicode.ToLower(ch)]
81 if ok {
82 c.SetKey(mod, k, handler)
83 return
84 }
85 }
86
87 c.mutex.Lock()
88 defer c.mutex.Unlock()
89
90 c.handlers[fmt.Sprintf("%d:%d", mod, ch)] = handler
91 }
92
93
94 func (c *Configuration) Capture(ev *tcell.EventKey) *tcell.EventKey {
95 c.mutex.RLock()
96 defer c.mutex.RUnlock()
97
98 if ev == nil {
99 return nil
100 }
101
102 var keyName string
103 if ev.Key() != tcell.KeyRune {
104 keyName = fmt.Sprintf("%d-%d", ev.Modifiers(), ev.Key())
105 } else {
106 keyName = fmt.Sprintf("%d:%d", ev.Modifiers(), ev.Rune())
107 }
108
109 handler := c.handlers[keyName]
110 if handler != nil {
111 return handler(ev)
112 }
113 return ev
114 }
115
116
117 func (c *Configuration) Clear() {
118 c.mutex.Lock()
119 defer c.mutex.Unlock()
120
121 c.handlers = make(map[string]eventHandler)
122 }
123
View as plain text