Squashed helper-macro branch

commit 62e33866ccc009c645adda95297e147a6bb1b5d4
Author: urob <978080+urob@users.noreply.github.com>
Date:   Wed Jul 13 16:00:08 2022 -0400

    Move helper.dtsi to subtree

commit 635cffa0c1c0a87dadd929701225d30c119a1a9f
Merge: d8dfef3 41c9041
Author: urob <978080+urob@users.noreply.github.com>
Date:   Wed Jul 13 16:56:44 2022 -0400

    Merge commit '41c9041ccc102d7acbc4882434fa5780050a9455' as 'zmk-nodefree-config'

commit 41c9041ccc102d7acbc4882434fa5780050a9455
Author: urob <978080+urob@users.noreply.github.com>
Date:   Wed Jul 13 16:56:44 2022 -0400

    Squashed 'zmk-nodefree-config/' content from commit c7dc05e

    git-subtree-dir: zmk-nodefree-config
    git-subtree-split: c7dc05eb52b14b69ea48059ff418edad6484500e

commit d8dfef3849436176bba1ff3da25ae59d1fa92abe
Author: urob <978080+urob@users.noreply.github.com>
Date:   Mon Jul 11 23:15:51 2022 -0400

    Convenience macros for a cleaner keymap config
This commit is contained in:
urob 2022-07-13 17:14:36 -04:00
parent 308fcb8401
commit 17737c8672
5 changed files with 290 additions and 106 deletions

2
zmk-nodefree-config/.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
*.dtsi linguist-language=C++
*.keymap linguist-language=C++

View file

@ -0,0 +1,111 @@
# zmk-nodefree-config
ZMK lets user customize their keyboard layout by providing a Devicetree file
(`.keymap`). The specific syntax requirements of the Devicetree file format can,
however, make this process a bit daunting for new users.
This repository provides simple convenience macros that simplify the configuration for
many common use cases. It results in a "node-free" user configuration with a more
streamlined syntax. Check out [example.keymap](example.keymap) to see it in action.
## Usage overview
1. Copy the file `helper.dtsi` from this repository into the "config" folder of your
private zmk-config repository
2. Source `helper.dtsi` near the top of your `.keymap` file:
```C++
#include <behaviors.dtsi>
#include <dt-bindings/zmk/keys.h>
#include "helper.dtsi"
```
3. Customize your keyboard's `.keymap` file. See [example.keymap](example.keymap) for a
complete example and read the documentation below for details.
## Usage details
`helper.dtsi` provides two convenience macros. `ZMK_BEHAVIOR` creates new behaviors, and
`ZMK_LAYER` adds new layers to your keymap.
### ZMK\_BEHAVIOR
The macro is invoked by calling `ZMK_BEHAVIOR(name, type, specification)`, expecting
3 arguments:
* `name` is a unique string chosen by the user (e.g., `my_behavior`). It can later be
used to reference the new behavior by preceding it by "&" (e.g., `&my_behavior`)
* `type` selects the behavior that is created. It must be one of the following:
`caps_word`, `hold_tap`, `key_repeat`, `macro`, `mod_morph`, `sticky_key` or
`tap_dance`. Note that two-word types use underscores ("\_") to separate words.
* `specification` contains the code customizing the new behavior. It should contain the
body of the corresponding [ZMK behavior configuration](https://zmk.dev/docs/config/behaviors)
without the `label`, `#binding-cells` and `compatible` properties and without the
surrounding node-specification.
#### Example 1: Creating a custom "homerow mod" tap-hold behavior
```C++
ZMK_BEHAVIOR(hrm, hold_tap,
flavor = "balanced";
tapping-term-ms = <280>;
quick-tap-ms = <125>;
global-quick-tap;
bindings = <&kp>, <&kp>;
)
```
The new behavior can be added to the keymap-layout using `&hrm` (e.g., `&hrm LSHIFT T`
creates a key that yields `T` on tap and `LSHIFT` on hold, using the custom
configuration above).
#### Example 2: Creating a custom tap-dance key
```C++
ZMK_BEHAVIOR(ss_cw, tap_dance,
tapping-term-ms = <200>;
bindings = <&sk LSHFT>, <&caps_word>;
)
```
The new behavior can be added to the keymap-layout using `&ss_cw`. The key yields
sticky-shift on tap and caps-word on double tap;
#### Example 3: Creating a custom "win-sleep" macro
```C++
ZMK_BEHAVIOR(win_sleep, macro,
wait-ms = <100>;
tap-ms = <5>;
bindings = <&kp LG(X) &kp U &kp S>;
)
```
This creates a "Windows sleep key" that can be added to the keymap-layout using
`&win_sleep`.
### ZMK\_LAYER
The function is invoked by calling `ZMK_LAYER(name, layout)`, expecting
2 arguments:
* `name` is a unique identifier string chosen by the user (it isn't used elsewhere)
* `layout` provides the layout specification using the same syntax as the `bindings`
property of the [ZMK keymap configuration](https://zmk.dev/docs/config/keymap)
Multiple layers can be defined with repeated calls of `ZMK_LAYER`. They will be ordered
in the same order in which they are created, with the first-specified layer being
the "lowest" one ([see here for details](https://zmk.dev/docs/features/keymaps#layers)).
#### Example usage
```C++
ZMK_KEYMAP(default_layer,
// ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮ ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮
&kp Q &kp W &kp F &kp P &kp B &kp J &kp L &kp U &kp Y &kp SQT
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&hrm LGUI A &hrm LALT R &hrm LCTRL S &hrm LSHFT T &kp G &kp M &hrm RSHFT N &hrm LCTRL E &hrm LALT I &hrm LGUI O
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp Z &kp X &kp C &kp D &kp V &kp K &kp H &kp COMMA &kp DOT &kp SEMI
// ╰─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp ESC &lt NAV SPACE &kp TAB &kp RET &ss_cw &bs_del_num
// ╰─────────────┴──── ────────┴─────────────╯ ╰─────────────┴─────────────┴─────────────╯
)
```

View file

@ -0,0 +1,80 @@
#include <behaviors.dtsi>
#include <dt-bindings/zmk/keys.h>
#include "helper.dtsi"
/* layer and key shortcuts */
#define ___ &trans
#define DEF 0
#define NAV 1
#define NUM 2
/* custom keys and macros */
// homerow mods
ZMK_BEHAVIOR(hrm, hold_tap,
flavor = "balanced";
tapping-term-ms = <280>;
quick-tap-ms = <125>;
global-quick-tap;
bindings = <&kp>, <&kp>;
)
// tap: sticky shift | double tap: capsword
ZMK_BEHAVIOR(ss_cw, tap_dance,
tapping-term-ms = <200>;
bindings = <&sk LSHFT>, <&caps_word>;
)
// tap: backspace | shift + tap: delete | hold: num layer
ZMK_BEHAVIOR(bs_del_num, mod_morph,
bindings = <&lt NUM BSPC>, <&kp DEL>;
mods = <(MOD_LSFT|MOD_RSFT)>;
)
// windows sleep key
ZMK_BEHAVIOR(win_sleep, macro,
wait-ms = <100>;
tap-ms = <5>;
bindings = <&kp LG(X) &kp U &kp S>;
)
/* keymap */
ZMK_LAYER(default_layer,
// ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮ ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮
&kp Q &kp W &kp F &kp P &kp B &kp J &kp L &kp U &kp Y &kp SQT
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&hrm LGUI A &hrm LALT R &hrm LCTRL S &hrm LSHFT T &kp G &kp M &hrm RSHFT N &hrm LCTRL E &hrm LALT I &hrm LGUI O
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp Z &kp X &kp C &kp D &kp V &kp K &kp H &kp COMMA &kp DOT &kp SEMI
// ╰─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp ESC &lt NAV SPACE &kp TAB &kp RET &ss_cw &bs_del_num
// ╰─────────────┴──── ────────┴─────────────╯ ╰─────────────┴─────────────┴─────────────╯
)
ZMK_LAYER(nav_layer,
// ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮ ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮
___ ___ ___ ___ ___ &kp PG_UP &kp HOME &kp UP &kp END &kp INS
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&sk LGUI &sk LALT &sk LCTRL &sk LSHFT ___ &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
___ ___ ___ ___ ___ ___ &kp LC(X) &kp LC(INS) &kp LS(INS) ___
// ╰─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
___ ___ ___ ___ &win_sleep ___
// ╰─────────────┴──── ────────┴─────────────╯ ╰─────────────┴─────────────┴─────────────╯
)
ZMK_LAYER(num_layer,
// ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮ ╭─────────────┬─────────────┬─────────────┬─────────────┬─────────────╮
&kp ESC &kp N7 &kp N8 &kp N9 &kp STAR ___ ___ ___ ___ ___
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp TAB &kp N4 &kp N5 &kp N6 &kp PLUS ___ &sk RSHFT &sk LCTRL &sk LALT &sk LGUI
// ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp RET &kp N1 &kp N2 &kp N3 &kp FSLH ___ ___ ___ ___ ___
// ╰─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
&kp DOT &kp N0 &kp MINUS ___ ___ ___
// ╰─────────────┴──── ────────┴─────────────╯ ╰─────────────┴─────────────┴─────────────╯
)

View file

@ -0,0 +1,32 @@
/* helper.dtsi: convenience macros simplifying ZMK's keymap configuration */
#define ZMK_HELPER_CORE_caps_word compatible = "zmk,behavior-caps-word"; #binding-cells = <0>
#define ZMK_HELPER_CORE_hold_tap compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>
#define ZMK_HELPER_CORE_key_repeat compatible = "zmk,behavior-key-repeat"; #binding-cells = <0>
#define ZMK_HELPER_CORE_macro compatible = "zmk,behavior-macro"; #binding-cells = <0>
#define ZMK_HELPER_CORE_mod_morph compatible = "zmk,behavior-mod-morph"; #binding-cells = <0>
#define ZMK_HELPER_CORE_sticky_key compatible = "zmk,behavior-sticky-key"; #binding-cells = <1>
#define ZMK_HELPER_CORE_tap_dance compatible = "zmk,behavior-tap-dance"; #binding-cells = <0>
#define ZMK_BEHAVIOR_STRINGIFY(x) #x
#define ZMK_BEHAVIOR(name, type, ...) \
/ { \
behaviors { \
name: name { \
label = ZMK_BEHAVIOR_STRINGIFY(ZB_ ## name); \
ZMK_HELPER_CORE_ ## type; \
__VA_ARGS__ \
}; \
}; \
};
#define ZMK_LAYER(name, layout) \
/ { \
keymap { \
compatible = "zmk,keymap"; \
name { \
bindings = <layout>; \
}; \
}; \
};