diff --git a/docs/feature_macros.md b/docs/feature_macros.md index 66d2bc090..050fb45aa 100644 --- a/docs/feature_macros.md +++ b/docs/feature_macros.md @@ -8,19 +8,19 @@ Macros allow you to send multiple keystrokes when pressing just one key. QMK has ## The new way: `SEND_STRING()` & `process_record_user` -Sometimes you just want a key to type out words or phrases. For the most common situations we've provided `SEND_STRING()`, which will type out your string for you. All ascii that is easily translated to a keycode is supported (eg `\n\t`). +Sometimes you just want a key to type out words or phrases. For the most common situations we've provided `SEND_STRING()`, which will type out your string (i.e. a sequence of characters) for you. All ASCII characters that are easily translated to a keycode are supported (e.g. `\n\t`). -For example: +For example, you could write in your `keymap.c`: ```c enum custom_keycodes { - PRINT_TRUTH = SAFE_RANGE + MY_CUSTOM_MACRO = SAFE_RANGE }; bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { switch(keycode) { - case PRINT_TRUTH: + case MY_CUSTOM_MACRO: SEND_STRING("QMK is the best thing ever!"); return false; break; } @@ -29,13 +29,46 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { }; ``` -### Tap/down/up +To activate this macro, assign the keycode `MY_CUSTOM_MACRO` to one of your keys in your keymap. +What happens here is this: +We first define a new custom keycode in the range not occupied by any other keycodes. +Then we use the `process_record_user` function, which is called whenever a key is pressed or released, to check if our custom keycode has been activated. +If yes, we send the string `"QMK is the best thing ever!"` to the computer via the `SEND_STRING` macro (this is a C preprocessor macro, not to be confused with QMK macros). +We return `false` to indicate to the caller that the key press we just processed need not be processed any further. + +You might want to add more than one macro. +You can do that by adding another keycode and adding another case to the switch statement, like so: + +```c +enum custom_keycodes { + MY_CUSTOM_MACRO = SAFE_RANGE, + MY_OTHER_MACRO +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + if (record->event.pressed) { + switch(keycode) { + case MY_CUSTOM_MACRO: + SEND_STRING("QMK is the best thing ever!"); + return false; break; + case MY_OTHER_MACRO: + SEND_STRING(SS_LCTRL("ac")); // selects all and copies + return false; break; + } + } + return true; +}; +``` + +### TAP, DOWN and UP + +You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`. You can send arbitary keycodes by wrapping them in: -* `SS_TAP()` -* `SS_DOWN()` -* `SS_UP()` +* `SS_TAP()` presses and releases a key. +* `SS_DOWN()` presses (but does not release) a key. +* `SS_UP()` releases a key. For example: @@ -53,11 +86,12 @@ There's also a couple of mod shortcuts you can use: * `SS_LGUI(string)` * `SS_LALT(string)` -That can be used like this: +These press the respective modifier, send the supplied string and then release the modifier. +They can be used like this: SEND_STRING(SS_LCTRL("a")); -Which would send LCTRL+a (LTRL down, a, LTRL up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes. +Which would send LCTRL+a (LCTRL down, a, LCTRL up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes. ### Alternative keymaps