ANSI keyboard layout to maximize actions per minute.
- Colemak-DH foundation
- Improved for thumb typing
- Better-placed modifier keys
- Navigation row
- Dead keys for symbols
- Number Layer
Note
These will overwrite existing destination files. Your original files such as evdev.xml will be saved as evdev.xml.bak
git clone --filter=blob:none --depth=1 https://github.com/amesaine/colejak
cd colejak
mkdir --parents $HOME/.config/xkb/rules
mkdir --parents $HOME/.config/xkb/symbols
cp --suffix=.bak rules/* $HOME/.config/xkb/rules/
cp --suffix=.bak symbols/* $HOME/.config/xkb/symbols/
cp --suffix=.bak .XCompose $HOME/.XCompose
git clone https://github.com/amesaine/colejak
cd colejak
mkdir --parents $HOME/.config/xkb
ln --symbolic --suffix=.bak $(realpath rules) $HOME/.config/xkb/rules
ln --symbolic --suffix=.bak $(realpath symbols) $HOME/.config/xkb/symbols
ln --symbolic --suffix=.bak $(realpath .XCompose) $HOME/.XCompose
Sway
input type:keyboard {
xkb_layout colejak(default)
}
Gnome
Search for Colejak in gnome-control-center > Keyboard > Input Sources
Neovim
local override = function(modes, new, default, desc, custom_behavior)
local behavior = default
if custom_behavior then
behavior = custom_behavior
end
vim.keymap.set(modes, default, "<nop>")
vim.keymap.set(modes, new, behavior, { desc = desc })
end
override({ "n", "v", "o" }, "<C-Y>", "<C-R>", "Redo")
vim.keymap.set("n", "<C-S>", "<CMD>w<CR>", { desc = "Save File" })
vim.keymap.set("i", "<C-S>", "<ESC><CMD>w<CR>", { desc = "Save File" })
vim.keymap.set("n", "<C-Q>", "<CMD>q<CR>", { desc = "Quit Pane" })
vim.keymap.set("n", "<C-S-Q>", "<CMD>qa!<CR>", { desc = "Force Quit Vim" })
override({ "n", "v", "o" }, "<C-Left>", "b", "Jump previous word")
override({ "n", "v", "o" }, "<S-Left>", "B", "Jump previous whitespace")
override({ "n", "v", "o" }, "<C-Right>", "w", "Jump next word")
override({ "n", "v", "o" }, "<S-Right>", "W", "Jump next whitespace")
override({ "n", "v", "o" }, "<C-Home>", "gg", "Jump first line")
override({ "n", "v", "o" }, "<C-End>", "G", "Jump last line")
vim.keymap.set({ "n", "v", "o" }, "<Home>", "^", { desc = "Jump to first char of current line" })
vim.keymap.set({ "i" }, "<Home>", "<C-o>^", { desc = "Jump to first char of current line" })
override({ "i", "c" }, "<C-H>", "<C-W>", "Kill word before cursor")
vim.keymap.set({ "n" }, "<C-H>", "db", { desc = "Kill word before cursor" })
vim.keymap.set({ "n" }, "<C-BS>", "db", { desc = "Kill word before cursor" })
override({ "i", "c" }, "<C-BS>", "<C-W>", "Kill word before cursor")
vim.keymap.set({ "i" }, "<C-Del>", "<Esc><Right>dwi", { desc = "Kill next word from cursor" })
vim.keymap.set({ "n" }, "<C-Del>", "dw", { desc = "Kill next word from cursor" })
vim.keymap.set({ "n" }, "<S-Del>", "dW", { desc = "Kill to whitespace from cursor" })
override("n", "<BS>", "x", "Kill char before cursor", "<Left>x")
override("v", "<BS>", "x", "Remap x to Backspace")
Vimium
unmapAll
map h scrollLeft
map <down> scrollDown
map <up> scrollUp
map <s-right> scrollRight
map <s-left> scrollLeft
map <home> scrollToTop
map <end> scrollToBottom
map <s-down> scrollPageDown
map <s-up> scrollPageUp
#focusing
map se focusInput
map t LinkHints.activateMode
map T LinkHints.activateModeWithQueue
map yt LinkHints.activateModeToCopyLinkUrl
#tabs
map <left> previousTab
map <right> nextTab
map <c-left> moveTabLeft
map <c-right> moveTabRight
map wt moveTabToNewWindow
map ? showHelp
nplseriaocm
Lesskey (Man Pages)
#command
\kl goto-line # left
\e[1;2B forw-scroll # shift down
\e[1;2A back-scroll # shift up
\kr goto-end # right
h quit
Cons:
- Each period, comma, and whatever else common symbol that you use will all take two keystrokes.
- Any behavior involving modifier key + symbol will not work through the dead key.
- This is hard/impossible to setup on Windows and MacOS.
- If you need dead keys for international symbols, you'd be using the worse Compose key which takes three keystrokes total. Although we do have three dead key types (grave, tilde, acute) so hopefully you don't run out lol.
- High learning curve
- Some browsers don't respect .XCompose (Firefox LTS on Debian). It does work in Brave though.
This is a tradeoff for:
- Significant increase in accuracy
- Fingers stay at/near homerow
Things to take note of:
- Vim keybinds and any application keybinds with symbols still work as long as it's the symbol alone. This means typing ":" in vim through dead keys still bring up the command line. In some websites however, this is finicky. (Discussed later)
Found inside .XCompose
Modifier_key + number
such as Ctrl + 1
won't work with this layer. A workaround
would be to have a Colejak variant. A.k.a you switch layouts everytime you want to
use to Modifier_key + number
and switch back.
Note
On Sway, you can add Mod5
to your config. Mod4 + 1
-> Mod4 + Mod5 + 1
Found inside symbols/colejak
We've now essentially brought the number row to the home row. This unlocks a whole row for remapping. What better keys to map than to place navigation-related keys here. Pros:
- Layout agnostic hjkl movemet + Home/End (no more getting confused with gg and G!).
- Arrow keys enable vim motions in ALL applications and textboxes.
- Vim motions in insert mode(??? for the lazy a.k.a me)
Especially within textboxes, here are available motions beyond hjkl:
- Word skipping -
Control+arrow
- Start/End of a line -
Home
/End
- Start/End of textbox -
Control+Home
/Control+End
- Visual mode - Hold shift while doing all the goodies above.
Dead Keys and the Compose Key are special "combo keys" that allow you to type
a character by combining multiple key presses. Dead Keys are two-combo keys,
commonly used for international symbols and diacritical marks, and come in types
such as grave, tilde, and acute, which should not be confused with the standard
grave and tilde keys. When pressed followed by a letter, they produce a special
character, like dead_tilde + n
outputting ñ
. Unlike the Shift key, which modifies
the next key press only when held down simultaneously, Dead Keys modify the next
key press even after they've been released.
- Use vim motions in your editor
- Install vimium in your browser
- Use a tiling window manager
- Install warpd
You'd reach for the mouse maybe 1-20 times a week. And if you're on a laptop, the trackpad is within thumb's reach. Guaranteed productivity gains.
I did it in 3 weeks just typing my brains out, averaging 100 wpm after 50 hours of typing tests. Here's how:
- Monkeytype English until 50 wpm average.
- Keybr. Apply these settings:
- 60 wpm target speed.
- Unlock next key only when the previous keys are also above the target speed.
- Beat all letters.
- Monkeytype
English 5k
until 80 wpm average. - PR 132 wpm on
Monkeytype English
. - Diversify wordsets
- Monkeytype
code rust
for numbers and symbols - Monkeytype
quotes
- Monkeytype
code javascript
for common programming words
- Monkeytype
No. And I don't recommend doing anything this complicated to your TTY settings... here be dragons
I don't have money for a $400 ergonomic keyboard. Also, maximizing ergonomics within the constraint of an ANSI layout means that this is guaranteed to work and feel better on an ortholinear, split, or whatever keyboard as is.
XKB Configuration Files Documentation
Libxkbcommon commit: Allow for custom rulesets through include files
Extending system layouts with custom variants
Youtube video where I discovered the blog posts from
This only works on Wayland and XWayland
Where I discovered about XCompose and Dead Keys (DreymaR's Big Bag)
- Created with keyboard-layout-editor.com.
- JSON for all layouts are available in assets.
- KCX Qwerty is my old layout. Improved with modifier/special keys closer to the homerow.
This instead extends the default
symbols/us(basic)
layout which some may find useful.