Normal mode

Make sure you are in Normal mode before trying out the commands in this chapter. Press Esc key to return to Normal mode from other modes. Press Esc again if needed.

Documentation links:

Arrow motions

The four arrow keys can be used in Vim to move around, just like other text editors. Vim also maps them to four characters in Normal mode.

  • h or move left by one character within the current line
  • j or move down by one line
  • k or move up by one line
  • l or move right by one character within the current line

Vim offers plenty of other motion commands. Several sections will discuss them later in this chapter.

info You can use the whichwrap setting to allow and arrow keys to cross lines. For example, :set ww+=<,> tells Vim to allow left and right arrow keys to move across lines in Normal and Visual modes. Add h and l to this comma separated list if want those commands to cross lines as well.

Cut

There are various ways to delete text. All of these commands can be prefixed with a count value. d and c commands can accept any motion commands. Only arrow motion examples are shown in this section, many more variations will be discussed later in this chapter.

  • dd delete the current line
  • 2dd delete the current line and the line below it (total 2 lines)
    • dj or d↓ can also be used
  • 10dd delete the current line and 9 lines below it (total 10 lines)
  • dk delete the current line and the line above it
    • d↑ can also be used
  • d3k delete the current line and 3 lines above it (total 4 lines)
    • 3dk can also be used
  • D delete from the current character to the end of line (same as d$, where $ is a motion command to move to the end of line)
  • x delete only the current character under the cursor (same as dl)
  • 5x delete the character under the cursor and 4 characters to its right (total 5 characters)
  • X delete only the current character before the cursor (same as dh)
    • if the cursor is on the first character in the line, deleting would depend on the whichwrap setting as discussed earlier
  • 5X delete 5 characters to the left of the cursor
  • cc delete the current line and change to Insert mode
    • indentation will be preserved depending on the autoindent setting
  • 4cc delete the current line and 3 lines below it and change to Insert mode (total 4 lines)
  • C delete from the current character to the end of line and change to Insert mode
  • s delete only the character under the cursor and change to Insert mode (same as cl)
  • 5s delete the character under the cursor and 4 characters to its right and change to Insert mode (total 5 characters)
  • S delete the current line and change to Insert mode (same as cc)
    • indentation will be preserved depending on the autoindent setting

info You can also select text (using mouse or visual commands) and then press d or x or c or s to delete the selected portions. Example usage will be discussed in the Visual mode chapter.

info The deleted portions can also be pasted elsewhere using the paste command (discussed later in this chapter).

Copy

There are various ways to copy text using the yank command y.

  • yy copy the current line
    • Y also copies the current line
  • y$ copy from the current character to the end of line
    • use :nnoremap Y y$ if you want Y to behave similarly to the D command
  • 2yy copy the current line and the line below it (total 2 lines)
    • yj and y↓ can also be used
  • 10yy copy the current line and 9 lines below it (total 10 lines)
  • yk copy the current line and the line above it
    • y↑ can also be used

info You can also select text (using mouse or visual commands) and then press y to copy them.

Paste

The put (paste) command p is used after cut or copy operations.

  • p paste the copied content once
    • If the copied text was line based, content is pasted below the current line
    • If the copied text was part of a line, content is pasted to the right of the cursor
  • P paste the copied content once
    • If the copied text was line based, content is pasted above the current line
    • If the copied text was part of a line, content is pasted to the left of the cursor
  • 3p and 3P paste the copied content three times
  • ]p paste the copied content like p command, but changes the indentation level to match the current line
  • [p paste the copied content like P command, but changes the indentation level to match the current line

Undo

  • u undo last change
    • press u again for further undos
  • U undo latest changes on last edited line
    • press U again to redo changes

info See :h 32.3 for details on g- and g+ commands that you can use to undo branches.

Redo

  • Ctrl+r redo a change undone by u
  • U redo changes undone by U

Replace characters

Often, you just need to change one character. For example, changing i to j, 2 to 4 and so on.

  • rj replace the character under the cursor with j
  • ry replace the character under the cursor with y
  • 3ra replace the character under cursor as well as the two characters to the right with aaa
    • no changes will be made if there aren't sufficient characters to match

To replace multiple characters with different characters, use R.

  • Rlion followed by Esc replace the character under cursor and three characters to the right with lion
    • Esc key marks the completion of R command
    • Backspace key will act as an undo command to give back the character that was replaced
    • if you are replacing at the end of a line, the line will be automatically extended if needed

The advantage of r and R commands is that you remain in the Normal mode, without needing to switch to Insert mode and back.

Repeat a change

  • . the dot command repeats the last change
  • If the last change was 2dd (delete current line and the line below), dot key will repeat 2dd
  • If the last change was 5x (delete current character and four characters to the right), dot key will repeat 5x
  • If the last change was C123<Esc> and dot key is pressed, it will clear from the current character to the end of the line, insert 123 and go back to Normal mode

From :h 4.3:

The . command works for all changes you make, except for u (undo), CTRL-R (redo) and commands that start with a colon (:).

info See :h repeat.txt for complex repeats, using Vim scripts, etc.

Open new line

  • o open a new line below the current line and change to Insert mode
  • O open a new line above the current line and change to Insert mode

info Indentation of the new line depends on autoindent, smartindent and cindent settings.

Moving within current line

  • 0 move to the beginning of the current line (i.e. column number 1)
    • you can also use the Home key
  • ^ move to the beginning of the first non-blank character of the current line (useful for indented lines)
  • $ move to the end of the current line
    • you can also use the End key
    • 3$ move to the end of 2 lines below the current line
  • g_ move to the last non-blank character of the current line
  • 3| move to the third column character
    • | is same as 0 or 1|

Moving within long lines that are spread over multiple screen lines:

  • g0 move to the beginning of the current screen line
  • g^ move to the first non-blank character of the current screen line
  • g$ move to the end of the current screen line
  • gj move down by one screen line, prefix a count to move down by that many screen lines
  • gk move up by one screen line, prefix a count to move up by that many screen lines
  • gm move to the middle of the current screen line
    • Note that this is based on the screen width, not the number of characters in the line!
  • gM move to the middle of the current line
    • Note that this is based on the total number of characters in the line

info See :h left-right-motions for more details.

Character motions

These commands allow you to move based on single character search, within the current line only.

  • f( move forward to the next occurrence of character (
  • fb move forward to the next occurrence of character b
  • 3f" move forward to the third occurrence of character "
  • t; move forward to the character just before ;
  • 3tx move forward to the character just before the third occurrence of character x
  • Fa move backward to the character a
  • Ta move backward to the character just after a
  • ; repeat previous f or F or t or T motion in the same direction
  • , repeat previous f or F or t or T motion in the opposite direction
    • for example, tc becomes Tc and vice versa

info Note that the previously used count prefix wouldn't be repeated with ; or , commands, but you can use a new count prefix. If you pressed a wrong motion command, use the Esc key to abandon the search instead of continuing with the wrongly chosen command.

Word motions

Definitions from :h word and :h WORD are quoted below to explain the difference between word and WORD.

word A word consists of a sequence of letters, digits and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, <EOL>). This can be changed with the iskeyword option. An empty line is also considered to be a word.

WORD A WORD consists of a sequence of non-blank characters, separated with white space. An empty line is also considered to be a WORD.

  • w move to the start of the next word
  • W move to the start of the next WORD
    • 192.1.168.43;hello is considered as a single WORD, but has multiple words
  • b move to the beginning of the current word if the cursor is not at the start of word. Otherwise, move to the beginning of the previous word
  • B move to the beginning of the current WORD if the cursor is not at the start of WORD. Otherwise, move to the beginning of the previous WORD
  • e move to the end of the current word if cursor is not at the end of word. Otherwise, move to the end of next word
  • E move to the end of the current WORD if cursor is not at the end of WORD. Otherwise, move to the end of next WORD
  • ge move to the end of the previous word
  • gE move to the end of the previous WORD
  • 3w move 3 words forward
    • Similarly, a number can be prefixed for all the other commands mentioned above

info All of these motions will work across lines. For example, if the cursor is on the last word of a line, pressing w will move to the start of the first word in the next line.

Text object motions

  • ( move backward a sentence
  • ) move forward a sentence
  • { move backward a paragraph
  • } move forward a paragraph

info More such text objects will be discussed later under the Context editing section. See :h object-motions for a complete list of such motions.

Moving within the current file

  • gg move to the first non-blank character of the first line
  • G move to the first non-blank character of the last line
  • 5G move to the first non-blank character of the fifth line
    • As an alternative, you can use :5 followed by Enter key (Command-line mode)
  • 50% move to halfway point
    • you can use other percentages as needed
  • % move to matching pair of brackets like (), {} and []
    • This will work across lines and nesting is taken into consideration as well
    • If the cursor is on a non-bracket character and a bracket character is present later in the line, the % command will move to the matching pair of that character (which could be present in some other line too)
    • Use the matchpairs option to customize the matching pairs. For example, :set matchpairs+=<:> will match <> as well

info It is also possible to match a pair of keywords like HTML tags, if-else, etc with %. See :h matchit-install for details.

Moving within the visible window

  • H move to the first non-blank character of the top (home) line of the visible window
  • M move to the first non-blank character of the middle line of the visible window
  • L move to the first non-blank character of the bottom (low) line of the visible window

Scrolling

  • Ctrl+d scroll half page down
  • Ctrl+u scroll half page up
  • Ctrl+f scroll one page forward
  • Ctrl+b scroll one page backward
  • Ctrl followed by Mouse Scroll scroll one page forward or backward

Reposition the current line

  • Ctrl+e scroll up by a line
  • Ctrl+y scroll down by a line
  • zz reposition the current line to the middle of the visible window
    • useful to see context around lines that are nearer to the top/bottom of the visible window
  • zt reposition the current line to the top of the visible window
  • zb reposition the current line to the bottom of the visible window

info See :h 'scrolloff' option if you want to always show context around the current line.

Indenting

  • > and < indent commands, waits for motion commands similar to d or y
  • >> indent the current line
  • 3>> indent the current line and two lines below (same as >2j)
  • >k indent the current line and the line above
  • >} indent till the end of the paragraph
  • << unindent the current line
  • 5<< unindent the current line and four lines below (same as <4j)
  • <2k unindent the current line and two lines above
  • = auto indent code, use motion commands to indicate the portion to be indented
    • =4j auto indent the current line and four lines below
    • =ip auto indent the current paragraph (you'll learn about ip later in the Context editing section)

info Indentation depends on the shiftwidth setting. See :h shift-left-right, :h = and :h 'shiftwidth' for more details.

info You can indent/unindent the same selection multiple times using a number prefix in the Visual mode.

Mark frequently used locations

  • ma mark location in the file using the alphabet a
    • you can use any of the 26 alphabets
    • use lowercase alphabets to work within the current file
    • use uppercase alphabets to work from any file
    • :marks will show a list of the existing marks
  • `a move to the exact location marked by a
  • 'a move to the first non-blank character of the line marked by a
  • 'A move to the first non-blank character of the line marked by A (this will work for any file where the mark was set)
  • d`a delete from the current character to the character marked by a
    • marks can be paired with any command that accept motions like d, y, >, etc

info Motion commands that take you across lines (for example, 10G) will automatically save the location you jumped from in the default ` mark. You can move back to that exact location using `` or the first non-blank character using '`. Note that the arrow and word motions aren't considered for the default mark even if they move across lines.

info See :h mark-motions for more ways to use marks.

Jumping back and forth

This is helpful if you are moving around often while editing a large file, moving between different buffers, etc. From :h jump-motions:

The following commands are jump commands: ', `, G, /, ?, n, N, %, (, ), [[, ]], {, }, :s, :tag, L, M, H and the commands that start editing a new file.

When making a change the cursor position is remembered. One position is remembered for every change that can be undone, unless it is close to a previous change.

  • Ctrl+o navigate to the previous location in the jump list (o as in old)
  • Ctrl+i navigate to the next location in the jump list (i and o are usually next to each other)
  • g; go to the previous change location
  • g, go to the newer change location
  • gi place the cursor at the same position where it was left last time in the Insert mode

info Use :jumps and :changes to view the jump and change lists respectively. See :h jump-motions for more details.

Edit with motion

From :h usr_03.txt:

You first type an operator command. For example, d is the delete operator. Then you type a motion command like 4l or w. This way you can operate on any text you can move over.

  • dG delete from the current line to the end of the file
  • dgg delete from the current line to the beginning of the file
  • d`a delete from the current character up to the location marked by a
  • d% delete up to the matching pairs for (), {}, [], etc
  • ce delete till the end of word and change to Insert mode
    • cw will also work the same as ce, this inconsistency is based on Vi behavior
    • use :nnoremap cw dwi if you don't want the old behavior
  • yl copy the character under the cursor
  • yfc copy from the character under the cursor up to the next occurrence of c in the same line
  • d) delete up to the end of the sentence

From :h usr_03.txt:

Whether the character under the cursor is included depends on the command you used to move to that character. The reference manual calls this "exclusive" when the character isn't included and "inclusive" when it is. The $ command moves to the end of a line. The d$ command deletes from the cursor to the end of the line. This is an inclusive motion, thus the last character of the line is included in the delete operation.

Context editing

You have seen examples for combining motions such as w, % and f with editing commands like d, c and y. Such combination of commands require precise positioning to be effective.

Vim also provides a list of handy context based options to make certain editing use cases easier using the i and a text object selections. You can easily remember the difference between these two options by thinking i as inner and a as around.

  • diw delete a word regardless of where the cursor is on that word
    • Equivalent to using de when the cursor is on the first character of the word
  • diW delete a WORD regardless of where the cursor is on that WORD
  • daw delete a word regardless of where the cursor is on that word as well as a space character to the left/right of the word depending on its position in the current sentence
  • dis delete a sentence regardless of where the cursor is on that sentence
  • yas copy a sentence regardless of where the cursor is on that sentence as well as a space character to the left/right
  • cip delete a paragraph regardless of where the cursor is on that paragraph and change to Insert mode
  • dit delete all characters within HTML/XML tags, nesting is taken care as well
  • di" delete all characters within a pair of double quotes, regardless of where the cursor is within the quotes
  • da' delete all characters within a pair of single quotes along with the quote characters
  • ci( delete all characters within () and change to Insert mode
    • Works even if the parenthesis are spread over multiple lines, nesting is taken care as well
  • ya} copy all characters within {} including the {} characters
    • Works even if the braces are spread over multiple lines, nesting is taken care as well

info You can use a count prefix for nested cases. For example, c2i{ will clear the inner braces (including the braces, and this could be nested too) and then only the text between braces for the next level.

info See :h text-objects for more details.

Named registers

You can use lowercase alphabets a-z to save some content for future use. You can also append some more content to those registers by using the corresponding uppercase alphabets A-Z at a later stage.

  • "ayy copy the current line to the "a register
  • "Ayj append the current line and the line below to the "a register
    • "ayy followed by "Ayj will result in total three lines in the "a register
  • "ap paste content from the "a register
  • "eyiw copy word under the cursor to the "e register

info You can use :reg (short for :registers) to view the contents of the registers. Specifying one or more characters (next to each other as a single string) will display contents only for those registers.

info The named registers are also used for saving macros (will be discussed in the Macro chapter). You can record an empty macro to clear the contents, for example qbq clears the "b register.

Special registers

Vim has nine other types of registers for different use cases. Here are some of them:

  • " all yanked/deleted text is stored in this register
    • So, p command is same as specifying ""p
  • "0 yanked text is stored in this register
    • A possible use case: yank some content, delete something else and then paste the yanked content using "0p
  • "1 to "9 deleted contents are stored in these registers and get shifted with each new deletion
    • "1p paste the contents of last deletion
    • "2p paste the contents of last but one deletion
  • "+ this register is used to work with the system clipboard contents
    • gg"+yG copy entire file contents to the clipboard
    • "+p paste content from the clipboard
  • "* this register stores visually selected text
    • contents of this register can be pasted using middle mouse button click or "*p
  • "_ black hole register, when you want to delete something without saving it anywhere

Further reading

Search word nearest to the cursor

  • * searches the word nearest to the cursor in the forward direction (matches only the whole word)
    • Shift followed by left mouse click can also be used in GVim
  • g* searches the word nearest to the cursor in the forward direction (matches as part of another word as well)
    • for example, if you apply this command on the word the, you'll also get matches for them, lather, etc
  • # searches the word nearest to the cursor in the backward direction (matches only the whole word)
  • g# searches the word nearest to the cursor in the backward direction (matches as part of another word as well)

info You can also provide a count prefix to these commands.

Join lines

  • J joins the current line and the next line
    • the deleted <EOL> character is replaced with a space (unless there are trailing spaces or the next line starts with a ) character)
    • indentation from the lines being joined are removed, except the current line
  • 3J joins the current line and next two lines with one space in between the lines
  • gJ joins the current line and the next line
    • <EOL> character is deleted (space character won't be added)
    • indentation won't be removed

info joinspaces, cpoptions and formatoptions settings will affect the behavior of these commands. See :h J and scroll down for more details.

Changing case

  • ~ invert the case of the character under the cursor (i.e. lowercase becomes UPPERCASE and vice versa)
  • g~ followed by motion command to invert the case of those characters
    • for example: g~e, g~$, g~iw, etc
  • gu followed by motion command to change the case of those characters to lowercase
    • for example: gue, gu$, guiw, etc
  • gU followed by motion command to change the case of those characters to UPPERCASE
    • for example: gUe, gU$, gUiw, etc

info You can also provide a count prefix to these commands.

Increment and Decrement numbers

  • Ctrl+a increment the number under the cursor or the first occurrence of a number to the right of the cursor
  • Ctrl+x decrement the number under the cursor or the first occurrence of a number to the right of the cursor
  • 3 followed by Ctrl+a adds 3 to the number
  • 1000 followed by Ctrl+x subtracts 1000 from the number

info Numbers prefixed with 0, 0x and 0b will be treated as octal, hexadecimal and binary respectively (you can also use uppercase for x and b).

info Decimal numbers prefixed with - will be treated as negative numbers. For example, using Ctrl+a on -100 will give you -99. While this is handy, this trips me up often when dealing with date formats like 2021-12-07.

Miscellaneous

  • gf opens a file using the path under the cursor
  • Ctrl+g display file information like name, number of lines, etc at the bottom of the screen
    • See :h CTRL-G for more details and related commands
  • g followed by Ctrl+g display information about the current location of the cursor (column, line, word, character and byte counts)
  • ga shows codepoint value of the character under the cursor in decimal, octal and hexadecimal formats
  • g? followed by motion command to change those characters with rot13 transformation
    • g?e on start of hello word will change it to uryyb
    • g?e on start of uryyb word will change it to hello

Switching modes

Normal to Insert mode

  • i place the cursor to the left of the current character (insert)
  • a place the cursor to the right of the current character (append)
  • I place the cursor before the first non-blank character of the line (helpful for indented lines)
  • gI place the cursor before the first column of the line
  • gi place the cursor at the same position where it was left last time in the Insert mode
  • A place the cursor at the end of the line
  • o open a new line below the current line and change to Insert mode
  • O open a new line above the current line and change to Insert mode
  • s delete character under the cursor and change to Insert mode
  • S delete the current line and change to Insert mode
    • cc can also be used
    • indentation will be preserved depending on the autoindent setting
  • C delete from the current character to the end of line and change to Insert mode

Normal to Command-line mode

  • : change to Command-line mode, awaits further commands
  • / change to Command-line mode for searching in the forward direction
  • ? change to Command-line mode for searching in the backward direction

Normal to Visual mode

  • v visually select the current character
  • V visually select the current line
  • Ctrl+v visually select column
  • gv select previously highlighted visual area

info See :h mode-switching for a complete table.