### West Manifest Integration for ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Example west manifest configuration for adding the zmk-adaptive-key module to a ZMK firmware project. Includes remote definitions and build commands. ```yaml # config/west.yml 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-adaptive-key remote: urob revision: main # Use matching version with your ZMK self: path: config # Build commands after adding module: # west update # west build -b your_board -- -DZMK_CONFIG="$(pwd)/config" ``` -------------------------------- ### Multi-Key Macro Sequences in ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Shows how to create automatic multi-key sequences triggered by specific key combinations. Includes examples for email and URL triggers with configurable timing. ```c / { behaviors { macro_adaptive: macro_adaptive { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&none>; // Default: do nothing email_trigger { trigger-keys = ; bindings = < &kp A &kp I &kp L // M + key → outputs "AIL" quickly >; }; url_trigger { trigger-keys = ; bindings = < &kp W &kp W &kp W &kp DOT // W + key → outputs "WWW." >; }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = < &kp M &kp W ¯o_adaptive >; }; }; }; // Usage: // Type 'M', then press macro_adaptive → outputs "AIL" (each key tapped for 5ms with 5ms wait) // Type 'W', then press macro_adaptive → outputs "WWW." // Default tap/wait timing: CONFIG_ZMK_ADAPTIVE_KEY_TAP_MS=5, CONFIG_ZMK_ADAPTIVE_KEY_WAIT_MS=5 ``` -------------------------------- ### Hands Down Layout Integration (C) Source: https://context7.com/urob/zmk-adaptive-key/llms.txt An example demonstrating adaptive key behavior for the Hands Down keyboard layout, specifically digraph replacement. This demonstrates how to configure triggers and bindings for context-aware typing. ```c / { behaviors { ak_h: ak_h { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp H>; \t// Default: outputs H akt_ah { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp U>; \t// AH → U (typed quickly) }; akt_uh { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp A>; \t// UH → A }; akt_eh { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp O>; \t// EH → O }; }; ak_g: ak_g { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp G>; akt_jg { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp P &kp G>; \t// JG → JPG (outputs P, G as macro) }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = <\n &kp A &kp E &kp J &ak_h &ak_g\n >; }; }; }; ``` -------------------------------- ### Sticky Key Integration in ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Demonstrates how to combine adaptive keys with sticky modifiers for modifier-aware behaviors. The example shows default bindings and trigger conditions based on previous key presses. ```c / { behaviors { adaptive_key: adaptive_key { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp SPACE>; // Default: space trigger_one { trigger-keys = ; // After 0: output A bindings = <&kp A>; }; trigger_two { trigger-keys = ; // After backspace: output B bindings = <&kp B>; strict-modifiers; // Only trigger without modifiers }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = < &kp N0 &kp BSPC &sk LSHFT &adaptive_key // Sticky shift + adaptive key >; }; }; }; // Usage: // Press 0, then adaptive_key → outputs A (or Shift+A if sticky shift active) // Press sticky shift, then BSPC, then adaptive_key → outputs Space (strict-modifiers prevents trigger) // Press BSPC (without shift), then adaptive_key → outputs B ``` -------------------------------- ### Loading ZMK Adaptive Key Module with west.yml (YAML) Source: https://github.com/urob/zmk-adaptive-key/blob/main/README.md This YAML snippet configures the west.yml file to include the ZMK-ADAPTIVE-KEY module as a remote project in ZMK firmware builds. It requires ZMK version v0.3 and matches the module revision accordingly. The purpose is to enable module loading via remotes and projects; no inputs or outputs beyond project setup, with limitation to compatible ZMK versions. ```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-adaptive-key remote: urob revision: v0.3 # set to same as ZMK version above self: path: config ``` -------------------------------- ### Build-Time Configuration for Adaptive Keys Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Kconfig settings for configuring adaptive key behavior limits and timing at build time. Includes maximum trigger conditions, macro sequence limits, and timing parameters. ```kconfig # In your board config file (e.g., my_keyboard.conf) # Maximum number of trigger conditions per adaptive-key instance CONFIG_ZMK_ADAPTIVE_KEY_MAX_TRIGGER_CONDITIONS=64 # Maximum number of behaviors in a macro sequence CONFIG_ZMK_ADAPTIVE_KEY_MAX_BINDINGS=8 # Wait time between key presses in macro sequences (milliseconds) CONFIG_ZMK_ADAPTIVE_KEY_WAIT_MS=10 # Hold time per key tap in macro sequences (milliseconds) CONFIG_ZMK_ADAPTIVE_KEY_TAP_MS=10 # Enable adaptive key behavior (auto-enabled when used in device tree) CONFIG_ZMK_BEHAVIOR_ADAPTIVE_KEY=y ``` -------------------------------- ### Configure Timing-Based Trigger Conditions in ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Demonstrates how to implement adaptive key behaviors with precise timing control using min-prior-idle-ms and max-prior-idle-ms properties. Allows different behaviors based on how long the user waits between key presses. Requires ZMK firmware with adaptive key support. ```C / { behaviors { timed_adaptive: timed_adaptive { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp X>; // Default output quick_combo { trigger-keys = ; bindings = <&kp Y>; // A + key (within 100-300ms) → Y min-prior-idle-ms = <100>; // Minimum 100ms gap required max-prior-idle-ms = <300>; // Maximum 300ms gap allowed }; slow_combo { trigger-keys = ; bindings = <&kp Z>; // B + key (after 500ms) → Z min-prior-idle-ms = <500>; // Only after 500ms idle }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = < &kp A &kp B &timed_adaptive >; }; }; }; // Usage: // Type 'A', wait 150ms, press timed_adaptive → outputs Y (within 100-300ms window) // Type 'A', wait 50ms, press timed_adaptive → outputs X (too quick, < 100ms) // Type 'A', wait 400ms, press timed_adaptive → outputs X (too slow, > 300ms) // Type 'B', wait 600ms, press timed_adaptive → outputs Z (> 500ms) ``` -------------------------------- ### Configure Adaptive Key Behavior (C) Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Demonstrates device tree configuration for defining adaptive key behaviors in ZMK. This allows keys to change output based on prior key presses and timing, or trigger macros. ```c / { behaviors { adaptive_key_instance: adaptive_key_instance { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp H>; \t// Default behavior when no trigger matches dead-keys = ; \t// Optional: keys that don't output until second press trigger_one { trigger-keys = ; \t// Keys that activate this trigger bindings = <&kp U>; \t// Behavior(s) to invoke when triggered max-prior-idle-ms = <300>; \t// Only trigger if previous key within 300ms strict-modifiers; \t// Require exact modifier match }; trigger_two { trigger-keys = ; bindings = <&kp P &kp G>; \t// Multiple bindings create macro sequence delete-prior; \t// Delete the trigger key before outputting }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = <\n &kp A &kp E &kp J\n &adaptive_key_instance &kp SPACE &kp ENTER\n >; }; }; }; ``` -------------------------------- ### Defining Adaptive Key Behaviors in ZMK (C) Source: https://github.com/urob/zmk-adaptive-key/blob/main/README.md This C-like Device Tree Source (DTS) code defines multiple adaptive key instances with triggers and bindings for ZMK behaviors. Triggers check prior keycodes within timeouts like 300ms, invoking sequences or defaults if unmatched; supports dead keys and modifier handling. Purpose is to enable context-aware key remapping; depends on ZMK module; inputs are keycodes and timings, outputs are bound behaviors, limited to sequential trigger evaluation. ```c / { behaviors { ak_h: ak_h { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp H>; akt_ah { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp U>; }; akt_uh { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp A>; }; akt_eh { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp O>; }; }; ak_m: ak_m { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp M>; akt_gm { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp L>; }; akt_pm { trigger-keys =

; max-prior-idle-ms = <300>; bindings = <&kp L>; }; }; // And similarly for VP->VL, PV->LV, BT->BL, TB->LB ak_g: ak_g { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp G>; // Binding two behaviors: JG->JPG akt_jg { trigger-keys = ; max-prior-idle-ms = <300>; bindings = <&kp P &kp G>; }; }; }; }; ``` -------------------------------- ### Define Adaptive Key Data Structures in C Source: https://context7.com/urob/zmk-adaptive-key/llms.txt This snippet declares the C structs that form the backbone of the ZMK adaptive-key module. They describe key parameters, trigger conditions, runtime state, and instance configuration, allowing developers to customize behavior based on modifiers, idle timing, and dead keys. These definitions depend on Zephyr types such as zmk_mod_flags_t and are compiled into the firmware via device-tree instantiation. ```C // From include/zmk-adaptive-key/keys.h and src/behaviors/behavior_adaptive_key.c // Represents a key with its modifiers and usage page/ID struct zmk_key_param { zmk_mod_flags_t modifiers; // Shift, Ctrl, Alt, GUI flags uint8_t page; // HID usage page (.g., 0x07 for keyboard) uint16_t id; // HID usage ID (keycode) }; // Configuration for a single trigger condition struct trigger_cfg { struct binding_list bindings; // Behavior(s) to invoke when triggered _t trigger_keys_len; // Number of keys in trigger_keys array const struct zmk_key_param trigger_keys[]; // Array of keys that activate this trigger int min_idle_ms; // Minimum idle time (-1 = disabled) int max_idle_ms; // Maximum idle time (-1 = disabled) bool delete_prior; // Delete previous key before output bool strict_modifiers; // Exact modifier match vs. subset match }; // Runtime state for an key instance struct behavior_adaptive_key_data { struct zmk_key_param last_keycode; // Last key pressed (any key, not just this instance) int64_t last_timestamp; // Timestamp of last keypress (milliseconds) const struct binding_list *pressed_bindings; // Currently active binding(s) }; // Configuration for an adaptive key instance struct behavior_adaptive_key_config { uint8_t index; // Instance index struct binding_list default_binding; // Default behavior when no trigger matches size_t triggers_len; // Number of trigger conditions const struct trigger_cfg *triggers; // Array of trigger configurations const struct key_list *dead_keys; // List of dead keys (optional) 32_t delete_keycode; // Keycode for backspace/delete operation }; // Example usage in device tree generates these structures at compile time: // DT_INST_FOREACH_STATUS_OKAY(AK_INST) expands to create one config/data pair per instance ``` -------------------------------- ### Create Smart Shift-Repeat Combo Behavior in ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Implements an adaptive key that functions as sticky shift or key repeat based on context. When pressed alone, it acts as sticky shift. When pressed after typing a letter or number within 350ms, it triggers key repeat. Requires ZMK firmware with adaptive key support. ```C / { behaviors { shift_repeat: shift_repeat { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&sk LSHFT>; // Default: sticky shift repeat { trigger-keys = < A B C D E F G H I J K L M N O P Q R S T U V W X Y Z N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 >; bindings = <&key_repeat>; // After any letter/number: repeat max-prior-idle-ms = <350>; // Only if typed within 350ms strict-modifiers; // Don't trigger if modifiers held }; }; }; keymap { compatible = "zmk,keymap"; default_layer { bindings = < &kp Q &kp W &kp E &kp R &kp T &shift_repeat &kp SPACE // Thumb keys >; }; }; }; // Usage: // Press shift_repeat → activates sticky shift // Type 'h' then quickly press shift_repeat → outputs 'hh' ``` -------------------------------- ### Handle adaptive key press in C Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Evaluates trigger conditions when an adaptive key is pressed and invokes corresponding behaviors. Handles default binding fallback and maintains pressed state. ```c static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev); const struct behavior_adaptive_key_config *cfg = dev->config; struct behavior_adaptive_key_data *data = dev->data; int64_t timestamp = k_uptime_get(); // Iterate through triggers in order for (int i = 0; i < cfg->triggers_len; i++) { const struct trigger_cfg *trigger = &cfg->triggers[i]; if (trigger_is_true(trigger, data, timestamp)) { // Trigger matched - invoke its bindings press_adaptive_key_behavior(data, &event, &trigger->bindings); data->pressed_bindings = &trigger->bindings; return ZMK_BEHAVIOR_OPAQUE; } } // No trigger matched - use default binding press_adaptive_key_behavior(data, &event, &cfg->default_binding); data->pressed_bindings = &cfg->default_binding; return ZMK_BEHAVIOR_OPAQUE; } ``` -------------------------------- ### Implement Dead Keys for French Accented Characters in ZMK Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Creates adaptive key behavior for generating French accented characters using dead keys. The implementation defines macro behaviors for grave, acute, circumflex, and diaeresis accents that combine with base characters. Requires ZMK firmware with adaptive key support. ```C / { macros { fr_e_grave: fr_e_grave { compatible = "zmk,behavior-macro"; #binding-cells = <0>; bindings = <¯o_tap &kp GRAVE &kp E>; }; fr_e_acute: fr_e_acute { compatible = "zmk,behavior-macro"; #binding-cells = <0>; bindings = <¯o_tap &kp APOS &kp E>; }; fr_e_circumflex: fr_e_circumflex { compatible = "zmk,behavior-macro"; #binding-cells = <0>; bindings = <¯o_tap &kp CARET &kp E>; }; fr_e_diaeresis: fr_e_diaeresis { compatible = "zmk,behavior-macro"; #binding-cells = <0>; bindings = <¯o_tap &kp QUOTE &kp E>; }; }; behaviors { ak_e: ak_e { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp E>; // Default: outputs E dead-keys = ; // These keys are "dead" - no output until second press grave { trigger-keys = ; bindings = <&fr_e_grave>; // GRAVE + E → è }; acute { trigger-keys = ; bindings = <&fr_e_acute>; // ' + E → é }; circumflex { trigger-keys = ; bindings = <&fr_e_circumflex>; // ^ + E → ê }; diaeresis { trigger-keys = ; bindings = <&fr_e_diaeresis>; // " + E → ë }; }; }; }; // Usage: // Press GRAVE (no output) // Press ak_e → outputs è // Press GRAVE twice → outputs ` ``` -------------------------------- ### Evaluate trigger conditions in C Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Checks if a trigger condition matches current context by evaluating idle time constraints and previous key matches. Returns boolean match result. ```c static bool trigger_is_true(const struct trigger_cfg *trigger, struct behavior_adaptive_key_data *data, int64_t timestamp) { // Check minimum idle time if (trigger->min_idle_ms >= 0) { int64_t idle = timestamp - data->last_timestamp; if (idle < trigger->min_idle_ms) return false; } // Check maximum idle time if (trigger->max_idle_ms >= 0) { int64_t idle = timestamp - data->last_timestamp; if (idle > trigger->max_idle_ms) return false; } // Check if last keycode matches any trigger key for (int i = 0; i < trigger->trigger_keys_len; i++) { if (keys_are_equal(&data->last_keycode, &trigger->trigger_keys[i], trigger->strict_modifiers)) { return true; } } return false; } ``` -------------------------------- ### Track keycode state changes in C Source: https://context7.com/urob/zmk-adaptive-key/llms.txt Global event listener that updates last keycode and timestamp for all adaptive key instances. Handles dead key suppression when configured. ```c static int adaptive_key_keycode_state_changed_listener(const zmk_event_t *eh) { struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); if (ev == NULL) return ZMK_EV_EVENT_BUBBLE; // Update last keycode and timestamp for all adaptive key instances const struct device *dev; for (int i = 0; i < NUM_INST; i++) { dev = DEVICE_DT_GET(DT_DRV_INST(i)); struct behavior_adaptive_key_data *data = dev->data; const struct behavior_adaptive_key_config *cfg = dev->config; if (ev->state) { // Key pressed data->last_keycode = extract_key_params(ev, cfg->index); data->last_timestamp = ev->timestamp; // Check if this is a dead key that should be suppressed if (last_keycode_is_dead && is_dead_key(&data->last_keycode, cfg->dead_keys)) { last_keycode_is_dead = false; return ZMK_EV_EVENT_HANDLED; // Suppress output } } } return ZMK_EV_EVENT_BUBBLE; } ``` -------------------------------- ### Configure Dead Keys for Adaptive Key in ZMK (C) Source: https://github.com/urob/zmk-adaptive-key/blob/main/README.md This snippet demonstrates configuring an adaptive key behavior for dead keys in ZMK, allowing accent characters like grave, acute, circumflex, and diaeresis on the letter E. It requires ZMK firmware and dependencies from zmk-helpers for French language bindings. Inputs are trigger keys for accents, outputs are the corresponding accented characters, with limitations on unused keycodes for custom definitions. ```c / { behaviors { ak_e: ak_e { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp E>; dead-keys = ; grave { trigger-keys = ; bindings = <&fr_e_grave>; }; acute { trigger-keys = ; bindings = <&fr_e_acute>; }; circumflex { trigger-keys = ; bindings = <&fr_e_circumflex>; }; diaeresis { trigger-keys = ; bindings = <&fr_e_diaeresis>; }; }; }; }; ``` ```c #define DEAD1 F21 #define DEAD2 F22 #define DEAD3 F23 #define DEAD4 F24 / { behaviors { ak_e: ak_e { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&kp E>; dead-keys = ; grave { trigger-keys = ; bindings = <&fr_e_grave>; }; acute { trigger-keys = ; bindings = <&fr_e_acute>; }; circumflex { trigger-keys = ; bindings = <&fr_e_circumflex>; }; diaeresis { trigger-keys = ; bindings = <&fr_e_diaeresis>; }; }; }; }; ``` -------------------------------- ### Configure Shift-Repeat Adaptive Key in ZMK (C) Source: https://github.com/urob/zmk-adaptive-key/blob/main/README.md This snippet sets up a shift-repeat adaptive key in ZMK, which sends left shift unless pressed within 350ms of an alpha key, then sends key repeat. Ideal for homing thumb keys in ergonomic layouts. It depends on ZMK behaviors and alpha keycodes. Input is key press timing, output is either shift or repeat, limited by the max prior idle time setting. ```c / { behaviors { shift-repeat: shift-repeat { compatible = "zmk,behavior-adaptive-key"; #binding-cells = <0>; bindings = <&sk LSHFT>; repeat { trigger-keys = ; bindings = <&key_repeat>; max-prior-idle-ms = <350>; strict-modifiers; }; }; }; }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.