Welcome to my personal Neovim config, and its incomplete documentation ;).
Always WIP.
Code outline/symbol tree. Supports LSP, treesitter, and markdown.
| Key | Action |
|---|---|
gO |
Toggle aerial outline |
Possible alternatives:
"nvim-cmp source for omnifunc." omnifunc allows other plugins to provide autocomplete options, for example vimtex.
"Tmux completion source for nvim-cmp."
Insert debug print statements with file/line info and variable values. Supports 40+ languages.
Keymappings:
| Key | Action |
|---|---|
g?p / g?P |
Insert plain debug print below/above |
g?v / g?V |
Insert variable debug print below/above (auto-detects variable under cursor) |
Commands:
| Command | Action |
|---|---|
:Debugprint delete |
Remove all debug statements |
:Debugprint commenttoggle |
Toggle comments on debug lines |
Enhanced <C-a>/<C-x> increment/decrement with support for booleans, dates, and more.
| Key | Action |
|---|---|
<C-a> |
Increment (numbers, booleans, dates) |
<C-x> |
Decrement |
g<C-a> |
Increment (sequential in visual) |
g<C-x> |
Decrement (sequential in visual) |
Supports: true/false, yes/no, on/off, enable/disable, dates (2025-01-04), numbers.
Possible alternatives:
- boole.nvim
- nvim-toggler
- vim-speeddating (only handles dates)
Nice git diffs with filelists.
Commands:
| Command | Action |
|---|---|
:DiffviewOpen origin/main...HEAD -- lua/diffview plugin |
show diff between origin/main and HEAD for lua/diffview and plugin |
:DiffviewRefresh |
Update stats and entries in the file list of the current Diffview |
:DiffviewFileHistory include/this and/this :!but/not/this |
Opens a new file history view that lists all commits that affected the given paths |
Possible alternatives:
Adds support for EditorConfig to neovim. It sets settings like indentation based on the EditorConfig config file.
Hex editor inside vim.
Commands:
| Command | Action |
|---|---|
:HexDump |
show hex view |
:HexAssemble |
show "normal" view |
:HexToggle |
toggle between views |
"This plugin adds indentation guides to all lines (including empty lines). It uses Neovims virtual text feature and no conceal"
Possible alternatives:
"lazydev.nvim is a plugin that properly configures LuaLS for editing your Neovim config by lazily updating your workspace libraries."
"Leap is a general-purpose motion plugin"
Keymappings:
| Key | Action |
|---|---|
r |
followed by 2 characters offers an selection to jump to one of the matches (after the cursor) |
R |
same as r, but backwards / before the cursor |
r |
same as r, but for operator-pending mode, for example after a d |
R |
same as R, but backwards and for operator-pending mode, for example after a d |
"Entering traversal mode after the first input is a useful shortcut, especially in operator-pending mode, but it can also be used as a substitute for normal-mode f/t motions. s{char}<enter> is the same as f{char}, but works over multiple lines."
Possible alternatives:
Show function signature as you type.
Helpers for configuring LSP servers.
"A blazing fast and easy to configure Neovim statusline written in Lua."
Possible alternatives:
Snippet engine written in Lua.
Keymappings:
| Key | Action |
|---|---|
<C-k> |
Expand the snippet under the cursor or jump to the next insert node |
<C-j> |
Jump to the previous insert node |
<C-l> |
Choose the next choice in a choice node |
"Markdown Preview for (Neo)vim". Browser-based preview with synchronized scrolling.
Possible alternatives:
- peek.nvim (requires Deno)
"bridges mason.nvim with the lspconfig plugin - making it easier to use both plugins together."
Note: run :PylspInstall pylsp-mypy pyls-isort pylsp-rope after installing pylsp (see README).
esbonio is the Sphinx/reStructuredText language server. It was set up, measured against a real project and then dropped again. This section exists so the evaluation does not get repeated.
What it delivers, all of it verified rather than taken from the docs:
- completion for
:ref:and:doc:from the built object inventory - live
undefined label: '...'diagnostics, which thedoc8/rstcheck/sphinx-lintpass in the wiki build scripts does not catch, because resolving labels needs Sphinx itself - document symbols, feeding the nvim-navic breadcrumb
What it costs:
- a background Sphinx build per project, cached under
~/.cache/esbonio/ - a first build that is slow and silent: completion returns nothing until it finishes, with no progress indication, which is indistinguishable from a broken setup
- esbonio pinned in the docs venv, because it imports
conf.pyand every Sphinx extension the project uses. Mason's build ships esbonio without Sphinx and is therefore unusable - a
[tool.esbonio.sphinx]section with an explicitbuildCommandin every project whoseconf.pysits outside the source root, since esbonio only auto-detectsconf.pyby walking upwards from the open file
Verdict: the gain is cross-reference completion plus catching broken references before the build.
For prose-heavy wikis with few cross-references that does not carry the moving parts, so esbonio is
absent from ensure_installed and from vim.lsp.enable().
Two findings worth keeping if this is ever revisited:
- mason-lspconfig hardcodes
cmd = { 'esbonio' }, but esbonio v2 needs a subcommand. The bare call prints its usage and exits 0, so the server never attaches, and neither:checkhealthnor the LSP log reports an error. A working command is{ '~/venvs/sphinx/bin/python', '-m', 'esbonio.server' }. Updating the plugins does not fix this: nvim-lspconfig corrected its own default, but the mason-lspconfig override wins over it. python -m esbonio sphinx -c pyproject.toml buildruns the server's build path from the shell, which is the fastest way to tell a broken config from a build that is merely still running. The-cgoes before thebuildsubcommand.
- Grammar/Spell Checker
- ltex is configured with
autostart = falsebecause it's resource-intensive (runs LanguageTool via Java). To use it:
:LspStart ltex- Start the LSP server manually:Lazy load ltex-extra.nvim- (Optional) Load extra features for dictionary management
Extended text objects with treesitter support. Works alongside nvim-treesitter-textobjects which provides the movement commands (]m, [[, etc.) while mini.ai handles the text object selection.
| Key | Action |
|---|---|
if/af |
Function (inner/around) |
ic/ac |
Class |
ia/aa |
Argument/parameter |
ii/ai |
Indent block |
iq/aq |
Quotes (', ", `) |
ib/ab |
Brackets ((), [], {}) |
it/at |
HTML tags |
Use with operators: daf (delete function), ciq (change inner quotes), vai (select indent block), etc.
Show available keybindings in a floating window after pressing a prefix key. Includes "submodes" for window operations.
After <C-w> you can keep pressing:
h/j/k/lto navigate windows+/-/</>to resize windows
Note on plugin mappings: Plugin mappings with doubled letters (like gcc from mini.comment) need explicit clues. The gen_clues.*() functions only know about built-in Vim commands. When you press gc, mini.clue doesn't know that another c can follow, so the second keypress gets lost. Fix this by adding { mode = 'n', keys = 'gc', postkeys = 'g' } to tell mini.clue to keep listening after gc.
Possible alternatives:
- which-key.nvim
- hydra.nvim (alternative for
postkeys)
Comment/uncomment lines with treesitter support via ts_context_commentstring.
Keymappings:
| Key | Action |
|---|---|
gc{motion} |
Toggle comment over motion |
gcc |
Toggle comment on current line |
gc (visual) |
Toggle comment on selection |
Possible alternatives:
Text edit operators for replace, exchange, and sort.
| Key | Action |
|---|---|
gz{motion} |
Replace with register |
gzz |
Replace line |
gz (visual) |
Replace selection |
gx{motion} |
Exchange text (use twice to swap) |
gxx |
Exchange line |
gs{motion} |
Sort text |
gss |
Sort line (characters) |
Possible alternatives:
- opsort.vim (would support visual-block column sorting / sorting lines by selected column)
Split and join arguments, array elements, etc. Toggles between single-line and multi-line formats.
| Key | Action |
|---|---|
gS |
Toggle split/join |
Examples: gS on foo(a, b, c) splits to multi-line; gS again joins back.
Possible alternatives:
Add, delete, replace surrounding pairs (brackets, quotes, tags, etc.).
| Key | Action |
|---|---|
sa{motion}{char} |
Add surrounding |
sd{char} |
Delete surrounding |
sr{old}{new} |
Replace surrounding |
sf{char} |
Find surrounding (forward) |
sF{char} |
Find surrounding (backward) |
sh{char} |
Highlight surrounding |
Examples: saiw" (surround word with quotes), sd" (delete quotes), sr"' (replace " with ').
Possible alternatives:
"A completion engine plugin for neovim written in Lua." Configured with sources for LSP, buffer, path, cmdline, snippets, tmux, calc, and omni.
Keymappings:
| Key | Action |
|---|---|
<C-d> |
scroll docs down |
<C-f> |
scroll docs up |
Possible alternatives:
- mini.completion (simpler, but fewer sources - no tmux, path, calc, etc.)
"A simple statusline/winbar component that uses LSP to show your current code context." Useful for seeing the current position in large JSON files.
Commands:
| Command | Action |
|---|---|
:lua require'nvim-navic'.get_location() |
Returns a pretty string with context information. |
Shown in the lualine statusline as the first component of section x, via navic's own navic component. Passing get_location by reference does not work: lualine calls function components as fn(self, is_focused), so the boolean ends up in navic's bufnr argument and the component silently renders empty in the focused window.
"A Neovim plugin for setting the commentstring option based on the cursor location in the file. The location is checked via treesitter queries."
Comment.nvim has in-built treesitter support, but recommends to use this plugin for "advanced use cases".
Helped me prevent Comment.nvim: nil messages.
Subword motion - w, e, b stop at camelCase, snake_case boundaries and skip insignificant punctuation.
| Key | Action |
|---|---|
w |
Move to next subword |
e |
Move to end of subword |
b |
Move to previous subword |
Example: myVariableName → 3 stops (my, Variable, Name) instead of 1.
Possible alternatives:
"A vim-vinegar like file explorer that lets you edit your filesystem like a normal Neovim buffer", basically better vidir.
Keymappings:
| Key | Action |
|---|---|
- |
open parent directory |
Possible alternatives:
Align text by delimiter. Uses vim regex.
Possible alternatives:
- mini.align (uses Lua patterns instead of regex)
"A simple, vimscript only, command runner for sending commands from vim to tmux." My fork of https://github.com/christoomey/vim-tmux-runner.
| Key | Action |
|---|---|
<leader>r |
Run a command in the attached tmux pane |
<leader>sc |
Set the command to be run |
Commands:
| Command | Action |
|---|---|
:VtrAttachToPane |
Attach to a pane |
Provides a yank-ring, allowing cycling through the yank history on paste. Also highlights yanks and pastes.
Keymappings:
| Key | Action |
|---|---|
<C-n> |
Cycle forward through the yank-ring. |
<C-p> |
Cycle backwards through the yank-ring. |
<leader>p |
Paste after from the system clipboard. |
<leader>P |
Paste before from the system clipboard. |
clipboard is intentionally not set to unnamedplus. Yanks go to the unnamed
register with their original indentation preserved (so in-editor p/P keep the
layout), while a TextYankPost autocmd (lua/config/autocmds.lua) mirrors a
dedented copy to the system clipboard — the common leading indentation is
stripped so pasting into other apps comes out flush-left. Use <leader>p /
<leader>P to paste the raw system-clipboard content back into Neovim.
Possible alternatives:
Description
Keymappings:
| Key | Action |
|---|---|
| 1 | 2 |
Commands:
| Command | Action |
|---|---|
| 1 | 2 |
Possible alternatives:
Also see my neovim todo GitHub stars.