diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 32e3c7eca..56a646391 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -48,6 +48,7 @@ * [Backlight](feature_backlight.md) * [Bluetooth](feature_bluetooth.md) * [Bootmagic](feature_bootmagic.md) + * [Combos](feature_combo) * [Command](feature_command.md) * [Dynamic Macros](feature_dynamic_macros.md) * [Grave Escape](feature_grave_esc.md) diff --git a/docs/_summary.md b/docs/_summary.md index 973428c9e..11aeb7cd3 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -47,6 +47,7 @@ * [Backlight](feature_backlight.md) * [Bluetooth](feature_bluetooth.md) * [Bootmagic](feature_bootmagic.md) + * [Combos](feature_combo) * [Command](feature_command.md) * [Dynamic Macros](feature_dynamic_macros.md) * [Grave Escape](feature_grave_esc.md) diff --git a/docs/config_options.md b/docs/config_options.md index 4678a7146..19861c9d2 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -155,6 +155,10 @@ If you define these options you will enable the associated feature, which may in going to produce the 500 keystrokes a second needed to actually get more than a few ms of delay from this. But if you're doing chording on something with 3-4ms scan times? You probably want this. +* `#define COMBO_COUNT 2` + * Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature. +* `#define COMBO_TERM 200` + * how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined. ## RGB Light Configuration @@ -234,6 +238,8 @@ Use these to enable or disable building certain features. The more you have enab * Console for debug(+400) * `COMMAND_ENABLE` * Commands for debug and configuration +* `COMBO_ENABLE` + * Key combo feature * `NKRO_ENABLE` * USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work * `AUDIO_ENABLE` diff --git a/docs/feature_combo.md b/docs/feature_combo.md new file mode 100644 index 000000000..f509e9f33 --- /dev/null +++ b/docs/feature_combo.md @@ -0,0 +1,88 @@ +# Combos + +The Combo feature is a chording type solution for adding custom actions. It lets you hit multiple keys at once and produce a different effect. For instance, hitting `A` and `S` within the tapping term would hit `ESC` instead, or have it perform even more complex tasks. + +To enable this feature, yu need to add `COMBO_ENABLE = yes` to your `rules.mk`. + +Additionally, in your `config.h`, you'll need to specify the number of combos that you'll be using, by adding `#define COMBO_COUNT 1` (replacing 1 with the number that you're using). + + +Also, by default, the tapping term for the Combos is set to the same value as `TAPPING_TERM` (200 by default on most boards). But you can specify a different value by defining it in your `config.h`. For instance: `#define COMBO_TERM 300` would set the time out period for combos to 300ms. + +Then, your `keymap.c` file, you'll need to define a sequence of keys, terminated with `COMBO_END`, and a structure to list the combination of keys, and it's resulting action. + +```c +const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END}; +combo_t key_combos[COMBO_COUNT] = {COMBO(test_combo, KC_ESC)}; +``` + +This will send "Escape" if you hit the A and B keys. + +!> This method only supports [basic keycodes](keycodes_basic.md). See the examples for more control. + +## Examples + +If you want to add a list, then you'd use something like this: + +```c +enum combos { + AB_ESC, + JK_TAB +} +const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; +const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [AB_ESC] = COMBO(ab_combo, KC_ESC), + [JK_TAB] = COMBO(jk_combo, KC_TAB) +}; +``` + +For a more complicated implementation, you can use the `process_combo_event` function to add custom handling. + +```c +enum combo_events { + ZC_COPY, + ZV_PASTE + }; + +const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END}; +const uint16_t PROGMEM paste_combo[] = {KC_Z, KC_V, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [ZC_COPY] = COMBO_ACTION(copy_combo), + [ZV_PASTE] = COMBO_ACTION(paste_combo), +}; + +void process_combo_event(uint8_t combo_index, bool pressed) { + switch(combo_index) { + case ZC_COPY: + if (pressed) { + register_code(KC_LCTL); + register_code(KC_C); + unregister_code(KC_C); + unregister_code(KC_LCTL); + } + break; + + case ZV_PASTE: + if (pressed) { + register_code(KC_LCTL); + register_code(KC_V); + unregister_code(KC_V); + unregister_code(KC_LCTL); + } + break; + } +} +``` + +This will send Ctrl+C if you hit Z and C, and Ctrl+V if you hit Z and V. But you could change this to do stuff like change layers, play sounds, or change settings. + +## Additional Configuration + +If you're using long combos, or even longer combos, you may run into issues with this, as the structure may not be large enough to accommodate what you're doing. + +In this case, you can add either `#define EXTRA_LONG_COMBOS` or `#define EXTRA_EXTRA_LONG_COMBOS` in your `config.h` file. + +You may also be able to enable action keys by defining `COMBO_ALLOW_ACTION_KEYS`.