(Neo)Vim

Published Sat 1 Feb 2025. Last update Tue 18 Feb 2025.
A post in the series.

I used to use Neovim as my main development environment. I like the fact that it’s small and fast, and that I can use it over an SSH connection. Neovim is a fork of Vim that I use for the Lua configuration and built-in Language Server Protocol support.

However, I mainly use Emacs these days. I extensively use evil (a Vi(m) compatibility layer for Emacs), so I haven’t really stopped using Vim but instead just use it inside a big Lisp machine.

You can find my configuration in my NixOS repository here.

Below are my working notes on learning and using (Neo)Vim.


  • References:
    • :help usr_toc.txt
    • :help index
  • ZZ / ZQ exit with / without saving
  • basic motions
    • h j k l
    • i I a A 0 $
    • w e b W E B
    • CTRL-e CTRL-d CTRL-u CTRL-y CTRL-f CTRL-b CTRL-b CTRL-f
    • / ?
    • n N
    • f t F T ;
    • G gg
    • object selection
      • iw inner word
      • aw a word (incl whitespace)
      • is / as sentence
      • ip / ap paragraph
      • i] / a]
      • i) / a)
      • i> / a>
      • i" / a"
      • i' / a'
      • it / at <tag> </tags>
  • basic operators
    • d c y double for a line
    • r R
  • basic commands
    • x
    • p P
    • u U CTRL-r
    • o O
    • :%s/x/y/g
    • :%s/x/y/gc with confirmation
    • #,#s/x/y/g replaces in selected line numbers
    • :%s/\(.\).../...\1/ regex capture
    • :norm
    • :nohls / :set hls
    • :reg / yA / "Ap
  • options
    • set options with :set <option>
    • prefix with no or inv
    • 'ic' ignore case
    • 'hls' highlight case
    • is incremental search
  • Enter to follow links
  • :help / K on word for documentation
  • help usage
    • mode prefix, e.g. :help i_CTRL+W
    • options, e.g. :help 'number'
    • special keys, e.g. :help i_<Up>
    • error codes :help E37
  • % jump to matching bracket
  • '<,'>w FILE - writes part of a file selected in visual mode
  • :r retrieve file or result of external command
  • CTRL-w CTRL-w switch window
  • c_CTRL-D and <Tab> command line completion
  • :d//<pattern>/
  • :g/<pattern>/<command>/
  • jump list CTRL-I CTRL-O
  • tag stack CTRL-] CTRL-T
  • J join lines (remove new lines)
    • gJ remove spaces too
  • gO help TOC
  • ( ) { } [ ] sentences/paragraphs/sections forwards/backwards (quickref)
  • spelling set language :setlocal spell spelllang=en_gb
    • ]s / [s move misspells
    • z get suggestions
    • insert mode: CTRL-Xs
    • add to spellfile zg
    • added shortcut for CTRL-S to ]s1z=
    • spell file in ~/.config/vim/spell.en.utf-8.add
  • searching repo / fuzzy match
    • telescope.nvim plugin
      • <leader><leader> find files
      • <leader>bb buffer search
      • <leader>fQ commands
      • <leader>fQ command history
      • <alt-q> open in quickfix
      • <leader>fd telecope file browser
        • iCTRL-t / nt change directory
        • e home
        • w current dir
  • :mksession and vim -S <file> to save/restore a session
  • g commands
    • gj gk g0 g$ gq(q)
    • gu(u) gU _{ g}(~)
    • gf gx
    • gv
    • g&
  • C-6 / C-^ / :b# go to last buffer
  • marks
    • make m{a-zA-Z}
      • NB a-z are file local
    • jump to line '{a-zA-Z}
    • jump to column `{a-zA-Z}
    • `` / '' previous mark
  • indent
    • << >>
    • i_CTRL-t i_CTRL-d
    • =<motion> or == for line
  • window management
    • :help windows
    • c / :close
    • o / :only
    • res / vert res
  • tab management
    • :tabnew
    • CTRL-wT
    • gt / gT
  • buffer management
    • :bd / :bn / :bp
  • Markdown formatting a la tutor
  • folds
    • zf create
    • zo open
    • zO open rec
    • zc close
    • zC close rec
    • za toggle
    • zA toggle rec
    • zi fold enable
    • :help usr_28.txt
    • :help folding
    • with markdown folding, we don’t want to have a file all folded on open
      • if we set nofoldenable, enabling any fold will enable them all
      • so we set foldlevel: 99
    • zM close all folds, set foldlevel=0
    • zR close all folds, set foldlevel=highest
    • zm / zr decrement/increment foldlevel
  • q: command line editing in normal mode
  • :ls t list buffers in recently used order
  • paste in insert mode i_CTRL-r
  • see lsp servers :lua =vim.lsp.get_active_clients()[1]
  • gi to enter insert mode at the place in the file where you last left it
  • i_CTRL-o perform one normal mode command
  • surround with brackets ciW""EscP
    • or with (n)vim-surround ysiW"
      • change with cs'"
      • NB open brackets add space and closed don’t
      • change including tags ysa"[
      • change brackets e.g. =cs[{=
      • visual mode: S
      • delete ds<motion>
  • insert date
    • expression register "=strftime('%F')
    • or in insert mode <C-r>=strftime('%F')
  • macros
    • record q<char><recording>q
    • replay @<char> reply last @@
    • Q repeat last recorded register [count] times
    • macros paste to the register, e.g. qrlq"rp will produce l
      • you can set macros from plain text in the inverse too
  • comment.nvim gcc line or gc<motion>
  • vimtex
  • gq format
  • netrw :Ex
    • % for file
    • d for dir
  • :h Select-mode
  • quickfix menu
    • copen (populated by search, e.g. :grep or telescope)
    • cdo %s/replace/with/gc
    • cdo w
    • and after make copen
    • cn cp
  • :changes
    • g; g,
  • :set paste
  • zz centre on line
  • register % / # current / prev file
  • gs go to sleep
  • gO outline
  • * / # search word under cursor
  • {Visual}g CTRL-A increment list
  • [% go to containing [
  • :g/^/m 0 Reverse line order :help 12.4
  • :e %:h/file another file in current file’s directory
    • more expansions at :help expand
  • luasnip insert node puts you in select mode
    • you can exit it and append with <Esc>Ea
    • they continue with <C-l>
  • r!<command> insert command output
  • . repeat last change
  • groking vim

issues:

to-do: