]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - docs/feature_macros.md
Replace Right key on base layer with RShift, convert adjust to KC_KEYMAP format
[qmk_firmware.git] / docs / feature_macros.md
index 66d2bc090a84002f717c0f07e44ca37e41a69623..dff692bd8f0cc28ee81d124ac241500668f78050 100644 (file)
@@ -1,41 +1,85 @@
 # Macros
 
-Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code. 
+Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code.
 
 {% hint style='danger' %}
-**Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets ahold of your keyboard will be able to access that information by opening a text editor.
+**Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor.
 {% endhint %}
 
-## The new way: `SEND_STRING()` & `process_record_user`
+## 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:
+Here is an example `keymap.c` for a two-key keyboard:
+
+```c
+enum custom_keycodes {
+       MY_CUSTOM_MACRO = SAFE_RANGE
+};
+
+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!"); // this is our macro!
+                               return false; break;
+               }
+       }
+       return true;
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+       [0] = {
+         {MY_CUSTOM_MACRO, KC_ESC}
+       }
+};
+```
+
+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.
+Finally, we define the keymap so that the first button activates our macro and the second button is just an escape button.
+
+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 {
-       PRINT_TRUTH = SAFE_RANGE
+       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 PRINT_TRUTH:
+                       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;
 };
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+       [0] = {
+         {MY_CUSTOM_MACRO, MY_OTHER_MACRO}
+       }
+};
 ```
 
-### Tap/down/up
+### TAP, DOWN and UP
 
-You can send arbitary keycodes by wrapping them in:
+You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`.
+You can send arbitrary 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:
 
@@ -52,20 +96,22 @@ There's also a couple of mod shortcuts you can use:
 * `SS_LCTRL(string)`
 * `SS_LGUI(string)`
 * `SS_LALT(string)`
+* `SS_LSFT(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
+### Alternative Keymaps
 
 By default, it assumes a US keymap with a QWERTY layout; if you want to change that (e.g. if your OS uses software Colemak), include this somewhere in your keymap:
 
     #include <sendstring_colemak.h>
 
-### Strings in memory
+### Strings in Memory
 
 If for some reason you're manipulating strings and need to print out something you just generated (instead of being a literal, constant string), you can use `send_string()`, like this:
 
@@ -83,7 +129,7 @@ send_string(my_str);
 SEND_STRING(".."SS_TAP(X_END));
 ```
 
-## The old way: `MACRO()` & `action_get_macro`
+## The Old Way: `MACRO()` & `action_get_macro`
 
 {% hint style='info' %}
 This is inherited from TMK, and hasn't been updated - it's recommend that you use `SEND_STRING` and `process_record_user` instead.
@@ -120,7 +166,7 @@ A macro can include the following commands:
 * W() wait (milliseconds).
 * END end mark.
 
-### Mapping a Macro to a key
+### Mapping a Macro to a Key
 
 Use the `M()` function within your `KEYMAP()` to call a macro. For example, here is the keymap for a 2-key keyboard:
 
@@ -146,7 +192,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
 
 When you press the key on the left it will type "Hi!" and when you press the key on the right it will type "Bye!".
 
-### Naming your macros
+### Naming Your Macros
 
 If you have a bunch of macros you want to refer to from your keymap while keeping the keymap easily readable you can name them using `#define` at the top of your file.
 
@@ -161,7 +207,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 };
 ```
 
-## Advanced macro functions
+## Advanced Macro Functions
 
 There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
 
@@ -197,9 +243,9 @@ This will clear all mods currently pressed.
 
 This will clear all keys besides the mods currently pressed.
 
-## Advanced Example: Single-key copy/paste
+## Advanced Example: Single-Key Copy/Paste
 
-This example defines a macro which sends `Ctrl-C` when pressed down, and `Ctrl-V` when released. 
+This example defines a macro which sends `Ctrl-C` when pressed down, and `Ctrl-V` when released.
 
 ```c
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
@@ -216,5 +262,3 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
        return MACRO_NONE;
 };
 ```
-
-