From 10683fe1f812862c4d25b074fed65ec87d254393 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Thu, 6 Aug 2020 15:04:31 -0400 Subject: [PATCH] Docs re-org, start of some keymap docs. --- docs/docs/{ => feature}/displays.md | 1 - docs/docs/{ => feature}/encoders.md | 1 - docs/docs/feature/keymaps.md | 150 +++++++++++++++++++++++++++ docs/docs/{ => feature}/underglow.md | 1 - docs/docs/keymaps.md | 7 -- docs/docusaurus.config.js | 2 +- docs/sidebars.js | 7 +- 7 files changed, 157 insertions(+), 12 deletions(-) rename docs/docs/{ => feature}/displays.md (88%) rename docs/docs/{ => feature}/encoders.md (86%) create mode 100644 docs/docs/feature/keymaps.md rename docs/docs/{ => feature}/underglow.md (82%) delete mode 100644 docs/docs/keymaps.md diff --git a/docs/docs/displays.md b/docs/docs/feature/displays.md similarity index 88% rename from docs/docs/displays.md rename to docs/docs/feature/displays.md index 2339fe2f..2b3d001d 100644 --- a/docs/docs/displays.md +++ b/docs/docs/feature/displays.md @@ -1,5 +1,4 @@ --- -id: displays title: OLED Displays sidebar_label: OLED Displays --- diff --git a/docs/docs/encoders.md b/docs/docs/feature/encoders.md similarity index 86% rename from docs/docs/encoders.md rename to docs/docs/feature/encoders.md index c0ea4b66..16537ad7 100644 --- a/docs/docs/encoders.md +++ b/docs/docs/feature/encoders.md @@ -1,5 +1,4 @@ --- -id: encoders title: Encoders sidebar_label: Encoders --- diff --git a/docs/docs/feature/keymaps.md b/docs/docs/feature/keymaps.md new file mode 100644 index 00000000..3eee1458 --- /dev/null +++ b/docs/docs/feature/keymaps.md @@ -0,0 +1,150 @@ +--- +id: keymaps +title: Keymaps & Behaviors +sidebar_label: Keymaps +--- + +ZMK uses an declarative approach to keymaps, instead of using C code for all keymap configuration. +Right now, ZMK uses the devicetree syntax to declare those keymaps; future work is envisioned for +supporting dynamic loading of declarative keymaps, e.g. over USB Mass Storage or via a custom BLE +service. + +:::note +For advanced users looking to implement custom behaviors for their keymaps, this will be possible +in the future by allowing user configs to add to the CMake application built by Zephyr. +::: + +## Big Picture + +All keyboard definitions (complete boards or shields) include the _default_ keymap for that keyboard, +so ZMK can produce a "stock" firmware for that keyboard without any further modifications. For users +looking to customize their keyboard's behavior, they can copy the stock `.keymap` file into their +user config directory, and customize the keymap to their liking. + +## Behaviors + +ZMK implements the concept of "behaviors", which can be bound to a certain key position, sensor (encoder), +or layer, to perform certain actions when events occur for that binding (e.g. when a certain key position +is pressed or released, or an encoder triggers a rotation event). + +For example, the simplest behavior in ZMK is the "key press" behavior, which responds to key position +(a certain spot on the keyboard), and when that position is pressed, send a keycode to the host, and +when the key position is released, updates the host to notify of the keycode being released. + +For the full set of possible behaviors, start at the [Key Press](/docs/behavior/key-press) behavior. + +## Layers + +Like many mechanical keyboard firmwares, ZMK keymaps are composed of a collection of layers, with a +minimum of at least one layer that is the default, usually near the bottom of the "stack". Each layer +in ZMK contains a set of bindings that bind a certain behavior to a certain key position in that layer. + +In addition to the base default layer (which can be changed), certain bound behaviors may also +enable/disable additional layers "on top" of the default layer. + +**TODO**: A diagram to help visualize layers + +When a key location is pressed/released, the stack of all active layers from "top to bottom" is used, +and the event is sent to the behavior bound at that position in each layer, for it to perform whatever +actions it wants to in reaction to the event. Those behaviors can choose to "handle" the event, and stop +it from being passed to any lower layers, or may choose to "pass it along", and let the next layer +in the stack _also_ get the event. + +## Behavior Bindings + +Binding a behavior at a certain key position may include up to two extra parameters that are used to +alter the behavior when that specific key position is activated/deactived. For example, when binding +the "key press" (`kp`) behavior at a certain key position, you must specific _which_ keycode should +be used for that key position. + +``` +&kp A +``` + +In this case, the `A` is actually a define for the raw HID keycode, to make keymaps easier to read and write. + +For example of a binding that uses two parameters, you can see how "mod-tap" (`mt`) is bound: + +``` +&mt MOD_LSFT D +``` + +Here, the first parameter is the set of modifiers that should be used for the "hold" behavior, and the second +parameter is the keycode that should be sent when triggering the "tap" behavior. + +## Keymap File + +A keymap file is composed of several sections, that together make up a valid devicetree file for describing the keymap and its layers. + +### Includes + +THe devicetree files are actually preprocessed before being finally leveraged by Zephyr. This allows using standard C defines to create meaningful placeholders +for what would otherwise be cryptic integer keycodes, etc. This also allows bringing in _other_ devicetree nodes from separate files. + +The top two lines of most keymaps should include: + +``` +#include +#include +``` + +The first defines the nodes for all the available behaviors in ZMK, which will be referenced in the behavior bindings. This is how bindings like `&kp` can reference the key press behavior defined with an anchor name of `kp`. + +The second include brings in the defines for all the keycodes (e.g. `A`, `NUM_1`, `M_PLAY`) and the modifiers (e.g. `MOD_LSFT`) used for various behavior bindings. + +### Root devicetree Node + +ALl the remaining keymap nodes will be nested inside of the root devicetree node, like so: + +```devicetree +/ { + // Everything else goes here! +}; +``` + +### Layers + +``` + layers { + compatible = "zmk,layers"; + + default: layer_0 { + label = "DEFAULT"; +// --------------------------------------------------------------------------------------------------------------------------------- +// | ESC | Q | W | E | R | T | | Y | U | I | O | P | \ | +// | TAB | A | S | D | F | G | | H | J | K | L | ; | ' | +// | SHIFT | Z | X | C | V | B | L SHIFT | L SHIFT | | L SHIFT | L SHIFT | N | M | , | . | / | CTRL | +// | GUI | DEL | RET | SPACE | ESC | | RET | SPACE | TAB | BSPC | R-ALT | + bindings = < + &kp ESC &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSLH + &kp TAB &kp A &kp S &mt MOD_LCTL D &mt MOD_LSFT F &kp G &kp H &mt MOD_LSFT J &mt MOD_LCTL K &kp L &kp SCLN &kp QUOT + &kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp LSFT &kp LSFT &kp LSFT &kp LSFT &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RCTL + &kp LGUI &kp DEL &kp RET &kp SPC &mo 1 &mo 2 &kp SPC &kp RET &kp BKSP &kp RALT + >; + + sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD &inc_dec_kp PGUP PGDN>; + }; + }; +``` + +### Keymap + +``` + keymap0: keymap { + compatible = "zmk,keymap"; + label ="Default Kyria Keymap"; + layers = <&default>; + }; +``` + +### Chosen Keymap + +``` + chosen { + zmk,keymap = &keymap0; + }; +``` + +### Complete Example + +You can see a complete example if you see the [stock Kyria keymap](https://github.com/zmkfirmware/zmk/blob/main/app/boards/shields/kyria/kyria.keymap). diff --git a/docs/docs/underglow.md b/docs/docs/feature/underglow.md similarity index 82% rename from docs/docs/underglow.md rename to docs/docs/feature/underglow.md index ff1a236b..0bf9a8d9 100644 --- a/docs/docs/underglow.md +++ b/docs/docs/feature/underglow.md @@ -1,5 +1,4 @@ --- -id: underglow title: RGB Underglow --- diff --git a/docs/docs/keymaps.md b/docs/docs/keymaps.md deleted file mode 100644 index d54b1309..00000000 --- a/docs/docs/keymaps.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: keymaps -title: Keymaps & Behaviors -sidebar_label: Keymaps ---- - -Keymaps! diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 2fdb36d3..44acd69c 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -7,7 +7,7 @@ module.exports = { organizationName: "zmkfirmware", // Usually your GitHub org/user name. projectName: "zmk", // Usually your repo name. themeConfig: { - sidebarCollapsible: false, + // sidebarCollapsible: false, navbar: { title: "ZMK Firmware", logo: { diff --git a/docs/sidebars.js b/docs/sidebars.js index b270a68e..f6256725 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1,7 +1,12 @@ module.exports = { someSidebar: { "Getting Started": ["intro", "hardware", "user-setup", "faq"], - Features: ["keymaps", "displays", "encoders", "underglow"], + Features: [ + "feature/keymaps", + "feature/displays", + "feature/encoders", + "feature/underglow", + ], Behaviors: ["behavior/key-press"], Development: [ "dev-clean-room",