Quit the Vim
<esc> :q! <enter>
Vim Forks and Neovim
Neovim is a fork of Vim and defines itself as an extension of Vim with the goal that make easy to contribute. Neovim can be used as a drop-in replacement of Vim.
Creating a file
$ vim <enter>
$ vim filename
$ vim directory/filename
Vim modes
Vim provides different modes to users for focus on content.
- normal mode: Vim starts in this mode. Esc is used to enter it.
:h Normal-modeπ
- insert mode: used to add text to the editor; it can be entered with one of the insert commands
:h Insert-modeπ
- replace mode: used to replace existing text by typing over it directly; it can be entered with
R :h Replace-modeπ
- visual mode: used to select an area of text. Character-wise selection can be made with v, line-wise selection with V, and block-wise selection with C-v
:h Visual-modeπ
- command mode: used to enter Ex commands; it can be entered with
:, and commands require pressing the Enter key. Example: :w <enter> :h Cmdline-modeπ
General
$ vimtutor Official tutorial of Vim
:h user-manual
:h help-summary On usage of built-in documentation
:h subject help about the *subject*. Ex: `:h python` (C-] to click hyperlinks, C-T to back)
:q quit
:w write
:saveas filename save as
:wa write all the changes
:wa[!] force Vim write all the changes
:wq write and quit
:x update and quit
:wqa write quit all
:q! if file is changed and not supposed to saved, quit
u undo example: 4u
C-r redo (push Ctrl button then r)
U Undo all line
s=seconds, m=minute, h=hour, d=day
:earlier #m turn back # minute ago of the file Ex: :earlier 2m or :ea 3d
:later #m turn back # minute later state of the file Ex: :later 7s or :lat 9h
y yank, copy
yy yank all line
p paste to below of cursor
P Paste to above of the cursor
c change, change the selected area
. repeat latest command
:term start a terminal session inside vim, more at `:h terminal`
:!<cmd> execute <cmd> commands without leaving Vim Ex: `!g++ -wall -std=c++14 main.cpp`, `!ruby %`
:sh go to shell, return by `exit`
$C-z send vim to background, return by $fg
Moving around
:h motionπ
k
h cursor left ^
j cursor down h < > l
l cursor right v
k cursor up j
0 beginning of line
$ end of line
w jump to first character of next word
e jump to last character of the current word
b jump to first character of the current word
H jump to *top* of the screen
M jump to *middle* of the screen
L jump to *lower* of the screen
C-b jump a full screen size up
C-f jump a full screen size down
C-u jump half screen size up
C-d jump half screen size down
:h scroll-cursorπ
z<enter> redraw, cursor on the top of window, and put cursor at first non-blank in the line
zt like above but leave the cursor in the same column
z- redraw, cursor on the bottom of window, and put cursor at first non-blank in the line
zb like above but leave the cursor in the same column
z. redraw, cursor on the center of window, and put cursor at first non-blank in the line
zz like above but leave the cursor in the same column
w jump beginning of next word (punctuation considered as a word)
e jump end of the word
ge jump end of the previous word
b jump beginning of the previous word
^ jump to first non space character on line
gg top of the file
G bottom of the file
+ beginning of the next line
- beginning of the previous line
W jump beginning of the next word (punctuation not considered words) v v
E jump end of the next word (punctuation is not considered part of a word) Ex: e (abcd) E (abcd)
B jump beginning of the previous word
#G go to line number # Ex: 38G
#gg same as #G
In more general:
gg
?
C-b
H
{
k
^ F T ( b ge h l w e ) t f $
j
}
L
C-f
/
G
Entering insert mode
/~~~~~~~~~~~~\
|command mode|
\~~~~~~~~~~~~/
| |
^ :/ v Esc Esc
| |
/~~~~~~~~~~~~\----Esc---->/~~~~~~~~~~~\<---Esc------/~~~~~~~~~~~\
|replace mode| |normal mode| |insert mode|
\~~~~~~~~~~~~/<----R------\~~~~~~~~~~~/--aAiIoOsS-->\~~~~~~~~~~~/
| |
v vV ^ Esc
| |
/~~~~~~~~~~~\
|visual mode|
\~~~~~~~~~~~/
i insert text before cursor
I insert text to start of the line
a append after cursor
A append text to end of line
o make newline below to current line and insert text
O make newline above to current line and insert text
s delete character under cursor and enter insert mode
S delete all line and enter insert mode
cc same as above
cw change from cursor position to start of the next word
S-r enters [replace mode](#replace-mode), change text in place
Working more than one file
:h usr_08.txtπ
C-ws split current window horizontally (alternative :split)
C-wv split current window vertically (alternative :vsplit)
C-ww jump to next window
C-w h jump from current window to window on the left
C-w j jump from current window to window on below
C-w k jump from current window to window on above
C-w l jump from current window to window on left
C-w t jump to top most left window
C-w b jump to bottom most right window
C-wq close current window
:close same as above
:only close windows other than current
C-w#< resize current window to the left # of times (default 1)
C-w#> resize current window to the right # of times (default 1)
:res # resize a horizontally split window # of times
:h window-movingπ
C-wH move current window to the far left
C-wJ move current window to the very bottom
C-wK move current window to the very top
C-wL move current window to the far right
$vim --help for a list of Vim parameters `h vim-arguments`:tropical_fish:
$ vim -O2 f1.txt f2.txt opens f1.txt and f2.txt in vertically split windows
$ vim -o2 f1.txt f2.txt opens them in horizontally split windows
$ vim -P2 f1.txt f2.txt like above but on tab pages
$ vim f1.txt f2.txt open the files but show only one at a time (navigate with :next and :prev)
using tab pages
:h tabpageπ
:tabedit filename edit specified file in a new tab
:tabfind filename open a new tab with filename given, searching the 'path' to find it
:tabn next tab
:tabp previous tab
:tabfirst first tab
:tablast last tab
:tabm {i} move current tab to i+1 place
:tabclose i close tab i
:tabclose close current tab
:tabonly close other tabs but current
:tabs list tabs
Repeating commands without repeating yourself
operator [number] move or [number] operator move
c3w or 3cw, cw cw cw
4j jjjj
2w w w, go to the beginning of the next 2 words
2dd delete 2 lines
repeating more than one command by recording
:h recordingπ
Recording more than 1 move would be greatly useful. Vim has 26 register(a-z), which can be considered 26 different clipboard!!!
- start recording with
q and choose a register to record on. Ex: qa
- exit from recording with Esc.
- apply what you record with
@<reg> Ex: @a
q[a-z] start recording
@[a-z] apply record
Editing
x delete the character under the cursor
X delete the character before the cursor
dw delete word from cursor position to start of the next word(punctuation considered as a word)
dW delete Word from cursor position to start of the next word
d^ delete from first non-whitespace character to end of line (inclusively)
d$ delete till end of the line
D same as above
dd delete all line
dib delete content inside the parentheses
r<c> change the character under the cursor to <c>
* find next word under cursor
f<c> find character <c> from current cursor position inside the line
'. jump to last edited line
g; jump back to the last edited position
:ab sth something in insert mode, when written 'sth'<space> change it with 'something'
:g/^#/d delete all the lines start with #
:g/^$/d delete all the empty lines
find and change
:h substituteπ
:s/old/new change first 'old' with 'new' on the current line
:s/old/new/g change all 'old' with 'new' on the current line
:s/old/new/gc change all 'old' with 'new' on the current line but before ask for permission
:#,#s/old/new/g change all 'old' with 'new' between the lines # and #
:%s/old/new/g change all 'old' with 'new' on the current file
:%s/old/new/gc change all 'old' with 'new' on the current file but before ask for permission
Some frequently used commands
yyp copy line and paste to below
yyP copy line and paste to above
ddp swap current line with the below
ea add end of the word
xp exchange two chacter Ex: sometihng -> something
dgg delete from current line to beginning of the file
dotfiles and .vimrc
:h vimrc-introπ :optionsπ
On Unix-like operating systems, most system tools are C programs, and some of these programs take arguments written in a file. Dotfiles, files whose names start with a ‘.’, provide these parameters and define program behavior at runtime. You can read an interesting story about the birth of this trend
here. Dotfiles are especially useful when you set up a new machine because they save you from configuring everything from scratch. Keeping dotfiles in a version control system is good practice; most users share their dotfiles in public repos.
.bashrc, .profile, .vimrc are examples of dotfiles.
.vimrc file defines setting of Vim at runtime. There are a system .vimrc and user .vimrc in
home directory of every user. The one on home directory override system .vimrc. If you don’t have .vimrc file on your home directory, you can download from
here.
mapping
:h mappingπ we can create shortcuts using mapping.
General formula:
map shortcut longCommands
we need to add mappings to .vimrc make them permanent.
there are 3 basic mappings for three modes:
- to work in normal mode nmap
- to work in insert mode imap
- to work in visual mode xmap
nmap m <C-d> "in normal mode: when typed m, ctrl-d (half page below) will be executed
imap jk <ESC> "in insert mode, when jk is typed, switch to normal mode
Some special characters: :h key-notationπ
RendeRenderCollectionViewrCode NYI
To check whether your mapping conflict other mappings: :verbose map shortcut
Sometimes mappings conflict other mappings, so that defining your mappings as no-recursive is a good practice.
The example below demonstrates such a case: o goes one line down and enters insert mode. The expected behavior of going 4 lines down and entering insert mode ends up in an endless loop. The o will call 4o, which will call another 4o, etc.
nmap o 4o
To make no-recursing mapping we add nore
- for normal mode nnoremap
- for insert mode inoremap
- for visual mode xnoremap
The mapping below does what we expect, from normal mode, goes 4 lines below and enter insert mode:
nnoremap o 4o
we can specify mappings to filetypes:
autocmd FileType cpp nnoremap <f5> :w <bar> !clang++ -stdlib=libc++ -fsyntax-only -std=c++1z % <cr>
autocmd FileType d nnoremap <f8> :call DTest()<cr>
autocmd FileType text nnoremap <C-s> :w <cr>
leader variable
:h leaderπ
You can choose a variable as a leader and use it as a mapping prefix.let mapleader = "-" now I chose - character as a leader. After nnoremap <leader>ve :vsplit $MYVIMRC<cr> mapping, when I want to edit the .vimrc, in normal mod, can press -ve characters.
See all the mappings with :map
Adding plugin
The easiest way to adding plugin to Vim is make use of a plugin manager. There are several of them:
adding plugin with vim-plug
vim-plug is a plugin manager for Vim which allows you to add, update, remove plugins.
run the following command:
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
and than add your .vimrc to this:
call plug#begin()
" plugins
call plug#end()
Add the plugin you want to install between call plug#begin() and call plug#end() commands. Most of vim plugins host and maintain on Github.
call plug#begin()
Plug 'https://github.com/tpope/vim-sensible'
call plug#end()
or
call plug#begin()
Plug 'tpope/vim-sensible'
call plug#end()
and then invoke
:PlugInstall
command, that’s it! After add the plugin, the usual step is reading its documentation to learn and make some more configuration.
Creating your own plugin
:h write-pluginπ :h pluginπ
You can write your own plugin! A Vim plugin is a program written in vimscript (VimL) language. Generally consist of following parts.
MyAwesomePlugin/
.
βββ autoload Autoloaded functions according to filetype
βββ doc Documentation file
βββ ftdetect File type detection
βββ ftplugin Plugin for a particular file type
βββ plugin Plugin file
βββ syntax Syntax highlighting
βββ after
βββ indent
βββ compiler
Hello World plugin
Add the folder contain the plugin to runtimepath: set runtimepath+=/path/to/helloworld
helloworld/
.
βββ autoload
βΒ Β βββ greet.vim
βββ plugin
Β Β βββ greet.vim
" plugin/greet.vim
if exists('g:loaded_greet')
finish
endif
let g:loaded_greet = 1
command! Greet call greet#hello_world()
" autoload/greet.vim
function! greet#hello_world() abort
echo "Hello World!!"
endfunction
That’s allπ Try with :Greet on command mode.
Vim for programmers
Vim is a great tool for programmers. There are several plugins for autocompletion, refactoring, linting, code formatting, and much more. Writing such plugins is a non-trivial job; porting them to other editors is almost impossible. People have come up with different approaches so far, some of them pretty successful.
In 2016 Microsoft developed
Language Server Protocol to stop reinventing the wheel, and regulating such operations. Unless you have a good reason to not using it,
LSP is the way to go for make Vim to gain IDE like features. To use it, you need to install
language server implementation for the language you programming in and add
language client plugin to Vim.
I use
clangd language server, and
coc.nvim as a client for programming C++. See the list of language servers and clients lists from
here.
An incomplete list of plugins
For newcomers
Code completion and language client
List of language servers
Lint and syntax check
Snippet
Programming language
GUI-like
Theme and colors
Plugins for a better user experience
Links
sites
books
Practical Vim: Edit Text at the Speed of Though by Drew Neil
1
Modern Vim by Drew Neil
Learning Vi and Vim Editors by Arnold Robbins, Elbert Hannah
The VimL Primer: Edit Like a Pro with Vim Plugins and Scripts by Benjamin Klein
Mastering Vim: Build a software development environment with Vim and Neovim by Ruslan Osipov
2
cheatsheets
Building Vim from source code
If you’re using a Unix-based operating system, Vi or Vim is probably preinstalled, but Vim needs some features that are not enabled by default. To enable them, you might need to build Vim from its source code.
Which features enabled by default is changing distro to distro, check out with:
:version
Download repo with Git:
$ git clone --depth=1 https://github.com/vim/vim.git && cd vim
Before starting the build, we need to run configure. This is the phase where you’ll choose which features to enable.
$ ./configure --help
These are the parameters I use:
$ sudo ./configure --enable-fail-if-missing \
--disable-darwin \
--disable-smack \
--disable-selinux \
--enable-luainterp=yes \
--with-python3-command=python3interp \
--enable-python3interp=yes \
--with-python3-config-dir=/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu \
--enable-cscope \
--disable-netbeans \
--enable-terminal \
--enable-autoservername \
--enable-multibyte \
--disable-rightleft \
--disable-arabic \
--disable-farsi \
--enable-fontset \
--enable-gui=no \
--enable-gtk2-check=no \
--enable-gtk3-check=no \
--enable-athena-check=no \
--enable-nextaw-check=no \
--enable-carbon-check=no \
--disable-gtktest \
--with-compiledby=p1v0t
Your options might differ according to your needs. Be ready to search for and install third-party libraries. After this step, the files the build system needs are generated with the GNU Make build tool:
$ sudo make -j 8
The ‘-j’ parameter says how many cores we dedicate to the build process. Generally the more cores used, the faster the build process, therefore the less time the build will take. At the end of this process, executables will be created. To make them available as system command, we need to copy them to appropriate directories (you need superuser permissions):
$ sudo make install
Don’t delete the repo yet, in order to apply patches or experiment with the latest features by git pulling them. The subsequent build will be a lot faster, because make compiles only changed files.