wiki/articles/vi.md

9.4 KiB

vi

vi is a family of visual text editors originated in BSD Unix.

vi was created by Bill Joy as a visual form of the line-based ex editor (an extension to the classic ed, also line-based).

In contrast to most editors, vi is a modal editor, in which its behavior depends on the current mode that is in. For example, the starting mode is the normal mode; the command mode entered by typing : in normal mode; the insert mode, where vi accepts keys and writes them to the current buffer; the replacement mode, similar to insert mode but replaces the characters under the cursor instead of adding them to the buffer; the visual mode which allows for selection of text.

vi keybinds or: why HJKL for navigation and Escape

vi was developed in a ADM-3A video terminal. This terminal had of course a different keyboard layout from the modern standard IBM PC layout. On that keyboard, the Escape key was actually where is now the Tab key. It also lacked dedicated arrow keys, instead using the keys H, J, K, L as the arrow keys.

Emacs is also a victim of the IBM PC keyboard (Control was where now the Alt key is located).

Tutorial

Vim provides a tutorial, accesible through the vimtutor shell command; Neovim provides the same tutorial with the :Tutor editor command.

TODO

Cheatsheet

This is a basic quick cheatsheet of some Vim commands/keybinds. Always refer to the documentation in doubt of something by using the :help <topic> command or <F1> to access the help index.

Some of these can be prefixed with a register name and a count number (in that order). Commands that work with registers use by default an anonymous registers if none is explicitly specified.

c: command mode, i = insert mode; v: visual mode; n: normal mode; t: terminal mode.

Basics

  • :e: open file in a new buffer, file needn't exist
  • :w: save current buffer
  • :wa: save all modified buffers
  • :wq: save current buffer and exit
  • :wqa: same as above, but all buffers
  • :x: same as :wq, saves only if buffer was changed
  • :q: quit
  • :q!: quit without saving current buffer
  • :qa!: quit regardless anything
  • :new: open empty buffer as split window
  • :enew: open empty buffer in current window

Common operations

  • (c,i,v) <Esc>: escape from insert, visual modes to normal mode.
  • (n) w: Jump to next word
  • (n) e: Jump to the end of the current word (and of the next one if you keep pressing it)
  • (n) b: Jump to previous word
  • (c,i) Ctrl-n: move to the next item in the completion menu
  • (c,i) Ctrl-p: move to the previous item in the completion menu
  • (c,i) Ctrl-y: confirm current selection
  • (i) Ctrl-o: temporarily exit insert mode to normal mode; goes back to insert mode after a command or normal mode binding was executed.
  • (n) Ctrl-e: scroll a line forward
  • (n) Ctrl-y: scroll a line backwards
  • (n) Ctrl-f: scroll a page forward
  • (n) Ctrl-b: scroll a page backwards
  • (n) Ctrl-o: moves to previous position
  • (n) Ctrl-i: moves to next position
  • (n) d: delete [works with registers, prefix count, movement]
    • dd: delete current line
    • "add: delete current line to the register a
    • 9dd: delete 9 lines (last d can also be a movement like j or k to control the direction)
    • dk: delete current line and the one above
    • dj: delete current line and the one under
  • (n) y: yank (copy) [works with registers, prefix count]
    • yy: yank current line
    • "ayy: yank current line to the register a
    • yk: yank current line and the one above
    • yj: yank current line and the one under
    • "+yy: yank current line to the system clipboard
    • 9yy: yank 9 lines (last y can also be a movement like j or k to control the direction)
  • (n) p: paste after cursor [works with registers, prefix count, movement]
    • "ap: paste from a register
    • 4p: paste from anonymous register 4 times
    • "a4p: paste from a register 4 times
  • (n) P: paste before cursor [works with registers, prefix count, movement]
  • (n) r: Replace a single character under the cursor
  • (n) x: Delete character under the cursor [works with registers, prefix count]
    • 2x: delete two characters
  • (n) X: delete character before the cursor
  • (n) c: change, roughly equivalent to a combined delete and insert

Mode changing

  • (n) :: Enter command mode
  • (n) i: Enter insert mode after the cursor
  • (n) I: Enter insert mode, at the start of the line
  • (n) a: Enter insert mode before the cursor
  • (n) A: Enter insert mode at the end of the line
  • (n) o: Enter insert mode, adding a newline under
  • (n) O: Enter insert mode, adding a newline above
  • (n) R: Enter replace mode
  • (n) v: Enter visual mode
  • (n) V: Enter visual line mode
  • (n) Ctrl-v: Enter visual block mode

Movement keys [can be prefixed with count]

It has to be noted that Home, End, PageUp/Down and cursor keys also work.

  • (n) h: Move left
  • (n) j: Move down
    • 4j: Move 4 lines down
  • (n) k: Move up
  • (n) l: Move right
  • (n) 0: move to start of line
  • (n) ^: move to first non-whitespace character of line
  • (n) $: move to the end of the line
  • (n) f: move to specified character, forwards
    • fe: move to e
  • (n) F: move to specified character, backwards

Search & Replace

  • (n) /: search for pattern, forwards
  • (n) ?: search for pattern, backwards
  • (n) s: replace (substitute) matches The % expands to the current file name of the current buffer. It is required if you want to apply s to the entire file, because it defaults to the current line only (therefore the g flag actually is global to the current line and not the file). This by the way, is legacy from earlier line-based editors.
    • %s/pattertosearch/replacement/g: replace all instances of pattertosearch by replacement in the file
    • %s/foo/bar/gc: prompt for each possible replacement

Other

  • (n) ~: change case of current character under the cursor
  • (v) u: lowercase the current selection
  • (v) U: uppercase the current selection
  • (n) q:: open command-line history window, here you can edit the commands and execute them with enter.
  • (n) q/: search pattern history
  • (n) K: look for the identifier under the cursor in the man pages, really useful when you're doing C programming.
  • (n) .: repeat last action
  • :help, :h: Vim help pages
  • :!: execute shell command (in the shell specified by the shell variable)
  • :r!: execute shell command and paste the stdout of that command in the current buffer at where the cursor is
  • :w !: (not :w!) send buffer or current range to the specified shell command
  • :term: opens a terminal window, enters to a special terminal mode, similar to insert mode.
  • (t) Ctrl-\ Ctrl-n: escape from terminal (Escape gets sent literally to the terminal process), also you may want to remap this
  • :mkses: saves current session (optionally takes a filename where to save the session; Session.vim by default)
  • :so: Source VimScript file, also used to restore from a session file.

Macros

  • (n) q: start recording macro to register
    • qq: record macro using register @q
  • (n) @: replay macro in register
    • @q: replay macro from @q register
    • 4@q: ditto, but repeat it four times
  • (n) Q: replay last recorded macro

Windows (splits)

  • :vs: create vertical split
  • :sp: horizontal split
  • :sb: open buffer as window
  • (n) Ctrl-w q: close window (buffer remains open)
  • (n) Ctrl-w w: cicle though opened windows
  • (n) Ctrl-w =: make windows have the same width
  • (n) Ctrl-w s: split current window horizontally
  • (n) Ctrl-w v: split current window vertically
  • (n) Ctrl-w +, Ctrl-w -: increase/decrease height of window
  • (n) Ctrl-w <, Ctrl-w >: change width of window

Undo-redo

  • (n) u: undo
  • (n) Ctrl-r: redo
  • (n) g+: go to newer undo tree state (see :h undo-tree)
  • (n) g-: go to older undo tree state

Buffers

  • :bd: delete (quit) current buffer (file is not deleted)
  • :bd!: same but doesn't nag if the buffer wasn't been saved
  • :bp: go to previous buffer
  • :bn: go to next buffer
  • :b#: go to last used buffer (# holds the ID of that buffer)

"Go to" binds

  • gg: go to..
    • gg: go to top of file
    • 30gg: go to line 30
  • G: go to bottom of file
    • 30G: same as 30gg
  • |: go to column of the current line
    • 20|: move to column 20
  • gT: move to previous tab
  • gt: move to next tab
  • gf: open the file path under the cursor in a new buffer
  • gx: tries to open whatever is under the cursor with the system handler (for example, you can use this to open an URL)

Special registers

  • +: system clipboard
  • *: system's clipboard primary selection

vi-like editors

  • Vim: vi improved, one of the most popular vi-like editors; includes a scripting language, VimScript for extending the editor.
  • Neovim: a fork of Vim, adds Lua as a replacement for VimScript, improves performance, cleans cruft from Vim's codebase (has less LOC than Vim).
  • nvi: reimplementation of the original Berkley vi, is the default vi editor in the BSDs.
  • vis: minimalistic vi-like editor, adds structured regular expressions inspired by the Sam and Acme editors, includes Lua for scripting.
  • ...

Resources

See also