https://github.com/urob/zmk-leader-key
A ZMK module adding a leader-key behavior
https://github.com/urob/zmk-leader-key
zmk zmk-module
Last synced: 8 months ago
JSON representation
A ZMK module adding a leader-key behavior
- Host: GitHub
- URL: https://github.com/urob/zmk-leader-key
- Owner: urob
- License: mit
- Created: 2024-11-25T04:44:41.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-01T20:17:09.000Z (over 1 year ago)
- Last Synced: 2025-03-01T21:23:08.384Z (over 1 year ago)
- Topics: zmk, zmk-module
- Language: C
- Homepage:
- Size: 43 KB
- Stars: 22
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-zmk - urob/zmk-leader-key - A ZMK module adding a leader-key behavior. (Community firmware Modules and Behaviors / Custom Behaviors)
- awesome-zmk - urob/zmk-leader-key - A ZMK module adding a leader-key behavior. (Behaviors)
README
# ZMK-LEADER-KEY
This module adds a `leader-key` behavior to ZMK. It is a reimplementation of
Nick Conway's [PR #1380](https://github.com/zmkfirmware/zmk/pull/1380). The most
important differences are:
- Works as a module without the need to patch ZMK.
- Sequences are `keycode`-based instead of `position`-based.
- Multiple leader-key instances with distinct sets of sequences are supported.
- Key codes that terminate the behavior are bubbled to other behaviors.
- Sequences inherit locality from the leader key (useful for `&sys_reset` and
`&bootloader`).
- Strictly nested sequences are considered bad form and aren't supported.
- The `timeout`, `immediate-trigger` and `layers` properties are removed as
their primary intend is to support nested sequences and to work around the
single-instance restriction of the original PR.
A one-for-one port of the original PR version as a ZMK module is available in
the [`legacy`](https://github.com/urob/zmk-leader-key/tree/legacy) branch.
## Usage
To load the module, add the following entries to `remotes` and `projects` in
`config/west.yml`.
```yaml
manifest:
remotes:
- name: zmkfirmware
url-base: https://github.com/zmkfirmware
- name: urob
url-base: https://github.com/urob
projects:
- name: zmk
remote: zmkfirmware
revision: v0.3
import: app/west.yml
- name: zmk-leader-key
remote: urob
revision: v0.3 # set to same as ZMK version above
self:
path: config
```
Note: This module uses a version scheme that is synchronized with upstream ZMK.
To ensure compatibility, I highly recommend setting the revision of this module
to the same as ZMK's.
## Configuration
### Leader sequences
Leader sequences are defined as child nodes of a leader-key instance. Each
sequence takes two arguments `sequence` and `bindings`. Example:
```c
/ {
behaviors {
leader1: leader1 {
compatible = "zmk,behavior-leader-key";
#binding-cells = <0>;
usb { sequence = ; bindings = <&out OUT_USB>; };
ble { sequence = ; bindings = <&out OUT_BLE>; };
bt0 { sequence = ; bindings = <&bt BT_SEL 0>; };
bt1 { sequence = ; bindings = <&bt BT_SEL 1>; };
bt2 { sequence = ; bindings = <&bt BT_SEL 2>; };
btc { sequence = ; bindings = <&bt BT_CLR>; };
boot { sequence = ; bindings = <&bootloader>; };
reset { sequence = ; bindings = <&sys_reset>; };
};
leader2: leader2 {
compatible = "zmk,behavior-leader-key";
#binding-cells = <0>;
de_ae { sequence = ; bindings = <&de_ae>; };
de_oe { sequence = ; bindings = <&de_oe>; };
de_ue { sequence = ; bindings = <&de_ue>; };
};
};
};
```
This sets up two leader key instances, `leader1` and `leader2`. The first one
has various system related sequences, the second one is for German umlauts (the
`&de_*` bindings must be defined elsewhere).
**Note:** By default, modifiers in sequences are treated as a lower bound. For
example, holding `LSHFT` will trigger sequence `LS(A) LS(B)` as well as sequence
`A B`, whereas not holding any modifier will only trigger `A B`. This is so that
case-sensitive behavior bindings work as expected.
**Locality:** Sequence bindings inherit their locality from the position of the
leader key. For example, on split keyboards, the `BOOT` and `RESET` sequences in
the example above will invoke the bootloader on the side on which `&leader1` is
bound. Tip: Add `&leader1` to both sides to be able to reset either side.
### Behavior properties
**`ignore-keys`** (optional): If set to a list of key codes, these keys are
ignored when evaluating sequences. For instance, if
`ignore-keys = `, "shift" is passed through without triggering or
terminating sequences.
### `Kconfig` options
- `CONFIG_ZMK_LEADER_MAX_KEYS_PER_SEQUENCE`: Maximum number of keys in a
sequence. Default is 5.
- `CONFIG_ZMK_LEADER_MAX_SEQUENCES`: Maximum number of sequences per leader key
instance. Default is 32.
## References
- The [legacy](https://github.com/urob/zmk-leader-key/tree/legacy) branch ports
Nick Conway's PR [#1380](https://github.com/zmkfirmware/zmk/pull/1380) as a
ZMK module.
- My personal [zmk-config](https://github.com/urob/zmk-config) contains advanced
usage examples.