[toc]
Modes
- Normal -
Esc - Insert -
i, a, c - Visual -
v, V, Ctrl-v - Command -
:, /
Operators
c- changed- deletey- yank into registery~- swap casegu- make lowergU- make uppper!- filter to external program<- shift left=- indent
Text Objects
aw- a wordiw- inner wordap- a paragraphat- a tagit- inner block
Motions
%- go to 1st matching paren/bracket[count]+- down to 1st non-blank char of line[count]$- to end of line[count]f/F{char}- to next of {char}[count]h/j/k/l[count]]m- go to onset of next method[count]w/W- go ot word/WORD to the right[count]b/B- go to word/WORD to the left[count]e/E- go to end of word/WORD right[count][ops][text obj / motions]6+- go down to 6x linegUaW- cap a WORD3ce- 3x change to word end4$- 4x go to end of lined]m- delete to start of next method
TRICK
- 0w - head first word
- d} - enter delete action + motion, e.g. delete till next block
- d% - delete entire content in ()
- C - change rest of cursor
- d/ct + CHAR - delete / change till CHAR
- Ctrl-w + s/v/q - split current window
- :windo - exec for ALL windows
- :sf FILE
- :tabc - close tab
- :tabo - close all other tabs
- :tabf FILE - find and open FILE in new tab
DEMO
vi -U NONE -O *- open all and splits- change inside quotation marks
ci' - reverse
u - find “p”
fp, deletexand pastep - creating index of pwd
:ctags- then go to definition
g<Ctrl-]> - go to file
gf
Always be Scrolling
zt- top of pagezz- middlezb- bottomH, M, LCtrl-U/D, Ctrl-F/B, Ctrl-Y/E
Basic Editing
!:e[dit][++opt][+cmd]{file}:fin[d][!][++opt][+cmd]{file}gfCtrl-^
/ Search
/{patt}[/]<CR>?{patt}[?]<CR>[Count]n- repeat last search [count] times[Count]N- opposite ibis*- serach#- bis oppositegd- go to local declaration:set hls!- toggle serach highlightig
Bookmarks
m{a-zA-Z}:marks- show all current mraks in use- ``{mark} , ‘{mark}` - access
- ``., ‘.` - jump to last update
Ctrl-] and Ctrl-t - PM
Ctrl-O and Ctrl-I - cycle through :jumps and g;, g cycle thru :changes
DEMO
Set bookmarks 'V as ~/.vimrc for easy setting
-
after accessing
'V, jump backCtrl-^ -
working dir-tree:
:20vs .read 20-char visual split current dir -
instead of
:e /path/fileto find and edit, do:find file.py -
find file and vertical split
:vert sf FILE -
change viewpoints
Ctrl-Wx -
change windows
Ctrl-Ww -
need to save current buffers viewpoints + windows -> add new tab[windows[buffers]]
:tabf FILE+:vert sf FILE- open tab + find + vert-split new files
-
go to next tab -
gt -
preview files via tree
pandCtrl-Wzto close -
navigate windows
Ctrl-W hjkl -
find in current file with {patt}
:vim {patt} %- navigate all matched via quick fix list
:cn<enter> - then do
@:to repeat {cmd}
- navigate all matched via quick fix list
-
find all matched in all files of interest
- make arglist first then “grep”
:args **/*.py:vim {patt} ##
-
replace {patt} with {patt1}
:cdo s/{patt}/{patt1}/g- navigate back to check
:cp<enter>
-
first, VISUAL mode for drag-selection
Ctrl-V hjkl(deletex)
Master VIM
.vimrc
- test before add to file
:set autoindentand find doc:set tabstop?
syntax on
filetype plugin indent on " Enable file type based on indentation.
set autoindent
set expandtab " Expand tabs to spaces. Essential in Python.
set tabstop=4 " Num. of spaces tab counted for.
set shiftwidth=4 " num. spaces to use for autoindent.
set backspace=2 " fix backspace bevaiour on most terminals.
colorscheme murphy
- cycle through built-in colorschemes
:colorscheme + <space> + <Tab>
Basic
- open-edit in vim
:e FILE - save-write
:w {FILE} <CR>file name optional - write-quit
:wqor just quit:qor force quit:q!
Swap files
Default tracking changes in swap files that are auto-gen during editing, recovered via VIM or SSH
- prevent
.swplittering in current dir set a dir in.vimrcbyset directory=$HOME/.vim/swap//or disableset noswapfile
Motion
-
n[hjkl]n times -
move to B-next-word
w, E-closest-worde, backward to B-wordb -
cap above to treat all but white-space as word! non-space sequence as WORD
-
move paragraph (>2 newlines)
{and}
Simple edit change
cwto change + next wordc3e(comma counts as a word)cbchange back wordc4lintriguing as change 4 chars untill- NOTE:
cw==cea legacy - structure
<cmd> <num> <move>/<text-object> - example:
- start by moving to
3<space>till last WORD3W - change-delete word + enter into insert mode
cw
- start by moving to
- delete
dbehave as normal withwande ccclears whole line + insert mode + keeping indentationdddeletes entire line- tip:
venter Visual mode to select before above edits
Persistent undo and repeat
-
uundo last ops and<Ctrl> rto redo -
enable persistent undo in vimrc
set undofile-
set file fir:
if !isdirectory("HOME/.vim/undodir") call mkdir("$HOME/.vom/undodir", "p") endif set undofir="$HOME/.vim/undodir"
-
loop through keyword in help
:h <keyword> + <Ctrl> + Dto loop through before- SEARCH in general:
/search <term>- forward and?search termbackward
Advanced Editing and Motion
plugin
mkdir -p ~/.vim/pack/plugins/start- vimcr:
packloadall " Load all pluginssilent! helptags ALL " Load help files for all plugins
- install plugin found on GitHub
git clone <.../nerdtree.git> ~/.vim/pack/plugins/start/nerdtree
Workspace
- Buffers = internal repr files for switching between files quickly
- Windows organise workspace by displaying multi-files next to each other
- Tabs a collection of windows
- Folds to hide and expand portions of files, making large files easier to navigate
Buffers
-
print all by these synonyms
:ls:buffers:files1 %a "file.py" line 30- 1 = buffer number staying constant over Vim session
- % = current window
- a = active, loaded, visible
- line 30 = current cursor pos
-
when open multiple files, switching files via buffer number
:b1or:b <partial filename> + <Tab>(for looping) or next-previous:bn :bp -
useful plugin
https://github.com/tpope/vim-unimpaired -
:bn- next buffers -
:b {filename}- go to buffer filename -
:bd- delete current buffers -
:buffers- print all buffers -
:bufdo {cmd}- exec cmd to all buffers -
:n- next file (based on arglist) -
:arga {filename}- add to arglist -
‘:argl {files}’ - make a local arg copy via files
-
:args- print all arguments
arglist
args **/**.yaml- make arglist with all such files- followed directly by
:sallto split all and display in a new tab (:vert sallibis) windo difft- do for all windows diff on files
Windows
- split
:split <file>or:spor vertical:vsplit :vs - move windows
Ctrl + w [+ hjkl]
# binding for ease split in vimrc
" Fast split navigation with Ctrl + hjkl
noremap <c-h> <c-w><c-h>
noremap <c-j> <c-w><c-j>
noremap <c-k> <c-w><c-k>
noremap <c-l> <c-w><c-l>
-
close
Ctrl + w + qor:bddelete-buffer-close-window -
close all else
Ctrl + w + o -
save all and quit
:wqa!!! -
:Bdkeeping window on closing buffercommand! Bd :bp | :sp | :bn | :bd -
movement prefix
<Ctrl> + w:Hto leftmostJto bottomKto topLto rightmost
-
Ctrl w rmoves all windows within the row / column to the right or downwardsRfor reverse -
Ctrl w xexchanges contents of a window with the next one (or previous one if it’s considered a last window) -
Ctrl w =equalise h-w of all windows!!! -
resizings:
:resize +Nup height by N rows (:res) (or just N):vertical resize -Ndown width by N columns (:vert res)- shortcut:
Ctrl w -/+/>/<
-
:windo {cmd}- exec for all windows -
:sf {FILE}- split windows and:find {FILE} -
:vert {cmd}- make any cmd use vert split -
:vnew {FILE}- open new file in vertical splits
Tabs
- used to switch between collections of windows for multi-workspace
- often used for different projects or set of files within the same session
:tabnewopen new with empty buffer or+ <file>gtto move to next tab,gTback:tabcloseor close all windows it contains:qtabmove Nto place tab after the Nth tab
Folds
- setting auto-folding python files
set foldmethod=indent zoopen current fold whilezcclose it orzato toggle- visualise pos of folds
:set foldcolumn=Nwere N [0, 12] zRopen allzMclose all
Folding methods following foldmethod
indent - langs having indentation syntax
expr - regex based and extremely powerful
marker - special markup like {{{ }}}
syntax - not every lang supported
diff - auto used when operating diff mode
File tree
- Netrw the built-in file manager
:Ex(:Explore) or a sym-key:e .<CR>opens files/dirs;-goes up dir;Ddeletes file/dir;Rrename:Vexopens Netrw vert-split (:Sex,:Lex)- go to remote
:Ex sftp://<domain>/<dir>/or:e scp://<domain>/<dir>/<file>
- :e with wildmenu enabled via
set wildmenu- emulating autocomplete
:e + <Tab>(Shift + Tabreverses) set wildmode=list:longest,full“complete till longest string then open wildmenu
- emulating autocomplete
- NERDTree invoking via
:NERDTree- move by
hjklor arrow Enter oroto open - bookmarking while cursor over:
:BookmarkthenBto display - always display bookmars
let NERDTreeShowBookmarks = 1 - toggle
:NERDTreeToggleor startup enabledautocmd VimEnter * NERDTree - close it when it’s last open window:
autocmd bufenter * if (winnr("$") == 1 && exists ("b:NERDTree") && \ b:NERDTree.isTabTree()) | q | endif
- move by
plugins
- Vinegar -
Itoggles help bar andShift ~take to home dir - CtrlP - fuzzy completion
Ctrl Pshows list of files in project dirCtrl j/kup/down list of filesf bto cycle thru options:CtrlPBufferfor buffers
Movement in Text
tuntil followed by character in line whileTbackwardsffind followed by character to search in lineFbackwards_moves to B of line$to end !!!- word = numbers, letters, underscores / WORD = any but space
gemoves to end of previous wordShift {to B of paragrahShift (to B of sentenesHto head of windowLto bottom of window (current)Ctrl f== page downCtrl bfor page up/followed by string searches documentShift ?backwardsggto top of fileGto end of file
gg
?
H
{
k
^ F T ( b ge h l w e ) t f $
j
}
L
Ctrl+f
/
G
- move by line numbers enabled by
:set nu(put in vimrc for startup)- jump
:Nwhere N is absolute line number - jump to N in file
vim file +14 - jump
:+Nrelative down (:set relativenumber)
- jump
Jump into INSERT
ainsert after cursorAat end of line (==$a)Iinsert at B-line after indentoadds new line below cursor + insertOabovegiinsert last exitCdeletes txt to the right of cursor til E-lineccorSdeletes contents of linesdeletes single char
Searching / and ?
- fastest way to move!!
- Cycling thru matches in the same buffer
nN set hlsearch(best in vimrc) highlights match (off by:noh)set incsearchmakes dynamic move to first match
Searching across files
:grepuses system grep:vimgrep+ <patt> <path>.pattbe string or Vim-like regex- e.g. searching
calcby:vimgrep animal **/*.py - navigate
:cnor:cpor visual quickfix window:copenthenj kto jump and enter - close by:qorCtrl w q
ack
- spiritual successor of grep for code search
sudo apt install ack-grep ack --python Animal- Vim plugin integrates
ack.vimthen do:Ack --python Aniimal
Text Object
di)== delete inside parentheses !!!c2aw== change outside of two words to delete two wordsiinner objects do not include white space or next char whileaouter do- common code text objects:
' " ) ] > } - Verb
dorc+ Number2+ Adjectiveiora+ Noun)orwetc
EasyMotion
- invoke by
\\+ desired movement key
Registers
- yank
yto copy text + movement or text object (usable in visual mode) yecopy till E-word to copy into register thenpto paste- more to see
Copying from outside VIM
*register the main clipboard+register Linux only used forCtrl c / vstyle"*pto paste from primary clipboard or"+yyto yank a line into Linux’s clipboard- setting default
set clipboard=unnamed " copy into system (*) registerset clipboard=unnamedplus
Plugin
Managers
- vim-plug - fetch file (
.../master/plug.vim) then save in./vim/autoload/plug.vim(fetch single filecurl -fLo <dest> --create-dirs <source>)- update .vimrc
call plug#begin()andcall plug#end() -
add some plugins between these 2 lines / format
Plug 'scrooloose/nerdtree'
- save and reload (
:w | source $MYVIMRC) Do:PlugInstallto install :PlugUpdateand:PlugCleanto delete:PlugUpgradefor vim-plug itself + reload file- two modes of loading (after above line
, { 'on': 'NERDTreeToggle'}and, {'for': 'markdow'}) - For UNIX, add this for transporting to new machine
- update .vimrc
if empty (glob ('~/.vim/autoload/plug.vim'))
silent !curl -fLo ...
autocmd VimEnter * PlugInstall --sync | source $MYVIMRX
endif
Profiling speed
vim --startuptime time.logcheck bottleneck timestams
MODE
- Normal Mode
Ctrl-b/eB-line and E-lineCtrl-fopens editable CLI window with history (as a buffer, edit and exec again,Ctrl-cto close)
- Insert mode
Ctrl-oto do single cmd then back to insert
- Visual and Select mode
vchar-wiseVline-wiseCtrl-vblock-wiseogo to other end of highlighted text to expand-select
- Replace mode
Randr - Terminal mode
:terminalor:term+ cmd for single exec
Text
Autocomplete
- type name of function +
Ctrl n/pto cycle - insert-completion mode
Ctrl x+Ctrl ito complete whole lineCtrl j]to complete tagsCtrl fcomplets filenames
YouCompleteMe
- semantic autocomplete; intelligent suggestion; display doc etc
- dependencies
sudo apt install cmake llvm - if using vim-plug:
let g:plug_timeout = 300 \n Plug 'Valloric/YouCompleteMe', { 'do': './install.py'} - save files then
:source $MYVIMRC | PlugInstall - enable semantic engine
.in insert or manuallyCtrl space - For python jumping to method definition:
noremap <leader>] :YcmCompleter GoTo<cr>then\]when cursor over func call
Navigating code base with tags
gdfor local andgDfor global
Exuberant Ctags
- External utility generating tag files
sudo apt install ctags ctags -R .to navigate project and creating tags file in dirset tags=tags;for looking files recursively in parent dirCtrl ]+ tag to the definition andCtrl tto go back in tag stack:tnand:tpcycle tags:tsselect manu
Build, Test, Execute
Integrating Git Vim - vim-fugitive
:Gstatus==git statusbut interactive for cycling through filesCtrl-n/p-stage/unstage file,ccor:Gcommit,Dor:GDiffopen a diff,Gloghistory- Tip:
:copenpops quickfix window,:cnext:cpreviousnavigate :Gblamewith shortcutsC, A, Dresizing,Enteropens a diff of chosen commit,oopens diff of chosen commit in split,
Resovling conflicts with vimdiff
- in terminal
vimdiff file1 file2 - move change
]cforward[cbackwards door:diffgetmoves change to active windowdpor:diffputpushes change from active window- configure Git to use vimdiff as merge tool:
git config --global merge.tool vimdiff,git config --global merge.conflictstyle diff3,git config --global mergetool.prompt false
- example:
git checkout -b branch-tmp
# edit some codes
git add . && git commit -m "Branch-chnage"
git checkout master
# edit some codes differently
git add . && git commit -m "Master-change"
git merge branch-tmp
# stdout: Conflict
git mergetool
-
In view are 4 windows:
- pos-1 is master branche or local changes
- pos-2 closest common ancestor
- pos-3 branch-tmp in conflict
- pos-4 MERGE shows conflict markers as
<<<< ... >>>>
<<<<<< [LOCAL commit/branch] [LOCAL change] ||||||| merged common ancestors [BASE - closest common ancestor] ======= [REMOTE change] >>>>>>> [REMOTE commint/branch]assuming keeping REMOTE (branch-tmp), move cursor to window MERGED (pos-4), move cursor to the next change (
]cand[cto move by changes), and executediffget REMOTE- this will change from REMOTE file and place it into MERGED file
- Get a REMOTE change using
:diffg R - Get a BASE change using
:diffg B - Get a LOCAL change using
:diffg L - Save-exit
:wqa - free to discard
.origfiles after - commit
- Get a REMOTE change using