https://github.com/alex-tdrn/zmk-config
A 36 key layout with few layers and many combos
https://github.com/alex-tdrn/zmk-config
chocofi keyboard-layout keymap-drawer zmk
Last synced: 9 months ago
JSON representation
A 36 key layout with few layers and many combos
- Host: GitHub
- URL: https://github.com/alex-tdrn/zmk-config
- Owner: alex-tdrn
- License: mit
- Created: 2023-06-21T20:50:33.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-05T10:55:53.000Z (over 1 year ago)
- Last Synced: 2025-09-11T20:42:16.558Z (9 months ago)
- Topics: chocofi, keyboard-layout, keymap-drawer, zmk
- Language: Nushell
- Homepage:
- Size: 1.12 MB
- Stars: 8
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
My personal ZMK config for the [chocofi](https://github.com/pashutk/chocofi)
# Base Layer

## Alphas
Alpha layout is [hands-down gold](https://sites.google.com/alanreiser.com/handsdown/home/hands-down-neu#h.8i2msuo3butx), with slight tweaks
to the locations of the letter and bigram combos:
- All bigrams are on the left side of the keyboard since they are all either surrounded by, or preceded by vowels, and typing a combo in
rapid succession with a vowel is hard for me.
This also makes room for all symbol combos on the right side
- The `Qu` combo was initially a hold-tap with `Qu` on tap and `Q` on hold.
This is perfect when typing prose, I found that I only needed `Q` for initialisms, and the hold-delay was not a problem for me.
However, `Q` is a common key in vim/nvim and it quickly became annoying having to hold the combo every time I needed to exit a dialog or
close a window.
`Qt` codebases are also painful to work in when having `Q` on hold.
So `Q` and `Qu` have been split into adjacent combos, maintaining the best of both worlds.
Tapping bigrams uses different casing depending on the modifier held:
- no modifier -> lowercase (e.g. `th`)
- `shift` -> uppercase (`Th`)
- `control` -> all caps (`TH`)
## Symbols
Symbols are changed form the original `hands-down gold`, mostly to group and arrange them by easy to memorize rules, while still thinking
about ergonomics:
- most math symbols are on the inner index column of keys, with the equal sign being on the home row middle + ring finger combo.
this makes common `*=`, `-=`, `/=` etc bigrams more comfortable to type when programming, by avoiding using the same finger for both
symbols.
the only symbols from this category that are not on the inner column are the logical operators `~`, and `^`
- sentence/statement ending punctuation symbols are all on the top row
- quotation symbols that normally appear in pairs are all (except for `'` in prose) on the ring + pinky column of combos
- the 4 bracket types are arranged in a rectangle, typed with the 3 strongest fingers:
index, middle, and ring.
The angle brackets and the square brackets are placed on the two stronger combos of the four (index + middle finger), since the square
brackets are regularly used in vim for 'prev/next' jumps, and the angle brackets double as mathematical operators as well.
Also, the `->` bigram is extremely common in C++ .
- `_` and `\` receive the most comfortable combo position, since they are among the most common symbols across all the programming
languages I use.
The need to manually type `_` may be reduced in the future by implementing something like [x-case with `_` replacing
`space`](https://github.com/andrewjrae/kyria-keymap/tree/e3ad77dc4d48b8e6a842c9136c76c1021ab5976b#x-case).
If that proves viable I'll reconsider this symbol arrangement
### Auto Pair
Bracket and quotation symbols have `autopair` functionality on hold with the following behaviors:
- hold without any modifier -> `opening symbol`, `closing symbol`
- hold + `shift` -> `opening symbol`, `closing symbol`, `left arrow`
- hold + `control` -> `opening symbol`, `return`, `closing symbol`, `up arrow`, `end`, `return`
This kind of functionality is normally available through text editor plugins but I never used it personally because I find that I often run
into cases where I **don't** want this functionality to kick in.
So having it optional, and activated manually is more convenient to me.
Also, this makes this feature available anywhere arrow key navigation works.
### Sentence Case
The sentence ending symbols (`.`, `!`, and `?`) can be held to trigger sentence case:
the symbol itself will be emitted, then a space, and finally sticky shift will be activated, automatically turning the next letter
uppercase.
The sticky shift is set to only deactivate after 10s if no input is received, to allow for a slight pause before the next sentence, if
needed.
## Numbers & Navigation
I hate switching layers, so I am currently experimenting with numbers and navigation keys on vertical (same finger) base layer combos.
The stronger fingers get smaller digits, since, according to [Benford's Law](https://en.m.wikipedia.org/wiki/Benford%27s_law) they tend to
appear more often in real-life numerical data (also in vim relative line jumps).
Idea taken from the [T34 layout](https://www.jonashietala.se/blog/2021/06/03/the-t-34-keyboard-layout/#where-are-the-digits).
The navigation keys are arranged on the lower combo rows, in the same order as vim navigation, but offset to include the pinky.
This loses the vim muscle memory and makes more use of the pinky, but might be worth it to be able to press all arrow combinations
simultaneously, which can be useful when scrolling in certain programs.
## Newline
Inspired by vim's `o`/`O`, hitting `enter` and `space` at the same time inserts a new line below the current one.
Holding down `shift` additionally, inserts the new line above the current one instead.
## Join Line
Tapping `space` and `tab` at the same time joins the current line with the one below.
Holding down `shift` while tapping, joins it up with the line above, instead.
## Delete Word/Line
Tapping `t` and `backspace` together deletes the entire line by executing `home, shift+end, backspace`.
Holding `shift` while tapping deletes the word under the cursor by executing `ctrl+left, ctrl+shift+right, backspace`.
Line deletion works pretty consistently across editors.
Word deletion varies, however, since some editors interpret `ctrl+left/right` to mean "jump to the beginning/end of the current word", while
others interpret it as "jump to the beginning/end of the next word".
The difference is that the former will only delete the word under the cursor, while the latter will also delete whitespace/symbol until the
next word.
Additionally, because of the keys executed, the macro does not work if the cursor lies on the first letter of a word (it will jump back and
delete the previous word instead).
# Function Layer (WIP)

# Lock Layer
The `LOCK` layer is used when travelling to prevent accidental key taps, since ZMK does not have a power on/off behavior.
Since it's (de)activated using 8 fingers, it should be very unlikely to go back to the base layer and send random key taps, while in a bag.
# ZMK tricks
If you have a custom hold-tap behavior that does not need any arguments and you don't want to have to pass `0 0` in your keymap to bind it,
you can wrap it in a macro that uses [`macro_pause_for_release`](https://zmk.dev/docs/behaviors/macros#processing-continuation-on-release):
```c
#define BIND_HOLD_TAP_ARGUMENTS(NAME, HOLD_TAP_BEHAVIOR, ARGUMENT_1, ARGUMENT_2) \
/ { \
macros { \
NAME##: NAME { \
label = #NAME; \
compatible = "zmk,behavior-macro"; \
#binding-cells = <0>; \
wait-ms = <0>; \
tap-ms = <0>; \
bindings = <¯o_press & ## HOLD_TAP_BEHAVIOR ARGUMENT_1 ARGUMENT_2>, <¯o_pause_for_release>, <¯o_release & ## HOLD_TAP_BEHAVIOR ARGUMENT_1 ARGUMENT_2>; \
}; \
}; \
}
```
# Acknowledgements
SVG keymaps are auto-generated using [keymap-drawer](https://github.com/caksoylar/keymap-drawer)
`chocofi` board definition taken from [`infused-kim`](https://github.com/infused-kim/zmk-config)
Uses `urob`'s parameters for [timer-less home row mods](https://github.com/urob/zmk-config#timeless-homerow-mods)
The keymap diagrams contain SVGs using `nerdfont` icons.
They embed the nerd font symbols and the `JetBrainsMono` font.
See `config/diagrams/update.nu` and `config/diagrams/font_embed.css` for more details.
Color palette used in the keymap SVGs is [Kanagawa](https://github.com/rebelot/kanagawa.nvim/)