Skip to content

Commit

Permalink
Compose Onboard Documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
oberien committed Apr 25, 2020
1 parent 0e69bb2 commit 6276b6d
Show file tree
Hide file tree
Showing 15 changed files with 201 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
* [Dynamic Macros](feature_dynamic_macros.md)
* [Grave Escape](feature_grave_esc.md)
* [Leader Key](feature_leader_key.md)
* [Compose Onboard](feature_compose_onboard.md)
* [Mod-Tap](mod_tap.md)
* [Macros](feature_macros.md)
* [Mouse Keys](feature_mouse_keys.md)
Expand Down
7 changes: 7 additions & 0 deletions docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ If you define these options you will enable the associated feature, which may in
* sets the timer for leader key chords to run on each key press rather than overall
* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
* Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
* `#define COMPOSE_ONBOARD_ABORT KC_COMPOSE_ONBOARD`
* which key to use to abort the current composing sequence (defaults to `KC_COMPOSE_ONBOARD`)
* `#define COMPOSE_ONBOARD_LEN 5`
* how many keys should be recorded at maximum in the composing sequence (defaults to `5`)
* should be equal to the largest configured input sequence in the compose dictionary
* `#define ONESHOT_TIMEOUT 300`
* how long before oneshot times out
* `#define ONESHOT_TAP_TOGGLE 2`
Expand Down Expand Up @@ -361,6 +366,8 @@ Use these to enable or disable building certain features. The more you have enab
* Enable keyboard underlight functionality
* `LEADER_ENABLE`
* Enable leader key chording
* `COMPOSE_ONBOARD_ENABLE`
* Enable composing onboard directly on the keyboard
* `MIDI_ENABLE`
* MIDI controls
* `UNICODE_ENABLE`
Expand Down
1 change: 1 addition & 0 deletions docs/de/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
* [Key Lock](de/feature_key_lock.md)
* [Layouts](de/feature_layouts.md)
* [Leader Key](de/feature_leader_key.md)
* [Compose Onboard](de/feature_compose_onboard.md)
* [LED Matrix](de/feature_led_matrix.md)
* [Macros](de/feature_macros.md)
* [Mouse Keys](de/feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions docs/es/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
* [Key Lock](es/feature_key_lock.md)
* [Layouts](es/feature_layouts.md)
* [Tecla Leader](es/feature_leader_key.md)
* [Compose Onboard](es/feature_compose_onboard.md)
* [Matriz LED](es/feature_led_matrix.md)
* [Macros](es/feature_macros.md)
* [Teclas del ratón](es/feature_mouse_keys.md)
Expand Down
170 changes: 170 additions & 0 deletions docs/feature_compose_onboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Compose Onboard

You may already know the concept of composing from linux, sometimes also called multi key. Composing allows to map a sequence of keystrokes to press different keys, insert a character, or perform any preconfigured action. For example this is often used to write foreign or unicode characters. This features allows you to define such mappings directly on the keyboard. For example, you can create a mapping to write the character `` by tapping `-` followed by `>` after pressing the compose key.

This is similar to how the [Leader Key](feature_leader_key.md) works. However, while the Leader Key is time-based, compose doesn't have any time constraints.

To use this feature, set one of your keys to `KC_COMPOSE_ONBOARD`, which you can then use to start a compose sequence. Also don't forget to enable the compose onboard feature as described in "Adding Compose Onboard Support in the `rules.mk`".

Imagine the example mapping from above (`-` `>```). After pressing `KC_COMPOSE_ONBOARD` any key press will be captured (i.e. not written on the computer). We can now type `-` and `>`, which will result in the character `` being sent to the computer instead. Composing stops by finishing a sequence (e.g. `-` `>`), typing a key for which no further mapping matches (`f`, or `-` `a`), or by pressing the abort key (which defaults to the compose key itself). In those cases no output will be generated.


```c
COMPOSE_ONBOARD_DICTIONARY(
// quantum keyboard
COMPOSE_ONBOARD_MAPPING(
COMPOSE_ONBOARD_INPUT(KC_Q, KC_M, KC_K),
COMPOSE_ONBOARD_ACTION(
KC_Q, KC_U, KC_A, KC_N, KC_T, KC_U, KC_M,
KC_SPC, KC_K, KC_E, KC_Y, KC_B, KC_O, KC_A, KC_R, KC_D
)
)
// →
COMPOSE_ONBOARD_MAPPING(
COMPOSE_ONBOARD_INPUT(KC_MINS, KC_GT),
{
unicode_input_start();
register_hex(0x2192);
unicode_input_finish();
}
)
// shrug
COMPOSE_ONBOARD_MAPPING(
COMPOSE_ONBOARD_INPUT(KC_S, KC_H, KC_R, KC_U, KC_G),
{
unicode_input_start();
register_hex(0xaf);
register_hex(0x5c);
register_hex(0x5f);
register_hex(0x28);
register_hex(0x30c4);
register_hex(0x29);
register_hex(0x5f);
register_hex(0x2f);
register_hex(0xaf);
unicode_input_finish();
}
)
)
```

* `COMPOSE_ONBOARD_DICTIONARY` starts the list of all mappings
* `COMPOSE_ONBOARD_MAPPING` defines a mapping from an input key sequence to an action
* the first argument is the input key sequence
* the second argument is the action
* `COMPOSE_ONBOARD_INPUT` is used to define the key sequence needed to be typed to trigger the action
* `COMPOSE_ONBOARD_ACTION` can be used to define a key sequence to be typed if the input sequence has been typed

The action can also be a code block containing any C code. This can be used like in the above example to write a unicode character, or to run any arbitrary code similar to a predefined macro.

## Adding Compose Onboard Support in the `rules.mk`

To add support for Compose Onboard you simply need to add a single line to your keymap's `rules.mk`:
```make
COMPOSE_ONBOARD_ENABLE = yes
```
## Configuring the Abort Key
The abort key can be used while in the middle of a sequence to abort composing. It defaults to the compose key itself. If you press the compose key to start a compose sequence, but want to abort halfway through, you can press the compose key (i.e. the configured abort key). (Or you could just continue with a key which doesn't have any mapping.)

```c
#define COMPOSE_ONBOARD_ABORT KC_COMPOSE_ONBOARD
```
## Configuring the Maximum Input Length
While performing a compose sequence, the pressed keys are recorded. The maximum number of keys recorded should match the longest input of any compose mapping (but can be larger). By default, the number of recorded keys is configured to be `5`. However, if you want to have an input sequence longer than that, you need to adjust that number.
```c
#define COMPOSE_ONBOARD_LEN 5
```

Notice that compilation will fail with "Number of keys in Compose Onboard input keystroke is too long. Consider increasing COMPOSE_ONBOARD_LEN" if you define an input which is longer than the configured `COMPOSE_ONBOARD_LEN`.

## Customization - Hooks

There are some functions which you can define, which will be called during composing.

* `void compose_onboard_start(void)` is called when the compose key is pressed and can for example be used to light up an LED to indicate that you are within a compose sequence.
* `void compose_onboard_end(void)` is called when composing is done, either by having been aborted or finished successfully. It can for example be used to turn off the composing LED again.

## Customization - Custom Dictionary

The macros used above to define the dictionary define a function, which is called for the mapping procedure. For fine-grained control, you can manually define that function instead of using the macros.

The mapping function has the signature `bool compose_onboard_mapping(uint16_t* sequence, uint8_t len)`. That function is called whenever a new key is pressed, after it has been added to the sequence array.

* `uint16_t* sequence`: a pointer to an array of recorded keys like `KC_MINS`
* `uint8_t len`: current length of that array


To get a feeling for that function, this is an example of the macros and their resulting function definition.

```c
COMPOSE_ONBOARD_DICTIONARY(
// quantum keyboard
COMPOSE_ONBOARD_MAPPING(
COMPOSE_ONBOARD_INPUT(KC_Q, KC_M, KC_K),
COMPOSE_ONBOARD_ACTION(
KC_Q, KC_U, KC_A, KC_N, KC_T, KC_U, KC_M,
KC_SPC, KC_K, KC_E, KC_Y, KC_B, KC_O, KC_A, KC_R, KC_D
)
)
// →
COMPOSE_ONBOARD_MAPPING(
COMPOSE_ONBOARD_INPUT(KC_MINS, KC_GT),
{
unicode_input_start();
register_hex(0x2192);
unicode_input_finish();
}
)
)
```

The above macros get converted to the following code.

```c
bool compose_onboard_mapping(uint16_t* sequence, uint8_t sequence_len) {
bool partial_match = false;
{
uint16_t input[] = {KC_Q, KC_M, KC_K};
_Static_assert((sizeof(input) / sizeof(input[0])) <= COMPOSE_ONBOARD_LEN, "Number of keys in Compose Onboard input keystroke is too long. Consider increasing COMPOSE_ONBOARD_LEN");
uint8_t input_len = (sizeof(input) / sizeof(input[0]));
int res = compose_onboard_compare_input(input, input_len, sequence, sequence_len);
if (res == -1) {
uint16_t actions[] = {
KC_Q, KC_U, KC_A, KC_N, KC_T, KC_U, KC_M,
KC_SPC, KC_K, KC_E, KC_Y, KC_B, KC_O, KC_A, KC_R, KC_D
};
for (int i = 0; i < (sizeof(actions) / sizeof(actions[0])); i++) {
register_code16(actions[i]);
unregister_code16(actions[i]);
}
return false;
}
partial_match |= res;
}
{
uint16_t input[] = {KC_MINS, KC_GT};
_Static_assert((sizeof(input) / sizeof(input[0])) <= 5, "Number of keys in Compose Onboard input keystroke is too long. Consider increasing COMPOSE_ONBOARD_LEN");
uint8_t input_len = (sizeof(input) / sizeof(input[0]));
int res = compose_onboard_compare_input(input, input_len, sequence, sequence_len);
if (res == -1) {
{
unicode_input_start();
register_hex(0x2192);
unicode_input_finish();
}
return false;
}
partial_match |= res;
}
return partial_match;
}
```
That code uses the helper function `int compose_onboard_compare_input(uint16_t* input, uint8_t input_len, uint16_t* seq, uint8_t seq_len)`. That function compares the compose mapping input to the sequence so far. Its return values are counter-intuitive for binary size reasons. It returns -1 on a full match (the input matched completely and the action can be performed), 0 on no match (it's never possible in the current sequence to get this input), and 1 on a partial match (the recorded sequence so far matches the beginning of the mapping input, but the mapping input still has some keys left).
1 change: 1 addition & 0 deletions docs/fr-fr/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
* [Touche à verrou / Lock-key](fr-fr/feature_key_lock.md)
* [Dispositions / layouts](fr-fr/feature_layouts.md)
* [Touche leader](fr-fr/feature_leader_key.md)
* [Compose Onboard](fr-fr/feature_compose_onboard.md)
* [Matrice LED](fr-fr/feature_led_matrix.md)
* [Macros](fr-fr/feature_macros.md)
* [Boutons de souris](fr-fr/feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions docs/he-il/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
* [Key Lock](he-il/feature_key_lock.md)
* [Layouts](he-il/feature_layouts.md)
* [Leader Key](he-il/feature_leader_key.md)
* [Compose Onboard](he-il/feature_compose_onboard.md)
* [LED Matrix](he-il/feature_led_matrix.md)
* [Macros](he-il/feature_macros.md)
* [Mouse Keys](he-il/feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions docs/ja/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
* [動的マクロ](ja/feature_dynamic_macros.md)
* [グレイブ エスケープ](ja/feature_grave_esc.md)
* [リーダーキー](ja/feature_leader_key.md)
* [Compose Onboard](ja/feature_compose_onboard.md)
* [モッドタップ](ja/mod_tap.md)
* [マクロ](ja/feature_macros.md)
* [マウスキー](ja/feature_mouse_keys.md)
Expand Down
8 changes: 8 additions & 0 deletions docs/keycodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,14 @@ See also: [Leader Key](feature_leader_key.md)
|---------|------------------------|
|`KC_LEAD`|Begins a leader sequence|

## Compose Onboard :id=compose-onboard

See also: [Compose Onboard](feature_compose_onboard.md)

|Key |Aliases |Description |
|--------------------|-----------|-----------------------------------------|
|`KC_COMPOSE_ONBOARD`|`KC_COMPOB`|Begins Composing directly on the keyboard|

## Mouse Keys :id=mouse-keys

See also: [Mouse Keys](feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions docs/pt-br/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
* [Key Lock](pt-br/feature_key_lock.md)
* [Layouts](pt-br/feature_layouts.md)
* [Leader Key](pt-br/feature_leader_key.md)
* [Compose Onboard](pt-br/feature_compose_onboard.md)
* [LED Matrix](pt-br/feature_led_matrix.md)
* [Macros](pt-br/feature_macros.md)
* [Mouse Keys](pt-br/feature_mouse_keys.md)
Expand Down
5 changes: 5 additions & 0 deletions docs/reference_glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ A feature that allows you to tap the leader key followed by a sequence of 1, 2,

* [Leader Key Documentation](feature_leader_key.md)

## Compose Onboard
Allows composing directly on the keyboard. After pressing the compose onboard key, the following keystrokes trigger a preconfigured action like pressing other keys, inserting a character, or any other quantum features.

* [Compose Onboard Documentation](feature_compose_onboard.md)

## LED
Light Emitting Diode, the most common device used for indicators on a keyboard.

Expand Down
1 change: 1 addition & 0 deletions docs/ru-ru/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
* [Key Lock](ru-ru/feature_key_lock.md)
* [Layouts](ru-ru/feature_layouts.md)
* [Leader Key](ru-ru/feature_leader_key.md)
* [Compose Onboard](ru-ru/feature_compose_onboard.md)
* [LED Matrix](ru-ru/feature_led_matrix.md)
* [Macros](ru-ru/feature_macros.md)
* [Mouse Keys](ru-ru/feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions docs/understanding_qmk.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ The `process_record()` function itself is deceptively simple, but hidden within
* [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46)
* [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95)
* [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51)
* [`bool process_compose_onboard(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/a0f2e292946c9a5535c70d9f2dfebb3055f1652a/quantum/process_keycode/process_compose_onboard.c#L24)
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
Expand Down
1 change: 1 addition & 0 deletions docs/zh-cn/_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
* [自锁键](zh-cn/feature_key_lock.md)
* [布局](zh-cn/feature_layouts.md)
* [前导键](zh-cn/feature_leader_key.md)
* [Compose Onboard](zh-cn/feature_compose_onboard.md)
* [LED阵列](zh-cn/feature_led_matrix.md)
* [宏指令](zh-cn/feature_macros.md)
* [鼠标键](zh-cn/feature_mouse_keys.md)
Expand Down
1 change: 1 addition & 0 deletions show_options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ OTHER_OPTION_NAMES = \
COMBO_ENABLE \
KEY_LOCK_ENABLE \
LEADER_ENABLE \
COMPOSE_ONBOARD_ENABLE \
PRINTING_ENABLE \
STENO_ENABLE \
TAP_DANCE_ENABLE \
Expand Down

0 comments on commit 6276b6d

Please sign in to comment.