keycode_string.h (5132B)
1 // Copyright 2024-2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://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 15 #pragma once 16 17 #include <stdint.h> 18 19 #if KEYCODE_STRING_ENABLE 20 21 /** 22 * @brief Formats a QMK keycode as a human-readable string. 23 * 24 * Given a keycode, like `KC_A`, this function returns a formatted string, like 25 * "KC_A". This is useful for debugging and diagnostics so that keys are more 26 * easily identified than they would be by raw numerical codes. 27 * 28 * @note The returned char* string should be used right away. The string memory 29 * is reused and will be overwritten by the next call to `keycode_string()`. 30 * 31 * Many common QMK keycodes are understood by this function, but not all. 32 * Recognized keycodes include: 33 * 34 * - Most basic keycodes, including letters `KC_A` - `KC_Z`, digits `KC_0` - 35 * `KC_9`, function keys `KC_F1` - `KC_F24`, and modifiers like `KC_LSFT`. 36 * 37 * - Modified basic keycodes, like `S(KC_1)` (Shift + 1 = !). 38 * 39 * - `MO`, `TO`, `TG`, `OSL`, `LM(layer,mod)`, `LT(layer,kc)` layer switches. 40 * 41 * - One-shot mod `OSM(mod)` keycodes. 42 * 43 * - Mod-tap `MT(mod, kc)` keycodes. 44 * 45 * - Tap dance keycodes `TD(i)`. 46 * 47 * - Swap hands keycodes `SH_T(kc)`, `SH_TOGG`, etc. 48 * 49 * - Joystick keycodes `JS_n`. 50 * 51 * - Programmable button keycodes `PB_n`. 52 * 53 * - Unicode `UC(codepoint)` and Unicode Map `UM(i)` and `UP(i,j)` keycodes. 54 * 55 * - Keyboard range keycodes `QK_KB_*`. 56 * 57 * - User range (SAFE_RANGE) keycodes `QK_USER_*`. 58 * 59 * Keycodes involving mods like `OSM`, `LM`, `MT` are fully supported only where 60 * a single mod is applied. 61 * 62 * Unrecognized keycodes are printed numerically as hex values like `0x1ABC`. 63 * 64 * Optionally, use `keycode_string_names_user` or `keycode_string_names_kb` to 65 * define names for additional keycodes or override how any of the above are 66 * formatted. 67 * 68 * @param keycode QMK keycode. 69 * @return Stringified keycode. 70 */ 71 const char* get_keycode_string(uint16_t keycode); 72 73 /** Defines a human-readable name for a keycode. */ 74 typedef struct { 75 uint16_t keycode; 76 const char* name; 77 } keycode_string_name_t; 78 79 // clang-format off 80 /** 81 * @brief Defines names for additional keycodes for `get_keycode_string()`. 82 * 83 * Define `KEYCODE_STRING_NAMES_USER` in your keymap.c to add names for 84 * additional keycodes to `keycode_string()`. This table may also be used to 85 * override how `keycode_string()` formats a keycode. For example, supposing 86 * keymap.c defines `MYMACRO1` and `MYMACRO2` as custom keycodes: 87 * 88 * KEYCODE_STRING_NAMES_USER( 89 * KEYCODE_STRING_NAME(MYMACRO1), 90 * KEYCODE_STRING_NAME(MYMACRO2), 91 * KEYCODE_STRING_NAME(KC_EXLM), 92 * ); 93 * 94 * The above defines names for `MYMACRO1` and `MYMACRO2`, and overrides 95 * `KC_EXLM` to format as "KC_EXLM" instead of the default "S(KC_1)". 96 */ 97 # define KEYCODE_STRING_NAMES_USER(...) \ 98 static const keycode_string_name_t keycode_string_names_user[] = {__VA_ARGS__}; \ 99 uint16_t keycode_string_names_size_user = \ 100 sizeof(keycode_string_names_user) / sizeof(keycode_string_name_t); \ 101 const keycode_string_name_t* keycode_string_names_data_user = \ 102 keycode_string_names_user 103 104 /** Same as above, but defines keycode string names at the keyboard level. */ 105 # define KEYCODE_STRING_NAMES_KB(...) \ 106 static const keycode_string_name_t keycode_string_names_kb[] = {__VA_ARGS__}; \ 107 uint16_t keycode_string_names_size_kb = \ 108 sizeof(keycode_string_names_kb) / sizeof(keycode_string_name_t); \ 109 const keycode_string_name_t* keycode_string_names_data_kb = \ 110 keycode_string_names_kb 111 112 /** Helper to define a keycode_string_name_t. */ 113 # define KEYCODE_STRING_NAME(kc) \ 114 { (kc), #kc } 115 // clang-format on 116 117 extern const keycode_string_name_t* keycode_string_names_data_user; 118 extern uint16_t keycode_string_names_size_user; 119 extern const keycode_string_name_t* keycode_string_names_data_kb; 120 extern uint16_t keycode_string_names_size_kb; 121 122 #else 123 124 // When keycode_string is disabled, fall back to printing keycodes numerically 125 // as decimal values, using get_u16_str() from quantum.c. 126 # define get_keycode_string(kc) get_u16_str(kc, ' ') 127 128 const char* get_u16_str(uint16_t curr_num, char curr_pad); 129 130 # define KEYCODE_STRING_NAMES_USER(...) 131 # define KEYCODE_STRING_NAMES_KB(...) 132 # define KEYCODE_STRING_NAME(kc) 133 134 #endif // KEYCODE_STRING_ENABLE