This is a collection of helper macros (formerly zmk-nodefree-config
), simplifying the
configuration of ZMK keymaps. The migration guide has instructions on how
to migrate from v1. Version 1 continuous to be available
here.
To use the helpers, it is recommended to add them as a module to your config/west.yml
by adding a
new entry to remotes
and projects
:
manifest:
remotes:
- name: zmkfirmware
url-base: https://github.com/zmkfirmware
- name: urob
url-base: https://github.com/urob
projects:
- name: zmk
remote: zmkfirmware
revision: main
import: app/west.yml
- name: zmk-helpers
remote: urob
revision: main
self:
path: config
If you are building locally, see the instructions for building with external modules in ZMK docs.
Manual installation
Alternatively, copy include/zmk-helpers
into your config/
directory:
zmk-config
├── config
│ ├── corne.keymap
│ ├── zmk-helpers
│ │ ├── helper.h
│ │ └── ...
│ └── ...
└── ...
Instead of copying, one could also add a git-submodule
1:
cd /path/to/zmk-config/
git submodule add -b v2 -- https://github.com/urob/zmk-helpers config/zmk-helpers-repo
ln -s zmk-helpers-repo/include/zmk-helpers config/zmk-helpers
Source helper.h
near the top of your .keymap
file. Optionally, source key-labels
and
unicode-chars
as needed:
#include "zmk-helpers/helper.h"
// Source desired key-position labels
#include "zmk-helpers/key-labels/glove80.h"
// Source unicode-chars for desired languages
#include "zmk-helpers/unicode-chars/german.dtsi"
The following subsections describe the available helpers. See the example configuration or my personal zmk-config for a demonstration.
The helper.h
header provides a number of convenience macros for defining behaviors, combos,
layers, etc.
Macro | Purpose |
---|---|
ZMK_BEHAVIOR |
Create a new behavior instance (generic form) |
ZMK_APPLY_MATRIX_TRANSFORM |
Apply a matrix_transform |
ZMK_COMBO |
Create a combo |
ZMK_CONDITIONAl_LAYER |
Create a tri-layer condition |
ZMK_LAYER |
Create a layer and add it to the keymap |
ZMK_LEADER_SEQUENCE |
Create a leader key sequence |
ZMK_UNICODE_SINGLE |
Create a unicode-char |
ZMK_UNICODE_PAIR |
Create a pair of lowercase/uppercase unicode-chars |
In addition to the generic ZMK_BEHAVIOR
macro, version 2 also provides the following explicit
variants.
Macro | Purpose |
---|---|
ZMK_AUTO_LAYER |
Create a new auto-layer behavior instance |
ZMK_CAPS_WORD |
Create a new caps-word behavior instance |
ZMK_HOLD_TAP |
Create a new hold-tap behavior instance |
ZMK_KEY_REPEAT |
Create a new key-repeat behavior instance |
ZMK_MACRO |
Create a new key-macro behavior instance |
ZMK_MACRO_ONE_PARAM |
Create a new macro-one-param behavior instance |
ZMK_MACRO_TWO_PARAM |
Create a new macro-two-param behavior instance |
ZMK_MOD_MORPH |
Create a new mod-morph behavior instance |
ZMK_STICKY_KEY |
Create a new sticky-key behavior instance |
ZMK_TAP_DANCE |
Create a new tap-dance behavior instance |
ZMK_TRI_STATE |
Create a new tri-state behavior instance (requires #1366) |
The explicit behavior helpers are inspired by the native ZMK implementation of ZMK_MACRO
. They
differ in that they automatically create all Devicetree nodes as needed. So instead of calling them
from inside the Devicetree, they should be placed outside the root node.
Note
By default, sourcing helper.h
will replace the native implementation of ZMK_MACRO
. To work
reliably, helper.h
should be included after behaviors.dtsi
. To keep the native
implementation of ZMK_MACRO
, set #define ZMK_HELPER_KEEP_NATIVE 1
before including helper.h
.
These layout headers define easy to remember "key-labels" for many popular keyboards, which can be used instead of numeric key-positions to configure position-based properties (e.g., in combos).
Key-labels are standardized to make keymaps portable across keyboards. For instance, the labels for the 60-key Sofle nest the labels for the 34-key Sweep as follows:
The following layouts are currently implemented.
Header | # of Keys | Examples |
---|---|---|
34.h |
34 | Ferris, Hypergolic, Sweep |
36.h |
36 | Corne (5 cols), Corne-ish Zen (5 cols) |
42.h |
42 | Corne, Corne-ish Zen |
4x12.h , 4x12_wide.h |
48 | Planck |
5x6.h |
60 | Caldera |
adv360_custom.h |
76 | Advantage360 Pro (custom matrix transform) |
glove80.h |
80 | Glove80 |
hillside_*.h |
46, 48, 52 or 56 | Hillside family |
jian.h |
44 | Jian, Jorne |
kyria.h |
50 | Kyria |
lily58.h |
58 | Lily58 |
osprette.h |
34 | Osprette |
sofle.h |
60 | Sofle |
totem.h |
38 | Totem |
This collection defines unicode behaviors for all relevant characters in a given language. For
instance, sourcing the German language file, one can add &de_ae
to the keymap, which will send
ä/Ä when pressed or shifted.
See the unicode-chars directory for a list of all currently available languages. To use these language files, follow the instructions for your OS below.
Windows
On your computer, install WinCompose. In your keymap,
source helper.h
and the desired language files. For example:
#include "zmk-helpers/helper.h"
#include "zmk-helpers/unicode-chars/german.dtsi"
Linux
In your keymap, set HOST_OS
to 1
, then source helper.h
and the desired language files.
For example:
#define HOST_OS 1
#include "zmk-helpers/helper.h"
#include "zmk-helpers/unicode-chars/german.dtsi"
macOS
On your computer, enable unicode input in the system preferences by selecting Unicode Hex Input
as
input source. In your keymap, set HOST_OS
to 2
, then source helper.h
and the desired
language files. For example:
#define HOST_OS 2
#include "zmk-helpers/helper.h"
#include "zmk-helpers/unicode-chars/german.dtsi"
Note
Unicodes allow typing international characters without changing the OS keyboard layout. See zmk-locale-generator for a collection of headers that configure ZMK to work with non-US layouts set in the OS.
Contributions of any form are very welcome! New key-labels
and unicode-chars
should follow these
guidelines:
- Key-position labels should stick to the label conventions whenever applicable.
- Language headers should namespace all characters using two-letter ISO language codes.
Footnotes
-
To enable the submodule when building with Github Actions, replace
zmk-config/.github/workflows/build.yml
with
↩on: [push, pull_request, workflow_dispatch] jobs: build: uses: urob/zmk/.github/workflows/build-user-config.yml@build-with-submodules