[NeoVim] Convenient Markdown Mappings
In the quiet economy of plain text editing, Markdown is the practical standard: terse enough for version control, expressive enough for publication, portable across platforms. Still, every formatting character—asterisks, tildes, brackets—interrupts the flow from thought to text.
-- ftplugin/markdown.lua
-- visual-mode transformations
vim.keymap.set('v', '<localleader>s', 'c~~<C-r>"~~')
vim.keymap.set('v', '<localleader>b', 'c**<C-r>"**')
vim.keymap.set('v', '<localleader>i', 'c_<C-r>"_')
vim.keymap.set('v', '<localleader>t', 'c[<C-r>"]()<Left>')
vim.keymap.set('v', '<localleader>u', 'c[](<C-r>")<C-o>F]')
vim.keymap.set('v', '<localleader>`', 'c`<C-r>"`')
-- normal-mode (word under cursor)
vim.keymap.set('n', '<localleader>s', 'viwc~~<C-r>"~~<Esc>')
vim.keymap.set('n', '<localleader>b', 'viwc**<C-r>"**<Esc>')
vim.keymap.set('n', '<localleader>i', 'viwc_<C-r>"_<Esc>')
vim.keymap.set('n', '<localleader>t', 'viwc[<C-r>"]()<Left>')
vim.keymap.set('n', '<localleader>u', 'viwc[](<C-r>")<C-o>F]')
vim.keymap.set('n', '<localleader>`', 'viwc`<C-r>"`<Esc>')
These mappings are defined in nvim/ftplugin/markdown.lua so they remain scoped exclusively to markdown files. They replace the usual snippet machinery with two primitive motions: visual-mode change (c) and register recall (<C-r>"). When I select a text object, viw for word, vip for the paragraph, c yanks the selection into the unnamed register while simultaneously deleting it, leaving the cursor in insert mode. The literal delimiters that follow (~~, **, _ back-ticks, brackets) are typed by the mapping itself. Finally <C-r>" regurgitates the captured text inplace. The register acts as a ghost writer; it stores exactly what I selected, with no whitespace jitters or newline stowaways.
I have two leaders which serve distinct purposes. I bind my localleader to ,, which handles mappings tied to filetype or buffer options, and the spacebar is reserved for global/plugin edicts.
After inserting a link skeleton the mapping lands the cursor where further text is required—inside the empty brackets if you invoked ,t, inside the parentheses if you invoked ,u. One may therefore alternate title and URL without leaving Insert mode.
Imagine you maintain a Hugo site, as I do—academic essays, perhaps, or a technical notebook. We take the following sentence as an example.
The Rosenbrock function is a unimodal function, that serves as a test problem for gradient-based optimization algorithms.
You can therefore do something like:
viwselects Rosenbrock;,bwraps it in**(bold). The cursor remains after the closing delimiter, ready for further text.- Reference links: highlight “optimization algorithms”, press
,twhich leaves you with[optimization algorithms]().
Typographic intent is conveyed in keystrokes measured in the dozens; hand-eye latency is imperceptible.
In practical terms, a mapping such as ,b saves four characters—** before, ** after; plus the need to exit Insert, reposition, and re-enter. If a session of writing contains a hundred such operations, the savings exceed thousand keystrokes. More importantly, these mappings reduce context switching. Interrupting prose to manually type formatting syntax, fragments attention and disrupts the flow of composition. Reducing these actions to single keystrokes maintains focus on the writing itself rather than its mechanical production."
Optimizing your editor matters for the same reason optimizing code does, because efficiency compounds. Good keybindings fade into muscle memory, letting you focus on the work rather than fighting your tools.