Vi: Difference between revisions

From miki
Jump to navigation Jump to search
No edit summary
Line 369: Line 369:


== Scripting ==
== Scripting ==
=== Variables vs Options ===
Some basic stuff on Vim scripts:
Some basic stuff on Vim scripts:
<source lang=bash>
<source lang=vim>
# let is for variables
" Use LET for VARIABLES
let myvar="Hello"
let myvar="Hello"
echo myvar
echo myvar
let myvar=call func(param1,param2)
let myvar=call func(param1,param2)

# set is for vim options:

set runtimepath=~/.vim # set option
" Use SET for OPTIONS
set runtimepath? # read option
set runtimepath=~/.vim " SET option"
# let <-> set
set runtimepath? " GET option"


" We can use LET with &{OPTIONS}
let myvar='batch'
let myvar='batch'
let &filetype=myvar # &{option} returns option value in an expression
let &filetype=myvar " &{option} returns option value in an expression"
echo &filetype
echo &filetype
if &filetype == 'java'
if &filetype == 'java'
...
...
endif
endif

# But these does not give the same:

set runtimepath? # No expansion
" But these does not give the same:
echo &runtimepath # Expansion occurs
set runtimepath? " No expansion within runtimepath (eg. replace ~ with /home/...)"
# Another example, use variable to prepend a path to runtimepath:
echo &runtimepath " Expansion occurs with runtimepath"


" Another example, use variable to prepend a path to runtimepath:
set runtimepath-=~/vimfiles
set runtimepath-=~/vimfiles
let tmp=&runtimepath
let tmp=&runtimepath
let &runtimepath="~/.vim,".tmp
let &runtimepath="~/.vim,".tmp
</source>

=== Expressions ===
See <code>:h expression-syntax</code> for more.

<source lang=text>
|expr1| expr2 ? expr1 : expr1 if-then-else

|expr2| expr3 || expr3 .. logical OR

|expr3| expr4 && expr4 .. logical AND

|expr4| expr5 == expr5 equal
expr5 != expr5 not equal
expr5 > expr5 greater than
expr5 >= expr5 greater than or equal
expr5 < expr5 smaller than
expr5 <= expr5 smaller than or equal
expr5 =~ expr5 regexp matches
expr5 !~ expr5 regexp doesn't match

expr5 ==? expr5 equal, ignoring case
expr5 ==# expr5 equal, match case
etc. As above, append ? for ignoring case, # for
matching case

expr5 is expr5 same |List| instance
expr5 isnot expr5 different |List| instance

|expr5| expr6 + expr6 .. number addition or list concatenation
expr6 - expr6 .. number subtraction
expr6 . expr6 .. string concatenation

|expr6| expr7 * expr7 .. number multiplication
expr7 / expr7 .. number division
expr7 % expr7 .. number modulo

|expr7| ! expr7 logical NOT
- expr7 unary minus
+ expr7 unary plus

|expr8| expr8[expr1] byte of a String or item of a |List|
expr8[expr1 : expr1] substring of a String or sublist of a |List|
expr8.name entry in a |Dictionary|
expr8(expr1, ...) function call with |Funcref| variable

|expr9| number number constant
"string" string constant, backslash is special
'string' string constant, ' is doubled
[expr1, ...] |List|
{expr1: expr1, ...} |Dictionary|
&option option value
(expr1) nested expression
variable internal variable
va{ria}ble internal variable with curly braces
$VAR environment variable
@r contents of register 'r'
function(expr1, ...) function call
func{ti}on(expr1, ...) function call with curly braces
</source>
=== Process control ===
<source lang=vim>
if filereadable("foo.cfg") " Boolean"
" ...
endif
while lnum <= line("$") " Number - other tests are =, !=, <=, >="
call FixLine(lnum)
let lnum = lnum + 1
endwhile
if $ENV_VAR != "" " String"
echo $ENV_VAR
endif

" FOR with LISTS
for item in ["foo", "bar"]
echo item
unlet item " E706 without this"
endfor
for item in ["foo", ["bar"]]
echo item
unlet item " E706 without this because different item types
endfor
for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
echo getline(lnum)[col]
endfor


</source>
=== Handy functions ===
(see <code>:h functions</code> for complete list)

<source lang=vim>
glob("/foo/bar") " String, extension file wildcard (here as file existence test)"
filereadable("foo.cfg") " Number, TRUE if file readable"
</source>
</source>



Revision as of 10:23, 15 November 2012

Related Pages

This page is about the editor vim itself. The other related pages are

  • Vimrc, which is dedicated to vim configuration settings and to the file ~/.vimrc.

External Links

General

Other General

Cheat sheets

Guides & Cheat sheets

Vim in Windows/Cygwin

Tips

Plugins (installed)

Plugins (not yet installed)

Some videos that illustrates those plugins:

Plugins (uninstalled)

Vimrc examples

Invocation

vi -p file1.txt file2.txt                  # Open each file in a different tab
vi -t tagname                              # Open file and move cursor at specified tag (requires ctags)
view file.txt                              # View file in vim, with syntax highlighting... (read-only)
vimdiff file1.txt file2.txt                # View differences in vim

The following is a description of the start up sequence as I understood by experience. It's certainly far from complete. For more information:

:version
:echo $HOME
:echo $VIM
:set runtimepath?
:help vimrc
:help gvimrc
:help runtimepath
  1. First, load the system config files:
  2. File description OS Location
    vimrc System config file for vim and gvim Unix & Win $VIM/vimrc
    gvimrc System config file for gvim only Unix & Win $VIM/gvimrc
  3. Second, load the user config files:
  4. File description OS Location
    vimrc User config file for vim and gvim Unix $HOME/.vimrc
    Win $HOME/_vimrc
    gvimrc User config file for gvim only Unix $HOME/.vimrc
    Win $HOME/_vimrc


  5. Search for runtime files in path 'runtimepath'. Basically vim looks for directories in that path for further runtime files to execute (see :help runtimepath for more information)

Windows

  • Tab Edit with &Vim — The following registry setting add a context menu item in explorer to open a file in a new tab in a running instance of gvim (see [5]):
  • REGEDIT4
    [HKEY_CLASSES_ROOT\*\Shell\Tab Edit with &Vim\command]
    @="\"C:\\Program Files\\vim\\vim71\\gvim.exe\" -p --remote-tab-silent \"%1\" \"%*\""
    
  • Share config with Cygwin — To have win32 gvim and cygwin vim, use the same config files
    • Simply define the env. var HOME to point to user home in cygwin:
    HOME=c:\cygwin\home\username
    
    • Create the file C:\Program Files\Vim\vimrc (system vimrc file for windows)
    set runtimepath-=~/vimfiles
    let tmp=&runtimepath
    let &runtimepath="~/.vim,".tmp
    

    Win32 gvim will read the standard configuration files .vimrc and .gvimrc (although this is not reported by :version). It will also fetch the plugins from cygwin home directory.

  • Enable Ruby support — there is a bug in Vim7.3_46 that crashes vim when ruby is loaded. This is fixed in a later release [1]. Install:
    • Latest Vim from Cream (currently Vim 7.3.260)
    • This version of Vim requires Ruby 1.8.x (and not Ruby 1.9.1 as indicated in :help ruby).
      Download ruby-1.8.7-p330-i386-mswin32.zip from here, and install it in C:\RUBY.
      Add C:\RUBY\bin to system path (before cygwin!)


Check also potential goodies Vi#Vim_in_Windows.2FCygwin above.

Managing Options

See :help options for more details

"Show all options that differ from default
:set
"Show value of {option}
:set {option}?
"Set {option} to value
:set {option}={value}
"Add value to {option}
:set {option}+={value}

Scripting

Variables vs Options

Some basic stuff on Vim scripts:

" Use LET for VARIABLES
let myvar="Hello"
echo myvar
let myvar=call func(param1,param2)


" Use SET for OPTIONS
set runtimepath=~/.vim         " SET option"
set runtimepath?               " GET option"


" We can use LET with &{OPTIONS}
let myvar='batch'        
let &filetype=myvar            " &{option} returns option value in an expression"
echo &filetype
if &filetype == 'java'         
    ...
endif


" But these does not give the same:
set runtimepath?               " No expansion within runtimepath (eg. replace ~ with /home/...)"
echo &runtimepath              " Expansion occurs with runtimepath"


" Another example, use variable to prepend a path to runtimepath:
set runtimepath-=~/vimfiles
let tmp=&runtimepath
let &runtimepath="~/.vim,".tmp

Expressions

See :h expression-syntax for more.

|expr1| expr2 ? expr1 : expr1	if-then-else

|expr2|	expr3 || expr3 ..	logical OR

|expr3|	expr4 && expr4 ..	logical AND

|expr4|	expr5 == expr5		equal
	expr5 != expr5		not equal
	expr5 >	 expr5		greater than
	expr5 >= expr5		greater than or equal
	expr5 <	 expr5		smaller than
	expr5 <= expr5		smaller than or equal
	expr5 =~ expr5		regexp matches
	expr5 !~ expr5		regexp doesn't match

	expr5 ==? expr5		equal, ignoring case
	expr5 ==# expr5		equal, match case
	etc.			As above, append ? for ignoring case, # for
				matching case

	expr5 is expr5		same |List| instance
	expr5 isnot expr5	different |List| instance

|expr5|	expr6 +	 expr6 ..	number addition or list concatenation
	expr6 -	 expr6 ..	number subtraction
	expr6 .	 expr6 ..	string concatenation

|expr6|	expr7 *	 expr7 ..	number multiplication
	expr7 /	 expr7 ..	number division
	expr7 %	 expr7 ..	number modulo

|expr7|	! expr7			logical NOT
	- expr7			unary minus
	+ expr7			unary plus

|expr8|	expr8[expr1]		byte of a String or item of a |List|
	expr8[expr1 : expr1]	substring of a String or sublist of a |List|
	expr8.name		entry in a |Dictionary|
	expr8(expr1, ...)	function call with |Funcref| variable

|expr9| number			number constant
	"string"		string constant, backslash is special
	'string'		string constant, ' is doubled
	[expr1, ...]		|List|
	{expr1: expr1, ...}	|Dictionary|
	&option			option value
	(expr1)			nested expression
	variable		internal variable
	va{ria}ble		internal variable with curly braces
	$VAR			environment variable
	@r			contents of register 'r'
	function(expr1, ...)	function call
	func{ti}on(expr1, ...)	function call with curly braces

Process control

if filereadable("foo.cfg")      " Boolean"
   " ...
endif
while lnum <= line("$")         " Number - other tests are =, !=, <=, >="
    call FixLine(lnum)
    let lnum = lnum + 1
endwhile
if $ENV_VAR != ""               " String"
    echo $ENV_VAR
endif

" FOR with LISTS
for item in ["foo", "bar"]
    echo item
    unlet item                  " E706 without this"
endfor
for item in ["foo", ["bar"]]
    echo item
    unlet item                  " E706 without this because different item types
endfor
for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
    echo getline(lnum)[col]
endfor

Handy functions

(see :h functions for complete list)

glob("/foo/bar")                " String, extension file wildcard (here as file existence test)"
filereadable("foo.cfg")         "  Number, TRUE if file readable"

Frequent caveats

  • Don't confuse variables and options. First are initialized with let, second with set. Options can be read/written like a variable with prefix &, like &filetype.
  • Don't confuse functions (like max, strlen), with editor commands (like let, set, call). Functions can be called directly in expression, but must be called with command call where commands are expected.
add(list,10)                    " WRONG! add is not an editor command"
list2=add(list,10)              " CORRECT"
call add(list,10)               " CORRECT"
  • Give regular expression patterns in single-quotes!
echo match("binary(blob)","b\|(",0)   " WRONG!"
echo match("binary(blob)",'b\|(',0)   " CORRECT"

Simple C/C++ IDE using plugin TagList

Thanks to plugin TagList, it is possible to turn Vim into a simple yet efficient development IDE. The basic idea is to use the TagList window as a simple file explorer. We use a session file to add all files in the project to the TagList window. For C/C++ projects, we add our common settings/mapping defined in our cpp.vim.

Here an example session file project.vim:

" Project specific settings
set tags=./tags
TlistAddFiles src/*.cpp
TlistAddFiles src/*.h
" Source our custom cpp script
source ~/.vim/cpp.vim
" Session Persistence
au VimLeave * mksession!
set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize
" Find in files
command! GREP :execute "grep -R <cword> ./src"|:cw
source Session.vim

Create the tag and cscope files:

ctags -R .
cscope -Rb

Then start the IDE session with:

gvim -S project.vim

Alternatively, one can use the filename Session.vim, and use the shorter command gvim -S.


Use the mappings A-Up / A-Down to switch the current window to the next/previous file. These mappings simply move and center the cursor in the TagList window to the previous/next file, open the file and put the cursor to its last position.

To build the project (assuming you have a valid Makefile in the project directory), just issue the command

:make

To easily navigate between the compilation errors, open the quickfix window:

" Open the window when there are compilation errors:
:cw
" Or open it always:
:cope

Finally you can run the program directly from Vim with:

:!./bin/myprogram
"To repeat the last :!{cmd}, do:
:!!

Persistent session

Using :mksession one can save the current session state for later:

" Save session in Session.vim
:mksession
" Save session in lastsession.vim
:mksession lastsession.vim

For ease add the following lines at the end of our project.vim:

set sessionoptions+=blank,buffers,curdir,folds,help,options,resize,tabpages,winpos,winsize
source ./Session.vim

Now start editing with:

gvim -S project.vim

And before quiting Vim, do:

" Overwrite! Session.vim and quit
:mksession!
:wqa

This can be done automatically (see [6]). Add to your configuration file either of these autocmd:

" Update the session file only if one already exists
au VimLeave * if v:this_session != "" | exe "mksession! " . v:this_session | endif
" Or always save the session file
au VimLeave * mksession!

Troubleshoot

  • FuzzyFinder plugin complains about:
Error detected while processing function 148..229..fuf#openTag:
line    1:
E432: Tags file not sorted: tags
Tags were generated with ctags --sort=foldcase -R .
Solution is to set option :set ignorecase

Keyboard & Mouse Shortcuts

  • ! If keys HJKLM have been remapped to MHJKL, shortcut below must be changed accordingly !
  • Mouse shortcuts requires :set mouse=a.
  • Customer shortcuts are underlined

Define new shortcuts

  • Note that not all combinations are possible (see [7] and help :keycodes)
    • S-b and S-B are the same
    • C-b and C-b (both mean 0x02)
    • A-b and A-B are different, but are represented by vim by setting the high bit (0x80), so A-b is same as 'â', and A-B is same as 'Â'
  • Note that GUI Vim some Alt key shortcuts select the menu. To disable that:
set guioptions-=m

Custom Cheatsheets

Plugin Cheatsheet

Plugin - a

:A
:AS
:AV
:AT
:AN
:IH Cih
:IHS
:IHV
:IHT
:IHN Leaderihn
Leaderis

Switch between header / source file
Split and Switch
Vertical split and Switch
New Tab and Switch
Cycles through matches
switches to file under cursor
splits and switches
vertical splits and switches
new tab and switches
cycles through matches
switches to the alternate file of file under cursor

Plugin - autoclose

{{

Insert & push closing brace down a new line

Plugin - cscope_vim

Leadercs ^Spaces
Leadercg ^Spaceg
Leadercc ^Spacec
Leaderct ^Spacet
Leaderce ^Spacee
Leadercf ^Spacef
Leaderci ^Spacei
Leadercd ^Spaced
^Space^Space s
:cs f s foo

symbol: Find all references to token, split
global: Find all global definitions, split
call: Find all calls to function, split
text: Find all instance of text, split
egrep: egrep search, split
file: open filename, split
includes: Find all files that include fname, split
called: Find functions that function calls, hsplit
Same but vsplit
Same but as command (use :scs for split)

Plugin - diffchanges

Leaderdcd
Leaderdcp

DiffChangesDiffToggle
DiffChangesPatchToggle

Plugin - MRU

:MRU
:MRU p
CR
o
t
v

Open MRU file list
Open MRU file list, only files containing p
Open file in previous window if possible
Open file in a new window
Open file in a new tab
Open file read-only (view)

Plugin - Surround

cs"'
cs'<q>
cst"
ds"
ysiw]
yssb or yss)
VmS<p id="a">
ysibspace

Change surrounding " to '
Change surrounding ' to <q>...</q>
Change surrounding tag back to "
Remove the surrounding "
Add [ ] around word (motion iw)
Add ( ) around current line (ignoring leading ws)
Add surrounding tag to selected lines
Add surrounding blank inside current () block

Plugin - taglist window (:help taglist-keys)

[[ or BS
]] or Tab
Space
- or zc
+ or zo
* or zR
=
x
CR or LMouse*2
o O
P
p
t
u
s

Previous file
Next file
Show tag prototype
Close a fold
Open a fold
Open all folds
Close all folds
Maximimze/Restore window
Jump to tag location
Jump to tag location (new window, vertical)
Jump to tag location (in previous window)
tag preview (cursor remains in taglist window)
Jump to tag (new tab)
Update tags
Change the sort order

Plugin - tComment

gcm
gcc
gCm
gCc

Toggle comments motion
Toggle comment for the current line
Comment region motion
Comment the current line

Cheatsheet

Window management

^W_ ^W| ^W=
^Wh ^Wl
^Wj ^Wk
^Wp
^Wo
^Wt

Max. h/w current window or tile
Move to left, right window
Move to down, up window
Move to previous window
Show current window only
Promote window to tab

Mouse

MouseL
gMouseR ^MouseR

Jump to tag
Return from tag

Command-line Mode (:)

^U
^R
^W

Remove auto-range (:help omap-info)

Insert register / object (:help c_CTRL-R)
Delete previous word

Insert Mode

^Space
^O

Same as Esc, but easier (see [8])
Execute one command, back to insert mode

Normal Mode

n^O
n^I
:ju[mps]
^R

Go to n older pos. in jump list
Go to n newer pos. in jump list
Print jump list
Redo

Miscellaneous

^^ or ^6 (azerty)

Edit alternate buffer (#)

Operator & motion

Operators in Vim acts

  • on the current selection (visual mode like v, V or ^v) when there is such a selection,
  • or must be followed by a motion indicating which part of the text must be modified.

Operators

c
d
y
~
g~
gu
gU
!
=
gq
g?
>
<
zf
g@

change
delete
yank into register (does not change the text)
swap case (only if 'tildeop' is set)
swap case
make lowercase
make uppercase
filter through an external program
filter through 'equalprg' or C-indenting if empty
text formatting
ROT13 encoding
shift right
shift left
define a fold
call function set with the 'operatorfunc' option

The motion is either one of the motion key (like >% for shift right until match) or an operator motion (like diB for delete inner {} block). See :help operator.

Frequently-used operator motion

iw

iW
is
ip

inner word

inner WORD
inner sentence
inner paragraph

aw

aW
as
ap

a word

a WORD
a sentence
a paragraph

i[

ib i(
i<
it
iB i{

inner [] block

inner () block
inner <> block
inner tag block
inner {} block

a[

ab a(
a<
at
aB a{

a [] block

a () block
a <> block
a tag block
a {} block

i"

i'
i`

inner "" string

inner '' string
inner `` string

a"

a'
a`

a "" string

a '' string
a `` string

Commands

" Search & replace - current line
:s/search/replace/g                               
" Search & replace - global scope
:%s/search/replace/g                              
" Set Vim option (here textwidth)
:set {option}=70                                  
" Show value of {option}
:echo &{option}                                   
:set {option}?                                    
" Search / replace in all opened buffers
:bufdo %s/pattern/substitution/ge | update
" Replace current line with register content
VP

Tips for Efficient Editing

  • Substitute current line — Use S ( or cc) to replace the current line, while keeping current indentation (instead of ddO to delete current line and open new one)
  • Quick variable renaming — Use the following mapping to search for last deleted word
  • " F3 (an improved UltraEdit F3 ;-) ) search for next occurrence of replaced word (actually register -) - handy for refactorizing code
    " Also mapped to ù (AZERTY power!)
    nnoremap <F3> /\<<C-R>-\><CR>
    nnoremap ù /\<<C-R>-\><CR>
    

    Using this mapping, one can:

    1. Rename a variable with ciw for instance, and type the new variable name (use ^R- to start from old name)
    2. Look for next occurent of the replaced variable with F3 (or ù)
    3. Repeat replacement with . (dot key)
    4. Repeat from step 2 (or use n), or N for previous occurrence.

This tip works better than using range:s/pattern, because you don't have to type the name of replaced variable, nor use the word delimiter \<...\>, and you don't have to specify a range in advance.

Tips and Tricks

Miscellaneous

  • Inserting only a single character (http://vim.wikia.com/wiki/Insert_a_single_character):
  • :nnoremap <space> :exec "normal i".nr2char(getchar())."\e"<CR>
    
  • Macro
    • qq to start recording a macro q. End macro with q again.
    • @q to replay macro, followed by . to replay it again.
  • Visual Block
    • Ctrl-v to start VISUAL BLOCK mode.
    • Shift-I to insert some text at the start of each line of selected block.
  • wrap-around
    • Set option whichwrap or ww that allows specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line.
    • In Vim, <space> and <backspace> are set to wrap-around by default.
  • Read-only viewer (with syntax highlighting):
  • $ vi -R sensitive_file
    $ view sensitive_file
    
  • Retab
  • To convert tabs in current file to current tab settings, use command :retab [9]. For instance to convert tabs into space
    :set expandtab
    :retab
    
  • View differences in vim
  • vimdiff file1.txt file2.txt
    
  • Interaction with X Clipboard
  • vim can use the X clipboard if it has been compiled with the clipboard feature (run vim --version and see if you have +clipboard in the output). In that case, yanking to the + register, or simply selecting with the mouse, will actually copy in the X clipboard, hence allowing other applications, or even other instances of vim to exchange text snippets. Also, it will ease the copy-paste of indented text, since in that case, vim will first disable autoindentation before pasting the text (see option paste). On system like Ubuntu, you need to install an instance of gvim (like package vim-gnome or vim-gtk) to have feature +clipboard turned on (i.e. installing package vim is not enough). When set mouse=a, use shift-mouse to still use the xterm copy/paste (see mouse-using).
    :set paste            " Enable paste mode, i.e. disable autoindent, mapping... "
    :set nopaste          " Disable paste mode (back to normal...) "
    
  • set incsearch, moves cursor as search pattern is typed. Ctrl-L to type letter under cursor, Ctrl-R Ctrl-W to type current word.
  • References:
  • http://vim.wikia.com/wiki/Best_Vim_Tips
  • type :help ctrl<C-D>, to get a list of all ctrl sequence. Type <C-D> in command line for auto-completion.
  • Support 256 colors in gnome-terminal: add set t_Co=256 in ~/.vimrc ([10])
  • Use :make and :grep instead of :!make or :!grep. Then use :cwin or :copen to view the results of either make or grep in a coloured list (from [11]).
  • (from [12]), The :g command is useful to apply a command to all lines matching a search.
  • " delete all lines matching pattern
    :g/pattern/d
    " --> example: delete empty lines
    :g/^$/d
    " --> example: delete lines with only whitespaces
    :g/^\s*$/d
    " delete all lines *NOT* matching pattern (:v same as :g!)
    :g!/pattern/d
    :v/pattern/d
    
  • Write the following in files ~/.vim/after/syntax/c.vim and ~/.vim/after/syntax/cpp.vim (or symlink) to highlight C/++ delimiters (see [13]):
  • syn match cDelimiter "[&\.!^,;:<>=|+%*-]"
    syn match cParenDelimiter "[][(){}]"
    hi def link cDelimiter Delimiter
    hi def link cParenDelimiter Delimiter
    
  • Replace a word with yanked text (see tip [14])
  • yiw         " Yank word under cursor "
    ...         " Move to next word "
    viwp        " Replace current word with yanked text. "
    ...
    viwp
    ...
    
  • Quickly switch between opened buffers. The commands :b and :sb accepts partial buffer name when specifying which buffer to edit:
  • :ls                    " List buffer list, say you have a file verylongfilename_spec.c and anotherverylong_code.c"
    :b spec                " Will switch to buffer verylongfilename_spec.c"
    :sb code               " Will split the window and switch to buffer anotherverylong_code.c"
    
  • Various command to interact with the shell:
  • :!{cmd} Execute {cmd} with the shell.
    :!! Repeat last ":!{cmd}".
    :[range]r[ead] !{cmd} Execute {cmd} and insert its standard output below the cursor or the specified line.
    :[range]w[rite] [++opt] !{cmd} Execute {cmd} with [range] lines as standard input.
  • Save a file you edited without the needed permissions (source [15])
  • :w !sudo tee %
    
  • Delete all trailing spaces ([16]):
  • :%s/\s\+$//                     " Remove all trailing spaces
    :%s/\s\+$                       " We can omit substitution text if blank
    

    Add this to .vimrc to have vim remove automatically trailing spaces before saving

    autocmd BufWritePre * :%s/\s\+$//e
    
  • Promote window to tab (see [17])
  • :noremap <C-W>t :tabedit <C-R>%<CR>gT<C-W>qgt
    
  • Find in files within Vim (commands :grep, :lgrep, :vimgrep, :lvimgrep)
  • Define this custom command to quickly look for current word, and displays the quicklist window:
    " We must embed :grep in :execute or otherwise vim will append /dev/null 
    " to :cw command and will complain of E488: trailing characters
    command! GREP :execute "grep -R <cword> ./src"|:cw
    
  • Use :E[xplore] for explore directory of current file (from netrw)
  • Formatting code with column shell filter. Say you have a code like the one on the left. To align this text, select the 3 lines, then !column -t. This will give:
  • int myint = 1;
    double a = 2.0;
    float verylongf = 1234.50;
    
    int     myint      =  1;
    double  a          =  2.0;
    float   verylongf  =  1234.50;
    
  • Use modeline to embed vim format settings in the document itself. This requires the following line in ~/.vimrc:
  • set modeline
    

    Now you can for instance for automatic word wrapping in a text document by adding the following line to the document (for instance as the last line or within a comment block):

    /* vim: set ai fo=tcroq tw=120: */
    

Command-line mode Tips

  • Ex special characters — These are special character that can be used in executed command line (:! ...) or when ex is expecting a filename (see also :help <cword>):
  • <cword>         replaced with word under cursor
    <CWORD>         replaced with WORD under cursor
    <cfile>         replaced with pathname under cursor
    ...
    
  • Insert register / object <C-R> — these can be used to insert some register content or text from context (see also :help c_CTRL-R):
  • <C-R>*          insert X11 clipboard content
    <C-R>+          insert clipboard content
    <C-R>=          expression register. You are prompted to enter an expression
    <C-R><C-W>      insert word under cursor
    <C-R><C-A>      insert WORD under cursor
    

    Example of expressions:

    nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR>
    

Clipboard support

  • On Linux, install gvim to get full clipboard support
    • On Terminator, use also shortcuts ^S-c and ^S-V to copy & paste.
  • On Cygwin, install gvim and a X server.
    • vim will not have clipboard support. But similar result can be obtained by using :set paste, then i, followed by S-Insert (under mintty)
    • gvim under Cygwin/X will have clipboard support.
    • There is also some plugin (e.g. [18])
  • Alternatively, install Win32 gvim (but this versions is not correctly integrated in cygwin, or requires use of wrapper)

Whitespaces

  • A nice tip about highlighting unwanted spaces
  • Use set list and set listchars to show trailing space, tags, extending spaces as another character...
    Some examples:
:set list listchars=tab:>-,trail:.,extends:>,precedes:<
" Enter the middle-dot by pressing Ctrl-k then .M
:set list listchars=tab:\|_,trail:·
" Enter the right-angle-quote by pressing Ctrl-k then >>
:set list listchars=tab:»·,trail:·
" Enter the Pilcrow mark by pressing Ctrl-k then PI
:set list listchars=tab:>-,eol" The command :dig displays other digraphs you can use.
To hide tabs even when using listchars:
:set list listchars=tab:\ \ ,trail:·,extends:>,precedes:<
This is also subject to highlighting ("NonText" is used for "eol", "extends" and "precedes" / "SpecialKey" for "nbsp", "tab" and "trail")

Advanced source highlighting

  • See file $VIMRUNTIME/syntax/c.vim for more advanced highlighting options for C files, like
    • Highlighting of space errors
    • Highlighting of curly, parens errors...

Digraphs

Digraph is an easy way to enter special character in Vim, much easier than using ^V. See :help dig for more details.

code result
^k.M ·
^k>> »
^kPI ¶ (Pilcrow mark)

Plugins

Install a plugin

  • Unzip the plugin in ~/.vim directory (or plugin, autoload...)
  • Generate the help tags with:
helptags ~/.vim/tags

SnipMate

C

main  main()
inc   #include <...>
Inc   #include "..."
Def   #ifndef ... #define ... #endif
def   #define
ifdef #ifdef ... #endif
#if   #if ... #endif
once  #ifndef HEADER_H .... # define HEADER_H ... #endif (Header Include-Guard)
if    If (...) { ... } 
el    else { ... } 
t     ... ? ... : ... (tertiary conditional)
do    do ... while ( ... )
wh    while (...) { ... }
for   for (... = 0; ...; ...) { ... }
forr  for (... = ...; ...; ...) { ... }
fun   ... function(...) { ... }
fund  ... function(...;)
td    typedef
st    struct
tds   typedef struct
tde   typedef enum
pr    printf
fpr   fprintf
.     [ ... ]
un    unsigned

CPP

readfile  snippet for reading file
map       std::map<... , ...> map...
vector    std::vector<...> v...
ns        namespace ... { ... }
cl        class { public: ... private: };

Building from Sources

See

To Do

http://www.faqs.org/docs/Linux-HOWTO/C-editing-with-VIM-HOWTO.html
http://www.ibiblio.org/pub/linux/docs/howto/translations/nl/onehtml/Vim-HOWTO-NL.html

Troubleshoot

  • Command syn match may create memory leaks which slowly impact performance. Do the following as temporary fix (from [19]):
autocmd BufWinLeave * call clearmatches()
Slow cursor move (vertical / horizontal)
  • references: [20],
  • Can be due to cursorline. Try set nocursorline. Also remove any occurence of highlight CursorLine ...
  • Can be due to cursorcolumn. Try set nocursorcolumn. Also remove any occurence of highlight CursorColumn ...
  • Can be due to slow matchparen. Add to .vimrc:
let loaded_matchparen = 1
set noshowmatch
  • Can be improved with set lazyredraw

Bugs

  • [2010-07-22] - (to bugs@vim.org) 'winfixheight' not honored when botright split is closed.
  • (2011-07-27) - infinite loop when using :bn after a :edit dir/ (breaks plugin minibufexpl.vim)