mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-05-20 16:20:31 +00:00
keycode_string review revisions.
* Rename keycode_string() -> get_keycode_string() for consistency with existing string utils like get_u8_str(). * Revise custom keycode names with separate _user and _kb tables.
This commit is contained in:
parent
075e001af8
commit
e8ded5a2f1
@ -79,13 +79,13 @@ KL: kc: 172, col: 2, row: 0, pressed: 0, time: 16411, int: 0, count: 0
|
||||
|
||||
### Which keycode is this keypress?
|
||||
|
||||
Keycodes are logged in the example above as numerical codes, which may be difficult to interpret. For more readable logging, add `KEYCODE_STRING_ENABLE = yes` in your `rules.mk` and use `keycode_string(kc)`. For example:
|
||||
Keycodes are logged in the example above as numerical codes, which may be difficult to interpret. For more readable logging, add `KEYCODE_STRING_ENABLE = yes` in your `rules.mk` and use `get_keycode_string(kc)`. For example:
|
||||
|
||||
```c
|
||||
uprintf("kc: %s\n", keycode_string(keycode));
|
||||
uprintf("kc: %s\n", get_keycode_string(keycode));
|
||||
```
|
||||
|
||||
This logs the keycode as a human-readable string like "`LT(2,KC_D)`" rather than a numerical code like "`0x4207`." See the [keycode_string](unit_testing#keycode-string) section of the Unit Testing page for more information.
|
||||
This logs the keycode as a human-readable string like "`LT(2,KC_D)`" rather than a numerical code like "`0x4207`." See the [Keycode String](unit_testing#keycode-string) section of the Unit Testing page for more information.
|
||||
|
||||
|
||||
### How long did it take to scan for a keypress?
|
||||
|
@ -58,33 +58,35 @@ It's not yet possible to do a full integration test, where you would compile the
|
||||
|
||||
In that model you would emulate the input, and expect a certain output from the emulated keyboard.
|
||||
|
||||
# Logging Keycodes {#keycode-string}
|
||||
# Keycode String {#keycode-string}
|
||||
|
||||
It's much nicer to read keycodes as names like "`LT(2,KC_D)`" than numerical codes like "`0x4207`." To convert keycodes to human-readable strings, add `KEYCODE_STRING_ENABLE = yes` to the `rules.mk` file, then use the `keycode_string(kc)` function to convert a given 16-bit keycode to a string.
|
||||
It's much nicer to read keycodes as names like "`LT(2,KC_D)`" than numerical codes like "`0x4207`." To convert keycodes to human-readable strings, add `KEYCODE_STRING_ENABLE = yes` to the `rules.mk` file, then use the `get_keycode_string(kc)` function to convert a given 16-bit keycode to a string.
|
||||
|
||||
```c
|
||||
const char *key_name = keycode_string(keycode);
|
||||
const char *key_name = get_keycode_string(keycode);
|
||||
dprintf("kc: %s\n", key_name);
|
||||
```
|
||||
|
||||
The stringified keycode may then be logged to console output with `dprintf()` or elsewhere.
|
||||
|
||||
::: warning
|
||||
Use the result of `keycode_string()` immediately. Subsequent invocations reuse the same static buffer and overwrite the previous contents.
|
||||
Use the result of `get_keycode_string()` immediately. Subsequent invocations reuse the same static buffer and overwrite the previous contents.
|
||||
:::
|
||||
|
||||
Many common QMK keycodes are recognized by `keycode_string()`, but not all. These include some common basic keycodes, layer switch keycodes, mod-taps, one-shot keycodes, tap dance keycodes, and Unicode keycodes. As a fallback, an unrecognized keycode is written as a hex number.
|
||||
Many common QMK keycodes are recognized by `get_keycode_string()`, but not all. These include some common basic keycodes, layer switch keycodes, mod-taps, one-shot keycodes, tap dance keycodes, and Unicode keycodes. As a fallback, an unrecognized keycode is written as a hex number.
|
||||
|
||||
Optionally, `custom_keycode_names` may be defined to add names for additional keycodes. For example, supposing keymap.c defines `MYMACRO1` and `MYMACRO2` as custom keycodes, the following adds their names:
|
||||
Optionally, `keycode_string_names_user` may be defined to add names for additional keycodes. For example, supposing keymap.c defines `MYMACRO1` and `MYMACRO2` as custom keycodes, the following adds their names:
|
||||
|
||||
```c
|
||||
const keycode_string_name_t custom_keycode_names[] = {
|
||||
const keycode_string_name_t keycode_string_names_user[] = {
|
||||
KEYCODE_STRING_NAME(MYMACRO1),
|
||||
KEYCODE_STRING_NAME(MYMACRO2),
|
||||
KEYCODE_STRING_NAMES_END // End of table sentinel.
|
||||
};
|
||||
```
|
||||
|
||||
Similarly, `keycode_string_names_kb` may be defined to add names at the keyboard level.
|
||||
|
||||
# Tracing Variables {#tracing-variables}
|
||||
|
||||
Sometimes you might wonder why a variable gets changed and where, and this can be quite tricky to track down without having a debugger. It's of course possible to manually add print statements to track it, but you can also enable the variable trace feature. This works for both variables that are changed by the code, and when the variable is changed by some memory corruption.
|
||||
|
@ -90,7 +90,9 @@ static const keycode_string_name_t keycode_names[] = {
|
||||
};
|
||||
// clang-format on
|
||||
/** Users can override this to define names of additional keycodes. */
|
||||
__attribute__((weak)) const keycode_string_name_t custom_keycode_names[] = {KEYCODE_STRING_NAMES_END};
|
||||
__attribute__((weak)) const keycode_string_name_t keycode_string_names_user[] = {KEYCODE_STRING_NAMES_END};
|
||||
/** Keyboard vendors can override this to define names of additional keycodes. */
|
||||
__attribute__((weak)) const keycode_string_name_t keycode_string_names_kb[] = {KEYCODE_STRING_NAMES_END};
|
||||
/** Names of the 4 mods on each hand. */
|
||||
static const char* mod_names[4] = {PSTR("CTL"), PSTR("SFT"), PSTR("ALT"), PSTR("GUI")};
|
||||
/** Internal buffer for holding a stringified keycode. */
|
||||
@ -198,14 +200,18 @@ static void append_unary_keycode(const char* name, const char* param) {
|
||||
|
||||
/** Stringifies `keycode` and appends it to `buffer`. */
|
||||
static void append_keycode(uint16_t keycode) {
|
||||
// Search the `custom_keycode_names` table first so that it is possible to
|
||||
// override how any keycode would be formatted otherwise.
|
||||
const char* keycode_name = find_keycode_name(custom_keycode_names, keycode);
|
||||
// In case there is overlap among tables, search `keycode_string_names_user`
|
||||
// first so that it takes precedence.
|
||||
const char* keycode_name = find_keycode_name(keycode_string_names_user, keycode);
|
||||
if (keycode_name) {
|
||||
append_P(keycode_name);
|
||||
return;
|
||||
}
|
||||
keycode_name = find_keycode_name(keycode_string_names_kb, keycode);
|
||||
if (keycode_name) {
|
||||
append_P(keycode_name);
|
||||
return;
|
||||
}
|
||||
// Search the `keycode_names` table.
|
||||
keycode_name = find_keycode_name(keycode_names, keycode);
|
||||
if (keycode_name) {
|
||||
append_P(keycode_name);
|
||||
@ -396,7 +402,7 @@ static void append_keycode(uint16_t keycode) {
|
||||
append_number(keycode, 16); // Fallback: write keycode as hex value.
|
||||
}
|
||||
|
||||
const char* keycode_string(uint16_t keycode) {
|
||||
const char* get_keycode_string(uint16_t keycode) {
|
||||
buffer_len = 0;
|
||||
buffer[0] = '\0';
|
||||
append_keycode(keycode);
|
||||
|
@ -55,13 +55,14 @@
|
||||
*
|
||||
* Unrecognized keycodes are printed numerically as hex values like `0x1ABC`.
|
||||
*
|
||||
* Optionally, use `custom_keycode_names` to define names for additional
|
||||
* keycodes or override how any of the above are formatted.
|
||||
* Optionally, use `keycode_string_names_user` or `keycode_string_names_kb` to
|
||||
* define names for additional keycodes or override how any of the above are
|
||||
* formatted.
|
||||
*
|
||||
* @param keycode QMK keycode.
|
||||
* @return Stringified keycode.
|
||||
*/
|
||||
const char* keycode_string(uint16_t keycode);
|
||||
const char* get_keycode_string(uint16_t keycode);
|
||||
|
||||
/** Defines a human-readable name for a keycode. */
|
||||
typedef struct {
|
||||
@ -70,7 +71,7 @@ typedef struct {
|
||||
} keycode_string_name_t;
|
||||
|
||||
/**
|
||||
* @brief Names for additional keycodes for `keycode_string()`.
|
||||
* @brief Names for additional keycodes for `get_keycode_string()`.
|
||||
*
|
||||
* @note The table *must* end with `KEYCODE_STRING_NAMES_END`.
|
||||
*
|
||||
@ -79,7 +80,7 @@ typedef struct {
|
||||
* override how `keycode_string()` formats a keycode. For example, supposing
|
||||
* keymap.c defines `MYMACRO1` and `MYMACRO2` as custom keycodes:
|
||||
*
|
||||
* const keycode_string_name_t custom_keycode_names[] = {
|
||||
* const keycode_string_name_t keycode_string_names_user[] = {
|
||||
* KEYCODE_STRING_NAME(MYMACRO1),
|
||||
* KEYCODE_STRING_NAME(MYMACRO2),
|
||||
* KEYCODE_STRING_NAME(KC_EXLM),
|
||||
@ -89,7 +90,9 @@ typedef struct {
|
||||
* The above defines names for `MYMACRO1` and `MYMACRO2`, and overrides
|
||||
* `KC_EXLM` to format as "KC_EXLM" instead of the default "S(KC_1)".
|
||||
*/
|
||||
extern const keycode_string_name_t custom_keycode_names[];
|
||||
extern const keycode_string_name_t keycode_string_names_user[];
|
||||
/** Same as `keycode_string_names_user`, but for use at the keyboard level. */
|
||||
extern const keycode_string_name_t keycode_string_names_kb[];
|
||||
|
||||
/** Helper to define a keycode_string_name_t. */
|
||||
# define KEYCODE_STRING_NAME(kc) \
|
||||
@ -102,7 +105,7 @@ extern const keycode_string_name_t custom_keycode_names[];
|
||||
|
||||
// When keycode_string is disabled, fall back to printing keycodes numerically
|
||||
// as decimal values, using get_u16_str() from quantum.c.
|
||||
# define keycode_string(kc) get_u16_str(kc, ' ')
|
||||
# define get_keycode_string(kc) get_u16_str(kc, ' ')
|
||||
|
||||
const char *get_u16_str(uint16_t curr_num, char curr_pad);
|
||||
|
||||
|
@ -22,8 +22,11 @@ enum {
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
extern "C" const keycode_string_name_t custom_keycode_names[] = {
|
||||
extern "C" const keycode_string_name_t keycode_string_names_kb[] = {
|
||||
KEYCODE_STRING_NAME(MYMACRO1),
|
||||
KEYCODE_STRING_NAMES_END // End of table sentinel.
|
||||
};
|
||||
extern "C" const keycode_string_name_t keycode_string_names_user[] = {
|
||||
KEYCODE_STRING_NAME(MYMACRO2),
|
||||
KEYCODE_STRING_NAME(KC_EXLM),
|
||||
KEYCODE_STRING_NAMES_END // End of table sentinel.
|
||||
@ -32,7 +35,7 @@ extern "C" const keycode_string_name_t custom_keycode_names[] = {
|
||||
|
||||
class KeycodeStringTest : public TestFixture {};
|
||||
|
||||
TEST_F(KeycodeStringTest, keycode_string) {
|
||||
TEST_F(KeycodeStringTest, get_keycode_string) {
|
||||
struct TestParams {
|
||||
uint16_t keycode;
|
||||
std::string expected;
|
||||
@ -98,6 +101,6 @@ TEST_F(KeycodeStringTest, keycode_string) {
|
||||
{MYMACRO2, "MYMACRO2"},
|
||||
{KC_EXLM, "KC_EXLM"},
|
||||
})) {
|
||||
EXPECT_EQ(keycode_string(keycode), expected) << "where keycode = 0x" << std::hex << keycode;
|
||||
EXPECT_EQ(get_keycode_string(keycode), expected) << "where keycode = 0x" << std::hex << keycode;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user