# vi vi is a family of **vi**sual text editors originated in [BSD](bsd.md) [Unix](unix.md). vi was created by Bill Joy as a visual form of the line-based ex editor (an extension to the classic [ed](ed.md), 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](emacs.md) 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 ` command or `` 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) ``: 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 **f**orward - (n) `Ctrl-b`: scroll a page **b**ackwards - (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 **ed**itors. - `%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](lua.md) 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](bsd.md). - vis: minimalistic vi-like editor, adds structured regular expressions inspired by the [Sam](sam.md) and [Acme](acme.md) editors, includes Lua for scripting. - ... ## Resources - [Vim Kōans](https://blog.sanctum.geek.nz/vim-koans/) - [The Dharma of Vi](https://blog.samwhited.com/2015/04/the-dharma-of-vi/) ## See also - [ed](ed.md)