From 7de28e17eb13f52728e3bebd34fb8b9923ada00d Mon Sep 17 00:00:00 2001 From: urob <978080+urob@users.noreply.github.com> Date: Thu, 14 Jul 2022 23:36:18 -0400 Subject: [PATCH] Update nodefree repo --- zmk-nodefree-config/.gitattributes | 2 - zmk-nodefree-config/README.md | 237 ++++++++++++++++-- zmk-nodefree-config/example.keymap | 29 ++- zmk-nodefree-config/helper.h | 20 +- .../international_chars/greek.dtsi | 1 + 5 files changed, 256 insertions(+), 33 deletions(-) delete mode 100644 zmk-nodefree-config/.gitattributes diff --git a/zmk-nodefree-config/.gitattributes b/zmk-nodefree-config/.gitattributes deleted file mode 100644 index 9b2b33d..0000000 --- a/zmk-nodefree-config/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.dtsi linguist-language=C++ -*.keymap linguist-language=C++ diff --git a/zmk-nodefree-config/README.md b/zmk-nodefree-config/README.md index fd98643..09e4382 100644 --- a/zmk-nodefree-config/README.md +++ b/zmk-nodefree-config/README.md @@ -10,11 +10,21 @@ streamlined syntax. Check out [example.keymap](example.keymap) to see it in acti ## Usage overview -1. Copy the file `helper.h` from this repository into the "config" folder of your - private zmk-config repository +1. Copy this repository into the root folder of your private zmk-config repository. The + folder structure should look as follows: + ``` + zmk-config + ├── config + │ ├── your.keyboard.conf + │ ├── your_keyboard.keymap + │ └── ... + ├── zmk-nodefree-config + │ ├── helper.h + │ ├── ... + ``` 2. Source `helper.h` near the top of your `.keymap` file: ```C++ - #include "helper.h" + #include "../zmk-nodefree-config/helper.h" ``` 3. Customize your keyboard's `.keymap` file. See [example.keymap](example.keymap) or [my personal zmk-config](https://github.com/urob/zmk-config/blob/main/config/base.keymap) @@ -22,19 +32,31 @@ streamlined syntax. Check out [example.keymap](example.keymap) to see it in acti ## Usage details -`helper.h` provides two convenience macros. `ZMK_BEHAVIOR` creates new behaviors, and -`ZMK_LAYER` adds new layers to your keymap. +This repository provides a number of convenience macros: +1. `ZMK_BEHAVIOR` can be used to create new behaviors such as hold-taps, tap-dances or + ZMK macros [\[doc\]](#zmk_behavior) +2. `ZMK_LAYER` adds new layers to your keymap [\[doc\]](#zmk_layer) +3. `ZMK_COMBO` defines new combos [\[doc\]](#zmk_combo) +4. `ZMK_UNICODE_SINGLE` and `ZMK_UNICODE_PAIR` create unicode characters [\[doc\]](#zmk_unicode) +5. `international_chars` define a number of international character definitions such + as ä/Ä or δ/Δ that can be added to the keymap + [\[doc\]](#international-characters) +6. `keypos_def` sets up human-readable key position shortcuts for a number of popular + keyboards that simplify the configuration of combos and positional hold-taps + [\[doc\]](#key-position-shortcuts) ### 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: +`ZMK_BEHAVIOR` can be used to create any of the following ZMK behaviors: caps-word, +hold-tap, key-repeat, macro, mod-morph, sticky-key or tap-dance + +**Syntax:** `ZMK_BEHAVIOR(name, type, specification)` +* `name`: a unique string chosen by the user (e.g., `my_behavior`). The new behavior can + be added to the keymap using `&name` (e.g., `&my_behavior`) +* `type`: the behavior to be 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 + `tap_dance`. Note that two-word types are separated by underscores (`_`). +* `specification`: the custom behavior code. 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. @@ -82,13 +104,14 @@ This creates a "Windows sleep key" that can be added to the keymap-layout using ### 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` +`ZMK_LAYER` adds new keymap layers to the configuration. + +**Syntax:** `ZMK_LAYER(name, layout)` +* `name`: a unique identifier string chosen by the user (usually this isn't referenced elsewhere) +* `layout`: 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 +Multiple layers can be added 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)). @@ -108,3 +131,183 @@ ZMK_KEYMAP(default_layer, ``` +### ZMK\_COMBO + +`ZMK_COMBO` defines new combos. + +**Syntax:** `ZMK_COMBO(name, bindings, keypos, layers)` +* `name`: a unique identifier string chosen by the user (usually this isn't referenced elsewhere) +* `binding`: the binding triggered by the combo (this can be any stock or previously defined behavior) +* `keypos`: a list of 2 or more key positions that trigger the combo (e.g., `12 + 13`). Note that the mapping from key positions to keys depends on your keyboard. To facilitate + the combo set-up and increase portability, this repository provides shortcuts for a number of popular keyboard. + See [below](#key-position-shortcuts) on how to use them. +* `layers`: a list of layers for which the combo is active (e.g., `0` for only the + default layer). If set to `ALL` the combo is active on all layers. + +By default, the timeout for combos created with `ZMK_COMBO` is 30ms. If `COMBO_TERM` is +set prior to calling `ZMK_COMBO`, the value of `COMBO_TERM` is used instead. Note: while +it is possible to set different timeout for different combos, this is known to cause +[issues](https://github.com/zmkfirmware/zmk/issues/905) with overlapping combos and should be avoided. + +#### Example: copy and paste combos + +```C++ +#define COMBO_TERM 50 +ZMK_COMBO(copy, &kp LC(C), 12 13, 0 1) +ZMK_COMBO(paste, &kp LC(V), 13 14, 0 1) +``` +This sets the combo timeout to 50ms, and then creates two combos which both are +active on the first two layers (layers 0 and 1). The first combo is triggered when the +12th and 13th keys are pressed jointly within the `COMBO_TERM`, sending Ctrl + C. The +second combo is triggered when the 13th and 14th keys are pressed jointly, sending +Ctrl + V. + +### ZMK\_UNICODE + +This repository provides two macros that simplify creating new unicode characters that +can be added to keymaps. `ZMK_UNICODE_SINGLE` creates single unicode characters such +as , whereas `ZMK_UNICODE_PAIR` creates pairs of shifted/unshifted unicode +characters that are useful for specifying international characters such as +ä/Ä or δ/Δ. + +Note that the input of unicode characters differs across operation systems. By default, +`ZMK_UNICODE` is configured for Windows (using WinCompose). The easiest way to set up unicode +characters for other operation systems is to set the variable `HOST_OS` **before** +sourcing `helper.h`. For Linux use: +```C++ +#define HOST_OS 1 // set to 1 for Linux +#include helper.h +``` +For macOS use: +```C++ +#define HOST_OS 2 // set to 2 for macOS +#include helper.h +``` +This will send unicode characters using the OS's default input channels. +For non-default input channels or for other operation systems, one can instead set the +variables `OS_UNICODE_LEAD` and `OS_UNICODE_TRAIL` to the character sequences that +initialize/terminate the unicode input. + +**Syntax:** `ZMK_UNICODE_SINGLE(name, L0, L1, L2, L3)` +* `name:` a unique string chosen by the user (e.g., `my_char`). The unicode character can + be added to the keymap using `&name` (e.g., `&my_char`) +* `L0` to `L3`: a 4-digit sequence defining the unicode string using standard [ZMK key + codes](https://zmk.dev/docs/codes/keyboard-keypad) + +**Syntax:** `ZMK_UNICODE_PAIR(name, L0, L1, L2, L3, U0, U1, U2, U3)` +* `name:` a unique string chosen by the user (e.g., `my_char`). The unicode character can + be added to the keymap using `&name` (e.g., `&my_char`) +* `L0` to `L3`: a 4-digit sequence defining the unshifted unicode string +* `U0` to `U3`: a 4-digit sequence defining the shifted unicode string (which is send when + holding Shift while pressing &name) + +Note: 5-digit unicode characters are currently not supported. + +#### Example 1: Euro sign (U+20AC) + +```C++ +ZMK_UNICODE_SINGLE(euro_sign, N2, N0, A, C) +``` +The Euro character can be added to the keymap using `&euro_sign`. + +#### Example 2: German umlauts (ä/Ä, ö/Ö, ü/Ü) + +```C++ +// name unshifted shifted +ZMK_UNICODE_PAIR( ae, N0, N0, E, N4, N0, N0, C, N4 ) +ZMK_UNICODE_PAIR( oe, N0, N0, F, N6, N0, N0, D, N6 ) +ZMK_UNICODE_PAIR( ue, N0, N0, F, C, N0, N0, D, C ) +``` +The "umlaut"-pairs can be added to the keymap using `&ae`, `&oe` and `&ue`. + +#### Dependencies for unicodes + +* `ZMK_UNICODE_PAIR` requires a ZMK version patched with + [PR#1114](https://github.com/zmkfirmware/zmk/pull/1114) (not needed when only using + `ZMK_UNICODE_SINGLE`). If you don't want to maintain + your own ZMK repository, you can use ZMK's [beta + testing](https://zmk.dev/docs/features/beta-testing) feature to configure Github + Actions to build against a patched remote branch of ZMK. To do so, replace the + contents of `west.yml` in your local `zmk-config/config` directory with the following + contents: + ``` + manifest: + remotes: + - name: urob + url-base: https://github.com/urob + projects: + - name: zmk + remote: urob + revision: masked-mods + import: app/west.yml + self: + path: config + ``` +* Depending on the operation system there are addition requirements for unicode input to + work. On Windows, one must install + [WinCompose](https://github.com/samhocevar/wincompose). On macOS one must enable + unicode input in the system preferences. + +### International characters + +This repository includes pre-defined definitions for international characters for a few +languages (currently German and Greek --- contributions are welcome 😀!). These can be +loaded by sourcing the corresponding files. +```C++ +#include "../zmk-nodefree-config/international_chars/greek.dtsi" +#include "../zmk-nodefree-config/international_chars/german.dtsi" +``` +These files make use of unicode in the background, please see the unicode documentation +above for prerequisites. Once sourced Greek and German characters can be added to the +keymap using, e.g., `&alpha`, `&upsilon`, `&tau` or `&omikron` (see the language files for +a complete list of available characters). + +### Key position shortcuts + +Certain configuration options such as combos and positional hold-taps are based on the +physical position of keys on your keyboard. This reduces portability of configuration +files across keyboards with different layouts. + +To increase portability, this repository comes with key position definitions for a +number of popular keyboard layouts (48-key boards such as Planck, 42-key boards such as Corne, +36-key boards and 34-key boards --- new contributions are welcome 😀!). + +These layouts provide a map from the physical key positions to human-readable shortcuts +such as "LT0" and "LT1" for the left-hand's top-row's first and second keys. +In general, all shortcuts are of the following form: +* `L/R` for **L**eft/**R**ight hand +* `T/M/B/H` for **T**op/**M**iddle/**B**ottom and t**H**umb row. +* `0/1/2/3/4` for the finger position starting from the inside (`0` is the inner + index-finger column, `1` is the home position of the index finger, ..., `4` is the home + position of the pinkie) + +For instance, the shortcuts layout for a 36-key board looks as follows: +``` +╭─────────────────────┬─────────────────────╮ +│ LT4 LT3 LT2 LT1 LT0 │ RT0 RT1 RT2 RT3 RT4 │ +│ LM4 LM3 LM2 LM1 LM0 │ RM0 RM1 RM2 RM3 RM4 │ +│ LB4 LB3 LB2 LB1 LB0 │ RB0 RB1 RB2 RB3 RB4 │ +╰───────╮ LH2 LH1 LH0 │ RH0 RH1 RH2 ╭───────╯ + ╰─────────────┴─────────────╯ +``` +Schematics to all of the layout files can be found inside the corresponding definition +files. + +To use these shortcut definitions, source the definition file for your keyboard +into your `.keymap` file. E.g., for a 36-key board, use: +```C++ +#include "../zmk-nodefree-config/keypos_def/keypos_36keys.h" +``` + +#### Example: Defining combos using key position shortcuts + +```C++ +ZMK_COMBO(copy, &kp LC(C), LH1 LM2, 0 1) +ZMK_COMBO(paste, &kp LC(V), LH1 LM1, 0 1) +``` + +This would define "copy"-combo on the home positions of the left thumb + the left middle finger, +and it would defined a "paste"-combo on the home positions of the left thumb + the left +index finger. + diff --git a/zmk-nodefree-config/example.keymap b/zmk-nodefree-config/example.keymap index e02633b..694b406 100644 --- a/zmk-nodefree-config/example.keymap +++ b/zmk-nodefree-config/example.keymap @@ -1,6 +1,9 @@ #include #include -#include "helper.h" + +#include "../zmk-nodefree-config/helper.h" +#include "../zmk-nodefree-config/keypos_def/keypos_36keys.h" +#include "../zmk-nodefree-config/international_chars/german.dtsi" /* layer and key shortcuts */ @@ -10,7 +13,7 @@ #define NAV 1 #define NUM 2 -/* custom keys and macros */ +/* custom behaviors */ // homerow mods ZMK_BEHAVIOR(hrm, hold_tap, @@ -33,13 +36,31 @@ ZMK_BEHAVIOR(bs_del_num, mod_morph, mods = <(MOD_LSFT|MOD_RSFT)>; ) -// windows sleep key +// windows sleep macro ZMK_BEHAVIOR(win_sleep, macro, wait-ms = <100>; tap-ms = <5>; bindings = <&kp LG(X) &kp U &kp S>; ) +/* combos */ + +// use timeout of 40ms (omitting the option yields default of 30ms) +#define COMBO_TERM 40 + +// combo for our custom sleep behavior from above, only active on NAV layer +ZMK_COMBO(combo_sleep, &win_sleep, RT3 RT4, NAV) + +// copy and paste combos, active on all layers +ZMK_COMBO(combo_copy, &kp LC(C), LB2 LB3, ALL) +ZMK_COMBO(combo_paste, &kp LC(V), LB1 LB2, ALL) + +// german umlauts on right thumb + letter, only active on default layer +ZMK_COMBO(combo_ae, &ae, RH1 LM4, DEF) +ZMK_COMBO(combo_oe, &oe, RH1 RM4, DEF) +ZMK_COMBO(combo_ue, &oe, RH1 RT2, DEF) +ZMK_COMBO(combo_eszett, &eszett, RH1 LM2, DEF) + /* keymap */ ZMK_LAYER(default_layer, @@ -62,7 +83,7 @@ ZMK_LAYER(nav_layer, // ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ___ ___ ___ ___ ___ ___ &kp LC(X) &kp LC(INS) &kp LS(INS) ___ // ╰─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ ├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤ - ___ ___ ___ ___ &win_sleep ___ + ___ ___ ___ ___ ___ ___ // ╰─────────────┴──── ────────┴─────────────╯ ╰─────────────┴─────────────┴─────────────╯ ) diff --git a/zmk-nodefree-config/helper.h b/zmk-nodefree-config/helper.h index 7e4d77f..8320f15 100644 --- a/zmk-nodefree-config/helper.h +++ b/zmk-nodefree-config/helper.h @@ -49,7 +49,7 @@ #define COMBO_TERM 30 #endif -#define COMBO(name, combo_bindings, keypos, combo_layers) \ +#define ZMK_COMBO(name, combo_bindings, keypos, combo_layers) \ / { \ combos { \ compatible = "zmk,combos"; \ @@ -64,22 +64,22 @@ /* ZMK_UNICODE */ -#if !defined OS_COMBO_LEAD +#if !defined OS_UNICODE_LEAD #if HOST_OS == 2 - // OSx + #define OS_UNICODE_LEAD ¯o_press &kp LALT // macOS #elif HOST_OS == 1 - // Linux + #define OS_UNICODE_LEAD &kp LS(LC(U)) // Linux #else - #define OS_COMBO_LEAD &kp RALT &kp U // Windows + WinCompose (default) + #define OS_UNICODE_LEAD &kp RALT &kp U // Windows + WinCompose (default) #endif #endif -#if !defined OS_COMBO_TRAIL +#if !defined OS_UNICODE_TRAIL #if HOST_OS == 2 - // OSx + #define OS_UNICODE_TRAIL ¯o_release &kp LALT // macOS #elif HOST_OS == 1 - // Linux + #define OS_UNICODE_TRAIL &kp SPACE // Linux #else - #define OS_COMBO_TRAIL &kp RET // Windows + WinCompose (default) + #define OS_UNICODE_TRAIL &kp RET // Windows + WinCompose (default) #endif #endif @@ -92,7 +92,7 @@ wait-ms = <0>; \ tap-ms = <1>; \ #binding-cells = <0>; \ - bindings = , , ; \ + bindings = , , ; \ }; \ }; \ }; diff --git a/zmk-nodefree-config/international_chars/greek.dtsi b/zmk-nodefree-config/international_chars/greek.dtsi index afcc970..e3bf6f7 100644 --- a/zmk-nodefree-config/international_chars/greek.dtsi +++ b/zmk-nodefree-config/international_chars/greek.dtsi @@ -13,6 +13,7 @@ ZMK_UNICODE_PAIR( lambda, N0, N3, B, B, N0, N3, N9, B) ZMK_UNICODE_PAIR( mu, N0, N3, B, C, N0, N3, N9, C) ZMK_UNICODE_PAIR( nu, N0, N3, B, D, N0, N3, N9, D) ZMK_UNICODE_PAIR( xi, N0, N3, B, E, N0, N3, N9, E) +ZMK_UNICODE_PAIR( omikron, N0, N3, B, F, N0, N3, N9, F) ZMK_UNICODE_PAIR( pi, N0, N3, C, N0, N0, N3, A, N0) ZMK_UNICODE_PAIR( rho, N0, N3, C, N1, N0, N3, A, N1) ZMK_UNICODE_PAIR( sigma, N0, N3, C, N3, N0, N3, A, N3)