From 0a34e444cc5156b799ad57c6efac8b25a8046ad7 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Mon, 26 Oct 2026 09:53:34 +0100 Subject: tweak(user): remap vi navigation for Colemak-DH Oof, this feels good. Should've done this sooner. --- user/ideavim/ideavimrc | 41 ++++++++++++++++++++++++++++++ user/lesskey | 10 ++++++++ user/nvim/init.lua | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ user/readline/inputrc | 16 ++++++++++++ user/zsh/.zshrc | 19 ++++++++++++++ 5 files changed, 155 insertions(+) create mode 100644 user/lesskey diff --git a/user/ideavim/ideavimrc b/user/ideavim/ideavimrc index 81dc523..fed7bc9 100644 --- a/user/ideavim/ideavimrc +++ b/user/ideavim/ideavimrc @@ -1,4 +1,45 @@ set clipboard+=unnamed +" Put Vim's directional keys on the Colemak-DH home-row positions. +noremap k h +noremap K H +noremap n j +noremap N J +noremap e k +noremap E K +noremap i l +noremap I L + +" Move the displaced commands onto the old directional keys. Use `o` for +" insert/inner text objects and `l` for open-line/switch-selection-end. +noremap h e +noremap H E +noremap o i +noremap O I +noremap l o +noremap L O + +" Navigate search results. +noremap n +noremap N + +" Remap g-prefixed commands. +noremap gn gj +noremap ge gk +noremap g gn +noremap g gN +noremap gh ge +noremap gk gh + +" Focus a window in the given direction. +noremap k h +noremap h +noremap n j +noremap j +noremap e k +noremap k +noremap i l +noremap l + " Disable annoying bell sound. Note that visual bell isn't implemented so nothing will be heard or seen. set visualbell diff --git a/user/lesskey b/user/lesskey new file mode 100644 index 0000000..fd1af49 --- /dev/null +++ b/user/lesskey @@ -0,0 +1,10 @@ +#command +# Colemak-DH directional keys. +k left-scroll +n forw-line +e back-line +i right-scroll + +# Navigate search results. +\40 repeat-search +\kb reverse-search diff --git a/user/nvim/init.lua b/user/nvim/init.lua index a129800..a3c160b 100644 --- a/user/nvim/init.lua +++ b/user/nvim/init.lua @@ -1,6 +1,61 @@ -- Configure settings that apply to all filetypes. -- Filetype-specific settings live in after/ftplugin/. +-- Put Vim's directional keys on the Colemak-DH home-row positions. Move the +-- displaced commands onto the old directional keys; use `o` for insert/inner +-- text objects and `l` for open-line/switch-selection-end. +local colemak_mappings = { + k = 'h', -- left + K = 'H', -- top of screen + n = 'j', -- down + N = 'J', -- join lines + e = 'k', -- up + E = 'K', -- keyword lookup + i = 'l', -- right + I = 'L', -- bottom of screen + h = 'e', -- end of word + H = 'E', -- end of WORD + [''] = 'n', -- next search result + [''] = 'N', -- previous search result + o = 'i', -- insert / inner text object + O = 'I', -- insert at start + l = 'o', -- open line / switch selection end + L = 'O', -- open line above / switch selection end + + -- g-prefixed commands + gn = 'gj', -- down one display line + ge = 'gk', -- up one display line + ['g'] = 'gn', -- select next search result + ['g'] = 'gN', -- select previous search result + gh = 'ge', -- previous end of word + gk = 'gh', -- start Select mode +} + +for lhs, rhs in pairs(colemak_mappings) do + vim.keymap.set({ 'n', 'x', 'o' }, lhs, rhs) +end + +-- Focus or move a window in the given direction. +local colemak_window_mappings = { + ['k'] = 'h', -- focus left + [''] = 'h', + ['K'] = 'H', -- move left + ['n'] = 'j', -- focus down + [''] = 'j', + ['N'] = 'J', -- move down + ['e'] = 'k', -- focus up + [''] = 'k', + ['E'] = 'K', -- move up + ['i'] = 'l', -- focus right + [''] = 'l', + ['I'] = 'L', -- move right + [''] = 'n', -- new window +} + +for lhs, rhs in pairs(colemak_window_mappings) do + vim.keymap.set('n', lhs, rhs) +end + -- Don't break words in the middle. vim.opt.linebreak = true @@ -141,6 +196,20 @@ vim.keymap.set('n', '', function() pick.builtin.files({ tool = tool }) end, { desc = 'Pick files' }) +-- Neovim normally maps K to LSP hover on attach, but K is already used by the +-- Colemak mappings. Put hover on E in buffers whose LSP supports it instead. +vim.api.nvim_create_autocmd('LspAttach', { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client and client:supports_method('textDocument/hover', args.buf) then + vim.keymap.set('n', 'E', vim.lsp.buf.hover, { + buffer = args.buf, + desc = 'LSP hover', + }) + end + end, +}) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { desc = 'LSP: Go to definition', }) diff --git a/user/readline/inputrc b/user/readline/inputrc index b2cc9d6..7ff2533 100644 --- a/user/readline/inputrc +++ b/user/readline/inputrc @@ -1 +1,17 @@ set editing-mode vi + +set keymap vi-command +# Colemak-DH directional keys. +"k": backward-char +"n": next-history +"e": previous-history +"i": forward-char + +# Commands displaced by the directional keys. +"h": vi-end-word +"H": vi-end-bigword +"o": vi-insertion-mode +"O": vi-insert-beg + +# Navigate search results. +" ": vi-search-again diff --git a/user/zsh/.zshrc b/user/zsh/.zshrc index 06f4fb4..7fbcc6b 100644 --- a/user/zsh/.zshrc +++ b/user/zsh/.zshrc @@ -4,6 +4,25 @@ ## Key bindings # vi mode bindkey -v +# Put vi's directional keys on the Colemak-DH home-row positions. +# As in Neovim, `o` enters insert mode and `l` opens a line below. +bindkey -M vicmd 'k' vi-backward-char +bindkey -M vicmd 'n' down-line-or-history +bindkey -M vicmd 'e' up-line-or-history +bindkey -M vicmd 'i' vi-forward-char +bindkey -M vicmd 'h' vi-forward-word-end +bindkey -M vicmd 'H' vi-forward-blank-word-end +bindkey -M vicmd 'o' vi-insert +bindkey -M vicmd 'O' vi-insert-bol +bindkey -M vicmd 'l' vi-open-line-below +bindkey -M vicmd 'L' vi-open-line-above + +# Navigate search results. +bindkey -M vicmd ' ' vi-repeat-search +bindkey -M vicmd '^?' vi-rev-repeat-search + +# Move to the previous end of a word. +bindkey -M vicmd 'gh' vi-backward-word-end # default in Bash bindkey "^R" history-incremental-search-backward -- cgit v1.3.1