1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
package config
import (
"bytes"
"errors"
"fmt"
"io"
"strings"
"github.com/gdamore/tcell"
)
type KeyStroke struct {
Key tcell.Key
Rune rune
}
type Binding struct {
Output []KeyStroke
Input []KeyStroke
}
type KeyBindings []*Binding
const (
BINDING_FOUND = iota
BINDING_INCOMPLETE
BINDING_NOT_FOUND
)
type BindingSearchResult int
func NewKeyBindings() *KeyBindings {
return &KeyBindings{}
}
func (bindings *KeyBindings) Add(binding *Binding) {
// TODO: Search for conflicts?
*bindings = append(*bindings, binding)
}
func (bindings *KeyBindings) GetBinding(
input []KeyStroke) (BindingSearchResult, []KeyStroke) {
incomplete := false
// TODO: This could probably be a sorted list to speed things up
// TODO: Deal with bindings that share a prefix
for _, binding := range *bindings {
if len(binding.Input) < len(input) {
continue
}
for i, stroke := range input {
if stroke != binding.Input[i] {
goto next
}
}
if len(binding.Input) != len(input) {
incomplete = true
} else {
return BINDING_FOUND, binding.Output
}
next:
}
if incomplete {
return BINDING_INCOMPLETE, nil
}
return BINDING_NOT_FOUND, nil
}
var (
keyNames map[string]tcell.Key
)
func ParseKeyStrokes(keystrokes string) ([]KeyStroke, error) {
var strokes []KeyStroke
buf := bytes.NewBufferString(keystrokes)
for {
tok, _, err := buf.ReadRune()
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
// TODO: make it possible to bind to < or > themselves (and default to
// switching accounts)
switch tok {
case '<':
name, err := buf.ReadString(byte('>'))
if err == io.EOF {
return nil, errors.New("Expecting '>'")
} else if err != nil {
return nil, err
} else if name == ">" {
return nil, errors.New("Expected a key name")
}
name = name[:len(name)-1]
if key, ok := keyNames[strings.ToLower(name)]; ok {
strokes = append(strokes, KeyStroke{
Key: key,
})
} else {
return nil, errors.New(fmt.Sprintf("Unknown key '%s'", name))
}
case '>':
return nil, errors.New("Found '>' without '<'")
default:
strokes = append(strokes, KeyStroke{
Key: tcell.KeyRune,
Rune: tok,
})
}
}
return strokes, nil
}
func ParseBinding(input, output string) (*Binding, error) {
in, err := ParseKeyStrokes(input)
if err != nil {
return nil, err
}
out, err := ParseKeyStrokes(output)
if err != nil {
return nil, err
}
return &Binding{
Input: in,
Output: out,
}, nil
}
func init() {
keyNames = make(map[string]tcell.Key)
keyNames["up"] = tcell.KeyUp
keyNames["down"] = tcell.KeyDown
keyNames["right"] = tcell.KeyRight
keyNames["left"] = tcell.KeyLeft
keyNames["upleft"] = tcell.KeyUpLeft
keyNames["upright"] = tcell.KeyUpRight
keyNames["downleft"] = tcell.KeyDownLeft
keyNames["downright"] = tcell.KeyDownRight
keyNames["center"] = tcell.KeyCenter
keyNames["pgup"] = tcell.KeyPgUp
keyNames["pgdn"] = tcell.KeyPgDn
keyNames["home"] = tcell.KeyHome
keyNames["end"] = tcell.KeyEnd
keyNames["insert"] = tcell.KeyInsert
keyNames["delete"] = tcell.KeyDelete
keyNames["help"] = tcell.KeyHelp
keyNames["exit"] = tcell.KeyExit
keyNames["clear"] = tcell.KeyClear
keyNames["cancel"] = tcell.KeyCancel
keyNames["print"] = tcell.KeyPrint
keyNames["pause"] = tcell.KeyPause
keyNames["backtab"] = tcell.KeyBacktab
keyNames["f1"] = tcell.KeyF1
keyNames["f2"] = tcell.KeyF2
keyNames["f3"] = tcell.KeyF3
keyNames["f4"] = tcell.KeyF4
keyNames["f5"] = tcell.KeyF5
keyNames["f6"] = tcell.KeyF6
keyNames["f7"] = tcell.KeyF7
keyNames["f8"] = tcell.KeyF8
keyNames["f9"] = tcell.KeyF9
keyNames["f10"] = tcell.KeyF10
keyNames["f11"] = tcell.KeyF11
keyNames["f12"] = tcell.KeyF12
keyNames["f13"] = tcell.KeyF13
keyNames["f14"] = tcell.KeyF14
keyNames["f15"] = tcell.KeyF15
keyNames["f16"] = tcell.KeyF16
keyNames["f17"] = tcell.KeyF17
keyNames["f18"] = tcell.KeyF18
keyNames["f19"] = tcell.KeyF19
keyNames["f20"] = tcell.KeyF20
keyNames["f21"] = tcell.KeyF21
keyNames["f22"] = tcell.KeyF22
keyNames["f23"] = tcell.KeyF23
keyNames["f24"] = tcell.KeyF24
keyNames["f25"] = tcell.KeyF25
keyNames["f26"] = tcell.KeyF26
keyNames["f27"] = tcell.KeyF27
keyNames["f28"] = tcell.KeyF28
keyNames["f29"] = tcell.KeyF29
keyNames["f30"] = tcell.KeyF30
keyNames["f31"] = tcell.KeyF31
keyNames["f32"] = tcell.KeyF32
keyNames["f33"] = tcell.KeyF33
keyNames["f34"] = tcell.KeyF34
keyNames["f35"] = tcell.KeyF35
keyNames["f36"] = tcell.KeyF36
keyNames["f37"] = tcell.KeyF37
keyNames["f38"] = tcell.KeyF38
keyNames["f39"] = tcell.KeyF39
keyNames["f40"] = tcell.KeyF40
keyNames["f41"] = tcell.KeyF41
keyNames["f42"] = tcell.KeyF42
keyNames["f43"] = tcell.KeyF43
keyNames["f44"] = tcell.KeyF44
keyNames["f45"] = tcell.KeyF45
keyNames["f46"] = tcell.KeyF46
keyNames["f47"] = tcell.KeyF47
keyNames["f48"] = tcell.KeyF48
keyNames["f49"] = tcell.KeyF49
keyNames["f50"] = tcell.KeyF50
keyNames["f51"] = tcell.KeyF51
keyNames["f52"] = tcell.KeyF52
keyNames["f53"] = tcell.KeyF53
keyNames["f54"] = tcell.KeyF54
keyNames["f55"] = tcell.KeyF55
keyNames["f56"] = tcell.KeyF56
keyNames["f57"] = tcell.KeyF57
keyNames["f58"] = tcell.KeyF58
keyNames["f59"] = tcell.KeyF59
keyNames["f60"] = tcell.KeyF60
keyNames["f61"] = tcell.KeyF61
keyNames["f62"] = tcell.KeyF62
keyNames["f63"] = tcell.KeyF63
keyNames["f64"] = tcell.KeyF64
keyNames["c-space"] = tcell.KeyCtrlSpace
keyNames["c-a"] = tcell.KeyCtrlA
keyNames["c-b"] = tcell.KeyCtrlB
keyNames["c-c"] = tcell.KeyCtrlC
keyNames["c-d"] = tcell.KeyCtrlD
keyNames["c-e"] = tcell.KeyCtrlE
keyNames["c-f"] = tcell.KeyCtrlF
keyNames["c-g"] = tcell.KeyCtrlG
keyNames["c-h"] = tcell.KeyCtrlH
keyNames["c-i"] = tcell.KeyCtrlI
keyNames["c-j"] = tcell.KeyCtrlJ
keyNames["c-k"] = tcell.KeyCtrlK
keyNames["c-l"] = tcell.KeyCtrlL
keyNames["c-m"] = tcell.KeyCtrlM
keyNames["c-n"] = tcell.KeyCtrlN
keyNames["c-o"] = tcell.KeyCtrlO
keyNames["c-p"] = tcell.KeyCtrlP
keyNames["c-q"] = tcell.KeyCtrlQ
keyNames["c-r"] = tcell.KeyCtrlR
keyNames["c-s"] = tcell.KeyCtrlS
keyNames["c-t"] = tcell.KeyCtrlT
keyNames["c-u"] = tcell.KeyCtrlU
keyNames["c-v"] = tcell.KeyCtrlV
keyNames["c-w"] = tcell.KeyCtrlW
keyNames["c-x"] = tcell.KeyCtrlX
keyNames["c-y"] = tcell.KeyCtrlY
keyNames["c-z"] = tcell.KeyCtrlZ
keyNames["c-]"] = tcell.KeyCtrlLeftSq
keyNames["c-\\"] = tcell.KeyCtrlBackslash
keyNames["c-["] = tcell.KeyCtrlRightSq
keyNames["c-^"] = tcell.KeyCtrlCarat
keyNames["c-_"] = tcell.KeyCtrlUnderscore
keyNames["NUL"] = tcell.KeyNUL
keyNames["SOH"] = tcell.KeySOH
keyNames["STX"] = tcell.KeySTX
keyNames["ETX"] = tcell.KeyETX
keyNames["EOT"] = tcell.KeyEOT
keyNames["ENQ"] = tcell.KeyENQ
keyNames["ACK"] = tcell.KeyACK
keyNames["BEL"] = tcell.KeyBEL
keyNames["BS"] = tcell.KeyBS
keyNames["TAB"] = tcell.KeyTAB
keyNames["LF"] = tcell.KeyLF
keyNames["VT"] = tcell.KeyVT
keyNames["FF"] = tcell.KeyFF
keyNames["CR"] = tcell.KeyCR
keyNames["SO"] = tcell.KeySO
keyNames["SI"] = tcell.KeySI
keyNames["DLE"] = tcell.KeyDLE
keyNames["DC1"] = tcell.KeyDC1
keyNames["DC2"] = tcell.KeyDC2
keyNames["DC3"] = tcell.KeyDC3
keyNames["DC4"] = tcell.KeyDC4
keyNames["NAK"] = tcell.KeyNAK
keyNames["SYN"] = tcell.KeySYN
keyNames["ETB"] = tcell.KeyETB
keyNames["CAN"] = tcell.KeyCAN
keyNames["EM"] = tcell.KeyEM
keyNames["SUB"] = tcell.KeySUB
keyNames["ESC"] = tcell.KeyESC
keyNames["FS"] = tcell.KeyFS
keyNames["GS"] = tcell.KeyGS
keyNames["RS"] = tcell.KeyRS
keyNames["US"] = tcell.KeyUS
keyNames["DEL"] = tcell.KeyDEL
}
|