aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/contributing.md14
-rw-r--r--docs/feature_advanced_keycodes.md2
-rw-r--r--docs/feature_tap_dance.md83
3 files changed, 98 insertions, 1 deletions
diff --git a/docs/contributing.md b/docs/contributing.md
index 88b9d7d9b..15066185b 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -129,6 +129,20 @@ Documentation is one of the easiest ways to get started contributing to QMK. Fin
129 129
130You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click "Suggest An Edit" at the top of each page on http://docs.qmk.fm/. 130You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click "Suggest An Edit" at the top of each page on http://docs.qmk.fm/.
131 131
132When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency:
133
134```c
135enum my_layers {
136 _FIRST_LAYER,
137 _SECOND_LAYER
138};
139
140enum my_keycodes {
141 FIRST_LAYER = SAFE_RANGE,
142 SECOND_LAYER
143};
144```
145
132## Keymaps 146## Keymaps
133 147
134Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap. 148Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap.
diff --git a/docs/feature_advanced_keycodes.md b/docs/feature_advanced_keycodes.md
index b20acf3c4..a6ddf458c 100644
--- a/docs/feature_advanced_keycodes.md
+++ b/docs/feature_advanced_keycodes.md
@@ -15,7 +15,7 @@ This will allow you to use `FN_CAPS` and `ALT_TAB` in your keymap, keeping it mo
15 15
16## Caveats 16## Caveats
17 17
18Currently, `LT()` and `MT()` are limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. Modifiers specified as part of a Layer Tap or Mod Tap's keycode will be ignored. 18Currently, `LT()` and `MT()` are limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. Modifiers specified as part of a Layer Tap or Mod Tap's keycode will be ignored. If you need to apply modifiers to your tapped keycode, [Tap Dance](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this.
19 19
20Additionally, if at least one right-handed modifier is specified in a Mod Tap or Layer Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two. 20Additionally, if at least one right-handed modifier is specified in a Mod Tap or Layer Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two.
21 21
diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md
index f2f274944..b5e5218b0 100644
--- a/docs/feature_tap_dance.md
+++ b/docs/feature_tap_dance.md
@@ -314,3 +314,86 @@ qk_tap_dance_action_t tap_dance_actions[] = {
314And then simply use `TD(X_CTL)` anywhere in your keymap. 314And then simply use `TD(X_CTL)` anywhere in your keymap.
315 315
316If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace. 316If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace.
317
318### Example 5: Using tap dance for advanced mod-tap and layer-tap keys
319
320Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`.
321
322Below your layers and custom keycodes, add the following:
323
324```c
325// tapdance keycodes
326enum td_keycodes {
327 ALT_LP // Our example key: `LALT` when held, `(` when tapped. Add additional keycodes for each tapdance.
328};
329
330// define a type containing as many tapdance states as you need
331typedef enum {
332 SINGLE_TAP,
333 SINGLE_HOLD,
334 DOUBLE_SINGLE_TAP
335} td_state_t;
336
337// create a global instance of the tapdance state type
338static td_state_t td_state;
339
340// declare your tapdance functions:
341
342// function to determine the current tapdance state
343int cur_dance (qk_tap_dance_state_t *state);
344
345// `finished` and `reset` functions for each tapdance keycode
346void altlp_finished (qk_tap_dance_state_t *state, void *user_data);
347void altlp_reset (qk_tap_dance_state_t *state, void *user_data);
348```
349
350Below your `LAYOUT`, define each of the tapdance functions:
351
352```c
353// determine the tapdance state to return
354int cur_dance (qk_tap_dance_state_t *state) {
355 if (state->count == 1) {
356 if (state->interrupted || !state->pressed) { return SINGLE_TAP; }
357 else { return SINGLE_HOLD; }
358 }
359 if (state->count == 2) { return DOUBLE_SINGLE_TAP; }
360 else { return 3; } // any number higher than the maximum state value you return above
361}
362
363// handle the possible states for each tapdance keycode you define:
364
365void altlp_finished (qk_tap_dance_state_t *state, void *user_data) {
366 td_state = cur_dance(state);
367 switch (td_state) {
368 case SINGLE_TAP:
369 register_code16(KC_LPRN);
370 break;
371 case SINGLE_HOLD:
372 register_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_on(_MY_LAYER)` here
373 break;
374 case DOUBLE_SINGLE_TAP: // allow nesting of 2 parens `((` within tapping term
375 tap_code16(KC_LPRN);
376 register_code16(KC_LPRN);
377 }
378}
379
380void altlp_reset (qk_tap_dance_state_t *state, void *user_data) {
381 switch (td_state) {
382 case SINGLE_TAP:
383 unregister_code16(KC_LPRN);
384 break;
385 case SINGLE_HOLD:
386 unregister_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_off(_MY_LAYER)` here
387 break;
388 case DOUBLE_SINGLE_TAP:
389 unregister_code16(KC_LPRN);
390 }
391}
392
393// define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions
394qk_tap_dance_action_t tap_dance_actions[] = {
395 [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset)
396};
397```
398
399Wrap each tapdance keycode in `TD()` when including it in your keymap, e.g. `TD(ALT_LP)`.