urob/zmk-config

repository·main·Indexed 23 days ago

https://github.com/urob/zmk-config

A customized ZMK firmware configuration for ergonomic keyboards including Corneish Zen, Glove80, and Planck. It features a Nix-powered local build environment using just, direnv, and keymap-drawer, alongside advanced typing optimizations such as 'timeless' homerow mods and ZMK combos.

Tokens
2K
Snippets
8
Records
13
Agent score
30%

What's inside urob-zmk-config

  1. Implement "Timeless" Homerow Mods (HRMs)

    main

    To achieve a "timer-less" typing experience with minimal misfires and delays, use a combination of ZMK's balanced flavor and specific timing properties. This setup avoids the traditional requirement of holding a key longer than tapping-term-ms to trigger a modifier.

    Key Configuration Properties

    • flavor = "balanced": Produces a "hold" if another key is both pressed and released within the tapping term. This allows modifiers to trigger without waiting for the full tapping term.
    • require-prior-idle-ms: Immediately resolves an HRM as a "tap" if it is pressed shortly after another key has been tapped, eliminating the typing delay.
    • hold-trigger-key-positions: Used with positional hold-tap to force HRMs to resolve as a "tap" when the next key is on the same side of the keyboard, preventing accidental nested sequences during key rolls.
    • hold-trigger-on-release: Delays the positional decision until the next key is released, allowing multiple modifiers to be combined on the same hand.

    Example Configuration

    Note: This example uses zmk-helpers macros for key labels. If not using them, replace KEYS_L, KEYS_R, and THUMBS with your specific key position indices.

    /* Left-hand HRMs. */
    ZMK_HOLD_TAP(hml,
        flavor = "balanced";
        tapping-term-ms = <280>;
        quick-tap-ms = <175>;
        require-prior-idle-ms = <150>;
        bindings = <&kp>, <&kp>;
        hold-trigger-key-positions = <KEYS_R THUMBS>;
        hold-trigger-on-release;
    )
    
    /* Right-hand HRMs. */
    ZMK_HOLD_TAP(hmr,
        flavor = "balanced";
        tapping-term-ms = <280>;
        quick-tap-ms = <175>;
        require-prior-idle-ms = <150>;
        bindings = <&kp>, <&kp>;
        hold-trigger-key-positions = <KEYS_L THUMBS>;
        hold-trigger-on-release;
    )
  2. Use Combos instead of Symbol Layers

    main
    Instead of using dedicated layers for symbols (which requires lateral thumb movement), you can use ZMK Combos. To prevent misfires when rolling keys, it is recommended to use the require-prior-idle-ms property in your configuration, which helps distinguish between intentional combos and rapid typing.
  3. Install Nix with flake support

    main

    To set up the local build environment, first install the Nix package manager with flake support enabled.

    curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
       sh -s -- install --no-confirm
  4. Configure the direnv shell-hook for Bash

    main

    To enable automatic environment loading when entering the workspace, configure the direnv shell-hook. For bash, add the following to your ~/.bashrc and configure nix-direnv:

    # Install the shell-hook
    echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
    
    # Enable nix-direnv
    mkdir -p ~/.config/direnv
    echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' >> ~/.config/direnv/direnvrc
    
    # Optional: make direnv less verbose
    echo '[global]\nwarn_timeout = "2m"\nhide_env_diff = true' >> ~/.config/direnv/direnv.toml
    
    # Activate the hook
    source ~/.bashrc
    # Install the shell-hook
    echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
    
    # Enable nix-direnv
    mkdir -p ~/.config/direnv
    echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' >> ~/.config/direnv/direnvrc
    
    # Optional: make direnv less verbose
    echo '[global]\nwarn_timeout = "2m"\nhide_env_diff = true' >> ~/.config/direnv/direnv.toml
    
    # Source the bashrc to activate the hook (or start a new shell)
    source ~/.bashrc
  5. Set up the ZMK workspace

    main
    1. Clone your fork of the repository into a directory named zmk-workspace.
    2. Enter the directory.
    3. Allow direnv to set up the isolated environment (this may take a while).
    4. Use just init to initialize the Zephyr workspace and pull in ZMK dependencies.
    git clone https://github.com/urob/zmk-config zmk-workspace
    cd zmk-workspace
    direnv allow
    just init
  6. Troubleshoot Homerow Mods (HRMs)

    main

    If your Homerow Mods are not behaving as expected, adjust the following parameters based on the symptom:

    SymptomRemedy
    Noticeable delay when tapping HRMsIncrease require-prior-idle-ms. (Rule of thumb: 10500 / WPM)
    False negatives (same-hand)Reduce tapping-term-ms OR disable hold-trigger-key-positions
    False negatives (cross-hand)Reduce require-prior-idle-ms OR set flavor = "hold-preferred" (requires a specific ZMK patch)
    False positives (same-hand)Increase tapping-term-ms
    False positives (cross-hand)Increase require-prior-idle-ms OR set flavor = "tap-preferred"
  7. Build ZMK firmware with `just`

    main

    The build process is managed via the just command runner.

    • Build all targets: just build all (uses build.yaml to build all board/shield combinations).
    • Build a specific target: just build <target> (e.g., just build zen for Corneish Zen).
    • Pristine build: just build all -p (passes -p to west).
    • List targets: just list.
    • Clean build cache: just clean.

    Additional arguments passed to just build are forwarded to west.

    just build all
    just build zen
    just build all -p
  8. Update ZMK dependencies and SDK

    main
    • Update ZMK and modules: Use just update to pull the latest versions of ZMK and modules defined in config/west.yml. Warning: This will overwrite local changes in those directories.
    • Upgrade Zephyr SDK and Python dependencies: Use just upgrade-sdk. Use with caution as this updates Nix packages and may affect build stability.