- Chord Mode - Type 220+ common words with just two letters! See the complete documentation for details.
- Design Philosophy - Learn about the hardware, ergonomics, and design principles behind this layout
- Home Row Mods - Modifiers on home row for ergonomic access
- Window/Tab Switching - Fast application and tab switching
- X-Case - Multiple case conversion modes (camelCase, snake_case, etc.)
- The keyboard layout is generated using generateKeyboard from this file. => link to Generator
- The generated keyboard can be found in the qmk directory.
- tested with Ferris Sweep keyboard
- To extract local source-word candidates for magic migration:
mise run extract-source-words -- ~/source --output source_words.tsv --limit 500 --min-count 3 - To extract authored GitHub/chat-style words for magic migration:
mise run extract-github-words -- --output github_words.tsv --limit 500 --min-count 3 - To extract local Codex/chat-export words for magic migration:
mise run extract-local-chat-words -- --output local_chat_words.tsv --limit 500 --min-count 3 - To merge candidate lists before ranking:
mise run merge-word-lists -- general_words.tsv source_words.tsv --output merged_words.tsv - To rank those candidates into free magic slots:
mise run find-available-chords -- --candidates-file source_words.tsv --limit 50 - To review explicit placement ideas against current table occupancy:
mise run suggest-magic-placements -- --prefer-row 'thank you=t' --prefer-row 'gregor=z' 'thank you' gregor - Prefer
mise run ...for these helper workflows; the implementations live underscripts/, not at repo root.
On all other layers, the modifiers are as shown in the table below.
| Home Row Modifiers | Finger |
|---|---|
| Alt | Ring |
| Ctrl | Middle |
| Shift | Index |
- win โก๏ธ and tab โก๏ธ are used to Short windows and tabs.
- Once you press any of those keys, you're in switcher mode, where all other keys are replaced by shift-tab.
- Switcher mode is exited when you go back to the base layer.
How to read this layout:
- ๐ = combo key (e.g. middle and index finger in top row pressed together produce "b")
- ๐ = key can't be used because the layer was activated with that key or because it's reserved for a modifier
- empty = use key from base layer
- FnSym = capitalized words are layer names - if they are a key, the layer is activated as toggled or one shot layer (if the "OneShot" flag is set in the layer flags)
- *Mouse = layer is active while key is held
- C-w = Ctrl-w (same for Alt and Shift)
- f12+Num = tab-mod - f12 on tap and Num on hold
- "that" = combo that produces "that"
- [ { = { is the shifted key of [, so it's used when Shift is held (only for information)
- The symbol table at the bottom shows the meaning of the symbols used in the layout.
Currently unused features:
- /+Ctrl = tab-mod - / on tab and CTRL on hold
- $Mouse = layer is active while key is held (double tap to lock layer)
- #Mouse = toggle layer
- @Num = layer is active for the next keypress
- Sym/Nav = layer is active for the next keypress: If the activation key is still down when the next key is pressed, the Nav layer is used, otherwise the Sym layer is used
Note: The layout is generated from this file directly.
Rows = preceding key. Columns = the nine physical magic keys (see the Layout table for their positions).
Cell = what to emit.
- Single-char letter cells append or tap (e.g.
a+eyieldsae). Single-char punctuation/symbol cells backspace the preceding letter first (e.g.t+.yields.). A repeated press of the same magic key then replays just the emitted letter or symbol, with no extra backspace. No suffix state. - Bare words/phrases (unquoted multi-char, e.g.
because,thank you): generator auto-appends a trailing space and activates the suffix state machine. From there, the next magic press chains a suffix:MAGIC_G=ed,MAGIC_E=ly,MAGIC_B=s,MAGIC_D=n't,ingkey (with vowel-drop).MAGIC_I=.+shift (exit),MAGIC_H=,(exit). Prefix-strip and BS rules below also apply to bare words. - Quoted strings (literal โ no auto-space, no suffix state):
- Preceding key is a letter and cell starts with it โ strip prefix.
b+"because"emitsecause, yieldingbecause. - Preceding key is a letter and cell does not start with it โ BS + cell.
- Preceding key is not a letter (spc, punctuation) โ append as-is.
,+" and "yields, andplus a trailing space.
- Preceding key is a letter and cell starts with it โ strip prefix.
[name]bracket tokens invoke named handlers (currently[dotSpc]= BS +.then one-shot shift;[llSpc]= BS +'ll).
| Magic | magic_a | magic_b | magic_c | magic_d | magic_e | magic_f | magic_g | magic_h | magic_i |
|---|---|---|---|---|---|---|---|---|---|
| a | e | ||||||||
| b | behind | between | because | d | business | before | elaborate | about | |
| c | n | "'ll" | p | "'d" | "'s" | "'re" | "n't" | ||
| d | c | h | doesn't | f | update | didn't | don't | does | |
| e | h | u | |||||||
| f | found | first | d | after | |||||
| g | global | f | k | d | again | organize | anything | thought | |
| h | y | ||||||||
| i | ' | ||||||||
| j | |||||||||
| k | r | know | x | knew | |||||
| l | m | h | r | c | b | language | leave | already | |
| m | r | h | "ment" | l | t | instrumentation | almost | ||
| n | r | h | "qu" | x | p | number | understand | only | |
| o | h | e | |||||||
| p | y | m | n | d | improve | production | people | probably | |
| r | ' | " | ! | ? | another | realize | , | . | |
| s | someone | r | "sion" | d | just | something | always | ||
| t | n | f | "tion" | without | thank you | though | everything | through | |
| u | h | ||||||||
| v | zeitlinger@gmail.com | gregor.zeitlinger@grafana.com | declarative config | gregor@zeitlinger.de | I've | have | never | "'ve" | observability |
| w | will | wasn't | worse | s | x | worry | where | which | when |
| x | exception | w | r | d | exclude | explain | explicit | ||
| y | r | ||||||||
| z | zeitlinger | gregor | Grafana | Grafana Labs | OpenTelemetry | Spring Boot | Prometheus | ||
| spc | [llSpc] | and | the | [dotSpc] | |||||
| tab | and | the | |||||||
| โฉ๏ธ๏ธ | and | the |
| Adaptives | Key | Output |
|---|---|---|
| a | e | u |
| b | d | s |
| c | d | c |
| c | n | k |
| d | c | v |
| d | f | d |
| d | h | g |
| e | h | e |
| e | u | o |
| f | d | f |
| g | d | n |
| g | f | l |
| k | r | n |
| l | b | k |
| l | c | v |
| l | h | p |
| l | r | l |
| m | h | m |
| m | r | p |
| m | t | b |
| n | h | n |
| n | p | k |
| n | r | g |
| n | x | l |
| o | h | o |
| p | d | l |
| p | n | p |
| p | y | s |
| r | x | r |
| s | d | p |
| s | r | s |
| t | f | w |
| t | n | t |
| u | h | a |
| w | x | n |
| x | d | c |
| x | w | p |
| y | r | i |
| Layer | L. Pin. | L. Ring | L. Mid. | L. Ind. | R. Ind. | R. Mid. | R. Ring | R. Pin. |
|---|---|---|---|---|---|---|---|---|
| Base | esc | x | w | dead3 | dead2 | magic_a | magic_b | dead1 |
| Base | s | c | n | t | a | e | i | h |
| Base | *Right | f | l | d | u | o | y | *Left |
| Base | *Nav | r | spc | *FnSym | ||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Base | v | ing | ||||||
| Base | ๐ | ๐ | ||||||
| Base | k | magic_g | ||||||
| Base | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Base | m | magic_d | ||||||
| Base | ๐ | ๐ | ||||||
| Base | g | magic_h | ||||||
| Base | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Base | p | magic_e | ||||||
| Base | ๐ | ๐ | ||||||
| Base | b | magic_i | ||||||
| Base | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Base | magic_c | magic_f | ||||||
| Base | ๐ | ๐ | ||||||
| Base | z | j | ||||||
| Base | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Right | dead3 | q | ' | |||||
| Right | C-f | C-r | ||||||
| Right | ๐ | ๐ | ๐ | ๐ | _ | |||
| Right | A-f7 | C-n | [ | ] | ||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Right | ` | |||||||
| Right | ๐ | ๐ | ||||||
| Right | CS-r | @ | ||||||
| Right | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Right | n't | |||||||
| Right | ๐ | ๐ | ||||||
| Right | CS-f | ! | ||||||
| Right | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Right | \ | |||||||
| Right | ๐ | |||||||
| Right | ? | |||||||
| Right | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Right | " | |||||||
| Right | ๐ | |||||||
| Right | ||||||||
| Right | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| RMods | ||||||||
| RMods | ||||||||
| RMods | ๐ | ๐ | ๐ | ๐ | = | |||
| RMods | [ | ] | ||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Left | dead1 | |||||||
| Left | *CNum | *Case | *Mm | |||||
| Left | : | ๐ | ๐ | ๐ | ๐ | |||
| Left | ; | *ANum | *Num | |||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Left | "Qu" | |||||||
| Left | ๐ | |||||||
| Left | ||||||||
| Left | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| LMods | ||||||||
| LMods | ||||||||
| LMods | - | ๐ | ๐ | ๐ | ๐ | |||
| LMods | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| FnSym | dead2 | f10 | f9 | dead2 | dead3 | ( | ) | dead1 |
| FnSym | f4 | f3 | f2 | f1 | ๐ | ๐ | ๐ | =+Num2 |
| FnSym | f8 | f7 | f6 | f5 | - | { | } | *Num |
| FnSym | f12 | ๐ | ๐ | |||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| FnSym | โ | win | ||||||
| FnSym | ๐ | ๐ | ||||||
| FnSym | โ | ~ | ||||||
| FnSym | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| FnSym | * | < | ||||||
| FnSym | ๐ | ๐ | ||||||
| FnSym | f11 | / | ||||||
| FnSym | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| FnSym | pipe | > | ||||||
| FnSym | ๐ | ๐ | ||||||
| FnSym | & | # | ||||||
| FnSym | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| FnSym | ๐ | ^ | ||||||
| FnSym | ๐ | ๐ | ||||||
| FnSym | $ | % | ||||||
| FnSym | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | dead3 | C-x | C-v | CS-z | dead1 | esc | ins | dead2 |
| Nav | copy | ๐ | ๐ | ๐ | โฌ ๏ธ | โฌ๏ธ | โฌ๏ธ | โก๏ธ |
| Nav | C-z | C-w | tab โก๏ธ | win โก๏ธ | โฉ๏ธ๏ธ | bspc | del | tab |
| Nav | ๐ | ๐ | spc | |||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | CS-v | รผ | ||||||
| Nav | ๐ | ๐ | ||||||
| Nav | C-y | โฌ ๏ธโฌ ๏ธ | ||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | C-a | รถ | ||||||
| Nav | ๐ | ๐ | ||||||
| Nav | C-d | โฌ๏ธโฌ๏ธ | ||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | CS-n | รค | ||||||
| Nav | ๐ | ๐ | ||||||
| Nav | C-k | โฌ๏ธโฌ๏ธ | ||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | C-e | ร | ||||||
| Nav | ๐ | ๐ | ||||||
| Nav | CS-c | โก๏ธโก๏ธ | ||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | ||||||||
| Nav | CA-b | ๐ | A-f12 | |||||
| Nav | ||||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | ||||||||
| Nav | C-b | ๐ | ||||||
| Nav | ||||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | ||||||||
| Nav | ||||||||
| Nav | C-f12 | ๐ | C-/ | |||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Nav | ||||||||
| Nav | ||||||||
| Nav | C-p | ๐ | ||||||
| Nav | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Num | dead1 | , | 9 | dead2 | ||||
| Num | 4 | 3 | 2 | 1 | ||||
| Num | 8 | 7 | 6 | 5 | ||||
| Num | . | 0 | ๐ | ๐ | ||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Num | CS-v | |||||||
| Num | ๐ | |||||||
| Num | C-g | |||||||
| Num | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Num | A-f1 | |||||||
| Num | ๐ | |||||||
| Num | CA-l | |||||||
| Num | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Num | AS-x | |||||||
| Num | ๐ | |||||||
| Num | AS-b | |||||||
| Num | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Num | ||||||||
| Num | ๐ | |||||||
| Num | AS-s | |||||||
| Num | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| ANum | ||||||||
| ANum | A-4 | A-3 | A-2 | A-1 | ||||
| ANum | A-8 | A-7 | A-6 | A-5 | ||||
| ANum | A-9 | A-0 | ๐ | ๐ | ||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| CNum | ||||||||
| CNum | C-4 | C-3 | C-2 | C-1 | ||||
| CNum | C-8 | C-7 | C-6 | C-5 | ||||
| CNum | C-9 | C-0 | ๐ | ๐ | ||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Mm | ๐ | ๐ | ||||||
| Mm | prt | ๐ | ๐ | ๐ | ๐ | |||
| Mm | ver | โฎ๏ธ | โญ๏ธ | โฏ๏ธ | ||||
| Mm | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | |
| Case | ||||||||
| Case | sl/case | PasCase | CapW | SN_CASE | ||||
| Case | do.case | camCase | kb-case | sn_case | ||||
| Case | ||||||||
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |
The order of the options is also the order of the layers in the layer stack.
| LayerOptions | Modifiers Left | Modifiers Right | Fallback Left | Fallback Right | Flags | Combo Timeout |
|---|---|---|---|---|---|---|
| Base | 200 | |||||
| Left | BottomRow+LMods | Base | Shifted | 200 | ||
| Right | BottomRow+RMods | Base | Shifted | 200 | ||
| LMods | BottomRow+LMods | Base | ||||
| RMods | BottomRow+RMods | Base | ||||
| Nav | HomeRow | DirectComboLeft | 200 | |||
| FnSym | HomeRow | DirectComboRight | 200 | |||
| Num | TriLayer | 200 | ||||
| Num2 | HomeRow | Num | ||||
| ANum | ||||||
| CNum | 200 | |||||
| Mm | ||||||
| Case |
| Symbol | Command |
|---|---|
| โฌ ๏ธ | KC_LEFT |
| โฌ ๏ธโฌ ๏ธ | KC_HOME |
| โฌ๏ธ | KC_DOWN |
| โฌ๏ธโฌ๏ธ | KC_PGDN |
| โฌ๏ธ | KC_UP |
| โฌ๏ธโฌ๏ธ | KC_PGUP |
| โก๏ธ | KC_RIGHT |
| โก๏ธโก๏ธ | KC_END |
| โ | KC_KP_MINUS |
| โ | KC_KP_PLUS |
| ins | KC_INS |
| del | KC_DEL |
| spc | KC_SPC |
| esc | KC_ESC |
| โฉ๏ธ๏ธ | KC_ENT |
| bspc | KC_BSPC |
| win | KC_LGUI |
| tab | KC_TAB |
| prt | KC_PSCR |
| pipe | KC_PIPE |
| ๐ | KC_MUTE |
| โฏ๏ธ | KC_MPLY |
| โฎ๏ธ | KC_MPRV |
| โญ๏ธ | KC_MNXT |
| ๐ | KC_VOLU |
| ๐ | KC_VOLD |
| ๐ | KC_BRIU |
| ๐ | KC_BRID |
| copy | C(KC_C) |
| รค | UP(UMLAUT_a, UMLAUT_A) |
| รถ | UP(UMLAUT_o, UMLAUT_O) |
| รผ | UP(UMLAUT_u, UMLAUT_U) |
| ร | UM(UMLAUT_s) |
| ๐ | UM(SMILEY) |
| magic_a | magic:MAGIC_A |
| magic_b | magic:MAGIC_B |
| magic_c | magic:MAGIC_C |
| magic_d | magic:MAGIC_D:qu |
| magic_e | magic:MAGIC_E |
| magic_f | magic:MAGIC_F |
| magic_g | magic:MAGIC_G |
| magic_h | magic:MAGIC_H |
| magic_i | magic:MAGIC_I |
| tab โก๏ธ | custom:NEXT_TAB NoHold |
| win โก๏ธ | custom:NEXT_WINDOW NoHold |
| n't | custom:N_T |
| ing | custom:ING |
| ver | custom:PRINT_VERSION |
| CapW | custom:CAPS_WORDS |
| sn_case | custom:SNAKE_CASE |
| SN_CASE | custom:SCREAMING_SNAKE_CASE |
| camCase | custom:CAMEL_CASE |
| PasCase | custom:PASCAL_CASE |
| sl/case | custom:SLASH_CASE |
| do.case | custom:DOT_CASE |
| kb-case | custom:KEBAP_CASE |
| dead1 | custom:DEAD1 |
| dead2 | custom:DEAD2 |
| dead3 | custom:DEAD3 |
- should be usable with any keyboard layout
QMK: https://github.com/zeitlinger/qmk_firmware/tree/ferris
- run
mise run installto install the dependencies in QMK directory - run
mise run flashto flash the keyboard in this directory