aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorskullY <skullydazed@gmail.com>2017-06-09 12:25:12 -0700
committerskullY <skullydazed@gmail.com>2017-06-09 12:25:12 -0700
commita0ac0d3cea0390875e7baf92adede4949c2b493e (patch)
tree4a34b5bedd5057065bf31ed4e1863fae5bf77aa1 /docs
parent767bcac23c6ea990881ed4dad8818a51e399b081 (diff)
downloadqmk_firmware-a0ac0d3cea0390875e7baf92adede4949c2b493e.tar.gz
qmk_firmware-a0ac0d3cea0390875e7baf92adede4949c2b493e.zip
Move Dynamic Macros into their own file
Diffstat (limited to 'docs')
-rw-r--r--docs/Dynamic-Macros.md63
-rw-r--r--docs/Macros.md192
-rw-r--r--docs/SUMMARY.md1
3 files changed, 124 insertions, 132 deletions
diff --git a/docs/Dynamic-Macros.md b/docs/Dynamic-Macros.md
new file mode 100644
index 000000000..8fb54c322
--- /dev/null
+++ b/docs/Dynamic-Macros.md
@@ -0,0 +1,63 @@
1# Dynamic macros: record and replay macros in runtime
2
3QMK supports temporarily macros created on the fly. We call these Dynamic Macros. They are defined by the user from the keyboard and are lost when the keyboard is unplugged or otherwise rebooted.
4
5You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM.
6
7To enable them, first add a new element to the `planck_keycodes` enum — `DYNAMIC_MACRO_RANGE`:
8
9```c
10enum planck_keycodes {
11 QWERTY = SAFE_RANGE,
12 COLEMAK,
13 DVORAK,
14 PLOVER,
15 LOWER,
16 RAISE,
17 BACKLIT,
18 EXT_PLV,
19 DYNAMIC_MACRO_RANGE,
20};
21```
22
23It must be the last element because `dynamic_macros.h` will add some more keycodes after it.
24
25Below it include the `dynamic_macro.h` header:
26
27```c
28 #include "dynamic_macro.h"`
29```
30
31Add the following keys to your keymap:
32
33* `DYN_REC_START1` — start recording the macro 1,
34* `DYN_REC_START2` — start recording the macro 2,
35* `DYN_MACRO_PLAY1` — replay the macro 1,
36* `DYN_MACRO_PLAY2` — replay the macro 2,
37* `DYN_REC_STOP` — finish the macro that is currently being recorded.
38
39Add the following code to the very beginning of your `process_record_user()` function:
40
41```c
42 if (!process_record_dynamic_macro(keycode, record)) {
43 return false;
44 }
45```
46
47That should be everything necessary. To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `DYN_REC_STOP` layer button. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`.
48
49Note that it's possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again.
50
51For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, use the following snippet instead of the one above:
52
53```c
54 uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode);
55
56 if (!process_record_dynamic_macro(macro_kc, record)) {
57 return false;
58 }
59```
60
61If the LED's start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header).
62
63For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header.
diff --git a/docs/Macros.md b/docs/Macros.md
index be277f176..1418d24ab 100644
--- a/docs/Macros.md
+++ b/docs/Macros.md
@@ -10,22 +10,22 @@ By default QMK assumes you don't have any macros. To define your macros you crea
10 10
11```c 11```c
12const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { 12const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
13 if (record->event.pressed) { 13 if (record->event.pressed) {
14 switch(id) { 14 switch(id) {
15 case 0: 15 case 0:
16 return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); 16 return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END);
17 case 1: 17 case 1:
18 return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); 18 return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END);
19 } 19 }
20 } 20 }
21 return MACRO_NONE; 21 return MACRO_NONE;
22}; 22};
23``` 23```
24 24
25This defines two macros which will be run when the key they are assigned to is pressed. If you'd like them to run when the release is released instead you can change the if statement: 25This defines two macros which will be run when the key they are assigned to is pressed. If you'd like them to run when the release is released instead you can change the if statement:
26 26
27```c 27```c
28 if (!record->event.pressed) { 28 if (!record->event.pressed) {
29``` 29```
30 30
31## Macro Commands 31## Macro Commands
@@ -47,14 +47,14 @@ For example:
47 47
48```c 48```c
49const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { 49const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
50 if (record->event.pressed) { 50 if (record->event.pressed) {
51 switch(id) { 51 switch(id) {
52 case 0: 52 case 0:
53 SEND_STRING("QMK is the best thing ever!"); 53 SEND_STRING("QMK is the best thing ever!");
54 return false; 54 return false;
55 } 55 }
56 } 56 }
57 return MACRO_NONE; 57 return MACRO_NONE;
58}; 58};
59``` 59```
60 60
@@ -64,21 +64,21 @@ Use the `M()` function within your `KEYMAP()` to call a macro. For example, here
64 64
65```c 65```c
66const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 66const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
67 [0] = KEYMAP( 67 [0] = KEYMAP(
68 M(0), M(1) 68 M(0), M(1)
69 ), 69 ),
70}; 70};
71 71
72const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { 72const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
73 if (record->event.pressed) { 73 if (record->event.pressed) {
74 switch(id) { 74 switch(id) {
75 case 0: 75 case 0:
76 return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); 76 return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END);
77 case 1: 77 case 1:
78 return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); 78 return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END);
79 } 79 }
80 } 80 }
81 return MACRO_NONE; 81 return MACRO_NONE;
82}; 82};
83``` 83```
84 84
@@ -86,145 +86,73 @@ When you press the key on the left it will type "Hi!" and when you press the key
86 86
87## Naming your macros 87## Naming your macros
88 88
89If 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. 89If 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.
90 90
91```c 91```c
92#define M_HI M(0) 92#define M_HI M(0)
93#define M_BYE M(1) 93#define M_BYE M(1)
94 94
95const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 95const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
96 [0] = KEYMAP( 96 [0] = KEYMAP(
97 M_HI, M_BYE 97 M_HI, M_BYE
98 ), 98 ),
99}; 99};
100``` 100```
101 101
102## Advanced macro functions 102# Advanced macro functions
103 103
104To get more control over the keys/actions your keyboard takes, the following functions are available to you in the `action_get_macro()` function block: 104While working within the `action_get_macro()` function block there are some functions you may find useful. 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.
105 105
106### `record->event.pressed` 106#### `record->event.pressed`
107 107
108This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is 108This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
109 109
110```c 110```c
111 if (record->event.pressed) { 111 if (record->event.pressed) {
112 // on keydown 112 // on keydown
113 } else { 113 } else {
114 // on keyup 114 // on keyup
115 } 115 }
116``` 116```
117 117
118### `register_code(<kc>);` 118#### `register_code(<kc>);`
119 119
120This sends the `<kc>` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`. 120This sends the `<kc>` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`.
121 121
122### `unregister_code(<kc>);` 122#### `unregister_code(<kc>);`
123 123
124Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent. 124Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
125 125
126### `layer_on(<n>);` 126#### `clear_keyboard();`
127
128This will turn on the layer `<n>` - the higher layer number will always take priority. Make sure you have `KC_TRNS` for the key you're pressing on the layer you're switching to, or you'll get stick there unless you have another plan.
129
130### `layer_off(<n>);`
131
132This will turn off the layer `<n>`.
133
134### `clear_keyboard();`
135 127
136This will clear all mods and keys currently pressed. 128This will clear all mods and keys currently pressed.
137 129
138### `clear_mods();` 130#### `clear_mods();`
139 131
140This will clear all mods currently pressed. 132This will clear all mods currently pressed.
141 133
142### `clear_keyboard_but_mods();` 134#### `clear_keyboard_but_mods();`
143 135
144This will clear all keys besides the mods currently pressed. 136This will clear all keys besides the mods currently pressed.
145 137
146### `update_tri_layer(layer_1, layer_2, layer_3);` 138# Advanced Example: Single-key copy/paste (hold to copy, tap to paste)
147
148If the user attempts to activate layer 1 AND layer 2 at the same time (for example, by hitting their respective layer keys), layer 3 will be activated. Layers 1 and 2 will _also_ be activated, for the purposes of fallbacks (so a given key will fall back from 3 to 2, to 1 -- and only then to 0).
149
150# Example: Single-key copy/paste (hold to copy, tap to paste)
151
152With QMK, it's easy to make one key do two things, as long as one of those things is being a modifier. :) So if you want a key to act as Ctrl when held and send the letter R when tapped, that's easy: `CTL_T(KC_R)`. But what do you do when you want that key to send Ctrl-V (paste) when tapped, and Ctrl-C (copy) when held?
153 139
154Here's what you do: 140This example defines a macro which sends `Ctrl-C` when pressed down, and `Ctrl-V` when released.
155 141
156```c 142```c
157const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { 143const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
158 switch(id) { 144 switch(id) {
159 case 0: { 145 case 0: {
160 if (record->event.pressed) { 146 if (record->event.pressed) {
161 return MACRO( D(LCTL), T(C), U(LCTL), END ); 147 return MACRO( D(LCTL), T(C), U(LCTL), END );
162 } else { 148 } else {
163 return MACRO( D(LCTL), T(V), U(LCTL), END ); 149 return MACRO( D(LCTL), T(V), U(LCTL), END );
164 } 150 }
165 break; 151 break;
166 } 152 }
167 } 153 }
168 return MACRO_NONE; 154 return MACRO_NONE;
169}; 155};
170``` 156```
171 157
172To assign this macro to a key on your keyboard layout, you just use `M(0)` on the key you want to press for copy/paste.
173
174# Dynamic macros: record and replay macros in runtime
175
176In addition to the static macros described above, you may enable the dynamic macros which you may record while writing. They are forgotten as soon as the keyboard is unplugged. Only two such macros may be stored at the same time, with the total length of 64 keypresses (by default).
177
178To enable them, first add a new element to the `planck_keycodes` enum — `DYNAMIC_MACRO_RANGE`:
179
180 enum planck_keycodes {
181 QWERTY = SAFE_RANGE,
182 COLEMAK,
183 DVORAK,
184 PLOVER,
185 LOWER,
186 RAISE,
187 BACKLIT,
188 EXT_PLV,
189 DYNAMIC_MACRO_RANGE,
190 };
191
192It must be the last element because `dynamic_macros.h` will add some more keycodes after it.
193
194Below it include the `dynamic_macro.h` header:
195
196 #include "dynamic_macro.h"`
197
198Add the following keys to your keymap:
199
200- `DYN_REC_START1` — start recording the macro 1,
201- `DYN_REC_START2` — start recording the macro 2,
202- `DYN_MACRO_PLAY1` — replay the macro 1,
203- `DYN_MACRO_PLAY2` — replay the macro 2,
204- `DYN_REC_STOP` — finish the macro that is currently being recorded.
205
206Add the following code to the very beginning of your `process_record_user()` function:
207
208```c
209 if (!process_record_dynamic_macro(keycode, record)) {
210 return false;
211 }
212```
213
214That should be everything necessary. To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `DYN_REC_STOP` layer button. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`.
215
216Note that it's possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again.
217
218For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, use the following snippet instead of the one above:
219
220```c
221 uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode);
222
223 if (!process_record_dynamic_macro(macro_kc, record)) {
224 return false;
225 }
226```
227
228If the LED's start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header).
229 158
230For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header.
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 99845a7b6..61d5a4261 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -10,6 +10,7 @@
10* [Layer switching](/Key-Functions.md) 10* [Layer switching](/Key-Functions.md)
11* [Leader Key](/Leader-Key.md) 11* [Leader Key](/Leader-Key.md)
12* [Macros](/Macros.md) 12* [Macros](/Macros.md)
13* [Dynamic Macros](/Dynamic-Macros.md)
13* [Space Cadet](/Space-Cadet-Shift.md) 14* [Space Cadet](/Space-Cadet-Shift.md)
14* [Tap Dance](/Tap-Dance.md) 15* [Tap Dance](/Tap-Dance.md)
15* [Mouse keys](/Mouse-keys.md) 16* [Mouse keys](/Mouse-keys.md)