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:helpeffectively --- 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:undol<cr>--- list all leafs in the undo treeQ--- replay last recorded macro (Neovim only)q:-q/- c<c-f>--- open command-line window@:--- repeat the last command-linegi--- 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---gFbut in new windowgx--- netrw open the file under the cursor in external program:cr<cr>--- rewind to the first quickfix item:cope<cr>-:ccl<cr>--- open/cloe the quickfix window:cpf<cr>-:cnf<cr>---:cn<cr>/:cp<cr>until a new file is hit:chi<cr>--- display the quickfix list history:col<cr>-:cnew<cr>--- go to an older/newer quickfix list in the history- v
O--- switch the parity of voin a blockwise selection - v
g<c-a>- vg<c-x>--- incrementally increment/decrement numbers in selection - v
P--- 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- o
v- oV- o<c-v>--- force the operator to work charwise/linewise/blockwise - o
v--- when motion is charwise, toggle inclusive/exclusive - o
2i'- 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 ccurrence/definition of word under cursor across includes<c-w>i-<c-w>d---[<c-i>/[<c-d>but in new window1gd-1gD---gd/gDbut ignore{}blocks before the cursor- v
zy-zp--- yank/paste a block, removing trailing spaces - c
<c-n>- c<c-p>--- recall next/previous command line :mes<cr>--- view message history- i
<c-g>k- i<c-g>j--- go to the column where insert was started, one line up/down [%-]%--- matchit.vim jump to beginning/end of%able groupg%--- matchit.vim cycle backward through%able groupszs-ze- scroll so the cursor is on the left/right of the windowN <c-w>q--- quit Nth window:tabs<cr>--- list open tabpages:tabe<cr>--- open new blank tabpage<c-w>T--- move current window to new tabpage<c-w>gf-<c-w>gF---gf/gFbut in new tabpage:tabe FILE<cr>-:tabf FILE<cr>---:e FILE<cr>/:fin FILE<cr>but in new tabpage:tab CMD<cr>--- runCMDbut open tabpages instead of windows:tabc<cr>--- close the current tabpage:tabo<cr>--- close all tabpages but the current onegt-gT-N gt--- go to next/previous/Nth tabpageg<tab>-<c-w>g<tab>--- toggle between two most recent tabpages:diffs FILE<cr>--- openFILEin new window and enable diff mode:diffp PATCH<cr>--- applyPATCHin 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 changeN do-N dp--- obtain/put a diff change from/to buffer number N
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 wordEa--- insert after WORDo<esc>-O<esc>--- insert a blank line below/aboveJx--- join lines, removing all leading whitespaceJde--- join lines, removing leading word (like//c comments and-markdown lists)xp--- swap a character with the nextddp--- swap a line with the nextr<cr>--- split a line at the cursor positionm'--- 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 tree99<c-r>--- jump to the latest change in the current undo tree branch*N--- highlight the word under the cursor0D--- clear out the current line without deleting itVP--- replace the current line with the contents of the unnamed register<cr>;--;--- repeat lastf/tsearch on the next/previous linegon-GN--- repeat last//?search from the start/end of the buffer<c-o><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
qqcommandsqthen mashingQ(Neovim only) - perform an interactive substitution with
/re, thencgnreplacement<esc>ordgn, then skip withnand repeat with.--- more flexible than:s/.../c<cr> - interactively append a suffix to the end of matches with
/re/e<cr>, thenasuffix<esc>, then skip withnand 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 listnote turn
:fininto a fuzzy finder withset wildmenu path+=**--- https://youtu.be/XA2WjJbmmoM?t=6m44s - when it exists, print the digraph for the character under the cursor using
ganote 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'whilehandlare not - jump to the first byte of a file with
go---ggwon't go to the first byte when'nostartofline'is setresource Byte Positions Are Better Than Line Numbers, by Casey Muratori --- 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/andF/--- slashes are uncommon and URLs and paths usually contain them - use undos from within insert mode by marking undo points with
<c-g>uand 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 thencmotion<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> - delete an entire
if/for/while (...) { ... }construct withdVaB
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