-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkey.go
More file actions
453 lines (434 loc) · 11.8 KB
/
Copy pathkey.go
File metadata and controls
453 lines (434 loc) · 11.8 KB
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
package vt
import (
"io"
uv "github.com/charmbracelet/ultraviolet"
"github.com/charmbracelet/x/ansi"
)
// KeyMod represents a key modifier.
type KeyMod = uv.KeyMod
// Modifier keys.
const (
ModShift = uv.ModShift
ModAlt = uv.ModAlt
ModCtrl = uv.ModCtrl
ModMeta = uv.ModMeta
)
// KeyPressEvent represents a key press event.
type KeyPressEvent = uv.KeyPressEvent
// SendKey returns the default key map.
func (e *Emulator) SendKey(k uv.KeyEvent) {
var seq string
ack := e.isModeSet(ansi.ModeCursorKeys) // Application cursor keys mode
akk := e.isModeSet(ansi.ModeNumericKeypad) // Application keypad keys mode
//nolint:godox
// TODO: Support Kitty, CSI u, and XTerm modifyOtherKeys.
switch key := k.(type) {
case KeyPressEvent:
if key.Mod&ModAlt != 0 {
// Handle alt-modified keys
seq = "\x1b" + seq
key.Mod &^= ModAlt // Remove the Alt modifier for easier matching
}
//nolint:godox
// FIXME: We remove any Base and Shifted codes to properly handle
// comparison. This is a workaround for the fact that we don't support
// extended keys yet.
key.BaseCode = 0
key.ShiftedCode = 0
switch key {
// Control keys
case KeyPressEvent{Code: KeySpace, Mod: ModCtrl}:
seq += "\x00"
case KeyPressEvent{Code: 'a', Mod: ModCtrl}:
seq += "\x01"
case KeyPressEvent{Code: 'b', Mod: ModCtrl}:
seq += "\x02"
case KeyPressEvent{Code: 'c', Mod: ModCtrl}:
seq += "\x03"
case KeyPressEvent{Code: 'd', Mod: ModCtrl}:
seq += "\x04"
case KeyPressEvent{Code: 'e', Mod: ModCtrl}:
seq += "\x05"
case KeyPressEvent{Code: 'f', Mod: ModCtrl}:
seq += "\x06"
case KeyPressEvent{Code: 'g', Mod: ModCtrl}:
seq += "\x07"
case KeyPressEvent{Code: 'h', Mod: ModCtrl}:
seq += "\x08"
case KeyPressEvent{Code: 'i', Mod: ModCtrl}:
seq += "\x09"
case KeyPressEvent{Code: 'j', Mod: ModCtrl}:
seq += "\x0a"
case KeyPressEvent{Code: 'k', Mod: ModCtrl}:
seq += "\x0b"
case KeyPressEvent{Code: 'l', Mod: ModCtrl}:
seq += "\x0c"
case KeyPressEvent{Code: 'm', Mod: ModCtrl}:
seq += "\x0d"
case KeyPressEvent{Code: 'n', Mod: ModCtrl}:
seq += "\x0e"
case KeyPressEvent{Code: 'o', Mod: ModCtrl}:
seq += "\x0f"
case KeyPressEvent{Code: 'p', Mod: ModCtrl}:
seq += "\x10"
case KeyPressEvent{Code: 'q', Mod: ModCtrl}:
seq += "\x11"
case KeyPressEvent{Code: 'r', Mod: ModCtrl}:
seq += "\x12"
case KeyPressEvent{Code: 's', Mod: ModCtrl}:
seq += "\x13"
case KeyPressEvent{Code: 't', Mod: ModCtrl}:
seq += "\x14"
case KeyPressEvent{Code: 'u', Mod: ModCtrl}:
seq += "\x15"
case KeyPressEvent{Code: 'v', Mod: ModCtrl}:
seq += "\x16"
case KeyPressEvent{Code: 'w', Mod: ModCtrl}:
seq += "\x17"
case KeyPressEvent{Code: 'x', Mod: ModCtrl}:
seq += "\x18"
case KeyPressEvent{Code: 'y', Mod: ModCtrl}:
seq += "\x19"
case KeyPressEvent{Code: 'z', Mod: ModCtrl}:
seq += "\x1a"
case KeyPressEvent{Code: '[', Mod: ModCtrl}:
seq += "\x1b"
case KeyPressEvent{Code: '\\', Mod: ModCtrl}:
seq += "\x1c"
case KeyPressEvent{Code: ']', Mod: ModCtrl}:
seq += "\x1d"
case KeyPressEvent{Code: '^', Mod: ModCtrl}:
seq += "\x1e"
case KeyPressEvent{Code: '_', Mod: ModCtrl}:
seq += "\x1f"
case KeyPressEvent{Code: KeyEnter}:
seq += "\r"
case KeyPressEvent{Code: KeyTab}:
seq += "\t"
case KeyPressEvent{Code: KeyBackspace}:
seq += "\x7f"
case KeyPressEvent{Code: KeyEscape}:
seq += "\x1b"
case KeyPressEvent{Code: KeyUp}:
if ack {
seq += "\x1bOA"
} else {
seq += "\x1b[A"
}
case KeyPressEvent{Code: KeyDown}:
if ack {
seq += "\x1bOB"
} else {
seq += "\x1b[B"
}
case KeyPressEvent{Code: KeyRight}:
if ack {
seq += "\x1bOC"
} else {
seq += "\x1b[C"
}
case KeyPressEvent{Code: KeyLeft}:
if ack {
seq += "\x1bOD"
} else {
seq += "\x1b[D"
}
case KeyPressEvent{Code: KeyInsert}:
seq += "\x1b[2~"
case KeyPressEvent{Code: KeyDelete}:
seq += "\x1b[3~"
case KeyPressEvent{Code: KeyHome}:
seq += "\x1b[H"
case KeyPressEvent{Code: KeyEnd}:
seq += "\x1b[F"
case KeyPressEvent{Code: KeyPgUp}:
seq += "\x1b[5~"
case KeyPressEvent{Code: KeyPgDown}:
seq += "\x1b[6~"
case KeyPressEvent{Code: KeyF1}:
seq += "\x1bOP"
case KeyPressEvent{Code: KeyF2}:
seq += "\x1bOQ"
case KeyPressEvent{Code: KeyF3}:
seq += "\x1bOR"
case KeyPressEvent{Code: KeyF4}:
seq += "\x1bOS"
case KeyPressEvent{Code: KeyF5}:
seq += "\x1b[15~"
case KeyPressEvent{Code: KeyF6}:
seq += "\x1b[17~"
case KeyPressEvent{Code: KeyF7}:
seq += "\x1b[18~"
case KeyPressEvent{Code: KeyF8}:
seq += "\x1b[19~"
case KeyPressEvent{Code: KeyF9}:
seq += "\x1b[20~"
case KeyPressEvent{Code: KeyF10}:
seq += "\x1b[21~"
case KeyPressEvent{Code: KeyF11}:
seq += "\x1b[23~"
case KeyPressEvent{Code: KeyF12}:
seq += "\x1b[24~"
case KeyPressEvent{Code: KeyKp0}:
if akk {
seq += "\x1bOp"
} else {
seq += "0"
}
case KeyPressEvent{Code: KeyKp1}:
if akk {
seq += "\x1bOq"
} else {
seq += "1"
}
case KeyPressEvent{Code: KeyKp2}:
if akk {
seq += "\x1bOr"
} else {
seq += "2"
}
case KeyPressEvent{Code: KeyKp3}:
if akk {
seq += "\x1bOs"
} else {
seq += "3"
}
case KeyPressEvent{Code: KeyKp4}:
if akk {
seq += "\x1bOt"
} else {
seq += "4"
}
case KeyPressEvent{Code: KeyKp5}:
if akk {
seq += "\x1bOu"
} else {
seq += "5"
}
case KeyPressEvent{Code: KeyKp6}:
if akk {
seq += "\x1bOv"
} else {
seq += "6"
}
case KeyPressEvent{Code: KeyKp7}:
if akk {
seq += "\x1bOw"
} else {
seq += "7"
}
case KeyPressEvent{Code: KeyKp8}:
if akk {
seq += "\x1bOx"
} else {
seq = "8"
}
case KeyPressEvent{Code: KeyKp9}:
if akk {
seq += "\x1bOy"
} else {
seq += "9"
}
case KeyPressEvent{Code: KeyKpEnter}:
if akk {
seq += "\x1bOM"
} else {
seq += "\r"
}
case KeyPressEvent{Code: KeyKpEqual}:
if akk {
seq += "\x1bOX"
} else {
seq += "="
}
case KeyPressEvent{Code: KeyKpMultiply}:
if akk {
seq += "\x1bOj"
} else {
seq += "*"
}
case KeyPressEvent{Code: KeyKpPlus}:
if akk {
seq += "\x1bOk"
} else {
seq += "+"
}
case KeyPressEvent{Code: KeyKpComma}:
if akk {
seq += "\x1bOl"
} else {
seq += ","
}
case KeyPressEvent{Code: KeyKpMinus}:
if akk {
seq += "\x1bOm"
} else {
seq += "-"
}
case KeyPressEvent{Code: KeyKpDecimal}:
if akk {
seq += "\x1bOn"
} else {
seq += "."
}
case KeyPressEvent{Code: KeyTab, Mod: ModShift}:
seq += "\x1b[Z"
default:
// Handle the rest of the keys.
if key.Mod == 0 {
seq += string(key.Code)
}
}
io.WriteString(e.pw, seq) //nolint:errcheck,gosec
}
}
// Key codes.
const (
KeyExtended = uv.KeyExtended
KeyUp = uv.KeyUp
KeyDown = uv.KeyDown
KeyRight = uv.KeyRight
KeyLeft = uv.KeyLeft
KeyBegin = uv.KeyBegin
KeyFind = uv.KeyFind
KeyInsert = uv.KeyInsert
KeyDelete = uv.KeyDelete
KeySelect = uv.KeySelect
KeyPgUp = uv.KeyPgUp
KeyPgDown = uv.KeyPgDown
KeyHome = uv.KeyHome
KeyEnd = uv.KeyEnd
KeyKpEnter = uv.KeyKpEnter
KeyKpEqual = uv.KeyKpEqual
KeyKpMultiply = uv.KeyKpMultiply
KeyKpPlus = uv.KeyKpPlus
KeyKpComma = uv.KeyKpComma
KeyKpMinus = uv.KeyKpMinus
KeyKpDecimal = uv.KeyKpDecimal
KeyKpDivide = uv.KeyKpDivide
KeyKp0 = uv.KeyKp0
KeyKp1 = uv.KeyKp1
KeyKp2 = uv.KeyKp2
KeyKp3 = uv.KeyKp3
KeyKp4 = uv.KeyKp4
KeyKp5 = uv.KeyKp5
KeyKp6 = uv.KeyKp6
KeyKp7 = uv.KeyKp7
KeyKp8 = uv.KeyKp8
KeyKp9 = uv.KeyKp9
KeyKpSep = uv.KeyKpSep
KeyKpUp = uv.KeyKpUp
KeyKpDown = uv.KeyKpDown
KeyKpLeft = uv.KeyKpLeft
KeyKpRight = uv.KeyKpRight
KeyKpPgUp = uv.KeyKpPgUp
KeyKpPgDown = uv.KeyKpPgDown
KeyKpHome = uv.KeyKpHome
KeyKpEnd = uv.KeyKpEnd
KeyKpInsert = uv.KeyKpInsert
KeyKpDelete = uv.KeyKpDelete
KeyKpBegin = uv.KeyKpBegin
KeyF1 = uv.KeyF1
KeyF2 = uv.KeyF2
KeyF3 = uv.KeyF3
KeyF4 = uv.KeyF4
KeyF5 = uv.KeyF5
KeyF6 = uv.KeyF6
KeyF7 = uv.KeyF7
KeyF8 = uv.KeyF8
KeyF9 = uv.KeyF9
KeyF10 = uv.KeyF10
KeyF11 = uv.KeyF11
KeyF12 = uv.KeyF12
KeyF13 = uv.KeyF13
KeyF14 = uv.KeyF14
KeyF15 = uv.KeyF15
KeyF16 = uv.KeyF16
KeyF17 = uv.KeyF17
KeyF18 = uv.KeyF18
KeyF19 = uv.KeyF19
KeyF20 = uv.KeyF20
KeyF21 = uv.KeyF21
KeyF22 = uv.KeyF22
KeyF23 = uv.KeyF23
KeyF24 = uv.KeyF24
KeyF25 = uv.KeyF25
KeyF26 = uv.KeyF26
KeyF27 = uv.KeyF27
KeyF28 = uv.KeyF28
KeyF29 = uv.KeyF29
KeyF30 = uv.KeyF30
KeyF31 = uv.KeyF31
KeyF32 = uv.KeyF32
KeyF33 = uv.KeyF33
KeyF34 = uv.KeyF34
KeyF35 = uv.KeyF35
KeyF36 = uv.KeyF36
KeyF37 = uv.KeyF37
KeyF38 = uv.KeyF38
KeyF39 = uv.KeyF39
KeyF40 = uv.KeyF40
KeyF41 = uv.KeyF41
KeyF42 = uv.KeyF42
KeyF43 = uv.KeyF43
KeyF44 = uv.KeyF44
KeyF45 = uv.KeyF45
KeyF46 = uv.KeyF46
KeyF47 = uv.KeyF47
KeyF48 = uv.KeyF48
KeyF49 = uv.KeyF49
KeyF50 = uv.KeyF50
KeyF51 = uv.KeyF51
KeyF52 = uv.KeyF52
KeyF53 = uv.KeyF53
KeyF54 = uv.KeyF54
KeyF55 = uv.KeyF55
KeyF56 = uv.KeyF56
KeyF57 = uv.KeyF57
KeyF58 = uv.KeyF58
KeyF59 = uv.KeyF59
KeyF60 = uv.KeyF60
KeyF61 = uv.KeyF61
KeyF62 = uv.KeyF62
KeyF63 = uv.KeyF63
KeyCapsLock = uv.KeyCapsLock
KeyScrollLock = uv.KeyScrollLock
KeyNumLock = uv.KeyNumLock
KeyPrintScreen = uv.KeyPrintScreen
KeyPause = uv.KeyPause
KeyMenu = uv.KeyMenu
KeyMediaPlay = uv.KeyMediaPlay
KeyMediaPause = uv.KeyMediaPause
KeyMediaPlayPause = uv.KeyMediaPlayPause
KeyMediaReverse = uv.KeyMediaReverse
KeyMediaStop = uv.KeyMediaStop
KeyMediaFastForward = uv.KeyMediaFastForward
KeyMediaRewind = uv.KeyMediaRewind
KeyMediaNext = uv.KeyMediaNext
KeyMediaPrev = uv.KeyMediaPrev
KeyMediaRecord = uv.KeyMediaRecord
KeyLowerVol = uv.KeyLowerVol
KeyRaiseVol = uv.KeyRaiseVol
KeyMute = uv.KeyMute
KeyLeftShift = uv.KeyLeftShift
KeyLeftAlt = uv.KeyLeftAlt
KeyLeftCtrl = uv.KeyLeftCtrl
KeyLeftSuper = uv.KeyLeftSuper
KeyLeftHyper = uv.KeyLeftHyper
KeyLeftMeta = uv.KeyLeftMeta
KeyRightShift = uv.KeyRightShift
KeyRightAlt = uv.KeyRightAlt
KeyRightCtrl = uv.KeyRightCtrl
KeyRightSuper = uv.KeyRightSuper
KeyRightHyper = uv.KeyRightHyper
KeyRightMeta = uv.KeyRightMeta
KeyIsoLevel3Shift = uv.KeyIsoLevel3Shift
KeyIsoLevel5Shift = uv.KeyIsoLevel5Shift
KeyBackspace = uv.KeyBackspace
KeyTab = uv.KeyTab
KeyEnter = uv.KeyEnter
KeyReturn = uv.KeyReturn
KeyEscape = uv.KeyEscape
KeyEsc = uv.KeyEsc
KeySpace = uv.KeySpace
)