1package tea
2
3import (
4 "fmt"
5
6 uv "github.com/charmbracelet/ultraviolet"
7)
8
9const (
10 // KeyExtended is a special key code used to signify that a key event
11 // contains multiple runes.
12 KeyExtended = uv.KeyExtended
13)
14
15// Special key symbols.
16const (
17
18 // Special keys.
19
20 KeyUp = uv.KeyUp
21 KeyDown = uv.KeyDown
22 KeyRight = uv.KeyRight
23 KeyLeft = uv.KeyLeft
24 KeyBegin = uv.KeyBegin
25 KeyFind = uv.KeyFind
26 KeyInsert = uv.KeyInsert
27 KeyDelete = uv.KeyDelete
28 KeySelect = uv.KeySelect
29 KeyPgUp = uv.KeyPgUp
30 KeyPgDown = uv.KeyPgDown
31 KeyHome = uv.KeyHome
32 KeyEnd = uv.KeyEnd
33
34 // Keypad keys.
35
36 KeyKpEnter = uv.KeyKpEnter
37 KeyKpEqual = uv.KeyKpEqual
38 KeyKpMultiply = uv.KeyKpMultiply
39 KeyKpPlus = uv.KeyKpPlus
40 KeyKpComma = uv.KeyKpComma
41 KeyKpMinus = uv.KeyKpMinus
42 KeyKpDecimal = uv.KeyKpDecimal
43 KeyKpDivide = uv.KeyKpDivide
44 KeyKp0 = uv.KeyKp0
45 KeyKp1 = uv.KeyKp1
46 KeyKp2 = uv.KeyKp2
47 KeyKp3 = uv.KeyKp3
48 KeyKp4 = uv.KeyKp4
49 KeyKp5 = uv.KeyKp5
50 KeyKp6 = uv.KeyKp6
51 KeyKp7 = uv.KeyKp7
52 KeyKp8 = uv.KeyKp8
53 KeyKp9 = uv.KeyKp9
54
55 // The following are keys defined in the Kitty keyboard protocol.
56 // XXX: Investigate the names of these keys.
57 KeyKpSep = uv.KeyKpSep
58 KeyKpUp = uv.KeyKpUp
59 KeyKpDown = uv.KeyKpDown
60 KeyKpLeft = uv.KeyKpLeft
61 KeyKpRight = uv.KeyKpRight
62 KeyKpPgUp = uv.KeyKpPgUp
63 KeyKpPgDown = uv.KeyKpPgDown
64 KeyKpHome = uv.KeyKpHome
65 KeyKpEnd = uv.KeyKpEnd
66 KeyKpInsert = uv.KeyKpInsert
67 KeyKpDelete = uv.KeyKpDelete
68 KeyKpBegin = uv.KeyKpBegin
69
70 // Function keys.
71
72 KeyF1 = uv.KeyF1
73 KeyF2 = uv.KeyF2
74 KeyF3 = uv.KeyF3
75 KeyF4 = uv.KeyF4
76 KeyF5 = uv.KeyF5
77 KeyF6 = uv.KeyF6
78 KeyF7 = uv.KeyF7
79 KeyF8 = uv.KeyF8
80 KeyF9 = uv.KeyF9
81 KeyF10 = uv.KeyF10
82 KeyF11 = uv.KeyF11
83 KeyF12 = uv.KeyF12
84 KeyF13 = uv.KeyF13
85 KeyF14 = uv.KeyF14
86 KeyF15 = uv.KeyF15
87 KeyF16 = uv.KeyF16
88 KeyF17 = uv.KeyF17
89 KeyF18 = uv.KeyF18
90 KeyF19 = uv.KeyF19
91 KeyF20 = uv.KeyF20
92 KeyF21 = uv.KeyF21
93 KeyF22 = uv.KeyF22
94 KeyF23 = uv.KeyF23
95 KeyF24 = uv.KeyF24
96 KeyF25 = uv.KeyF25
97 KeyF26 = uv.KeyF26
98 KeyF27 = uv.KeyF27
99 KeyF28 = uv.KeyF28
100 KeyF29 = uv.KeyF29
101 KeyF30 = uv.KeyF30
102 KeyF31 = uv.KeyF31
103 KeyF32 = uv.KeyF32
104 KeyF33 = uv.KeyF33
105 KeyF34 = uv.KeyF34
106 KeyF35 = uv.KeyF35
107 KeyF36 = uv.KeyF36
108 KeyF37 = uv.KeyF37
109 KeyF38 = uv.KeyF38
110 KeyF39 = uv.KeyF39
111 KeyF40 = uv.KeyF40
112 KeyF41 = uv.KeyF41
113 KeyF42 = uv.KeyF42
114 KeyF43 = uv.KeyF43
115 KeyF44 = uv.KeyF44
116 KeyF45 = uv.KeyF45
117 KeyF46 = uv.KeyF46
118 KeyF47 = uv.KeyF47
119 KeyF48 = uv.KeyF48
120 KeyF49 = uv.KeyF49
121 KeyF50 = uv.KeyF50
122 KeyF51 = uv.KeyF51
123 KeyF52 = uv.KeyF52
124 KeyF53 = uv.KeyF53
125 KeyF54 = uv.KeyF54
126 KeyF55 = uv.KeyF55
127 KeyF56 = uv.KeyF56
128 KeyF57 = uv.KeyF57
129 KeyF58 = uv.KeyF58
130 KeyF59 = uv.KeyF59
131 KeyF60 = uv.KeyF60
132 KeyF61 = uv.KeyF61
133 KeyF62 = uv.KeyF62
134 KeyF63 = uv.KeyF63
135
136 // The following are keys defined in the Kitty keyboard protocol.
137 // XXX: Investigate the names of these keys.
138
139 KeyCapsLock = uv.KeyCapsLock
140 KeyScrollLock = uv.KeyScrollLock
141 KeyNumLock = uv.KeyNumLock
142 KeyPrintScreen = uv.KeyPrintScreen
143 KeyPause = uv.KeyPause
144 KeyMenu = uv.KeyMenu
145
146 KeyMediaPlay = uv.KeyMediaPlay
147 KeyMediaPause = uv.KeyMediaPause
148 KeyMediaPlayPause = uv.KeyMediaPlayPause
149 KeyMediaReverse = uv.KeyMediaReverse
150 KeyMediaStop = uv.KeyMediaStop
151 KeyMediaFastForward = uv.KeyMediaFastForward
152 KeyMediaRewind = uv.KeyMediaRewind
153 KeyMediaNext = uv.KeyMediaNext
154 KeyMediaPrev = uv.KeyMediaPrev
155 KeyMediaRecord
156
157 KeyLowerVol = uv.KeyLowerVol
158 KeyRaiseVol = uv.KeyRaiseVol
159 KeyMute = uv.KeyMute
160
161 KeyLeftShift = uv.KeyLeftShift
162 KeyLeftAlt = uv.KeyLeftAlt
163 KeyLeftCtrl = uv.KeyLeftCtrl
164 KeyLeftSuper = uv.KeyLeftSuper
165 KeyLeftHyper = uv.KeyLeftHyper
166 KeyLeftMeta = uv.KeyLeftMeta
167 KeyRightShift = uv.KeyRightShift
168 KeyRightAlt = uv.KeyRightAlt
169 KeyRightCtrl = uv.KeyRightCtrl
170 KeyRightSuper = uv.KeyRightSuper
171 KeyRightHyper = uv.KeyRightHyper
172 KeyRightMeta = uv.KeyRightMeta
173 KeyIsoLevel3Shift = uv.KeyIsoLevel3Shift
174 KeyIsoLevel5Shift = uv.KeyIsoLevel5Shift
175
176 // Special names in C0.
177
178 KeyBackspace = uv.KeyBackspace
179 KeyTab = uv.KeyTab
180 KeyEnter = uv.KeyEnter
181 KeyReturn = uv.KeyReturn
182 KeyEscape = uv.KeyEscape
183 KeyEsc = uv.KeyEsc
184
185 // Special names in G0.
186
187 KeySpace = uv.KeySpace
188)
189
190// KeyPressMsg represents a key press message.
191type KeyPressMsg Key
192
193// String implements [fmt.Stringer] and is quite useful for matching key
194// events. For details, on what this returns see [Key.String].
195func (k KeyPressMsg) String() string {
196 return Key(k).String()
197}
198
199// Keystroke returns the keystroke representation of the [Key]. While less type
200// safe than looking at the individual fields, it will usually be more
201// convenient and readable to use this method when matching against keys.
202//
203// Note that modifier keys are always printed in the following order:
204// - ctrl
205// - alt
206// - shift
207// - meta
208// - hyper
209// - super
210//
211// For example, you'll always see "ctrl+shift+alt+a" and never
212// "shift+ctrl+alt+a".
213func (k KeyPressMsg) Keystroke() string {
214 return uv.Key(k).Keystroke()
215}
216
217// Key returns the underlying key event. This is a syntactic sugar for casting
218// the key event to a [Key].
219func (k KeyPressMsg) Key() Key {
220 return Key(k)
221}
222
223// KeyReleaseMsg represents a key release message.
224type KeyReleaseMsg Key
225
226// String implements [fmt.Stringer] and is quite useful for matching key
227// events. For details, on what this returns see [Key.String].
228func (k KeyReleaseMsg) String() string {
229 return Key(k).String()
230}
231
232// Keystroke returns the keystroke representation of the [Key]. While less type
233// safe than looking at the individual fields, it will usually be more
234// convenient and readable to use this method when matching against keys.
235//
236// Note that modifier keys are always printed in the following order:
237// - ctrl
238// - alt
239// - shift
240// - meta
241// - hyper
242// - super
243//
244// For example, you'll always see "ctrl+shift+alt+a" and never
245// "shift+ctrl+alt+a".
246func (k KeyReleaseMsg) Keystroke() string {
247 return uv.Key(k).Keystroke()
248}
249
250// Key returns the underlying key event. This is a convenience method and
251// syntactic sugar to satisfy the [KeyMsg] interface, and cast the key event to
252// [Key].
253func (k KeyReleaseMsg) Key() Key {
254 return Key(k)
255}
256
257// KeyMsg represents a key event. This can be either a key press or a key
258// release event.
259type KeyMsg interface {
260 fmt.Stringer
261
262 // Key returns the underlying key event.
263 Key() Key
264}
265
266// Key represents a Key press or release event. It contains information about
267// the Key pressed, like the runes, the type of Key, and the modifiers pressed.
268// There are a couple general patterns you could use to check for key presses
269// or releases:
270//
271// // Switch on the string representation of the key (shorter)
272// switch msg := msg.(type) {
273// case KeyPressMsg:
274// switch msg.String() {
275// case "enter":
276// fmt.Println("you pressed enter!")
277// case "a":
278// fmt.Println("you pressed a!")
279// }
280// }
281//
282// // Switch on the key type (more foolproof)
283// switch msg := msg.(type) {
284// case KeyMsg:
285// // catch both KeyPressMsg and KeyReleaseMsg
286// switch key := msg.Key(); key.Code {
287// case KeyEnter:
288// fmt.Println("you pressed enter!")
289// default:
290// switch key.Text {
291// case "a":
292// fmt.Println("you pressed a!")
293// }
294// }
295// }
296//
297// Note that [Key.Text] will be empty for special keys like [KeyEnter],
298// [KeyTab], and for keys that don't represent printable characters like key
299// combos with modifier keys. In other words, [Key.Text] is populated only for
300// keys that represent printable characters shifted or unshifted (like 'a',
301// 'A', '1', '!', etc.).
302type Key struct {
303 // Text contains the actual characters received. This usually the same as
304 // [Key.Code]. When [Key.Text] is non-empty, it indicates that the key
305 // pressed represents printable character(s).
306 Text string
307
308 // Mod represents modifier keys, like [ModCtrl], [ModAlt], and so on.
309 Mod KeyMod
310
311 // Code represents the key pressed. This is usually a special key like
312 // [KeyTab], [KeyEnter], [KeyF1], or a printable character like 'a'.
313 Code rune
314
315 // ShiftedCode is the actual, shifted key pressed by the user. For example,
316 // if the user presses shift+a, or caps lock is on, [Key.ShiftedCode] will
317 // be 'A' and [Key.Code] will be 'a'.
318 //
319 // In the case of non-latin keyboards, like Arabic, [Key.ShiftedCode] is the
320 // unshifted key on the keyboard.
321 //
322 // This is only available with the Kitty Keyboard Protocol or the Windows
323 // Console API.
324 ShiftedCode rune
325
326 // BaseCode is the key pressed according to the standard PC-101 key layout.
327 // On international keyboards, this is the key that would be pressed if the
328 // keyboard was set to US PC-101 layout.
329 //
330 // For example, if the user presses 'q' on a French AZERTY keyboard,
331 // [Key.BaseCode] will be 'q'.
332 //
333 // This is only available with the Kitty Keyboard Protocol or the Windows
334 // Console API.
335 BaseCode rune
336
337 // IsRepeat indicates whether the key is being held down and sending events
338 // repeatedly.
339 //
340 // This is only available with the Kitty Keyboard Protocol or the Windows
341 // Console API.
342 IsRepeat bool
343}
344
345// String implements [fmt.Stringer] and is quite useful for matching key
346// events. It will return the textual representation of the [Key] if there is
347// one, otherwise, it will fallback to [Key.Keystroke].
348//
349// For example, you'll always get "?" and instead of "shift+/" on a US ANSI
350// keyboard.
351func (k Key) String() string {
352 return uv.Key(k).String()
353}
354
355// Keystroke returns the keystroke representation of the [Key]. While less type
356// safe than looking at the individual fields, it will usually be more
357// convenient and readable to use this method when matching against keys.
358//
359// Note that modifier keys are always printed in the following order:
360// - ctrl
361// - alt
362// - shift
363// - meta
364// - hyper
365// - super
366//
367// For example, you'll always see "ctrl+shift+alt+a" and never
368// "shift+ctrl+alt+a".
369func (k Key) Keystroke() string {
370 return uv.Key(k).Keystroke()
371}