Skip to main content

Vim

Last updated: 3 Jan 2023 ·
Posted in wiki#notes

Basic commands

Quiting Vim

CommandDescription
:q[uit]Quit
:q[uit]!Quit without writing
:cq[uit]Quit without writing (exit with error)
:wqWrite the current file and exit
:xWrite the current file and exit (only write if there are changes)
:wq!Write the current file and exit (force write)
:wq {file}Write to file and quit
:wq! {file}Write to file and quit (force write)
:qaQuit all
:[range]wq[!] [file]Same as above, but only write the lines in [range]
ZZWrite current file, if modified, and exit
ZQQuit current file and exit (same as ":q!")

Left-right motions

CommandDescription
<N>hLeft (also: Ctrl-h, BS, or Left key)
<N>lRight (also: Space or Right key)
0To first character in the line (also: Home key)
^To first non-blank character in the line
<N>$To the last character in the line (N-1 lines lower) (also: End key)
g0To first character in screen line (differs from "0" when lines wrap)
g^To first non-blank character in screen line (differs from "^" when lines wrap)
<N>g$To last character in screen line (differs from "$" when lines wrap)
gmTo middle of the screen line
<N>|To column N (default: 1)
<N>f{char}To the Nth occurrence of char to the right
<N>F{char}To the Nth occurrence of char to the left
<N>t{char}Till before the Nth occurrence of char to the right
<N>T{char}Till before the Nth occurrence of char to the left
<N>;Repeat the last "f", "F", "t", or "T" N times
<N>,Repeat the last "f", "F", "t", or "T" N times in opposite direction
g,Move forward through the change list
g;Move backward through the change list
:changesPrint the change list

Up-down motions

CommandDescription
<N>kUp N lines (also: Ctrl-P and Up)
<N>jDown N lines (also: Ctrl-J, Ctrl-N, NL, and Down)
<N>-Up N lines, on the first non-blank character
<N>+Down N lines, on the first non-blank character (also: Ctrl-M and CR)
<N>_Down N-1 lines, on the first non-blank character
<N>G Goto line N (default: last line), on the first non-blank character
<N>ggGoto line N (default: first line), on the first non-blank character
<N>%Goto line N percentage down in the file; N must be given, otherwise it is the % command
<N>gkUp N screen lines (differs from "k" when line wraps)
<N>gjDown N screen lines (differs from "j" when line wraps)

Text object motions

CommandDescription
<N>wN words forward
<N>WN blank-separated WORDs forward
<N>eN words forward to the end of the Nth word
<N>EN words forward to the end of the Nth blank-separated WORD
<N>bN words backward
<N>BN blank-separated WORDs backward
<N>geN words backward to the end of the Nth word
<N>gEN words backward to the end of the Nth blank-separated WORD
<N>)N sentences forward
<N>(N sentences backward
<N>}N paragraphs forward
<N>{N paragraphs backward
<N>]]N sections forward, at start of section
<N>[[N sections backward, at start of section
<N>][N sections forward, at end of section
<N>[]N sections backward, at end of section
<N>[(N times back to unclosed '('
<N>[{N times back to unclosed '{'
<N>[mN times back to start of method (for Java)
<N>[MN times back to end of method (for Java)
<N>])N times forward to unclosed ')'
<N>]}N times forward to unclosed '}'
<N>]mN times forward to start of method (for Java)
<N>]MN times forward to end of method (for Java)
<N>[#N times back to unclosed "#if" or "#else"
<N>]#N times forward to unclosed "#else" or "#endif"
<N>[*N times back to start of a C comment "/*"
<N>]*N times forward to end of a C comment "*/"

Pattern searches

CommandDescription
<N>/{pattern}[/[offset]]<CR>Search forward for the Nth occurrence of pattern
<N>?{pattern}[?[offset]]<CR>Search backward for the Nth occurrence of pattern
<N>/<CR>Repeat last search, in the forward direction
<N>?<CR>Repeat last search, in the backward direction
<N>nRepeat last search
<N>NRepeat last search, in opposite direction
<N>*Search forward for the identifier under the cursor
<N>#Search backward for the identifier under the cursor
<N>g*Like "*", but also find partial matches
<N>g#Like "#", but also find partial matches
gdGoto local declaration of identifier under the cursor
gDGoto global declaration of identifier under the cursor

Marks and motions

CommandDescription
m{a-zA-Z}Mark current position with mark a-zA-Z
`{a-z}Go to mark a-z within current file
`{a-z}Go to mark a-z within current file
`{A-Z}Go to mark A-Z in any file
`{0-9}Go to the position where Vim was previously exited
`Go to the position before the last jump
`"Go to the position when last editing this file
`[ or '[Go to the start of the previously operated or put text
`] or ']Go to the end of the previously operated or put text
`<Go to the start of the (previous) Visual area
`>Go to the end of the (previous) Visual area
`. or '.Go to the position of the last change in this file
'{a-zA-Z0-9[]'"<>.}Same as `, but on the first non-blank in the line
:marksPrint the active marks
<N>Ctrl-oGo to Nth older position in jump list
<N>Ctrl-iGo to Nth newer position in jump list
:ju[mps]Print the jump list
:cle[arjumps]Clear the jump list of the current window

Various motions

CommandDescription
%Find the next brace, bracket, comment, or "#if"/ "#else"/"#endif" in this line and go to its match
<N>HGo to the Nth line in the window, on the first non-blank
MGo to the middle line in the window, on the first non-blank
<N>LGo to the Nth line from the bottom, on the first non-blank
<N>goGo to Nth byte in the buffer
:[range]go[to][off]Go to [off] byte in the buffer

Using tags

CommandDescription
:ta[g][!] {tag}Jump to tag tag
:[count]ta[g][!]Jump to [count]'th newer tag in tag list
Ctrl-]Jump to the tag under cursor, unless changes have been made
:ts[elect][!] [tag]List matching tags and select one to jump to
:tj[ump][!] [tag]Jump to tag [tag] or select from list when there are multiple matches
:lt[ag][!] [tag]Jump to tag [tag] and add matching tags to the location list
:tagsaPrint tag list
<N>Ctrl-tJump back from Nth older tag in tag list
:[count]po[p][!]Jump back from [count]'th older tag in tag list
:[count]tn[ext][!]Jump to [count]'th next matching tag
:[count]tp[revious][!]Jump to [count]'th previous matching tag
:[count]tr[ewind][!]Jump to [count]'th matching tag
:tl[ast][!]Jump to last matching tag
:pt[ag] {tag}Open a preview window to show tag tag
Ctrl-w }Like Ctrl-] but show tag in preview window
:pts[elect]Like ":tselect" but show tag in preview window
:ptj[ump]Like ":tjump" but show tag in preview window
:pc[lose]Close tag preview window
Ctrl-w zClose tag preview window`

Scrolling

CommandDescription
<N>Ctrl-eWindow N lines downwards (default: 1)
<N>Ctrl-dWindow N lines Downwards (default: 1/2 window)
<N>Ctrl-fWindow N pages Forwards (downwards)
<N>Ctrl-yWindow N lines upwards (default: 1)
<N>Ctrl-uWindow N lines Upwards (default: 1/2 window)
<N>Ctrl-bWindow N pages Backwards (upwards)
z CR or ztRedraw, current line at top of window
z. or zzRedraw, current line at center of window
z- or zbRedraw, current line at bottom of window
<N>zhScroll screen N characters to the right
<N>zlScroll screen N characters to the left
<N>zHScroll screen half a screenwidth to the right
<N>zLScroll screen half a screenwidth to the left

Inserting text

CommandDescription
<N>aAppend text after the cursor (N times)
<N>AAppend text at the end of the line (N times)
<N>iInsert text before the cursor (N times) (also: Insert)
<N>IInsert text before the first non-blank in the line (N times)
<N>gIInsert text in column 1 (N times)
giInsert at the end of the last change
<N>oOpen a new line below the current line, append text (N times)
<N>OOpen a new line above the current line, append text (N times)

in Visual block mode:

CommandDescription
IInsert the same text in front of all the selected lines
AAppend the same text after all the selected lines

Insert mode keys

leaving Insert mode:

CommandDescription
EscEnd Insert mode, back to Normal mode
Ctrl-cLike Esc, but do not use an abbreviation
Ctrl-o {command}Execute command and return to Insert mode

moving around:

CommandDescription
cursor keysMove cursor left/right/up/down
Shift-left/rightOne word left/right
Shift-up/downOne screenful backward/forward
EndCursor after last character in the line
HomeCursor to first character in the line

Special keys in Insert mode

CommandDescription
Ctrl-v {char}..Insert character literally, or enter decimal byte value
NL or CR or Ctrl-m or Ctrl-jBegin new line
Ctrl-eInsert the character from below the cursor
Ctrl-yInsert the character from above the cursor
Ctrl-aInsert previously inserted text
Ctrl-@Insert previously inserted text and stop Insert mode
Ctrl-r {0-9a-z%#:.-="}Insert the contents of a register
Ctrl-nInsert next match of identifier before the cursor
Ctrl-pInsert previous match of identifier before the cursor
Ctrl-x ...Complete the word before the cursor in various ways
BS or Ctrl-HDelete the character before the cursor
DelDelete the character under the cursor
Ctrl-wDelete word before the cursor
Ctrl-uDelete all entered characters in the current line
Ctrl-tInsert one shiftwidth of indent in front of the current line
Ctrl-dDelete one shiftwidth of indent in front of the current line
0 Ctrl-dDelete all indent in the current line
^ Ctrl-dDelete all indent in the current line, restore indent in next line

Digraphs

CommandDescription
:dig[raphs]Show current list of digraphs
:dig[raphs] {char1}{char2} {number} ...Add digraph(s) to the list

Special inserts

CommandDescription
:r [file]Insert the contents of [file] below the cursor
:r! {command}Insert the standard output of command below the cursor

Deleting text

CommandDescription
<N>xDelete N characters under and after the cursor
<N>DelDelete N characters under and after the cursor
<N>XDelete N characters before the cursor
<N>d{motion}Delete the text that is moved over with motion
{visual}dDelete the highlighted text
<N>ddDelete N lines
<N>DDelete to the end of the line (and N-1 more lines)
<N>JJoin N-1 lines (delete EOLs)
{visual}JJoin the highlighted lines
<N>gJLike "J", but without inserting spaces
{visual}gJLike {visual}J, but without inserting spaces
:[range]d [x]Delete [range] lines [into register x]

Copying and moving text

CommandDescription
"{char}Use register char for the next delete, yank, or put
"*Use register * to access system clipboard
:regShow the contents of all registers
:reg {arg}Show the contents of registers mentioned in arg
<N>y{motion}Yank the text moved over with motion into a register
{visual}yYank the highlighted text into a register
<N>yyYank N lines into a register
<N>YYank N lines into a register
<N>pPut a register after the cursor position (N times)
<N>PPut a register before the cursor position (N times)
<N>]pLike p, but adjust indent to current line
<N>[pLike P, but adjust indent to current line
<N>gpLike p, but leave cursor after the new text
<N>gPLike P, but leave cursor after the new text
:[range]t.Yank and paste text in range under current line. Prefix range with - for relativenumber

Changing text

CommandDescription
<N>r{char}Replace N characters with char
<N>gr{char}Replace N characters without affecting layout
<N>REnter Replace mode (repeat the entered text N times)
<N>gREnter virtual Replace mode: Like Replace mode but without affecting layout
{visual}r{char}In Visual block, visual, or visual line modes: Replace each char of the selected text with char
<N>c{motion}Change the text that is moved over with motion
{visual}cChange the highlighted text
<N>ccChange N lines
<N>SChange N lines
<N>CChange to the end of the line (and N-1 more lines)
<N>sChange N characters
{visual}cIn Visual block mode: Change each of the selected lines with the entered text
{visual}CIn Visual block mode: Change each of the selected lines until end-of-line with the entered text
{visual}~Switch case for highlighted text
{visual}uMake highlighted text lowercase
{visual}UMake highlighted text uppercase
g~{motion}Switch case for the text that is moved over with motion
gu{motion}Make the text that is moved over with motion lowercase
gU{motion}Make the text that is moved over with motion uppercase
{visual}g?Perform rot13 encoding on highlighted text
g?{motion}Perform rot13 encoding on the text that is moved over with motion
<N>Ctrl-aAdd N to the number at or after the cursor
<N>Ctrl-xSubtract N from the number at or after the cursor
<N><{motion}Move the lines that are moved over with motion one shiftwidth left
<N><<Move N lines one shiftwidth left
<N>>{motion}Move the lines that are moved over with motion one shiftwidth right
<N>>>Move N lines one shiftwidth right
<N>gq{motion}Format the lines that are moved over with motion to 'textwidth' length
:[range]ce[nter][width]Center the lines in [range]
:[range]le[ft][indent]Left-align the lines in [range] (with [indent])
:[range]ri[ght][width]Right-align the lines in [range]

Complex changes

CommandDescription
<N>!{motion}{command}<CR>Filter the lines that are moved over through command
<N>!!{command}<CR>Filter N lines through command
{visual}!{command}<CR>Filter the highlighted lines through command
:[range]! {command}<CR>Filter [range] lines through command
<N>={motion}Filter the lines that are moved over through 'equalprg'
<N>==Filter N lines through 'equalprg'
{visual}=Filter the highlighted lines through 'equalprg'
:[range]s[ubstitute]/{pattern}/{string}/[g][c]Substitute pattern by string in [range] lines; with [g], replace all occurrences of pattern; with [c], confirm each replacement
:[range]s[ubstitute][g][c]Repeat previous ":s" with new range and options
&Repeat previous ":s" on current line without options
:&&Repeat the last substitution with its flags
:~Repeat the last substitute command with the same replacement, but with the last used search pattern
:[range]ret[ab][!] [tabstop]Set 'tabstop' to new value and adjust white space accordingly
&Repeat the last substitute, without its range and flags
g&Repeat the last substitute with the same flags but without the same range (it’s global), and replace its pattern with the last search pattern

Visual mode

CommandDescription
vStart highlighting characters or stop highlighting
VStart highlighting linewise or stop highlighting
Ctrl-vStart highlighting blockwise or stop highlighting
oExchange cursor position with start of highlighting
gvStart highlighting on previous visual area

Text objects (only in Visual mode or after an operator)

CommandDescription
<N>awSelect "a word"
<N>iwSelect "inner word"
<N>aWSelect "a WORD"
<N>iWSelect "inner WORD"
<N>asSelect "a sentence"
<N>isSelect "inner sentence"
<N>apSelect "a paragraph"
<N>ipSelect "inner paragraph"
<N>a], a[select '[' ']' blocks
<N>i], i[select inner '[' ']' blocks
<N>ab, a(, a)Select "a block" (from "[(" to "])")
<N>ib, i), i(Select "inner block" (from "[(" to "])")
<N>a>, a<Select "a <> block"
<N>i>, i<Select "inner <> block"
<N>aB, a{, a}Select "a Block" (from "[{" to "]}")
<N>iB, i{, i}Select "inner Block" (from "[{" to "]}")
<N>atSelect "a tag block" (from to )
<N>itSelect "inner tag block" (from to )
<N>a'Select "a single quoted string"
<N>i'Select "inner single quoted string"
<N>a"Select "a double quoted string"
<N>i"Select "inner double quoted string"
<N>`aSelect "a backward quoted string"
<N>`iSelect "inner backward quoted string"

Repeating commands

CommandDescription
<N>.Repeat last change (with count replaced with N)
q{a-z}Record typed characters into register a-z
q{A-Z}Record typed characters, appended to register a-z
qStop recording
<N>@{a-z}Execute the contents of register a-z (N times)
<N>@@Repeat previous @a-z (N times)
:@{a-z}Execute the contents of register a-z as an Ex command
:@@Repeat previous :@a-z
:[range]g[lobal]/{pattern}/[cmd]Execute Ex command cmd (default: ':p') on the lines within [range] where pattern matches
:[range]g[lobal]!/{pattern}/[cmd]Execute Ex command cmd (default: ':p') on the lines within [range] where pattern does NOT match
:so[urce] {file}Read Ex commands from file
:so[urce]! {file}Read Vim commands from file
:sl[eep][sec]Don't do anything for [sec] seconds
<N>gsGoto Sleep for N seconds
q//q:Open commandline window

Note: Pressing Ctrl-f in commandline mode opens the commandline window.

Undo/Redo commands

CommandDescription
<N>uUndo last N changes
<N>Ctrl-rRedo last N undone changes
URestore last changed line

External commands

CommandDescription
:sh[ell]Start a shell
:!{command}Execute command with a shell
KLookup keyword under the cursor with 'keywordprg' program (default: "man")

Ex ranges

CommandDescription
,Separates two line numbers
;Idem, set cursor to the first line number before interpreting the second one
{number}An absolute line number
.The current line
$The last line in the file
%Equal to 1,$ (the entire file)
*Equal to '<,'> (visual area)
'tPosition of mark t
/{pattern}[/]The next line where pattern matches
?{pattern}[?]The previous line where pattern matches
+[num]Add [num] to the preceding line number (default: 1)
-[num]Subtract [num] from the preceding line number (default: 1)

Buffers

CommandDescription
:lsSee a list of current buffers
:e[dit] ../file.txtOpen ../file.txt
:bnOpen next buffer
:bpOpen previous buffer
:b {file}Switch between all open buffers
:b#Open last buffer

Windows

CommandDescription
<Ctrl-w> hlSwitching between windows
<Ctrl-w> [HJKL]Move current window left/right/top/bottom
:sp {file}/:splitHorizontal split
:newCreate a new window horizontally and start editing an empty file in it
:10sp10 lines high horizontal split
Ctrl-w _Maximize a horizontal split
:resize +5/:res +5Increase a split width by 5 lines
:vs[p]/:vsplitVertical split
:vne[w]Create a new window vertically and start editing an empty file in it
Ctrl-w |Maximize a vertical split
:vertical resize +5/:vert res +5Increase a split height by 5 lines
<Ctrl-w> sSplit current window in two
<Ctrl-w> vSplit vertically current window in two
<Ctrl-w> o / :onlyClose other editor groups
<Ctrl-w> =Equalize the sizes of all windows
Ctrl-w cClose a window
Ctrl-w rRotate windows
Ctrl-w RRotate windows in opposite direction
Ctrl-w xSwap current window with its neighbor
Ctrl-w TMove current window to new tab

Tabs

CommandDescription
:tabn[ext]<N>Go to next tab page or tab page count. The first tab page has number one
{count}<C-PageDown>, {count}gtSame as above
:tabp[revious]<N>Go to the previous tab page. Wraps around from the first one to the last one
:tabN[ext]<N>Same as above
{count}<C-PageUp>, {count}gTSame as above
:tabfir[st]Go to the first tab page
:tabl[ast]Go to the last tab page
:tabe[dit] {file}Open a new tab page with an empty window, after the current tab page
:[count]tabe[dit], :[count]tabnewSame as above
:tabnew {file}Open a new tab page with an empty window, after the current tab page
:[count]tab {cmd}Execute cmd and when it opens a new window open a new tab page instead
:tabc[lose][!]<N>Close current tab page or close tab page count
:tabo[nly][!]Close all other tab pages
:tabm[ove][n]Move the current tab page to after tab page N
:tabsList the tab pages and the windows they contain
:tabd[o] {cmd}Execute cmd in each tab page
gtGo to next tab
gTGo to previous tab
<N>gtGo to Nth tab

Folding

CommandDescription
zf{motion} or {Visual}zfOperator to create a fold
zFCreate a fold for [count] lines. Works like "zf"
zdDelete one fold at the cursor
zDDelete folds recursively at the cursor
zEEliminate all folds in the window
zoOpen one fold under the cursor.When a count is given, that many folds deep will be opened
zOOpen all folds under the cursor recursively
zcClose one fold under the cursor. When a count is given, that many folds deep are closed
zCClose all folds under the cursor recursively
zaWhen on a closed fold: open it. When on an open fold: close it and set 'foldenable'
zAWhen on a closed fold: open it recursively. When on an open fold: close it recursively and set 'foldenable'
zvView cursor line: Open just enough folds to make the line in which the cursor is located not folded
zxUpdate folds: Undo manually opened and closed folds: re-apply 'foldlevel', then do "zv": View cursor line
zXUndo manually opened and closed folds
zmFold more: Subtract one from 'foldlevel'
zMClose all folds: set 'foldlevel' to 0. 'foldenable' will be set
zrReduce folding: Add one to 'foldlevel'
zROpen all folds. This sets 'foldlevel' to highest fold level
znFold none: reset 'foldenable'. All folds will be open
zNFold normal: set 'foldenable'. All folds will be as they were before
ziInvert 'foldenable'
[zMove to the start of the current open fold
]zMove to the end of the current open fold
zjMove downwards to the start of the next fold
zkMove upwards to the end of the previous fold

File explorer

CommandDescription
:e.Open file explorer at current working directory
:sp.Open file explorer in split at current working directory
:vs.Open file explorer in vertical split at current working directory
:EOpen file explorer at directory of current file
:SeOpen file explorer in split at directory of current file
:VexOpen file explorer in vertical split at directory of current file
:LexToggle left file explorer
:help netrw

Exploring the file system:

CommandDescription
%Create a new file
dCreate a new directory
RRename the file/directory under the cursor
DDelete the file/directory under the cursor

Options

CommandDescription
:se[t]Show all modified options
:se[t] allShow all non-termcap options
:se[t] termcapShow all termcap options
:se[t] {option}Set boolean option (switch it on), show string or number option
:se[t] no{option}Reset boolean option (switch it off)
:se[t] inv{option}Invert boolean option
:se[t] {option}={value}Set string/number option to value
:se[t] {option}+={value}Append value to string option, add value to number option
:se[t] {option}-={value}Remove value to string option, subtract value from number option
:se[t] {option}?Show value of option
:se[t] {option}&Reset option to its default value
:setl[ocal]Like ":set" but set the local value for options that have one
:setg[lobal]Like ":set" but set the global value of a local option
:fix[del]Set value of 't_kD' according to value of 't_kb'
:opt[ions]Open a new window to view and set options, grouped by functionality, a one line explanation and links to the help
tabstop (ts)Number of spaces that <Tab> in file uses
hlsearch (hls)When there is a previous search pattern, highlight all its matches
ignorecase (ic)Ignore case in search patterns
smartcase (scs)override the 'ignorecase' option if the search pattern contains upper case characters
iskeyword (isk)Keywords contain alphanumeric characters and '_'
scroll (scr)Number of lines to scroll with Ctrl-u and Ctrl-d commands
expandtab (et)Use spaces when <Tab> is inserted
autoindentKeep indentation when doing cc or S in normal mode to replace a line
wrapWrap lines

Misc

  • :earlier 10m: Time travel in time to 10 minutes ago inside Vim.

  • :later 10m: Time travel in time to 10 minutes later inside Vim.

  • :ab: View all abbreviations.

  • :norm Ibegin: Go to the beginning of a line and enter begin, then repeat across all selected lines.

  • !pwd: Run pwd terminal command from vim.

  • :read! date: Insert the output of date command in current line.

    • :30read! date: Insert the output of date command in line 30.
    • :$read! date: Insert the output of date command in the last line.
  • :10,15s/old/new/g: Substitute all occurences of old with new from line 10 to 15.

  • :.,.+5s/old/new/g: Substitute all occurences of old with new from the current line to the next 5 lines.

  • :g/import/d: Delete all lines including the word import.

  • :g!/import/d: Delete all lines not including the word import.

  • :g/^@/m$: Move all lines starting with @ to the end of the document.

  • :g/^$/d: Delete all blank lines in a document.

  • Start Vim by ignoring .vimrc: vim -u NONE

  • Default leader is \ (recommended remappings: <space>/,).

  • Alternative to Esc: Ctrl-c or Ctrl-[ (recommended remappings: jk/jj).

  • <CR> (aka carriage return/cartridge return) means Enter/Return.

Easter eggs

  • :set rightleft
  • :help 42
  • :help holy-grail
  • :help uganda
  • :help quotes
  • :smile (doesn't work on Neovim)