See [maketecheasier cheatsheet](https://www.maketecheasier.com/cheatsheet/vim-keyboard-shortcuts/) and [the scaron.info blog](https://scaron.info/blog/vim-keyboard-shortcuts.html) and [learnbyexample.github.io](https://learnbyexample.github.io/vim_reference/Insert-mode.html) ## Normal Mode ``` hjkl -- left down up right gg -- start of buffer G -- end of buffer GG -- start of file ^ -- beginning of line (first nonempty char) 0 -- start of line (character 0) $ -- end of line ( -- one sentence forward ) -- one sentence backward { -- one para back } -- one para forward [[ -- previous section ]] -- next section [] -- end of previous section ][ -- end of next section w -- forward one word, alphanumeric W -- forward one wird, delimited by whitespace given 1,2,3,4 5,6,7,8 w will to from 1 to 2 to 3... W will go from 1,2 to 5,6 b -- back one word alphanumeric B -- back one word whitespace i -- insert text at cursor I -- insert at start of line o -- insert text in new line below current O -- insert text in new line above current a -- append text (after cursor) A -- append to end of line x -- delete char under cursor X -- delete char before cursor dd -- delete current line D -- delete from cursor to end of line p -- paste below current line (see registers, e.g. "qp pastes from register q) P -- paste above current line y -- yank (copy to register) dw dW -- delete word d -- delete from current to wherever takes us (deleting lines in case of j, but chars in case of h) r -- replace char under cursor 3r -- replace three chars starting with one under cursor cc -- change current line ce -- change from cursor to end of word ci" -- change between "..." ci< -- change between <...> c0 -- change from start of line to cursor c$ -- change from cursor to end of line G~ -- toggle uppercase and lowercase G~~ -- for current line gU -- uppercase gUU -- for current line guu -- lowercase ciw -- change current word ci" -- change inside ".." ci' -- change inside '..' ci( -- change inside (..) similarly for [..], <..> and {..} (respects nesting) Xi( -- similar for other actions (e.g. yi{ yanks everything between {..} yip -- yank entire block or para (e.g. a class {...} or function in C) caw -- change word including following whitespace ca{ -- change contents of (..) including the parens "xyy -- copy current line into register x "x -- use register x rather than default register for ''' ## undo/redo ''' u -- undo -- redo :earlier 1m -- go back 1 minute in history of document :later 1m -- go forward 1 minute in history of document ``` ## text manipulation ``` gq -- wrap selected lines (by inserting newlines) see :set textwidth=60 < -- unindent > -- indent gg=G -- autoindent document >% -- indent entire code block <% -- unindent entire code block .. delimited block >at -- indent tag delimited block ``` #### TODO ``` ib ``` ## macros ``` qa -- start recording macro a @a -- execute macro a @@ -- execute last executed macro ``` ## searching ``` /pat -- search forward for pat ?pat -- search backward for pat * -- search forward for next occurrence of exact word under cursor g* -- search forward for next word containing the word under the cursor gd -- go to local variable definition gD -- go to global variable definition n -- next match when searching N -- previous match when searching s/pat/rep/gc -- replace all, confirming ``` ## ranges ``` :s/pat/rep -- replace first occurrence of pat with rep -- current line :s/pat/rep/ -- same as above :s/pat/rep/g -- replace all occurrences :s/pat/rep/i -- case insensitive :s/pat/rep/gi -- combines above :%s/pat/rep -- apply to all lines :2,6s/... -- apply to lines 2..6 :m,ns/... -- apply to lines from m to n (s/ can be any action) :.,$s/... -- apply to lines from current to end :m,$s/... -- apply to lines from m to end :1,ns/... -- apply to lines from 1 to n :-3s/... -- apply to 3rd line before current :-3,+3s/... -- apply to lines from 3rd before to 3rd after (be careful about off-by-ones) :1,$s/... -- equivalent to :%s/... ``` ## regex match ranges ``` g/flibble/s/mr/lord -- s/mr/lord on lines matching pattern 'flibbble' g!/script/d -- delete all lines not matching pattern 'script' ``` ## bookmarks ``` mx -- set bookmark x (in range [a-zA-Z]) :marks -- list bookmarks `x -- jump to bookmark x ``` ## numerical prefix ``` 2x -- delete 2 chars 3j -- go up 3 lines dd -- delete current line f" -- forward to next " F> -- bacwards to previous > "qyy -- yank into register q "app -- paste from register a : -- : command s -- split horizontally into upper and lower windows, same buffer in each, top buffer selected v -- split vertically into left and right windows, same buffer in each, left buffer selected ``` ## Insert Mode ``` -- delete from cursor to start of current word -- delete from cursor to start of line, preserving indent -- autocomplete word (next) -- autocomplete word (prev) -- select word to autocomplete (i.e.y to accept autocompletion) -- cancel autocompletion -- line autocompletion -- execute single normal mode command and return to insert mode -- indent current line -- unindent current line 0 -- delete all indentation on current line % -- insert current filename a -- paste contents of register a a -- as a but e.g. backspaces are inserted as literal ^H's rather than interpreting them as if typed ``` note `:set paste` and `:set nopaste` — nopaste mode autoindents as if you were typing the characters pasted — paste mode doesn't autoindent,and just dumps the text into the buffer. ``` x -- insert literal (e.g. inserts ^M) Ye -- for inserting digraphs (use Xcompose instead if you can) :digraphs -- list of digraphs ``` ## Colon commands File and buffer commands ``` :w -- save file :w filename -- write buffer to filename, will refuse to overwrite :w! filename -- write buffer to filename, overwriting a preexisting file :w !command -- pipe buffer into command :e filename -- open filename in current buffer :r filename -- paste contents of filename below current line :vsplit filename -- split vertically, current buffer on right, load filename into left :split filename -- split horizontally, current buffer below, load filename above :wq -- save and close buffer, exiting if last buffer :q! -- close current buffer without saving, even if modified :n -- open next file (specified on command line) ZZ -- write if modified and quit ZQ -- quit without writing :sav -- save as :saveas -- idem :clo -- close current pane :close -- close current pane ``` Editing commands ```` :sort -- sort selected lines :sort u -- sort selected lines, removing duplicates (u is for unique, as in sort|uniq) ``` terminal and shell ``` :!echo hello world -- run 'echo hello world' in shell :term -- open a new terminal ## Visual keys From normal mode ``` v -- character by character -- line by line -- select column/rectangle ``` then in visual mode ``` hjkl -- move end of selection v etc -- exit visual mode (press the same combo as for current visual mode) ``` ## Visual commands ``` :'<,'> -- do something to the currently selected lines :'<,'>s/hello/world -- including partially touched files :'<,'>d -- such as regex search/replace or delete :'<.'>w filename -- write selected lines to filename :'<,'>w !command -- pipe selected lines to command ``` ## Tabs ``` :tabe filename -- open filename in new tab :tabn -- next tab :tabp -- previous tab :tabc -- close tab :tabo -- close all inactive tabs in buffer ``` ## Split ``` :split filename -- split horizontally :sp -- shorthand for :split :vsplit filename -- idem for vertical split :vsp :ls -- list all open buffers S -- split, same buffers V -- vsplit -- switch buffers -- move to buffer in direction given by hjkl (or cursor keys) ``` ## Buffer ``` :bn -- next buffer :bp -- previous buffer ```