(root)/Notes/Notes/notes/vim.md RSS

Vim

a highly customizable text editor with efficient key bindings

see procedural memory, undo tree

resource vim bindings cheat sheet --- YLInLlY.png --- https://i.imgur.com/YLInLlY.png

resource :h quickref, specifically the key bindings --- https://vimdoc.sourceforge.net/htmldoc/quickref.html

resource :h registers, good reference on registers --- https://vimdoc.sourceforge.net/htmldoc/change.html#registers

resource :h help-summary, on using :help effectively --- https://vimdoc.sourceforge.net/htmldoc/usr_02.html#help-summary

vim bindings are susceptible to fossilization

some useful bindings not present in the quickref:

  • g+ - g- --- go to newer/older text state in the undo tree
  • :u!<cr> --- undo one change and remove it from the undo tree (Neovim only)
  • :undol<cr> --- list all leafs in the undo tree
  • Q --- replay last recorded macro (Neovim only)
  • q: - q/ - c<c-f> --- open command-line window
  • @: --- repeat the last command-line
  • gi --- resume insert at the position the last insert was stopped
  • i<c-e> --- abort an autocompletion (see |ins-compl| and |popupmenu|)
  • i<c-y> --- accept an autocompletion (see |ins-compl| and |popupmenu|)
  • gF --- edit the file under the cursor at the line specified
  • <c-w>F --- gF but in new window
  • gx --- netrw open the file under the cursor in external program
  • :cr<cr> - :lr<cr> --- rewind to the first quickfix/location list item
  • :cope<cr> - :ccl<cr> - :lop<cr> - :lcl<cr> --- open/close quickfix/location list window
  • :cpf<cr> - :cnf<cr> - :lnf<cr> - :lpf<cr> --- :cn/:cp/:ln/:lp until a new file is hit
  • :chi<cr> - :lhi<cr> --- display the quickfix/location list history
  • :col<cr> - :cnew<cr> - :lol<cr> - :lnew<cr> --- go to older/newer quickfix/location list in history
  • :ln<cr> - :lp<cr> - :ll<cr> - :lli<cr> --- :cn/:cp/:cc/:cl but for location list
  • :lmak - :lgr - :lv - :lh --- :mak/:gr/:vim/:helpg but for location list
  • vO --- switch the parity of vo in a blockwise selection
  • vg<c-a> - vg<c-x> --- incrementally increment/decrement numbers in selection
  • vP --- put from register without overwriting the unnamed register
  • c<c-r><c-w> --- insert the word under the cursor
  • c<c-r><c-a> --- insert the WORD under the cursor
  • c<c-r><c-l> --- insert the line under the cursor
  • gn - gN --- select next/previous match, applying an operator if one is pending
  • ov - oV - o<c-v> --- force the operator to work charwise/linewise/blockwise
  • ov --- when motion is charwise, toggle inclusive/exclusive
  • o2i' - o2i" --- oa'/oa" but without surrounding whitespace
  • i<c-x><c-e> - i<c-x><c-y> --- scroll from within insert mode
  • i<c-x><c-l> --- autocomplete the entire line, ignoring indent
  • i<c-x><c-l> --- after <c-x><c-l>, autocomplete subsequent lines
  • i<c-x><c-f> --- autocomplete from filenames in working directory
  • i<c-x><c-n> - i<c-x><c-p> --- after <c-n>/<c-p>, autocomplete subsequent words
  • i<c-x><c-i> - i<c-x><c-d> --- autocomplete from occurrences/definitions across includes
  • [i - [d --- display first occurrence/definition of word under cursor across includes
  • [I - [D --- display all occurrences/definitions of word under cursor across includes
  • [<c-i> - [<c-d> --- go to first occurrence/definition of word under cursor across includes
  • ]<c-i> - ]<c-d> --- go to next occurrence/definition of word under cursor across includes
  • <c-w>i - <c-w>d --- [<c-i>/[<c-d> but in new window
  • 1gd - 1gD --- gd/gD but ignore {} blocks before the cursor
  • vzy --- yank a block, remove trailing whitespace at the end of each line
  • vzp - vzP --- put a block, don't add trailing spaces to pad to the block's width
  • c<c-n> - c<c-p> --- recall next/previous command line
  • :mes<cr> --- view message history
  • i<c-g>k - i<c-g>j --- jump to column where insert was started, one line up/down
  • [% - ]% --- matchit.vim jump to beginning/end of %able group
  • g% --- matchit.vim cycle backward through %able groups
  • zs - ze - scroll so the cursor is on the left/right of the window
  • i<c-g>U --- prevent the next left/right cursor movement from closing the undo sequence
  • N<c-w>q --- quit Nth window
  • :tabs<cr> --- list open tabpages
  • :tabe<cr> --- open new blank tabpage
  • :tabe FILE<cr> - :tabf FILE<cr> --- :e FILE<cr>/:fin FILE<cr> but in new tabpage
  • :tab CMD<cr> --- run CMD but open tabpages instead of windows
  • <c-w>T --- move current window to new tabpage
  • <c-w>gf - <c-w>gF --- gf/gF but in new tabpage
  • :tabc<cr> --- close the current tabpage
  • :tabo<cr> --- close all tabpages but the current one
  • :tabm<cr> - :tabmN<cr> --- move current tabpage after last/Nth tabpage
  • :tabm#<cr> --- move current tabpage after last accessed tabpage
  • :tabm+<cr> - :tabm-<cr> --- move current tabpage right/left
  • gt - gT - Ngt --- go to next/previous/Nth tabpage
  • g<tab> - <c-w>g<tab> --- toggle between two most recent tabpages
  • :diffs FILE<cr> --- open FILE in new window and enable diff mode
  • :diffp PATCH<cr> --- apply PATCH in new window and enable diff mode
  • :difft<cr> - :diffo<cr> --- add/remove current window to/from the diff windows
  • :diffo!<cr> --- switch off diff mode for all windows of current tabpage
  • [c - ]c --- jump to previous/next diff change
  • Ndo - Ndp --- obtain/put a diff change from/to buffer number N
  • :bw<cr> --- :bd but actually delete the buffer; :bd just unlist it
  • :Nmat GRP /RE/<cr> --- temporarily highlight RE with GRP in current window
  • :Nmat<cr> --- clear previous :Nmat GRP /RE/<cr>
  • i<c-^> - c<c-^> --- toggle :lmap mappings
  • :wind<cr> - :bufd<cr> - :tabd<cr> - :cfd<cr> - :lfd<cr> - :ld<cr> --- shorter
  • :argdo<cr> - :cdo<cr> --- can't shorten
  • i<c-r><c-o> --- like i<c-r><c-r> but . uses register contents at the time of repeat
  • :1<cr> - :$<cr> - :N<cr> --- gg/G/Ngg but without changing the jumplist

useful shell bindings spread a little all over the quickref:

  • :!cmd --- run shell command cmd
  • :r!cmd --- read in output of shell command cmd
  • v:w !cmd --- write out selected lines to shell command cmd
  • !!cmd --- filter current line through shell command cmd
  • !motion cmd --- filter motion motion through shell command cmd
  • v!cmd --- filter selected lines through shell command cmd

some "compound" bindings to be treated as units for procedural memory:

  • ea --- insert after word
  • Ea --- insert after WORD
  • o<esc> - O<esc> --- insert a blank line below/above
  • Jx --- join lines, removing all leading whitespace
  • Jde --- join lines, removing leading word (like // c comments and - markdown lists)
  • xp --- swap a character with the next
  • ddp --- swap a line with the next
  • r<cr> --- split a line at the cursor position
  • m' --- push current cursor position onto the jumplist (well kind of)
  • == --- push current text state onto the undo tree (well kind of)
  • 99g+ --- jump to the latest change in the undo tree
  • 99<c-r> --- jump to the latest change in the current undo tree branch
  • *N --- highlight the word under the cursor
  • 0D --- clear out the current line without deleting it
  • VP --- replace the current line with the contents of the unnamed register
  • <cr>; - -; --- repeat last f/t search on the next/previous line
  • gon - GN --- repeat last //? search from the start/end of the buffer
  • <c-^><c-w>^ --- reopen just-opened buffer in new window instead
  • <space><bs> - <bs><space> --- set curswant to the current column number

some small tricks and workflows I use:

  • peek at occurrences of a pattern---without clobbering the last search or cluttering up the jumplist---with /re, then <c-g> and <c-t>, then <esc>
  • quickly repeat a compound change by recording it with the usual qqcommandsq then mashing Q (Neovim only)
  • perform an interactive substitution with /re, then cgnreplacement<esc> or dgn, then skip with n and repeat with . --- more flexible than :s/.../c<cr>
  • interactively append a suffix to the end of matches with /re/e<cr>, then asuffix<esc>, then skip with n and repeat with .
  • keep or delete lines matching a pattern with :g/re/d<cr> and :v/re/d<cr>
  • grep recursively from the working directory with :vim/re/**<cr>; matches are put in the quickfix list

    note turn :fin into a fuzzy finder with set wildmenu path+=** --- https://youtu.be/XA2WjJbmmoM?t=6m44s

  • when it exists, print the digraph for the character under the cursor using ga

    note useful digraphs worth memorizing: “”‘’‥…•·‾–—   §¶№¢ °′″‴ µΩÅ℃℉ ×÷−±∓∗∘∙⋅∶∷∴∵∼≈≡≤≥≮≯≠∞∝ √⌈⌉⌊⌋∫∏∑∂∆∇αβγ ∃∀∧∨¬∩∪∈∋∅⊂⊃⊆⊇ ⅠⅡⅢⅩⅪⅫⅰⅱⅲⅹⅺⅻ ½⅔¾₀₁₂₊₋₍₎⁰¹²⁺⁻⁽⁾ⁿ

  • if 'noruler' is set, query the cursor position with <c-g>
  • query the word count for a selection and for an entire buffer with g<c-g>
  • append a suffix to the end of a range of lines with <c-v>selection$Asuffix<esc>
  • edit the current command-line in normal mode with <c-f>
  • move left and right, wrapping across lines, with <bs> and <space> --- by default, <bs> and <space> are in 'whichwrap' while h and l are not
  • jump to the first byte of a file with go --- gg won't go to the first byte when 'nostartofline' is set

    resource Byte Positions Are Better Than Line Numbers, by Casey Muratori --- Byte Positions Are Better Than Line Numbers.pdf --- https://www.computerenhance.com/p/byte-positions-are-better-than-line

  • hold the shift key to temporarily disable the mouse
  • view a searchable digraph table with :h euro<cr>
  • jump to a URL or path on the current line with f/ and F/ --- slashes are uncommon and URLs and paths usually contain them
  • use undos from within insert mode by marking undo points with <c-g>u and undoing with <c-o>u. delete all entered characters with <c-u>
  • temporarily isolate a window with <c-w>|/<c-w>_ then revert to equal window size with <c-w>=
  • insert something of the form first second first third using ifirst<esc>asecond<c-a>third
  • repeat a change with a different motion using cmotion replacement then cmotion<c-a>
  • fill out one cell of a plaintext table with gRcell contents then move to the next cell up/down with <c-g>k/<c-g>j
  • perform a * without clobbering the last search with ]<tab> aka ]<c-i>
  • set curswant to the current column number by hitting <space> and <bs> simultaneously
  • delete the current buffer without closing the window by editing another buffer with say <c-^> then running :bd#<cr> or :bw#<cr>
  • delete an entire if/for/while (...) { ... } construct with dVaB
  • to edit binary files use :e ++enc=ansi<cr> or :se fenc=ansi<cr> --- each glyph is one byte, ga works, i<c-v> works, etc.
  • put a blockwise register linewise using :pu<cr>; put a linewise register charwise using vp
  • quit Vim without writing to the viminfo file with :se vi=|q<cr>

Vim patterns support a \& operator that may look like regular expression intersection, but unfortunately it's just a lookahead because the subpattern matches are not required to end at the same positions. what a shame