installation via terminal

| The main strength of vim is that you can control or edit file with keyboard only, and not using a mouse.

To install the standard vi package on Ubuntu

sudo apt update
sudo apt install vim -y
vim --version | shows vim version and features included (+) or not (-)
sudo apt-get install vim-gnome | Install with xtern support

To add clipboard option to vim

sudo apt remove vim-tiny
sudo apt install vim-gtk3

modes and help

These are some of the vim modes:
  1. Normal/navigation mode: This is the default mode, when you open a file. You can only run commands but cannot type text directly.
  2. Insert mode: You can edit the text, but you cannot run commands. To enter this mode from the normal mode, press "i", to exit the insert mode (go back to the normal mode), press "Esc".
  3. Command mode: If you press ":" in the normal mode, it opens the command prompt. Command prompt is used to run extended commands. The extended commands in this tutorial start with ":".
  4. Visual mode: You can select and copy to the clipboard. The visual mode has three options. Press v in the command mode, to select a text character by character. Press V to select the whole line, and press ctrl+v to select columns (rectangular block). Esc/cntrl+c to exit the visual mode.
In the tutorial, the commands in each mode are indicated by [normal] or [insert].
:help <command> | opens a vim split window with the help page for that command. For command mode keyword use :<command>
i/a | starts the insert mode, cursor moves one character before/after the current position of cursor
I/A | starts the insert mode, cursor moves to the beginning/end of the line
o/O | starts the instert mode, by adding a blank line below/above current line
Esc/ctrl+[/ctrl + c | exits the insert mode to normal mode
v | starts visual mode for character selection (then run another command such as yank)
V | starts visual mode for line selection (then run another command such as yank)
ctrl + v | starts visual mode for block selection (then run another command such as yank)
:ter | opens a terminal window in vim. To exit, print exit in the terminal.

exit

:w | saves/writes the file
:w !sudo tee % | saves/writes the current file using sudo
:q | quits and closes the vim window (fails if there are unsaved changes)
:wq or :x or ZZ | saves/writes and quit
:q! or ZQ | ignores unsaved changes and quits
:qa | quits all open vim tabs
:wqa | saves/writes and quits all open vim tabs
:clo | closes current pane

multiple files/buffer

| When you open a file in vim, it loads in buffer. In other words, a buffer is and open file in memory. A buffer can be visible, hidden (still in memory but not displayed), or unloaded (closed from memory). Instructions to switch between windows is listed below. Then, there is window, which is a viewport to show buffers and splits. Tab is a collection of windows.
:e <filename> | edit/open filename. Files open in buffer (which is different from tab).
:bn | go to the next buffer/file
:bp | go to the previous buffer/file
:bd | closes/deletes a buffer/file
:b <buffer #> | go to a buffer number #
:b file <filename> | go to a buffer/file by filename
:ls (or :buffers) | list all open buffers/files
:sav <filename> | save as filename

tabs and split window

Let's learn about buffer first. A buffer is where vim stores the contents of a file in memory after you open it. File on disk stores on permanent storage, but the buffer is temporary working copy inside vim. When you save (:w), the buffer is written back to the file.
Tabs and windows are different in vim.
  1. Window is a viewport into a buffer. You can have multiple windows showing the same buffer, for example using window splits. Windows live inside a tab. Use windows when when you want to compare files, edit multiple files at once, or see code + test + documentation at the same time.
  2. Tab is a collection of window or windows (it is different from the browser tab with a single page). Use tabs when you want separate workspaces, different split layouts for different tasks or if you want to switch projects quickly.
:tabe | create a new tab
:tabn (or gt) | go to the next tab
:tabp (or gT) | go to the previous tab
<tab#>gt | moves to tab number #
:tabnew (or :tabnew <filename>) | opens a tab (or filename in a new tab)
:tabm <tab #> | moves current tab to tab # (first is indexed at 0)
:tabc | closes the current tab and all its windows
:tabo | closes all tabs except for the current one
:tabdo <command> | runs the same command on all open tabs (e.g. :tabdo w - saves all tabs)
:sp (ctrl+ws)| horizontally splits the window (same file)
:vp (ctrl+wv)| vertically splits the window (same file)
:ps/vs <file> | opens a file in a new buffer and horizontally/vertically splits the window
ctrl+ww | switches between windows
ctrl+ww | Switch between windows
ctrl+wq | quits a window
ctrl + w= | makes all windows the same size
ctrl + wx | replaces the current window with next one
ctrl + wh/l | moves the cursor to the left/right window for vertical splits
ctrl + wj/k | moves the cursor to the bottom/top window for horizontal splits
ctrl + wT | moves the current split window into a new tab
ctrl + wH/L | maximizes the window vertically and moves it to left/right edge of the screen
ctrl + wJ/K | maximizes the window horizontally and moves it to bottom/top edge of the screen

cursor movement [normal mode]

h/l | move cursor left/right
k/j | move cursor up/down
w/b | nex/previous word
H/M/L | move to top/middle/bottom of screen (not page)
e/ge | next/previous end of word
0/$ | start/end of line
gg/G (or :$) | top/bottom of the page (first/last line of document)
ctrl+y/ctrl+e | scroll up/down one line
^/0 | first non-blank character of line
<line number>gg - <line number>G - : <line number> [enter] | go to <line number>
ctrl + b/f | move screen up/down one page (cursor to last/first line)
}/{ | next/previous block/paragraph/function
% | move to the matching character. Default (:), {:}, ["]
zt/zb/zz | top/bottom/center of the screen

copy (yank)/cut/paste

yy | yanks (copy) a line from where the cursor is in the register
2yy | yanks (copy) 2 lines from where the cursor is in the register
<#lines> yy | yanks (copy) # lines from where the cursor is in the register
Y (or y$) | yanks/copies to end of line
yw | yanks/copies the characters of the word from the cursor position to the start of the next word
yiw | yanks/copies the entire word under the cursor
yaw | yanks/copies the entire word under the cursor and the space after it
dd | deletes (cuts) one line to register where the cursor is
2dd | deletes (cuts) 2 line to register where the cursor is
<#lines>dd | deletes (cuts) #lines from register to where the cursor is
:<line #1>,<line #2>d | deletes (cuts) a range of lines (from line #1 to line #2) with :
D (or d$) | deletes/cuts to the end of the line
dw | deletes/cuts the characters of the word from the cursor position to the start of the next word
diw | deletes/cuts the entire word under the cursor
daw | deletes/cuts word under the cursor and the space after it
p | puts/pastes whatever is in register after cursor
P | puts/pastes whatever is in register before cursor
gp | puts/pastes the clipboard after cursor (cursor remains after the new text)
gP | puts/pastes the clipboard before cursor (cursor remains after the new text)
c | deletes the character, then starts in the insert mode
cc | deletes the line, then starts in the insert mode
x | deletes/cuts the character under the cursor
:g/{pattern}/d | deletes all lines containing the pattern
:g!/{pattern}/d | deletes all lines not containing the pattern
|The following two commands require vim with the clipboard option. Run "vim --version" to see all features (+) installed, (-) not installed. For the two next commands, you need "+clipboard". To add clipboard, see the installation section.
"+y | yanks/copies a selection (from the visual mode) to the system clipboard. This allows you to copy from vim to another text editor. You need vim+clipboard (See above comment).
"+p | puts/pastes from the system clipboard in vim. This allows you to copy a text from outside vim to vim. You need vim+clipboard (See above comment).

registers

Registers are storage locations inside vim where text can be saved, retrieved, or even manipulated. To use any register, you prefix the command with "<register>. Here are various types of registers:
  1. "unnamed register ("") default register used for most operations. If you don't specify a register, Vim uses this one automatically.
  2. "0 yank register that stores the most recent yank operation (last yank, y command). Deleting does NOT overwrite register 0. Useful because you can yank something, delete something else, and still paste the yanked text.
  3. "1 to "9 numbered registers that store the most recent delete operations (with "1 being the most recent). Vim rotates these when you delete text using d, c, or x. Examples: First delete goes into register 1. Second delete moves old register 1 to register 2, up to register 9.
  4. "a ~ "z named registers are user-controlled registers, allows for manual storage and retrieval of text. It is possible to append to these registers as well, using capital letters, for example, "Ayy appends to register a.
  5. ., %, : read-Only registers, you cannot write to these registers; you can only read from them.
  6. (=) expression Register, lets you evaluate expressions or insert the result of a calculation. Example: insert the result of 5 * 8: Ctrl-r =5*8, or use in normal mode: "=5*8p pastes 40.
  7. * and + selection registers. These relate to the system clipboard, used by GUI vim clipboard support.
  8. _ black hole register, deletes text without storing it anywhere. Useful when you don't want to overwrite the unnamed register.
  9. - small-delete register, stores small deletes (less than one line). Useful for single character deletions that you might want to paste later without affecting larger deletions.
  10. / last search register, holds the most recent search pattern.
:reg | shows the content of registers/clipboard
yy | stores into unnamed register
p | pastes from unnamed register
".p | pastes the text you last typed in insert mode
"0p | pastes latest copied/yanked text
"1p | pastes most recent delete
"2p | pastes the one before the last delete
"xy | copies/yanks into register x
"xp | pastes contents of register x
"ayy | copies/yanks into register a (named register a)
"ap | pastes register a (named register a)
"Ayy | appends to register a (uppercase A)
". | last inserted text register
% | current file name, for example :%s/foo/bar/g uses % in commands
"% | current file name register
": | stores the last command-line input
":p | pastes the last command
"=5*8p | pastes 40
+ | system clipboard
"+yy | yank to system clipboard
"+p | paste from system clipboard
* | X11 primary selection, middle-click buffer (Linux only).
"*yy | copies/yanks to primary selection
"*p | pastes from primary selection
"_dd | deletes a line with NO copy (black hole register)
x | stores deleted character into "-" (small-delete register)
"-p | paste small-delete register character
"/p | paste the last search pattern

find/replace

/&lt;pattern&gt; | searches for "pattern" (forward)
?&lt;pattern&gt; | searches for pattern (backward)
:noh | removes highlighting of search pattern matches
"magic" controls how strictly special regex characters are interpreted during searches (/ or :s commands). Vim's regex engine can treat symbols like *, +, ?, |, () etc. as: Special regex operators, or Literal characters (if β€œmagic” is reduced). There are four levels of magicness:
  • \m: Magic, (default) Most regex characters are special.
  • \M: Nomagic, Only ^ and $ are special; everything else is literal unless escaped.
  • \v Very Magic, almost all regex symbols are special β€” minimal escaping needed (easiest to use).
  • \V Very nomagic, almost nothing is special β€” almost all characters are literal.
/\v&lt;pattern&gt; | searches very magic pattern (no escaping is needed)
n/N | repeats the previous search (forward/backward)
:%s/&lt;old pattern&gt;/&lt;new pattern&gt;/g | replaces all &lt;old pattern&gt; with &lt;new pattern&gt; throughout file, globally
:%s/&lt;old pattern&gt;/&lt;new pattern&gt;/gc | replaces all &lt;old pattern&gt; with &lt;new pattern&gt; throughout file, globally, with confirmation. % means current file.
:vim /&lt;pattern&gt;/ &lt;path/*&gt; | search for pattern in multiple files

editing

u/ctrl+r | undo/redo the previous text edit
>> / << | indents line one shiftwidth to the right/left
> / < | [visual commands] shifts the selected text to the right/left
y | [visual commands] copies/yanks marked text
d | [visual commands] deletes selected text
u/U | [visual commands] changes selected text to lowercase/uppercase
~ | [visual commands] switches case
o/O | [visual commands] moves the cursor to the beginning/end of the selected area

bookmarks

|Mark (or bookmark) allows you to jump to a previously set points.
m{a-z} | sets mark at cursor position, named {a-z} (lowercase) for current file only
m{A-Z} | sets mark at cursor position, named {A-Z} (capital) for all files
`{a-z} | moves the cursor to the position where the mark was set
`` | jumps back to the previous jump location
:marks | lists of marks/bookmarks
y`a | copies/yanks text from the current cursor position to position of mark a
:ju | list of jumps

reference

vim.org