Skip to main content

zmk_studio_api/
keycode.rs

1use num_enum::TryFromPrimitive;
2use strum_macros::{AsRefStr, EnumIter, EnumString, IntoStaticStr};
3
4/// ZMK keycode value
5///
6/// This is the primary key type used by typed behavior APIs.
7#[derive(
8    Debug,
9    Clone,
10    Copy,
11    PartialEq,
12    Eq,
13    Hash,
14    TryFromPrimitive,
15    AsRefStr,
16    EnumString,
17    IntoStaticStr,
18    EnumIter,
19)]
20#[repr(u32)]
21#[allow(non_camel_case_types)]
22pub enum Keycode {
23    #[strum(serialize = "SYS_PWR")]
24    SYSTEM_POWER = 0x00010081,
25    #[strum(serialize = "SYS_SLEEP")]
26    SYSTEM_SLEEP = 0x00010082,
27    #[strum(serialize = "SYS_WAKE")]
28    SYSTEM_WAKE_UP = 0x00010083,
29    A = 0x00070004,
30    B = 0x00070005,
31    C = 0x00070006,
32    D = 0x00070007,
33    E = 0x00070008,
34    F = 0x00070009,
35    G = 0x0007000A,
36    H = 0x0007000B,
37    I = 0x0007000C,
38    J = 0x0007000D,
39    K = 0x0007000E,
40    L = 0x0007000F,
41    M = 0x00070010,
42    N = 0x00070011,
43    O = 0x00070012,
44    P = 0x00070013,
45    Q = 0x00070014,
46    R = 0x00070015,
47    S = 0x00070016,
48    T = 0x00070017,
49    U = 0x00070018,
50    V = 0x00070019,
51    W = 0x0007001A,
52    X = 0x0007001B,
53    Y = 0x0007001C,
54    Z = 0x0007001D,
55    #[strum(serialize = "N1")]
56    #[strum(serialize = "NUM_1")]
57    NUMBER_1 = 0x0007001E,
58    #[strum(serialize = "N2")]
59    #[strum(serialize = "NUM_2")]
60    NUMBER_2 = 0x0007001F,
61    #[strum(serialize = "N3")]
62    #[strum(serialize = "NUM_3")]
63    NUMBER_3 = 0x00070020,
64    #[strum(serialize = "N4")]
65    #[strum(serialize = "NUM_4")]
66    NUMBER_4 = 0x00070021,
67    #[strum(serialize = "N5")]
68    #[strum(serialize = "NUM_5")]
69    NUMBER_5 = 0x00070022,
70    #[strum(serialize = "N6")]
71    #[strum(serialize = "NUM_6")]
72    NUMBER_6 = 0x00070023,
73    #[strum(serialize = "N7")]
74    #[strum(serialize = "NUM_7")]
75    NUMBER_7 = 0x00070024,
76    #[strum(serialize = "N8")]
77    #[strum(serialize = "NUM_8")]
78    NUMBER_8 = 0x00070025,
79    #[strum(serialize = "N9")]
80    #[strum(serialize = "NUM_9")]
81    NUMBER_9 = 0x00070026,
82    #[strum(serialize = "N0")]
83    #[strum(serialize = "NUM_0")]
84    NUMBER_0 = 0x00070027,
85    #[strum(serialize = "ENTER")]
86    #[strum(serialize = "RET")]
87    RETURN = 0x00070028,
88    #[strum(serialize = "ESC")]
89    ESCAPE = 0x00070029,
90    #[strum(serialize = "BKSP")]
91    #[strum(serialize = "BSPC")]
92    BACKSPACE = 0x0007002A,
93    TAB = 0x0007002B,
94    #[strum(serialize = "SPC")]
95    SPACE = 0x0007002C,
96    MINUS = 0x0007002D,
97    #[strum(serialize = "EQL")]
98    EQUAL = 0x0007002E,
99    #[strum(serialize = "LBKT")]
100    LEFT_BRACKET = 0x0007002F,
101    #[strum(serialize = "RBKT")]
102    RIGHT_BRACKET = 0x00070030,
103    #[strum(serialize = "BSLH")]
104    BACKSLASH = 0x00070031,
105    #[strum(serialize = "NUHS")]
106    NON_US_HASH = 0x00070032,
107    #[strum(serialize = "SCLN")]
108    #[strum(serialize = "SEMI")]
109    SEMICOLON = 0x00070033,
110    #[strum(serialize = "APOS")]
111    #[strum(serialize = "APOSTROPHE")]
112    #[strum(serialize = "QUOT")]
113    #[strum(serialize = "SQT")]
114    SINGLE_QUOTE = 0x00070034,
115    #[strum(serialize = "GRAV")]
116    GRAVE = 0x00070035,
117    #[strum(serialize = "CMMA")]
118    COMMA = 0x00070036,
119    #[strum(serialize = "DOT")]
120    PERIOD = 0x00070037,
121    #[strum(serialize = "FSLH")]
122    SLASH = 0x00070038,
123    #[strum(serialize = "CAPS")]
124    #[strum(serialize = "CLCK")]
125    CAPSLOCK = 0x00070039,
126    F1 = 0x0007003A,
127    F2 = 0x0007003B,
128    F3 = 0x0007003C,
129    F4 = 0x0007003D,
130    F5 = 0x0007003E,
131    F6 = 0x0007003F,
132    F7 = 0x00070040,
133    F8 = 0x00070041,
134    F9 = 0x00070042,
135    F10 = 0x00070043,
136    F11 = 0x00070044,
137    F12 = 0x00070045,
138    #[strum(serialize = "PRSC")]
139    #[strum(serialize = "PSCRN")]
140    PRINTSCREEN = 0x00070046,
141    #[strum(serialize = "SCLK")]
142    #[strum(serialize = "SLCK")]
143    SCROLLLOCK = 0x00070047,
144    #[strum(serialize = "PAUS")]
145    PAUSE_BREAK = 0x00070048,
146    #[strum(serialize = "INS")]
147    INSERT = 0x00070049,
148    HOME = 0x0007004A,
149    #[strum(serialize = "PG_UP")]
150    #[strum(serialize = "PGUP")]
151    PAGE_UP = 0x0007004B,
152    #[strum(serialize = "DEL")]
153    DELETE = 0x0007004C,
154    END = 0x0007004D,
155    #[strum(serialize = "PG_DN")]
156    #[strum(serialize = "PGDN")]
157    PAGE_DOWN = 0x0007004E,
158    #[strum(serialize = "RARW")]
159    #[strum(serialize = "RIGHT")]
160    RIGHT_ARROW = 0x0007004F,
161    #[strum(serialize = "LARW")]
162    #[strum(serialize = "LEFT")]
163    LEFT_ARROW = 0x00070050,
164    #[strum(serialize = "DARW")]
165    #[strum(serialize = "DOWN")]
166    DOWN_ARROW = 0x00070051,
167    #[strum(serialize = "UARW")]
168    #[strum(serialize = "UP")]
169    UP_ARROW = 0x00070052,
170    #[strum(serialize = "KP_NLCK")]
171    #[strum(serialize = "KP_NUM")]
172    KP_NUMLOCK = 0x00070053,
173    #[strum(serialize = "KDIV")]
174    #[strum(serialize = "KP_SLASH")]
175    KP_DIVIDE = 0x00070054,
176    #[strum(serialize = "KMLT")]
177    #[strum(serialize = "KP_MULTIPLY")]
178    KP_ASTERISK = 0x00070055,
179    #[strum(serialize = "KMIN")]
180    #[strum(serialize = "KP_MINUS")]
181    KP_SUBTRACT = 0x00070056,
182    #[strum(serialize = "KPLS")]
183    KP_PLUS = 0x00070057,
184    KP_ENTER = 0x00070058,
185    #[strum(serialize = "KP_N1")]
186    KP_NUMBER_1 = 0x00070059,
187    #[strum(serialize = "KP_N2")]
188    KP_NUMBER_2 = 0x0007005A,
189    #[strum(serialize = "KP_N3")]
190    KP_NUMBER_3 = 0x0007005B,
191    #[strum(serialize = "KP_N4")]
192    KP_NUMBER_4 = 0x0007005C,
193    #[strum(serialize = "KP_N5")]
194    KP_NUMBER_5 = 0x0007005D,
195    #[strum(serialize = "KP_N6")]
196    KP_NUMBER_6 = 0x0007005E,
197    #[strum(serialize = "KP_N7")]
198    KP_NUMBER_7 = 0x0007005F,
199    #[strum(serialize = "KP_N8")]
200    KP_NUMBER_8 = 0x00070060,
201    #[strum(serialize = "KP_N9")]
202    KP_NUMBER_9 = 0x00070061,
203    #[strum(serialize = "KP_N0")]
204    KP_NUMBER_0 = 0x00070062,
205    KP_DOT = 0x00070063,
206    #[strum(serialize = "NUBS")]
207    #[strum(serialize = "NON_US_BSLH")]
208    NON_US_BACKSLASH = 0x00070064,
209    #[strum(serialize = "GUI")]
210    #[strum(serialize = "K_APP")]
211    #[strum(serialize = "K_APPLICATION")]
212    #[strum(serialize = "K_CMENU")]
213    K_CONTEXT_MENU = 0x00070065,
214    #[strum(serialize = "K_PWR")]
215    K_POWER = 0x00070066,
216    KP_EQUAL = 0x00070067,
217    F13 = 0x00070068,
218    F14 = 0x00070069,
219    F15 = 0x0007006A,
220    F16 = 0x0007006B,
221    F17 = 0x0007006C,
222    F18 = 0x0007006D,
223    F19 = 0x0007006E,
224    F20 = 0x0007006F,
225    F21 = 0x00070070,
226    F22 = 0x00070071,
227    F23 = 0x00070072,
228    F24 = 0x00070073,
229    #[strum(serialize = "K_EXEC")]
230    K_EXECUTE = 0x00070074,
231    K_HELP = 0x00070075,
232    K_MENU = 0x00070076,
233    K_SELECT = 0x00070077,
234    K_STOP = 0x00070078,
235    #[strum(serialize = "K_REDO")]
236    K_AGAIN = 0x00070079,
237    #[strum(serialize = "UNDO")]
238    K_UNDO = 0x0007007A,
239    #[strum(serialize = "CUT")]
240    K_CUT = 0x0007007B,
241    #[strum(serialize = "COPY")]
242    K_COPY = 0x0007007C,
243    #[strum(serialize = "PSTE")]
244    K_PASTE = 0x0007007D,
245    K_FIND = 0x0007007E,
246    K_MUTE = 0x0007007F,
247    #[strum(serialize = "K_VOL_UP")]
248    #[strum(serialize = "VOLU")]
249    K_VOLUME_UP = 0x00070080,
250    #[strum(serialize = "K_VOL_DN")]
251    #[strum(serialize = "VOLD")]
252    K_VOLUME_DOWN = 0x00070081,
253    #[strum(serialize = "LCAPS")]
254    LOCKING_CAPS = 0x00070082,
255    #[strum(serialize = "LNLCK")]
256    LOCKING_NUM = 0x00070083,
257    #[strum(serialize = "LSLCK")]
258    LOCKING_SCROLL = 0x00070084,
259    KP_COMMA = 0x00070085,
260    KP_EQUAL_AS400 = 0x00070086,
261    #[strum(serialize = "INT_RO")]
262    #[strum(serialize = "INT1")]
263    INTERNATIONAL_1 = 0x00070087,
264    #[strum(serialize = "INT_KANA")]
265    #[strum(serialize = "INT2")]
266    #[strum(serialize = "INTERNATIONAL_2")]
267    INT_KATAKANAHIRAGANA = 0x00070088,
268    #[strum(serialize = "INT_YEN")]
269    #[strum(serialize = "INT3")]
270    INTERNATIONAL_3 = 0x00070089,
271    #[strum(serialize = "INT_HENKAN")]
272    #[strum(serialize = "INT4")]
273    INTERNATIONAL_4 = 0x0007008A,
274    #[strum(serialize = "INT_MUHENKAN")]
275    #[strum(serialize = "INT5")]
276    INTERNATIONAL_5 = 0x0007008B,
277    #[strum(serialize = "INT_KPJPCOMMA")]
278    #[strum(serialize = "INT6")]
279    INTERNATIONAL_6 = 0x0007008C,
280    #[strum(serialize = "INT7")]
281    INTERNATIONAL_7 = 0x0007008D,
282    #[strum(serialize = "INT8")]
283    INTERNATIONAL_8 = 0x0007008E,
284    #[strum(serialize = "INT9")]
285    INTERNATIONAL_9 = 0x0007008F,
286    #[strum(serialize = "LANG1")]
287    #[strum(serialize = "LANGUAGE_1")]
288    LANG_HANGEUL = 0x00070090,
289    #[strum(serialize = "LANG2")]
290    #[strum(serialize = "LANGUAGE_2")]
291    LANG_HANJA = 0x00070091,
292    #[strum(serialize = "LANG3")]
293    #[strum(serialize = "LANGUAGE_3")]
294    LANG_KATAKANA = 0x00070092,
295    #[strum(serialize = "LANG4")]
296    #[strum(serialize = "LANGUAGE_4")]
297    LANG_HIRAGANA = 0x00070093,
298    #[strum(serialize = "LANG5")]
299    #[strum(serialize = "LANGUAGE_5")]
300    LANG_ZENKAKUHANKAKU = 0x00070094,
301    #[strum(serialize = "LANG6")]
302    LANGUAGE_6 = 0x00070095,
303    #[strum(serialize = "LANG7")]
304    LANGUAGE_7 = 0x00070096,
305    #[strum(serialize = "LANG8")]
306    LANGUAGE_8 = 0x00070097,
307    #[strum(serialize = "LANG9")]
308    LANGUAGE_9 = 0x00070098,
309    ALT_ERASE = 0x00070099,
310    #[strum(serialize = "SYSREQ")]
311    ATTENTION = 0x0007009A,
312    K_CANCEL = 0x0007009B,
313    CLEAR = 0x0007009C,
314    PRIOR = 0x0007009D,
315    #[strum(serialize = "RET2")]
316    RETURN2 = 0x0007009E,
317    SEPARATOR = 0x0007009F,
318    OUT = 0x000700A0,
319    OPER = 0x000700A1,
320    CLEAR_AGAIN = 0x000700A2,
321    CRSEL = 0x000700A3,
322    EXSEL = 0x000700A4,
323    #[strum(serialize = "KP_LPAR")]
324    KP_LEFT_PARENTHESIS = 0x000700B6,
325    #[strum(serialize = "KP_RPAR")]
326    KP_RIGHT_PARENTHESIS = 0x000700B7,
327    KP_CLEAR = 0x000700D8,
328    #[strum(serialize = "LCTL")]
329    #[strum(serialize = "LCTRL")]
330    LEFT_CONTROL = 0x000700E0,
331    #[strum(serialize = "LSFT")]
332    #[strum(serialize = "LSHFT")]
333    #[strum(serialize = "LSHIFT")]
334    LEFT_SHIFT = 0x000700E1,
335    #[strum(serialize = "LALT")]
336    LEFT_ALT = 0x000700E2,
337    #[strum(serialize = "LCMD")]
338    #[strum(serialize = "LEFT_GUI")]
339    #[strum(serialize = "LEFT_META")]
340    #[strum(serialize = "LEFT_WIN")]
341    #[strum(serialize = "LGUI")]
342    #[strum(serialize = "LMETA")]
343    #[strum(serialize = "LWIN")]
344    LEFT_COMMAND = 0x000700E3,
345    #[strum(serialize = "RCTL")]
346    #[strum(serialize = "RCTRL")]
347    RIGHT_CONTROL = 0x000700E4,
348    #[strum(serialize = "RSFT")]
349    #[strum(serialize = "RSHFT")]
350    #[strum(serialize = "RSHIFT")]
351    RIGHT_SHIFT = 0x000700E5,
352    #[strum(serialize = "RALT")]
353    RIGHT_ALT = 0x000700E6,
354    #[strum(serialize = "RCMD")]
355    #[strum(serialize = "RGUI")]
356    #[strum(serialize = "RIGHT_GUI")]
357    #[strum(serialize = "RIGHT_META")]
358    #[strum(serialize = "RIGHT_WIN")]
359    #[strum(serialize = "RMETA")]
360    #[strum(serialize = "RWIN")]
361    RIGHT_COMMAND = 0x000700E7,
362    #[strum(serialize = "K_PP")]
363    K_PLAY_PAUSE = 0x000700E8,
364    K_STOP2 = 0x000700E9,
365    #[strum(serialize = "K_PREV")]
366    K_PREVIOUS = 0x000700EA,
367    K_NEXT = 0x000700EB,
368    K_EJECT = 0x000700EC,
369    #[strum(serialize = "K_VOL_UP2")]
370    K_VOLUME_UP2 = 0x000700ED,
371    #[strum(serialize = "K_VOL_DN2")]
372    K_VOLUME_DOWN2 = 0x000700EE,
373    K_MUTE2 = 0x000700EF,
374    K_WWW = 0x000700F0,
375    K_BACK = 0x000700F1,
376    K_FORWARD = 0x000700F2,
377    K_STOP3 = 0x000700F3,
378    K_FIND2 = 0x000700F4,
379    K_SCROLL_UP = 0x000700F5,
380    K_SCROLL_DOWN = 0x000700F6,
381    K_EDIT = 0x000700F7,
382    K_SLEEP = 0x000700F8,
383    #[strum(serialize = "K_COFFEE")]
384    #[strum(serialize = "K_LOCK")]
385    K_SCREENSAVER = 0x000700F9,
386    K_REFRESH = 0x000700FA,
387    #[strum(serialize = "K_CALC")]
388    K_CALCULATOR = 0x000700FB,
389    #[strum(serialize = "C_PWR")]
390    C_POWER = 0x000C0030,
391    C_RESET = 0x000C0031,
392    C_SLEEP = 0x000C0032,
393    C_SLEEP_MODE = 0x000C0034,
394    C_MENU = 0x000C0040,
395    #[strum(serialize = "C_MENU_PICK")]
396    C_MENU_SELECT = 0x000C0041,
397    C_MENU_UP = 0x000C0042,
398    C_MENU_DOWN = 0x000C0043,
399    C_MENU_LEFT = 0x000C0044,
400    C_MENU_RIGHT = 0x000C0045,
401    #[strum(serialize = "C_MENU_ESC")]
402    C_MENU_ESCAPE = 0x000C0046,
403    #[strum(serialize = "C_MENU_INC")]
404    C_MENU_INCREASE = 0x000C0047,
405    #[strum(serialize = "C_MENU_DEC")]
406    C_MENU_DECREASE = 0x000C0048,
407    C_DATA_ON_SCREEN = 0x000C0060,
408    #[strum(serialize = "C_CAPTIONS")]
409    C_SUBTITLES = 0x000C0061,
410    C_SNAPSHOT = 0x000C0065,
411    C_PIP = 0x000C0067,
412    #[strum(serialize = "C_RED")]
413    C_RED_BUTTON = 0x000C0069,
414    #[strum(serialize = "C_GREEN")]
415    C_GREEN_BUTTON = 0x000C006A,
416    #[strum(serialize = "C_BLUE")]
417    C_BLUE_BUTTON = 0x000C006B,
418    #[strum(serialize = "C_YELLOW")]
419    C_YELLOW_BUTTON = 0x000C006C,
420    C_ASPECT = 0x000C006D,
421    #[strum(serialize = "C_MODE_STEP")]
422    C_MEDIA_STEP = 0x000C0082,
423    #[strum(serialize = "C_CHAN_LAST")]
424    C_RECALL_LAST = 0x000C0083,
425    C_MEDIA_TV = 0x000C0089,
426    C_MEDIA_WWW = 0x000C008A,
427    C_MEDIA_DVD = 0x000C008B,
428    C_MEDIA_PHONE = 0x000C008C,
429    C_MEDIA_GAMES = 0x000C008F,
430    C_MEDIA_CD = 0x000C0091,
431    C_MEDIA_VCR = 0x000C0092,
432    C_MEDIA_TUNER = 0x000C0093,
433    C_QUIT = 0x000C0094,
434    C_HELP = 0x000C0095,
435    C_MEDIA_TAPE = 0x000C0096,
436    C_MEDIA_CABLE = 0x000C0097,
437    C_MEDIA_HOME = 0x000C009A,
438    #[strum(serialize = "C_CHAN_INC")]
439    C_CHANNEL_INC = 0x000C009C,
440    #[strum(serialize = "C_CHAN_DEC")]
441    C_CHANNEL_DEC = 0x000C009D,
442    C_MEDIA_VCR_PLUS = 0x000C00A0,
443    C_PLAY = 0x000C00B0,
444    C_PAUSE = 0x000C00B1,
445    #[strum(serialize = "C_REC")]
446    C_RECORD = 0x000C00B2,
447    #[strum(serialize = "C_FF")]
448    C_FAST_FORWARD = 0x000C00B3,
449    #[strum(serialize = "C_RW")]
450    C_REWIND = 0x000C00B4,
451    #[strum(serialize = "M_NEXT")]
452    C_NEXT = 0x000C00B5,
453    #[strum(serialize = "C_PREV")]
454    #[strum(serialize = "M_PREV")]
455    C_PREVIOUS = 0x000C00B6,
456    #[strum(serialize = "M_STOP")]
457    C_STOP = 0x000C00B7,
458    #[strum(serialize = "M_EJCT")]
459    C_EJECT = 0x000C00B8,
460    #[strum(serialize = "C_SHUFFLE")]
461    C_RANDOM_PLAY = 0x000C00B9,
462    C_REPEAT = 0x000C00BC,
463    #[strum(serialize = "C_SLOW2")]
464    C_SLOW_TRACKING = 0x000C00BF,
465    C_STOP_EJECT = 0x000C00CC,
466    #[strum(serialize = "C_PP")]
467    #[strum(serialize = "M_PLAY")]
468    C_PLAY_PAUSE = 0x000C00CD,
469    C_VOICE_COMMAND = 0x000C00CF,
470    #[strum(serialize = "M_MUTE")]
471    C_MUTE = 0x000C00E2,
472    C_BASS_BOOST = 0x000C00E5,
473    #[strum(serialize = "C_VOL_UP")]
474    #[strum(serialize = "M_VOLU")]
475    C_VOLUME_UP = 0x000C00E9,
476    #[strum(serialize = "C_VOL_DN")]
477    #[strum(serialize = "M_VOLD")]
478    C_VOLUME_DOWN = 0x000C00EA,
479    C_SLOW = 0x000C00F5,
480    #[strum(serialize = "C_ALT_AUDIO_INC")]
481    C_ALTERNATE_AUDIO_INCREMENT = 0x000C0173,
482    #[strum(serialize = "C_BRI_INC")]
483    #[strum(serialize = "C_BRI_UP")]
484    C_BRIGHTNESS_INC = 0x000C006F,
485    #[strum(serialize = "C_BRI_DEC")]
486    #[strum(serialize = "C_BRI_DN")]
487    C_BRIGHTNESS_DEC = 0x000C0070,
488    #[strum(serialize = "C_BRI_MIN")]
489    C_BRIGHTNESS_MINIMUM = 0x000C0073,
490    #[strum(serialize = "C_BRI_MAX")]
491    C_BRIGHTNESS_MAXIMUM = 0x000C0074,
492    #[strum(serialize = "C_BRI_AUTO")]
493    C_BRIGHTNESS_AUTO = 0x000C0075,
494    #[strum(serialize = "C_BKLT_TOG")]
495    C_BACKLIGHT_TOGGLE = 0x000C0072,
496    C_MEDIA_COMPUTER = 0x000C0088,
497    C_MEDIA_GUIDE = 0x000C008D,
498    C_MEDIA_VIDEOPHONE = 0x000C008E,
499    C_MEDIA_MESSAGES = 0x000C0090,
500    C_MEDIA_SATELLITE = 0x000C0098,
501    #[strum(serialize = "C_KBIA_PREV")]
502    C_KEYBOARD_INPUT_ASSIST_PREVIOUS = 0x000C02C7,
503    #[strum(serialize = "C_KBIA_NEXT")]
504    C_KEYBOARD_INPUT_ASSIST_NEXT = 0x000C02C8,
505    #[strum(serialize = "C_KBIA_PREV_GRP")]
506    C_KEYBOARD_INPUT_ASSIST_PREVIOUS_GROUP = 0x000C02C9,
507    #[strum(serialize = "C_KBIA_NEXT_GRP")]
508    C_KEYBOARD_INPUT_ASSIST_NEXT_GROUP = 0x000C02CA,
509    #[strum(serialize = "C_KBIA_ACCEPT")]
510    C_KEYBOARD_INPUT_ASSIST_ACCEPT = 0x000C02CB,
511    #[strum(serialize = "C_KBIA_CANCEL")]
512    C_KEYBOARD_INPUT_ASSIST_CANCEL = 0x000C02CC,
513    C_AL_CCC = 0x000C0183,
514    C_AL_WORD = 0x000C0184,
515    C_AL_TEXT_EDITOR = 0x000C0185,
516    #[strum(serialize = "C_AL_SHEET")]
517    C_AL_SPREADSHEET = 0x000C0186,
518    C_AL_GRAPHICS_EDITOR = 0x000C0187,
519    C_AL_PRESENTATION = 0x000C0188,
520    #[strum(serialize = "C_AL_DB")]
521    C_AL_DATABASE = 0x000C0189,
522    #[strum(serialize = "C_AL_MAIL")]
523    C_AL_EMAIL = 0x000C018A,
524    C_AL_NEWS = 0x000C018B,
525    C_AL_VOICEMAIL = 0x000C018C,
526    #[strum(serialize = "C_AL_CAL")]
527    C_AL_CALENDAR = 0x000C018E,
528    #[strum(serialize = "C_AL_ADDRESS_BOOK")]
529    C_AL_CONTACTS = 0x000C018D,
530    C_AL_TASK_MANAGER = 0x000C018F,
531    C_AL_JOURNAL = 0x000C0190,
532    C_AL_FINANCE = 0x000C0191,
533    #[strum(serialize = "C_AL_CALC")]
534    C_AL_CALCULATOR = 0x000C0192,
535    C_AL_WWW = 0x000C0196,
536    C_AL_AV_CAPTURE_PLAYBACK = 0x000C0193,
537    C_AL_MY_COMPUTER = 0x000C0194,
538    #[strum(serialize = "C_AL_CHAT")]
539    C_AL_NETWORK_CHAT = 0x000C0199,
540    #[strum(serialize = "C_AL_PREV_TASK")]
541    C_AL_PREVIOUS_TASK = 0x000C01A4,
542    C_AL_NEXT_TASK = 0x000C01A3,
543    C_AL_SELECT_TASK = 0x000C01A2,
544    #[strum(serialize = "C_AL_IM")]
545    C_AL_INSTANT_MESSAGING = 0x000C01BC,
546    #[strum(serialize = "C_AL_TIPS")]
547    #[strum(serialize = "C_AL_TUTORIAL")]
548    C_AL_OEM_FEATURES = 0x000C01BD,
549    C_AL_KEYBOARD_LAYOUT = 0x000C01AE,
550    #[strum(serialize = "C_AL_COFFEE")]
551    #[strum(serialize = "C_AL_LOCK")]
552    C_AL_SCREENSAVER = 0x000C019E,
553    C_AL_LOGOFF = 0x000C019C,
554    C_AL_CONTROL_PANEL = 0x000C019F,
555    C_AL_HELP = 0x000C01A6,
556    #[strum(serialize = "C_AL_DOCS")]
557    C_AL_DOCUMENTS = 0x000C01A7,
558    #[strum(serialize = "C_AL_SPELL")]
559    C_AL_SPELLCHECK = 0x000C01AB,
560    C_AL_SCREEN_SAVER = 0x000C01B1,
561    #[strum(serialize = "C_AL_FILES")]
562    C_AL_FILE_BROWSER = 0x000C01B4,
563    #[strum(serialize = "C_AL_IMAGES")]
564    C_AL_IMAGE_BROWSER = 0x000C01B6,
565    #[strum(serialize = "C_AL_AUDIO")]
566    #[strum(serialize = "C_AL_MUSIC")]
567    C_AL_AUDIO_BROWSER = 0x000C01B7,
568    #[strum(serialize = "C_AL_MOVIES")]
569    C_AL_MOVIE_BROWSER = 0x000C01B8,
570    C_AC_NEW = 0x000C0201,
571    C_AC_OPEN = 0x000C0202,
572    C_AC_CLOSE = 0x000C0203,
573    C_AC_EXIT = 0x000C0204,
574    C_AC_SAVE = 0x000C0207,
575    C_AC_PRINT = 0x000C0208,
576    #[strum(serialize = "C_AC_PROPS")]
577    C_AC_PROPERTIES = 0x000C0209,
578    C_AC_UNDO = 0x000C021A,
579    C_AC_COPY = 0x000C021B,
580    C_AC_CUT = 0x000C021C,
581    C_AC_PASTE = 0x000C021D,
582    C_AC_FIND = 0x000C021F,
583    C_AC_SEARCH = 0x000C0221,
584    C_AC_GOTO = 0x000C0222,
585    C_AC_HOME = 0x000C0223,
586    C_AC_BACK = 0x000C0224,
587    C_AC_FORWARD = 0x000C0225,
588    C_AC_STOP = 0x000C0226,
589    C_AC_REFRESH = 0x000C0227,
590    #[strum(serialize = "C_AC_BOOKMARKS")]
591    #[strum(serialize = "C_AC_FAVORITES")]
592    C_AC_FAVOURITES = 0x000C022A,
593    C_AC_ZOOM_IN = 0x000C022D,
594    C_AC_ZOOM_OUT = 0x000C022E,
595    C_AC_ZOOM = 0x000C022F,
596    C_AC_VIEW_TOGGLE = 0x000C0232,
597    C_AC_SCROLL_UP = 0x000C0233,
598    C_AC_SCROLL_DOWN = 0x000C0234,
599    C_AC_EDIT = 0x000C023D,
600    C_AC_CANCEL = 0x000C025F,
601    #[strum(serialize = "C_AC_INS")]
602    C_AC_INSERT = 0x000C0269,
603    C_AC_DEL = 0x000C026A,
604    C_AC_REDO = 0x000C0279,
605    C_AC_REPLY = 0x000C0289,
606    C_AC_FORWARD_MAIL = 0x000C028B,
607    C_AC_SEND = 0x000C028C,
608    C_AC_DESKTOP_SHOW_ALL_WINDOWS = 0x000C029F,
609    C_AC_DESKTOP_SHOW_ALL_APPLICATIONS = 0x000C02A2,
610    #[strum(serialize = "GLOBE")]
611    C_AC_NEXT_KEYBOARD_LAYOUT_SELECT = 0x000C029D,
612    #[strum(serialize = "BANG")]
613    #[strum(serialize = "EXCL")]
614    EXCLAMATION = 0x0207001E,
615    #[strum(serialize = "AT")]
616    #[strum(serialize = "ATSN")]
617    AT_SIGN = 0x0207001F,
618    #[strum(serialize = "HASH")]
619    POUND = 0x02070020,
620    #[strum(serialize = "DLLR")]
621    DOLLAR = 0x02070021,
622    #[strum(serialize = "PRCNT")]
623    #[strum(serialize = "PRCT")]
624    PERCENT = 0x02070022,
625    #[strum(serialize = "CRRT")]
626    CARET = 0x02070023,
627    #[strum(serialize = "AMPS")]
628    AMPERSAND = 0x02070024,
629    #[strum(serialize = "ASTRK")]
630    #[strum(serialize = "STAR")]
631    ASTERISK = 0x02070025,
632    #[strum(serialize = "LPAR")]
633    LEFT_PARENTHESIS = 0x02070026,
634    #[strum(serialize = "RPAR")]
635    RIGHT_PARENTHESIS = 0x02070027,
636    #[strum(serialize = "UNDER")]
637    UNDERSCORE = 0x0207002D,
638    PLUS = 0x0207002E,
639    #[strum(serialize = "LBRC")]
640    LEFT_BRACE = 0x0207002F,
641    #[strum(serialize = "RBRC")]
642    RIGHT_BRACE = 0x02070030,
643    PIPE = 0x02070031,
644    TILDE2 = 0x02070032,
645    #[strum(serialize = "COLN")]
646    COLON = 0x02070033,
647    #[strum(serialize = "DQT")]
648    DOUBLE_QUOTES = 0x02070034,
649    #[strum(serialize = "TILD")]
650    TILDE = 0x02070035,
651    #[strum(serialize = "LABT")]
652    #[strum(serialize = "LT")]
653    LESS_THAN = 0x02070036,
654    #[strum(serialize = "GT")]
655    GREATER_THAN = 0x02070037,
656    #[strum(serialize = "QMARK")]
657    QUESTION = 0x02070038,
658    CLEAR2 = 0x02070053,
659    PIPE2 = 0x02070064,
660}
661
662impl Keycode {
663    /// Returns the raw HID usage value as encoded by ZMK.
664    pub const fn to_hid_usage(self) -> u32 {
665        self as u32
666    }
667
668    /// Converts a raw HID usage value into a known [`Keycode`].
669    ///
670    /// Returns `None` when the usage is not present in this enum table.
671    pub fn from_hid_usage(encoded: u32) -> Option<Self> {
672        Self::try_from(encoded).ok()
673    }
674
675    /// Parses a keycode from a ZMK name/alias (for example `"A"` or `"LSHFT"`).
676    pub fn from_name(name: &str) -> Option<Self> {
677        name.parse().ok()
678    }
679
680    /// Returns the canonical static name for this keycode variant.
681    pub fn to_name(self) -> &'static str {
682        <&'static str>::from(self)
683    }
684}
685
686#[cfg(test)]
687mod tests {
688    use super::Keycode;
689
690    #[test]
691    fn bracket_keycodes_roundtrip_hid_usage() {
692        assert_eq!(Keycode::LEFT_BRACKET.to_hid_usage(), 0x0007_002F);
693        assert_eq!(Keycode::RIGHT_BRACKET.to_hid_usage(), 0x0007_0030);
694        assert_eq!(Keycode::LEFT_BRACE.to_hid_usage(), 0x0207_002F);
695        assert_eq!(Keycode::RIGHT_BRACE.to_hid_usage(), 0x0207_0030);
696
697        assert_eq!(
698            Keycode::from_hid_usage(0x0007_002F),
699            Some(Keycode::LEFT_BRACKET)
700        );
701        assert_eq!(
702            Keycode::from_hid_usage(0x0007_0030),
703            Some(Keycode::RIGHT_BRACKET)
704        );
705        assert_eq!(
706            Keycode::from_hid_usage(0x0207_002F),
707            Some(Keycode::LEFT_BRACE)
708        );
709        assert_eq!(
710            Keycode::from_hid_usage(0x0207_0030),
711            Some(Keycode::RIGHT_BRACE)
712        );
713    }
714
715    #[test]
716    fn bracket_keycodes_parse_aliases() {
717        assert_eq!(Keycode::from_name("LBKT"), Some(Keycode::LEFT_BRACKET));
718        assert_eq!(Keycode::from_name("RBKT"), Some(Keycode::RIGHT_BRACKET));
719
720        assert_eq!(Keycode::from_name("LBRC"), Some(Keycode::LEFT_BRACE));
721        assert_eq!(Keycode::from_name("RBRC"), Some(Keycode::RIGHT_BRACE));
722
723        assert_eq!(
724            Keycode::from_name(Keycode::LEFT_BRACKET.to_name()),
725            Some(Keycode::LEFT_BRACKET)
726        );
727        assert_eq!(
728            Keycode::from_name(Keycode::RIGHT_BRACKET.to_name()),
729            Some(Keycode::RIGHT_BRACKET)
730        );
731        assert_eq!(
732            Keycode::from_name(Keycode::LEFT_BRACE.to_name()),
733            Some(Keycode::LEFT_BRACE)
734        );
735        assert_eq!(
736            Keycode::from_name(Keycode::RIGHT_BRACE.to_name()),
737            Some(Keycode::RIGHT_BRACE)
738        );
739    }
740}