Neovim
Neovim keybindings and recipes. Leader is Space. Config: one file per concern in
.config/nvim/lua/{config,plugins}/— seedoc/nvim/README.md.
Vim basics
Vim’s own motions and operators, not this config’s — they work anywhere vim bindings do.
Motion
- Left / down / up / right:
hjkl - Start of next / previous word:
w/b - Start / end of line:
0/$ - Start / end of file:
gg/G
Editing
- Insert before / after the cursor:
i/a - Delete line:
dd - Yank line:
yy - Paste after the cursor:
p - Undo / redo:
u/Ctrl+r
Files
- Save:
:w(this config also maps<leader>w) - Quit:
:q - Save and quit:
:wq - Quit without saving:
:q!
General
Save file:
<leader>wClear search highlight:
EscapeFormat buffer (conform.nvim; python = ruff):
<leader>fOpen diagnostic quickfix list:
<leader>qToggle file explorer (neo-tree):
\
Telescope / Fuzzy Finder
- Search help tags:
<leader>sh - Search keymaps:
<leader>sk - Search files:
<leader>sf - Search current word:
<leader>sw - Live grep:
<leader>sg - Search diagnostics:
<leader>sd - Resume previous search:
<leader>sr - Search recent files:
<leader>s. - Find existing buffers:
<leader><leader> - Fuzzy search in current buffer:
<leader>/ - Live grep in open files:
<leader>s/ - Find Neovim config files:
<leader>sn - Search Telescope pickers:
<leader>ss
LSP
Servers: basedpyright + ruff (python), clangd (C/C++), roslyn (C#), lua_ls.
- Rename symbol:
grn - Code action (ruff autofix, organize imports, …):
gra - Find references:
grr - Go to implementation:
gri - Go to definition:
grd - Go to declaration:
grD - Go to type definition:
grt - Document symbols:
gO - Workspace symbols:
gW - Toggle inlay hints:
<leader>th
Debug / DAP
Workflow, docker attach, launch.json: see nvim-debugging.
- Toggle breakpoint:
<leader>db - Conditional breakpoint:
<leader>dB - Start / continue (opens config picker):
<leader>dc - Run to cursor:
<leader>dC - Step into / over / out:
<leader>di/<leader>dO/<leader>do - Terminate:
<leader>dt - Toggle debug UI:
<leader>du - Eval expression under cursor:
<leader>de - Run last config again:
<leader>dl - Toggle REPL:
<leader>dr - Debug python test method / class:
<leader>dm/<leader>dM - VS Code style:
F5continue,F10over,F11into,F12out
Autocompletion (blink.cmp)
- Next item:
Ctrl+n - Previous item:
Ctrl+p - Scroll docs up:
Ctrl+b - Scroll docs down:
Ctrl+f - Confirm completion:
Ctrl+Space(orCtrl+y) - Cancel:
Ctrl+e - Next / previous snippet placeholder:
Tab/Shift+Tab
Tmux Navigation (vim-tmux-navigator)
- Navigate left:
Ctrl+h - Navigate down:
Ctrl+j - Navigate up:
Ctrl+k - Navigate right:
Ctrl+l - Navigate previous:
Ctrl+\
Mini.nvim Text Objects / Surrounds
- Visual select around parenthesis:
va) - Yank inside next quote:
yinq - Change inside single quotes:
ci' - Surround add inner word with parenthesis:
saiw) - Surround delete quotes:
sd' - Surround replace parenthesis with quotes:
sr)'
Recipes
Filtering through shell commands: :read !cmd inserts a command’s output below the
cursor, and :'<,'>!cmd replaces the selected lines with whatever the command makes
of them.
Insert the date
- Full:
:read !date→Sun Dec 21 01:24:39 PM CET 2025 - Date only:
:read !date +\%F→2025-12-21 - Date and time:
:read !date +\%F\ \%T→2025-12-21 13:35:47
% means “the current filename” inside :!, so every % in the format string has
to be escaped as \%.
Number a list
Select the lines, then filter them through nl:
:'<,'>!nl -w1 -s.
First item 1. First item
Second item → 2. Second item
Third item 3. Third item
-w1 is the number width, -s. the separator after it. The leading space on each
input line is what puts a space after the dot.
Count lines, words and characters across files
:read !wc -l -w -m ~/Repos/benou-site/content/docs/tools/* | sort -n
sort -n puts the biggest last; wc prints a warning line for any directory in the
glob, which you delete along with the rest once you are done reading it.
Find and replace in a selection
:'<,'>s/kangaroo/koala/gIc
g— every match on a line, not just the firstI— case-sensitive, whateverignorecaseis set toc— confirm each replacement
Because of I, a capitalised Kangaroo is left alone and needs a second pass.
Manual alternative, good when the matches want different treatment: ciw the first
one, then move to the next match and repeat with ..
Search for the text you just yanked
Yank it, press /, then Ctrl+r " to paste the unnamed register into the search
prompt. Walk the matches with n and N.
Maintenance
- Update plugins (review diff,
:wapplies,:qdiscards)::PackUpdate - What is installed, without fetching:
:PackStatus - Roll everything back to the lockfile:
:PackRestore - Delete plugins nothing references any more:
:PackClean - LSP / formatter / debugger installer:
:Mason - Attached servers for this buffer:
:LspInfo - Which formatter ran:
:ConformInfo - Diagnose problems:
:checkhealth