Skip to content

feat(keymap): expand CODE layer with 24 programming macros + |> combo#13

Merged
rdlu merged 3 commits intomainfrom
feat/code-layer-expansion
Apr 11, 2026
Merged

feat(keymap): expand CODE layer with 24 programming macros + |> combo#13
rdlu merged 3 commits intomainfrom
feat/code-layer-expansion

Conversation

@rdlu
Copy link
Copy Markdown
Owner

@rdlu rdlu commented Apr 11, 2026

Summary

Implements the CODE layer expansion plan locked in #12 (comment). Adds 24 programming-oriented macros to the CODE layer (layer_2), a base-layer combo for the Elixir pipe operator, and extends caps_word to survive common code punctuation. All pre-existing CODE layer bindings on rows 2–3 left hand are preserved unchanged.

Closes #12

Rendered keymap

eyelash_sofle keymap

Final CODE layer layout

Row Left hand Right hand
0 (num row) ~s() · ~w() · ~r// · ~D[] · <> { } · <% %>
1 (top row) <- · |> · -> · => :: · |_| · dbg!() · todo!() · ::<>
2 (home row) ` · { · } (LALT) · [ (LCTRL) · ] (LSHFT) · + (unchanged) () · [] · {} · ""
3 (bottom row) - · _ · ( · ) · = (unchanged) == · != · <= · >=
  • Rows 2–3 left hand: user's original single-char brackets and mod-tap combos preserved (no muscle-memory disruption)
  • New 24 macros distributed across row 0 (num row), row 1 (top row), and the right hand on rows 2–3
  • Auto-paired macros (() [] {} "") land the cursor between the delimiters
  • Sigils (~s() ~w() ~r// ~D[]) and cursor macros (::<> dbg!() todo!() { } <% %>) reposition cursor after emission
  • Arrows cluster on row 1 left: <- |> -> => with |> on middle finger (E position), -> on index (R position)
  • Rust cluster on row 1 right: :: (strongest finger) · |_| · dbg!() · todo!() · ::<>
  • Brackets on row 2 right home positions (H J K L)
  • Comparisons on row 3 right (N M , .)

|> base-layer combo

  • Trigger: BSLH + DOT positions (| + . mnemonic), 40ms timeout, scoped to layer 0
  • Shared with the CODE-layer |> macro (single M_PIPE definition used by both)
  • Scoped to base layer only (layers = <0>) so pressing both while holding CODE does NOT fire the combo — CODE layer |> key takes precedence

caps_word continue-list extension

&caps_word override adds code punctuation to the default continue-list:
EQUAL SEMICOLON COMMA PERIOD BACKSLASH GRAVE LEFT_BRACKET RIGHT_BRACKET APOSTROPHE SLASH

This preserves CapsWord across ::, =, ==, <=, ->, <>, brackets, etc. so SCREAMING_SNAKE_CASE identifiers survive mid-symbol edits. Space is intentionally NOT in the continue-list (normal CapsWord termination preserved).

.gitignore housekeeping

Separate chore commit adds eyelash_sofle/, zephyr/, and .claude/settings.local.json to .gitignore. These are west-managed vendor sources and personal machine settings. Project skills under .claude/commands/ remain tracked.

Test plan

  • GH Actions build passes on both halves
  • Check Memory region / flash usage in build log — record baseline (per issue Expand CODE layer with more programming symbols and multi-char macros #12 action item: <70% ideal, 70–85% ok, >85% revisit)
  • Flash to left half and verify CODE layer macros emit correct sequences
  • Verify |> base combo fires reliably without false-triggering on normal typing
  • Verify CapsWord survives FOO_BAR :: u32 = 10 style identifiers
  • Verify cursor positioning works in target editor (auto-paired brackets, turbofish, sigils, HEEx tags)
  • Verify pre-existing row 2–3 left bindings still work (GRAVE, LBRC, mod-tap LALT/LCTRL/LSHFT, PLUS, MINUS, UNDER, LPAR, RPAR, EQUAL)
  • Smoke-test that Elixir / Rust / HEEx real-world typing flow improves

Notes

  • Plan is fully documented in #12 comment
  • Deferred items (remaining Tier B, :: Rust combo, gaming layers) tracked there
  • Only open item at implementation time was CapsWord interaction — resolved via continue-list extension
  • First implementation pass incorrectly replaced the pre-existing row 2–3 left bindings; corrected in fixup commit 00eef54

🤖 Generated with Claude Code

@rdlu
Copy link
Copy Markdown
Owner Author

rdlu commented Apr 11, 2026

Interaction log — implementation from locked plan

User request: proceed with implementation from the decisions locked in #12.

Changes in this push:

  1. Defined 24 macros + M_PIPE in the macros {} block. Each uses wait-ms = 0; tap-ms = 0 for speed. Shared M_PIPE drives both the CODE-layer |> key and the base-layer combo — single source of truth.
  2. Replaced CODE layer (layer_2) with the categorical grouping (arrows home-row left, brackets home-row right, sigils top-row left, Rust top-row right, comparisons bottom-row left, HEEx bottom-row right).
  3. Added combo_pipe_op on positions 39 49 (BSLH + DOT), timeout-ms = 40, layers = <0> — scoped to base layer only so CODE-layer |> key uses its dedicated binding, not the combo.
  4. Overrode &caps_word with an extended continue-list including EQUAL SEMICOLON COMMA PERIOD BACKSLASH GRAVE LEFT_BRACKET RIGHT_BRACKET APOSTROPHE SLASH. ZMK's caps_word checks against unshifted keycodes, so SEMICOLON in the list preserves CapsWord across ::, PERIOD across >, etc. Space intentionally excluded so normal CapsWord termination still works.
  5. Kept single-char convenience keys on column 1: ` - = — these aren't in the 24-slot macro budget but provide quick single-char access on CODE without reaching back to shift+number.

Non-obvious rationale:

  • M_SIGD uses LS(D) (shifted D) to force uppercase — Elixir ~D[] is the only sigil with a capital letter, and using LS(D) means the macro works correctly regardless of CapsWord state.
  • M_HEEXI and M_HEEXNP will break CapsWord because their SPACE emissions aren't in the continue-list. This is intentional — HEEx templates don't contain SCREAMING_CASE identifiers so the tradeoff is worth preserving normal space-terminates-capsword behavior.
  • Combo scoped to layers = <0> (base only) so that pressing BSLH+DOT while CODE is held does NOT fire the combo (CODE layer bindings take precedence). Prevents double-fire if the user holds CODE and rolls into the combo positions.

Action item from #12 still pending: check the GH Actions build log for flash usage on both halves and record baseline numbers as a follow-up comment on #12.

@rdlu rdlu self-assigned this Apr 11, 2026
@rdlu rdlu added the enhancement New feature or request label Apr 11, 2026
rdlu and others added 2 commits April 11, 2026 11:26
Adds 24 multi-char / auto-paired macros on the CODE layer, grouped by
category across both hands:

- Arrows (home row left): -> => <- |>
- Brackets/quotes (home row right): () [] {} "" (auto-paired, cursor between)
- Comparisons (bottom row left): == != <= >=
- Elixir sigils (top row left): ~s() ~w() ~r// ~D[] (cursor between delims)
- Rust cluster (top row right): dbg!() todo!() ::<> |_| ::
- HEEx (bottom row right): <> {  } <% %> (cursor-positioning)

Adds a base-layer combo on BSLH+DOT (| + . mnemonic, 40ms) that fires
the |> macro — zero layer-hop for the most-typed Elixir sequence.

Extends caps_word continue-list with common code punctuation so
SCREAMING_SNAKE_CASE survives ::, =, ==, comparison ops, etc.

Refs #12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds eyelash_sofle/, zephyr/, and .claude/settings.local.json to
.gitignore. These are all build-environment artifacts (vendor board
source, Zephyr tree, personal machine settings) that shouldn't be
tracked. Project skills under .claude/commands/ remain tracked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rdlu rdlu force-pushed the feat/code-layer-expansion branch from f692bc7 to 1d578ba Compare April 11, 2026 14:27
Preserves user's muscle memory for the single-char brackets / mod-tap
combos on CODE layer left hand (rows 2-3). The new 24 macros are now
distributed across row 0 (num row), row 1 (top), and the right hand
on rows 2-3.

- Row 0: Elixir sigils + <> (left), HEEx macros (right)
- Row 1: arrows cluster (left), Rust cluster (right)
- Row 2 left: GRAVE LBRC mt(LALT,RBRC) mt(LCTRL,LBKT) mt(LSHFT,RBKT) PLUS (UNCHANGED)
- Row 2 right: auto-paired brackets () [] {} ""
- Row 3 left: MINUS UNDER LPAR RPAR EQUAL (UNCHANGED)
- Row 3 right: comparisons == != <= >=

No change to macro definitions, combo, or caps_word override.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rdlu rdlu merged commit c95703e into main Apr 11, 2026
5 checks passed
@rdlu rdlu deleted the feat/code-layer-expansion branch April 11, 2026 14:42
github-actions Bot pushed a commit that referenced this pull request Apr 11, 2026
…> combo (#13)

* feat(keymap): expand CODE layer with 24 programming macros + |> combo

Adds 24 multi-char / auto-paired macros on the CODE layer, grouped by
category across both hands:

- Arrows (home row left): -> => <- |>
- Brackets/quotes (home row right): () [] {} "" (auto-paired, cursor between)
- Comparisons (bottom row left): == != <= >=
- Elixir sigils (top row left): ~s() ~w() ~r// ~D[] (cursor between delims)
- Rust cluster (top row right): dbg!() todo!() ::<> |_| ::
- HEEx (bottom row right): <> {  } <% %> (cursor-positioning)

Adds a base-layer combo on BSLH+DOT (| + . mnemonic, 40ms) that fires
the |> macro — zero layer-hop for the most-typed Elixir sequence.

Extends caps_word continue-list with common code punctuation so
SCREAMING_SNAKE_CASE survives ::, =, ==, comparison ops, etc.

Refs #12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: ignore west vendor sources and local Claude settings

Adds eyelash_sofle/, zephyr/, and .claude/settings.local.json to
.gitignore. These are all build-environment artifacts (vendor board
source, Zephyr tree, personal machine settings) that shouldn't be
tracked. Project skills under .claude/commands/ remain tracked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fixup(keymap): restore original CODE layer left-hand bindings

Preserves user's muscle memory for the single-char brackets / mod-tap
combos on CODE layer left hand (rows 2-3). The new 24 macros are now
distributed across row 0 (num row), row 1 (top), and the right hand
on rows 2-3.

- Row 0: Elixir sigils + <> (left), HEEx macros (right)
- Row 1: arrows cluster (left), Rust cluster (right)
- Row 2 left: GRAVE LBRC mt(LALT,RBRC) mt(LCTRL,LBKT) mt(LSHFT,RBKT) PLUS (UNCHANGED)
- Row 2 right: auto-paired brackets () [] {} ""
- Row 3 left: MINUS UNDER LPAR RPAR EQUAL (UNCHANGED)
- Row 3 right: comparisons == != <= >=

No change to macro definitions, combo, or caps_word override.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rdlu rdlu mentioned this pull request Apr 11, 2026
6 tasks
rdlu added a commit that referenced this pull request Apr 11, 2026
Updates the three project skills to match reality after PR #13-16:

- edit-keymap: create-or-update PR with --assignee rdlu + --label
  keymap; pull main after [Draw Keymap] workflow; new 'Local iteration
  loop' section for edit→draw→build→flash experimentation without CI.
- adjust-timing: same PR hygiene + same local iteration guidance,
  since timing tuning is always faster locally than through CI.
- build-flash: lead with 'mise run flash-release' (one-command from
  GH Actions). Add a prominent ZMK Studio overlay warning with the
  reset→normal two-step fix (covers both local and release variants).
  Local build/flash section updated to describe the new wait-for-mount
  behavior of flash-left / flash-right / flash-reset.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rdlu added a commit that referenced this pull request Apr 11, 2026
* chore(mise): flash-left/right/reset wait for NICENANO mount

Previously these tasks ran a bare 'cp' to /run/media/\$USER/NICENANO/,
which silently fails if the device isn't in bootloader mode yet. Now
each task:

- Verifies the locally-built uf2 exists (errors clearly if not)
- Prints a prompt to double-tap RESET
- Polls for the NICENANO mount up to 60s
- Copies the uf2 and syncs
- Prints a success marker

Matches the behavior of flash-release / flash-release-reset added in
the previous chore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: promote mise flash tasks in README, move manual flow to FLASHING_MANUAL.md

- README 'Flashing' section now leads with 'mise run flash-release' as
  the one-command happy path. Adds a prominent section about ZMK Studio
  overlay persistence and the settings_reset-then-normal-flash fix
  (this gotcha cost an hour of confusion this afternoon).
- Building-locally section updated to describe the new wait-for-mount
  behavior of flash-left / flash-right / flash-reset.
- New FLASHING_MANUAL.md documents the drag-and-drop fallback flow for
  users without mise/gh, plus the same Studio overlay warning, plus
  troubleshooting for common flashing issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(skills): add PR hygiene, flash-release, Studio warning, local loop

Updates the three project skills to match reality after PR #13-16:

- edit-keymap: create-or-update PR with --assignee rdlu + --label
  keymap; pull main after [Draw Keymap] workflow; new 'Local iteration
  loop' section for edit→draw→build→flash experimentation without CI.
- adjust-timing: same PR hygiene + same local iteration guidance,
  since timing tuning is always faster locally than through CI.
- build-flash: lead with 'mise run flash-release' (one-command from
  GH Actions). Add a prominent ZMK Studio overlay warning with the
  reset→normal two-step fix (covers both local and release variants).
  Local build/flash section updated to describe the new wait-for-mount
  behavior of flash-left / flash-right / flash-reset.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expand CODE layer with more programming symbols and multi-char macros

1 participant