Below is a organized list of keys and commands for vim.

When you open a file set the current directory
:cd %:p:h
| Key | Mode |
|---|---|
| i | Insert mode |
| R | Replace mode |
| v | Visual mode |
| V | Visual line mode |
| Ctrl + V | Visual block mode |
| : | Command line mode |
| Esc | Return to normal mode |
| Key | Insertion Behavior |
|---|---|
| a | Insert after cursor |
| A | Insert after line |
| [n]i | Insert text before the cursor n times |
| [n]I | Insert text before the first char of the line n times |
| [n]a | Append text after the cursor n times |
| [n]A | Append text after the end of line n times |
| [n]o | Begin a new line below the cursor and insert text, repeat n times |
| [n]O | Begin a new line above the cursor and insert text, repeat n times |
| [n][“x]cc | Delete current line [into register x] and enter insert mode |
| [n][“x]C | same as c$ but also take into register |
| c$ | Delete from the cursor position to the end of the line and enter insert mode |
| cw | Delete from the cursor position to the end of the current word and enter insert mode |
| ce | Delete from the cursor position to the end of the current word and enter insert mode |
| ciw | Delete the current inner word and enter insert mode |
| [n]yy | Yank the current n lines, default is only the current line |
| yiw | Yank inner word |
| y$ | Yank to the end of current line |
| [n][“x]s | (substitute) delete n characters [into register x] and start insert |
| [n][“x]S | (substitute) delete n lines [into register x] and start insert |
| Key | Movement Behavior |
|---|---|
| H | Left |
| J | Down |
| K | Up |
| L | Right |
| [n]w | Jump to start of nth word |
| [n]e | Jump to end of nth word |
| [n]b | Jump to start previous nth word |
| [n]h | Cursor n chars to the left |
| [n]l | Cursor n chars to the right |
| [n]j | Cursor n lines downward |
| [n]k | Cursor n lines upward |
| [n]H | Cursor to the line n from top of screen |
| M | Cursor to the middle of screen |
| [n]L | Cursor to the line n from bottom of screen |
| [n]gg | Cursor to line n, default first line |
| [n]G | Cursor to line n, default last line |
| 0 | Jump to beginning of line |
| $ | Jump to end of line |
| ^ | Jump to beginning character of line |
| g + g | Go to the end of document |
| G | Go to the beginning of document |
| CtrlD | Move cursor down half page |
| CtrlU | Move cursor up half page |
| CtrlB | Move screen up one page |
| CtrlF | Move screen down one page |
| Key | Search Behavior |
|---|---|
| f + s | Find first occurrence of ‘s’ after the cursor |
| ; | Repeat last find forward |
| , | Repeat last find backwards |
| Key | Window Behavior |
|---|---|
| [n]CtrlW s | Split current window in two parts, new window n lines high |
| [n]CtrlW v | Split current window vertically, new window n columns wide |
to open a file in a split window
:split /file_path
:vsplit /file_path
CtrlW c Close current split window
[n]CtrlW h Go to nth left window (stop at first window) [n]CtrlW j Go to n windows down (stop at last window) [n]CtrlW k Go to n windows up (stop at first window) [n]CtrlW l Go to nth right window (stop at last window) [n]CtrlW x Exchange current window with window n (default: next window)
To keep the window number visible across all split viewports, add it to your status line format string. Open your configuration file (usually ~/.vimrc) and append the following syntax:
set statusline+=Window:\ %{winnr()}
" Always display the statusline
set laststatus=2
" Clear any existing statusline configuration
set statusline=
" Left Side Info
set statusline+=%f\ " File path
set statusline+=%m " Modified flag
set statusline+=%r " Read-only flag
set statusline+=%h " Help file flag
" Right Side Info (pushed via %=)
set statusline+=%= " Switch to right side alignment
set statusline+=[%Y]\ " File type
set statusline+=[%l/%L]\ " Line number / Total lines
set statusline+=col:%c\ " Column number
set statusline+=(%p%%) " Percentage through file
To open an existing buffer in a new window in Vim, run
:sbuffer [N] (for a horizontal split) or
:vert sbuffer [N] (for a vertical split), replacing [N] with the buffer’s number or name
Split to the Right:
:vert belowright sbuffer [N]
To toggle line numbers:
set number!
" Ensure the status line is always visible
set laststatus=2
" Set color for the active window status line
highlight StatusLine ctermfg=white ctermbg=darkblue guifg=#ffffff guibg=#00008b
" Set color for inactive window status lines
highlight StatusLineNC ctermfg=gray ctermbg=darkgray guifg=#a0a0a0 guibg=#444444
"+y Copy word into system clipboard "+yy Copy line into system clipboard
"+p Paste from system clipboard
y + w Copy word d + w Delete word (cut)
y + y Copy line d + d Delete line (cut)
p Paste after the cursor/line
P Paste before the cursor/line
u Undo
v Visual mode
V Line visual mode
[n]r{char} Replace n chars with {char} R Replace mode
[n]r{char} Replace n chars with {char}
J Join lines default is 2 gJ Join lines without inserting space
% Go to matching scope beginning/end (paranthessis, curly braces, etc. )
d + i + w Delete in word
d + i + ( Delete in paranthesis
[n]d + $ Delete from the cursor to the end of the line (and the next n - 1 lines) [n]D Delete from the cursor to the end of the line (and the next n - 1 lines) [n][“x]x Delete n characters under and after the cursor [into register x]
c + i + ( Change in paranthesis
Ctrl + o Cursor to previous position
Ctrl + i Cursor to next position
To replace all occurrences of a term in the entire file in Vim, press Esc to enter Normal mode and run
:%s/old_text/new_text/g
(% Specifies the range as the entire file. s Calls the substitute command. g Stands for global, replacing every match on a line rather than just the first one.)
Confirm each change -> Add the c flag to accept or reject every instance interactively:
:%s/old_text/new_text/gc (Press y to replace, n to skip, or a to replace all remaining)
Ignore case sensitivity -> Add the i flag if you want to find matches regardless of capitalization:
:%s/old_text/new_text/gi
Replace exact whole words only -> Wrap your text in word boundary markers (< and >) so it doesn’t modify partial matches inside longer words:
:%s/\<old_text\>/new_text/g
Use alternative delimiters if your text contains slash characters (like file paths or URLs), use a different delimiter like # or | to avoid escaping them:
:%s#/var/www/old#/var/www/new#g
Entire File :%s/foo/bar/g Replaces all instances of foo with bar. Current Line :s/foo/bar/g Replaces all instances on your active line only. Line Range :5,12s/foo/bar/g Replaces all instances between lines 5 and 12.
If you want to replace an occurrence in every html and twig files, you can type the following:
:arg *.html - Populate the arglist with all html files in the current working directory, and edit the first one.
:argadd *.twig - Add twig files to the arglist.
:argdo %s/pattern/replace/ge | update - Replace the occurence pattern by replace in every file of the arglist.
Even if the argument list (:help arglist) and the buffer list (:help :buffers) are different, every files added in the argument list will be added in the buffer list.
You can delete files in one of these lists without changing the other. For example, :argdelete * will remove everything in your argument list.
At that point, you might scream to your screen, violently shacked by extrem curiosity: what means the flag e at the end of the substitute command? It prevents Vim to display an error message when the pattern is not found in a file.
What about doing a find and replace in the working directory and the subdirectories? You can populate the arglist as follow:
:arg **/*.html
:argadd **/*.php
> + i + } increase indent
< + i + } decrease indent
= + i + B autoindent block
> + % put your cursor on one of the curly braces
If you’re copying blocks of text around and need to align the indent of a block in its new location, use ]+p instead of just p. This aligns the pasted block with the surrounding text.
execute ctags to generate tags for you project.
After this step Ctrl + ] will go to definition.
g then Ctrl + ] — Show a list of matching definitions if there are duplicates.
cd /path/to/your/project
ctags -f tags -R --fields=+K+a
ctags -R .
In your ~/.vimrc file, add this short block:
" ctags optimization
set autochdir
set tags=tags;
” denotes a comment. set autochdir tells vim that if it doesn’t find a tags file in the $PWD it will look in the directory parent for the tags file, recursively. set tags=tags; tells vim that the name of your tags file will always be the same as the default tags file generated by ctags.
Ctrl+] - go to definition
Ctrl+T - Jump back from the definition.
Ctrl+W Ctrl+] - Open the definition in a horizontal split
Ctrl + t: Jump back up one level in your tag stack.
g + Ctrl + ]: View a list of matching definitions if the name is used in multiple places.
Ctrl + x then Ctrl + ]: Trigger auto-completion in Insert Mode using your tags file.
Add these lines in vimrc
map <C-> :tab split
map <A-]> :vsp
Ctrl+\ - Open the definition in a new tab
Alt+] - Open the definition in a vertical split
After the tags are generated. You can use the following keys to tag into and tag out of functions:
Ctrl+Left MouseClick - Go to definition
Ctrl+Right MouseClick - Jump back from definition
To run a terminal command without input or output
:!{command}
To run a terminal command and pass the output to current buffer
:read !{command}
| Key | Macro Behavior |
|---|---|
| q{0-9a-zA-Z”} | Record typed characters into named register {0-9a-zA-Z”}(uppercase to append) |
| q | (while recording) stops recording |
| [n]@{a-z} | Execute the contents of register {a-z} n times |
| [n]@@ | Repeat the previously executed macro n times |
syntax on
set background=dark
colorscheme desert
" Always display the statusline
set laststatus=2
" Clear any existing statusline configuration
set statusline=
" Left Side Info
set statusline+=%F\ " Full path to the file
set statusline+=%m " Modified flag
" Right Side Info (pushed via %=)
set statusline+=%= " Switch to right side alignment
set statusline+=Window:\ %{winnr()}
set statusline+=\ %y " File type
set statusline+=\ [%L\ lines] " Line number / Total lines