1// Copyright 2016 The TCell Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use file except in compliance with the License.
5// You may obtain a copy of the license at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tcell
16
17import (
18	"fmt"
19	"strings"
20	"time"
21)
22
23// EventKey represents a key press.  Usually this is a key press followed
24// by a key release, but since terminal programs don't have a way to report
25// key release events, we usually get just one event.  If a key is held down
26// then the terminal may synthesize repeated key presses at some predefined
27// rate.  We have no control over that, nor visibility into it.
28//
29// In some cases, we can have a modifier key, such as ModAlt, that can be
30// generated with a key press.  (This usually is represented by having the
31// high bit set, or in some cases, by sending an ESC prior to the rune.)
32//
33// If the value of Key() is KeyRune, then the actual key value will be
34// available with the Rune() method.  This will be the case for most keys.
35// In most situations, the modifiers will not be set.  For example, if the
36// rune is 'A', this will be reported without the ModShift bit set, since
37// really can't tell if the Shift key was pressed (it might have been CAPSLOCK,
38// or a terminal that only can send capitals, or keyboard with separate
39// capital letters from lower case letters).
40//
41// Generally, terminal applications have far less visibility into keyboard
42// activity than graphical applications.  Hence, they should avoid depending
43// overly much on availability of modifiers, or the availability of any
44// specific keys.
45type EventKey struct {
46	t   time.Time
47	mod ModMask
48	key Key
49	ch  rune
50}
51
52// When returns the time when this Event was created, which should closely
53// match the time when the key was pressed.
54func (ev *EventKey) When() time.Time {
55	return ev.t
56}
57
58// Rune returns the rune corresponding to the key press, if it makes sense.
59// The result is only defined if the value of Key() is KeyRune.
60func (ev *EventKey) Rune() rune {
61	return ev.ch
62}
63
64// Key returns a virtual key code.  We use this to identify specific key
65// codes, such as KeyEnter, etc.  Most control and function keys are reported
66// with unique Key values.  Normal alphanumeric and punctuation keys will
67// generally return KeyRune here; the specific key can be further decoded
68// using the Rune() function.
69func (ev *EventKey) Key() Key {
70	return ev.key
71}
72
73// Modifiers returns the modifiers that were present with the key press.  Note
74// that not all platforms and terminals support this equally well, and some
75// cases we will not not know for sure.  Hence, applications should avoid
76// using this in most circumstances.
77func (ev *EventKey) Modifiers() ModMask {
78	return ev.mod
79}
80
81// KeyNames holds the written names of special keys. Useful to echo back a key
82// name, or to look up a key from a string value.
83var KeyNames = map[Key]string{
84	KeyEnter:          "Enter",
85	KeyBackspace:      "Backspace",
86	KeyTab:            "Tab",
87	KeyBacktab:        "Backtab",
88	KeyEsc:            "Esc",
89	KeyBackspace2:     "Backspace2",
90	KeyDelete:         "Delete",
91	KeyInsert:         "Insert",
92	KeyUp:             "Up",
93	KeyDown:           "Down",
94	KeyLeft:           "Left",
95	KeyRight:          "Right",
96	KeyHome:           "Home",
97	KeyEnd:            "End",
98	KeyUpLeft:         "UpLeft",
99	KeyUpRight:        "UpRight",
100	KeyDownLeft:       "DownLeft",
101	KeyDownRight:      "DownRight",
102	KeyCenter:         "Center",
103	KeyPgDn:           "PgDn",
104	KeyPgUp:           "PgUp",
105	KeyClear:          "Clear",
106	KeyExit:           "Exit",
107	KeyCancel:         "Cancel",
108	KeyPause:          "Pause",
109	KeyPrint:          "Print",
110	KeyF1:             "F1",
111	KeyF2:             "F2",
112	KeyF3:             "F3",
113	KeyF4:             "F4",
114	KeyF5:             "F5",
115	KeyF6:             "F6",
116	KeyF7:             "F7",
117	KeyF8:             "F8",
118	KeyF9:             "F9",
119	KeyF10:            "F10",
120	KeyF11:            "F11",
121	KeyF12:            "F12",
122	KeyF13:            "F13",
123	KeyF14:            "F14",
124	KeyF15:            "F15",
125	KeyF16:            "F16",
126	KeyF17:            "F17",
127	KeyF18:            "F18",
128	KeyF19:            "F19",
129	KeyF20:            "F20",
130	KeyF21:            "F21",
131	KeyF22:            "F22",
132	KeyF23:            "F23",
133	KeyF24:            "F24",
134	KeyF25:            "F25",
135	KeyF26:            "F26",
136	KeyF27:            "F27",
137	KeyF28:            "F28",
138	KeyF29:            "F29",
139	KeyF30:            "F30",
140	KeyF31:            "F31",
141	KeyF32:            "F32",
142	KeyF33:            "F33",
143	KeyF34:            "F34",
144	KeyF35:            "F35",
145	KeyF36:            "F36",
146	KeyF37:            "F37",
147	KeyF38:            "F38",
148	KeyF39:            "F39",
149	KeyF40:            "F40",
150	KeyF41:            "F41",
151	KeyF42:            "F42",
152	KeyF43:            "F43",
153	KeyF44:            "F44",
154	KeyF45:            "F45",
155	KeyF46:            "F46",
156	KeyF47:            "F47",
157	KeyF48:            "F48",
158	KeyF49:            "F49",
159	KeyF50:            "F50",
160	KeyF51:            "F51",
161	KeyF52:            "F52",
162	KeyF53:            "F53",
163	KeyF54:            "F54",
164	KeyF55:            "F55",
165	KeyF56:            "F56",
166	KeyF57:            "F57",
167	KeyF58:            "F58",
168	KeyF59:            "F59",
169	KeyF60:            "F60",
170	KeyF61:            "F61",
171	KeyF62:            "F62",
172	KeyF63:            "F63",
173	KeyF64:            "F64",
174	KeyCtrlA:          "Ctrl-A",
175	KeyCtrlB:          "Ctrl-B",
176	KeyCtrlC:          "Ctrl-C",
177	KeyCtrlD:          "Ctrl-D",
178	KeyCtrlE:          "Ctrl-E",
179	KeyCtrlF:          "Ctrl-F",
180	KeyCtrlG:          "Ctrl-G",
181	KeyCtrlJ:          "Ctrl-J",
182	KeyCtrlK:          "Ctrl-K",
183	KeyCtrlL:          "Ctrl-L",
184	KeyCtrlN:          "Ctrl-N",
185	KeyCtrlO:          "Ctrl-O",
186	KeyCtrlP:          "Ctrl-P",
187	KeyCtrlQ:          "Ctrl-Q",
188	KeyCtrlR:          "Ctrl-R",
189	KeyCtrlS:          "Ctrl-S",
190	KeyCtrlT:          "Ctrl-T",
191	KeyCtrlU:          "Ctrl-U",
192	KeyCtrlV:          "Ctrl-V",
193	KeyCtrlW:          "Ctrl-W",
194	KeyCtrlX:          "Ctrl-X",
195	KeyCtrlY:          "Ctrl-Y",
196	KeyCtrlZ:          "Ctrl-Z",
197	KeyCtrlSpace:      "Ctrl-Space",
198	KeyCtrlUnderscore: "Ctrl-_",
199	KeyCtrlRightSq:    "Ctrl-]",
200	KeyCtrlBackslash:  "Ctrl-\\",
201	KeyCtrlCarat:      "Ctrl-^",
202}
203
204// Name returns a printable value or the key stroke.  This can be used
205// when printing the event, for example.
206func (ev *EventKey) Name() string {
207	s := ""
208	m := []string{}
209	if ev.mod&ModShift != 0 {
210		m = append(m, "Shift")
211	}
212	if ev.mod&ModAlt != 0 {
213		m = append(m, "Alt")
214	}
215	if ev.mod&ModMeta != 0 {
216		m = append(m, "Meta")
217	}
218	if ev.mod&ModCtrl != 0 {
219		m = append(m, "Ctrl")
220	}
221
222	ok := false
223	if s, ok = KeyNames[ev.key]; !ok {
224		if ev.key == KeyRune {
225			s = "Rune[" + string(ev.ch) + "]"
226		} else {
227			s = fmt.Sprintf("Key[%d,%d]", ev.key, int(ev.ch))
228		}
229	}
230	if len(m) != 0 {
231		if ev.mod&ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
232			s = s[5:]
233		}
234		return fmt.Sprintf("%s+%s", strings.Join(m, "+"), s)
235	}
236	return s
237}
238
239// NewEventKey attempts to create a suitable event.  It parses the various
240// ASCII control sequences if KeyRune is passed for Key, but if the caller
241// has more precise information it should set that specifically.  Callers
242// that aren't sure about modifier state (most) should just pass ModNone.
243func NewEventKey(k Key, ch rune, mod ModMask) *EventKey {
244	if k == KeyRune && (ch < ' ' || ch == 0x7f) {
245		// Turn specials into proper key codes.  This is for
246		// control characters and the DEL.
247		k = Key(ch)
248		if mod == ModNone && ch < ' ' {
249			switch Key(ch) {
250			case KeyBackspace, KeyTab, KeyEsc, KeyEnter:
251				// these keys are directly typeable without CTRL
252			default:
253				// most likely entered with a CTRL keypress
254				mod = ModCtrl
255			}
256		}
257	}
258	return &EventKey{t: time.Now(), key: k, ch: ch, mod: mod}
259}
260
261// ModMask is a mask of modifier keys.  Note that it will not always be
262// possible to report modifier keys.
263type ModMask int16
264
265// These are the modifiers keys that can be sent either with a key press,
266// or a mouse event.  Note that as of now, due to the confusion associated
267// with Meta, and the lack of support for it on many/most platforms, the
268// current implementations never use it.  Instead, they use ModAlt, even for
269// events that could possibly have been distinguished from ModAlt.
270const (
271	ModShift ModMask = 1 << iota
272	ModCtrl
273	ModAlt
274	ModMeta
275	ModNone ModMask = 0
276)
277
278// Key is a generic value for representing keys, and especially special
279// keys (function keys, cursor movement keys, etc.)  For normal keys, like
280// ASCII letters, we use KeyRune, and then expect the application to
281// inspect the Rune() member of the EventKey.
282type Key int16
283
284// This is the list of named keys.  KeyRune is special however, in that it is
285// a place holder key indicating that a printable character was sent.  The
286// actual value of the rune will be transported in the Rune of the associated
287// EventKey.
288const (
289	KeyRune Key = iota + 256
290	KeyUp
291	KeyDown
292	KeyRight
293	KeyLeft
294	KeyUpLeft
295	KeyUpRight
296	KeyDownLeft
297	KeyDownRight
298	KeyCenter
299	KeyPgUp
300	KeyPgDn
301	KeyHome
302	KeyEnd
303	KeyInsert
304	KeyDelete
305	KeyHelp
306	KeyExit
307	KeyClear
308	KeyCancel
309	KeyPrint
310	KeyPause
311	KeyBacktab
312	KeyF1
313	KeyF2
314	KeyF3
315	KeyF4
316	KeyF5
317	KeyF6
318	KeyF7
319	KeyF8
320	KeyF9
321	KeyF10
322	KeyF11
323	KeyF12
324	KeyF13
325	KeyF14
326	KeyF15
327	KeyF16
328	KeyF17
329	KeyF18
330	KeyF19
331	KeyF20
332	KeyF21
333	KeyF22
334	KeyF23
335	KeyF24
336	KeyF25
337	KeyF26
338	KeyF27
339	KeyF28
340	KeyF29
341	KeyF30
342	KeyF31
343	KeyF32
344	KeyF33
345	KeyF34
346	KeyF35
347	KeyF36
348	KeyF37
349	KeyF38
350	KeyF39
351	KeyF40
352	KeyF41
353	KeyF42
354	KeyF43
355	KeyF44
356	KeyF45
357	KeyF46
358	KeyF47
359	KeyF48
360	KeyF49
361	KeyF50
362	KeyF51
363	KeyF52
364	KeyF53
365	KeyF54
366	KeyF55
367	KeyF56
368	KeyF57
369	KeyF58
370	KeyF59
371	KeyF60
372	KeyF61
373	KeyF62
374	KeyF63
375	KeyF64
376)
377
378// These are the control keys.  Note that they overlap with other keys,
379// perhaps.  For example, KeyCtrlH is the same as KeyBackspace.
380const (
381	KeyCtrlSpace Key = iota
382	KeyCtrlA
383	KeyCtrlB
384	KeyCtrlC
385	KeyCtrlD
386	KeyCtrlE
387	KeyCtrlF
388	KeyCtrlG
389	KeyCtrlH
390	KeyCtrlI
391	KeyCtrlJ
392	KeyCtrlK
393	KeyCtrlL
394	KeyCtrlM
395	KeyCtrlN
396	KeyCtrlO
397	KeyCtrlP
398	KeyCtrlQ
399	KeyCtrlR
400	KeyCtrlS
401	KeyCtrlT
402	KeyCtrlU
403	KeyCtrlV
404	KeyCtrlW
405	KeyCtrlX
406	KeyCtrlY
407	KeyCtrlZ
408	KeyCtrlLeftSq // Escape
409	KeyCtrlBackslash
410	KeyCtrlRightSq
411	KeyCtrlCarat
412	KeyCtrlUnderscore
413)
414
415// Special values - these are fixed in an attempt to make it more likely
416// that aliases will encode the same way.
417
418// These are the defined ASCII values for key codes.  They generally match
419// with KeyCtrl values.
420const (
421	KeyNUL Key = iota
422	KeySOH
423	KeySTX
424	KeyETX
425	KeyEOT
426	KeyENQ
427	KeyACK
428	KeyBEL
429	KeyBS
430	KeyTAB
431	KeyLF
432	KeyVT
433	KeyFF
434	KeyCR
435	KeySO
436	KeySI
437	KeyDLE
438	KeyDC1
439	KeyDC2
440	KeyDC3
441	KeyDC4
442	KeyNAK
443	KeySYN
444	KeyETB
445	KeyCAN
446	KeyEM
447	KeySUB
448	KeyESC
449	KeyFS
450	KeyGS
451	KeyRS
452	KeyUS
453	KeyDEL Key = 0x7F
454)
455
456// These keys are aliases for other names.
457const (
458	KeyBackspace  = KeyBS
459	KeyTab        = KeyTAB
460	KeyEsc        = KeyESC
461	KeyEscape     = KeyESC
462	KeyEnter      = KeyCR
463	KeyBackspace2 = KeyDEL
464)
465