Vim: The Ubiquitous Text Editor

This article introduces the Vim usage and configure.

Overview

Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. It is included as vi with most UNIX systems and with Apple OS X.

Vim is rock stable and is continuously being developed to become even better. Among its features are:

  • persistent, multi-level undo tree
  • extensive plugin system
  • support for hundreds of programming languages and file formats
  • powerful search and replace
  • integrates with many tools
$ vim --version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Jun 16 2016 10:50:38)
Included patches: 1-1689
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by pkg-vim-maintainers@lists.alioth.debian.org
Huge version with GTK2 GUI.  Features included (+) or not (-):
+acl             +farsi           +mouse_netterm   +tag_binary
+arabic          +file_in_path    +mouse_sgr       +tag_old_static
+autocmd         +find_in_path    -mouse_sysmouse  -tag_any_white
+balloon_eval    +float           +mouse_urxvt     +tcl
+browse          +folding         +mouse_xterm     +terminfo
++builtin_terms  -footer          +multi_byte      +termresponse
+byte_offset     +fork()          +multi_lang      +textobjects
+channel         +gettext         -mzscheme        +timers
+cindent         -hangul_input    +netbeans_intg   +title
+clientserver    +iconv           +packages        +toolbar
+clipboard       +insert_expand   +path_extra      +user_commands
+cmdline_compl   +job             +perl            +vertsplit
+cmdline_hist    +jumplist        +persistent_undo +virtualedit
+cmdline_info    +keymap          +postscript      +visual
+comments        +langmap         +printer         +visualextra
+conceal         +libcall         +profile         +viminfo
+cryptv          +linebreak       -python          +vreplace
+cscope          +lispindent      +python3         +wildignore
+cursorbind      +listcmds        +quickfix        +wildmenu
+cursorshape     +localmap        +reltime         +windows
+dialog_con_gui  +lua             +rightleft       +writebackup
+diff            +menu            +ruby            +X11
+digraphs        +mksession       +scrollbind      -xfontset
+dnd             +modify_fname    +signs           +xim
-ebcdic          +mouse           +smartindent     +xsmp_interact
+emacs_tags      +mouseshape      +startuptime     +xterm_clipboard
+eval            +mouse_dec       +statusline      -xterm_save
+ex_extra        +mouse_gpm       -sun_workshop    +xpm
+extra_search    -mouse_jsbterm   +syntax          
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "$VIM/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libpng12 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -Wdate-time  -g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1      
Linking: gcc   -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector -rdynamic -Wl,-export-dynamic -Wl,-E  -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -o vim   -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig -lfreetype -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE  -lm -ltinfo -lnsl  -lselinux  -lacl -lattr -lgpm -ldl  -L/usr/lib -llua5.2 -Wl,-E  -fstack-protector-strong -L/usr/local/lib  -L/usr/lib/x86_64-linux-gnu/perl/5.22/CORE -lperl -ldl -lm -lpthread -lcrypt  -L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -lpython3.5m -lpthread -ldl -lutil -lm -L/usr/lib/x86_64-linux-gnu -ltcl8.6 -ldl -lz -lpthread -lieee -lm -lruby-2.3 -lpthread -lgmp -ldl -lcrypt -lm  

Vim Usage

Vim-Mode-Switch

Command Mode

  • 进入命令模式
Key Description
Esc 编辑模式命令行模式进入命令模式

  • 移动光标
Key Description
h 控制光标左移一个字符
j 控制光标下移一个字符
k 控制光标上移一个字符
l 控制光标右移一个字符
ctrl+b 向后(上)翻一页,同 Page Up
ctrl+f 向前(下)翻一页,同 Page Down
gg 移动光标到第一行行首,同1G
G 将光标移到最后一行行首
#G 移动光标到第#行行首
0 将光标移到当前行行首 (注意是数字零),同 Home
$ 将光标移到当前行行尾,同 End
#<Enter> 将光标向下移动#行
#<Space> 将光标在本行向右移动#个字符

  • 删除
Key Description
x 删除光标所在字符
#x 删除自光标所在字符开始的#个字符 (包括当前字符)
X 删除光标所在位置的前一个字符,相当于 Backspace
#X 删除自光标所在位置的前一个字符开始的#个字符 (不包括当前字符)
dw 删除光标所在单词
#dw 删除当前光标所在字符开始的#个单词 (包含当前单词)
d0 删除自光标所在字符至行首的所有字符 (不包括当前字符)
d$ 删除自光标所在字符至行尾的所有字符 (包括当前字符), 功能同 D
dd 删除光标所在行
#dd 删除自当前行起的#行
d1G 删除光标所在行至第一行的所有行 (包括当前行)
dG 删除光标所在行至最后一行的所有行 (包括当前行)

  • 替换
Key Description
r 替换光标所在的字符
R 替换字符序列,直到按为止
cw 替换光标所在的字符至词尾的部分
c#w 替换光标所在的字符至此单词后(包含此单词)第#个单词词尾的部分
c$ 替换自光标开始至行尾的所有字符, 功能同 C
cc 替换一整行内容

  • 复制
Key Description
yy 复制当前行
#yy 复制自当前行开始的#行
y1G 复制光标所在行至第一行的所有行
yG 复制光标所在行至最后一行的所有行
yw 复制自光标所在字符至词尾的所有字符
y0 复制自光标所在字符至行首的所有字符
y$ 复制自光标所在字符至行尾的所有字符, 同 Y
p 粘贴(put)剪贴板中的字符到光标之后
#p 粘贴(put)剪贴板中的字符#次到光标之后
P 粘贴(put)剪贴板中的字符到光标之前
#P 粘贴(put)剪贴板中的字符#次到光标之前

NOTE: 指令 ywp 必须搭配使用.

  • 撤销与重做
Key Description
u 复原前一个操作
ctrl+r 重做前一个操作
. 重复前一个的操作

Insert Mode

  • 进入编辑模式
Key Description
i 在当前光标之前插入文字
I 在当前行行首插入文字
a 在当前光标之后插入文字
A 在当前行末尾插入文字
o 在当前行之后输入新的一行
O 在当前行之前输入新的一行
r 取代光标所在字符一次
R 一直取代光标所在的字符,直到按下Esc为止

Command Line Mode

  • 进入命令行模式

使用前,请先按 Esc 键确定在命令模式下,按 :/? 三键即可进入命令行模式。

  • 列出行号
Key Description
:set nu 列出行号
:set nonu 取消行号
:set all 列出所有的选择项

  • 寻找字串
Key Description
/word 由首至尾寻找
?word 由尾至首寻找
n 继续向相同方向查询
N 继续向相反方向查询

  • 保存
Key Description
:w filename 存入指定文件 filename
:w! filename 强制将文档存入指定文件 filename
:wq 保存并退出vim
:wqa 保存所有打开文件并退出vim
:wq! 强制保存并退出vi
:wq! 强制保存所有打开文件并退出vim
:q! 强制退出编辑的文件
:qa! 强制退出打开的所有文件

  • 其他
Key Description
:! command 执行外部命令 command

Visual Mode

在命令模式下,直接按键v就可以进入默认visual模式,可以使用h/j/k/l进行文本选择,然后对于选中的文本进行:

Key Description
d 剪切操作
y 复制操作
p 粘贴操作
^ 选中当前行,光标位置到行首(或者使用键盘的HOME键)
$ 选中当前行,光标位置到行尾(或者使用键盘的END键)

Multiwindow Editing

Key Description
:e filename 创建新文件 filename
:n filename 加载文件 filename
:o filename 加载文件 filename
:r filename 将文件 filename 中的内容插入到光标所在行后
:ls 显示缓存中文件列表
ctrl+6 下一个文件
:bn 下一个文件
:bp 上一个文件
:split
:sp
在当前窗口中水平分割一个窗口
:vsplit
:vsp
在当前窗口中垂直分割一个窗口
ctrl+w+方向键 切换到前/下/上/后一个窗口
ctrl+w+h/j/k/l 切换到前/下/上/后一个窗口
ctrl+ww 依次向后切换到下一个窗格中

Vim Cheat Sheet

Vi/Vim Graphical Cheat Sheet (English):

Vi-Vim_Graphical_Cheat_Sheet

Vi/Vim Graphical Cheat Sheet (Simple Chinese):

Vi-Vim_Graphical_Cheat_Sheet_sch1

Vi/Vim Graphical Cheat Sheet Tutorials:

Vi-Vim_Graphical_Cheat_Sheet_Tutorial1_Basic_Editing

Vi-Vim_Graphical_Cheat_Sheet_Tutorial2_Operators_Repetition

Vi-Vim_Graphical_Cheat_Sheet_Tutorial3_Yank_Paste

Vi-Vim_Graphical_Cheat_Sheet_Tutorial4_Searching

Vi-Vim_Graphical_Cheat_Sheet_Tutorial5_Marks_Macros

Vi-Vim_Graphical_Cheat_Sheet_Tutorial6_Various_Motions

Vi-Vim_Graphical_Cheat_Sheet_Tutorial7_Various_Commands

A Basic Vim Cheat Sheet:

A_Basic_Vim_Cheat_Sheet

Vim Cheat Sheet for Programmers:

Vim_Cheat_Sheet_For_Programmers

Vim Cheat Sheet Morden:

Vim_Cheat_Sheet_Morden

Vim Cheat Sheet Text:

Vim_Cheat_Sheet_Text

Vim Configure

In order to enable the following vim configure, save it to ~/.vimrc:

"****************************************************************************
" Common configuration
"****************************************************************************

" 判定当前操作系统类型
if(has("win32") || has("win95") || has("win64") || has("win16"))
    let g:iswindows=1
else
    let g:iswindows=0
endif

" 最大化窗口
"au GUIEnter * simalt ~x
winpos 0 0                     "指定窗口出现的位置,坐标原点在屏幕左上角
set lines=200 columns=500      "指定窗口大小,lines为高度,columns为宽度

" 不要vim模仿vi模式,建议设置,否则会有很多不兼容的问题
set nocompatible

" show chinese characters
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8

" 打开语法高亮
syntax on

" 高亮显示匹配的括号
set showmatch

" 设定配色方案
colorscheme desert

" 突出显示当前行 (underline on current line)
set cursorline

" 打开状态栏标尺
set ruler

if has("autocmd")
    " 根据文件进行缩进
    filetype plugin indent on
    augroup vimrcEx
        au!
        autocmd FileType text setlocal textwidth=78
        autocmd BufReadPost *
                    \ if line("'\"") > 1 && line("'\"") <= line("$") |
                    \ exe "normal! g`\"" |
                    \ endif
    augroup END
else
    " always set autoindenting on
    set autoindent
endif " has("autocmd")

" 让一个tab等于4个空格
set tabstop=8

" 关闭错误信息响铃
set noerrorbells

" 关闭使用可视响铃代替呼叫
set novisualbell

" 置空错误铃声的终端代码
set vb t_vb=

" show line number
set number
set relativenumber

" 不自动换行
set nowrap

" 高亮显示结果
set hlsearch

" 在输入要搜索的文字时,vim会实时匹配
set incsearch

" 禁止在搜索到文件两端时重新搜索
set nowrapscan

" 允许退格键的使用
set backspace=indent,eol,start whichwrap+=<,>,[,]

" 允许鼠标的使用
if(g:iswindows==1)
    " 防止linux终端下无法拷贝
    if has('mouse')
        set mouse=a
    endif
    au GUIEnter * simalt ~x
endif

" show different color after 80 characters in a line
match ErrorMsg '\%>80v.\+'

" Maximize window when open gvim
if has('win32')    
	au GUIEnter * simalt ~x
else    
	au GUIEnter * call MaximizeWindow()
endif

function! MaximizeWindow()    
	silent !wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz
endfunction

" 开启插件
filetype plugin indent on

" turn syntax highlighting on, and show the file name in the terminal title bar
syn on se title

" 自动切换当前目录为当前文件所在的目录
set autochdir

" 显示状态栏 (默认值为1, 无法显示状态栏)
set laststatus=2

" 设置在状态行显示的信息
set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %l:%c%)


"****************************************************************************
" Plug-in configuration
"****************************************************************************

"=======================================
" Pathogen
"=======================================

execute pathogen#infect()

"=======================================
" Taglist
"=======================================

" automatically open the taglist window on Vim startup, or
" use command 'vim +TlistOpen' in shell.
" NOTE: don't enable this feature when using WinManager
"let Tlist_Auto_Open=1

" automatically update taglist window
let Tlist_Auto_Update=1

" 在右侧窗口中显示taglist窗口
" NOTE: don't enable this feature when using WinManager
"let Tlist_Use_Right_Window=1

" 如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Exit_OnlyWindow=1

" 将taglist与ctags关联
let Tlist_Ctags_Cmd="/usr/bin/ctags"

" 不同时显示多个文件的tag,只显示当前文件的
let Tlist_Show_One_File=1

" always use mouse
set mouse=a

" jump to a tag on a single mouse click
let Tlist_Use_SingleClick=1

" sort tags by their name
let Tlist_Sort_Type='name'

" 在vim中使用定位快捷键时会先在当前目录中查找tags文件,找不到的话,就会到父目录中找,依次类推
set tags=tags;

" create a normal mode mapping for <F8> to toggle taglist window
" NOTE: don't enable this feature when using WinManager
"nnoremap <silent> <F8> :TlistToggle<CR>

"=======================================
" Netrw settings
"=======================================

let g:netrw_browse_split = 4
let g:netrw_altv = 1

"=======================================
" WinManager config
"=======================================

" automatically open 'FileExplorer|Taglist' window when logging in gvim
" Don't enable this function. Use key F2 to open it
"au VimEnter * WMToggle

" 设置winmanager界面分割
let g:winManagerWindowLayout='FileExplorer|TagList'

" 打开/关闭winmanager的快捷键
nmap <F2> :WMToggle<CR>

" 设置winmanager的宽度,默认为25 
let g:winManagerWidth=35

"=======================================
" Cscope config
"=======================================

" 导入Linux kernel生成的cscope文件
:cs add /home/chenwx/linux/cscope.out /home/chenwx/linux

" 设定是否使用quickfix窗口来显示cscope结果
" NOTE: See help by command :help cscopequickfix
:set cscopequickfix=c-,d-,e-,f-,g-,i-,t-,s-

" 设定cscope快捷键
" e.g.: <C-_>g的用法是,先按"Ctrl+Shift+-",然后快速再按"g"
nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>i :cs find i <C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>

"=======================================
" QuickFix config
"=======================================

" automatically open QuickFix window when logging in gvim
" Don't enable this function. Use key F3/F4 to open/close it
"au VimEnter * copen 5

" 设定QuickFix快捷键, 窗口高度为5行
nmap <F3> :copen 5<CR>
nmap <F4> :cclose<CR>
nmap <F5> :col<CR>
nmap <F6> :cnew<CR>

"=======================================
" SuperTab config
"=======================================

" 0 - 不记录上次的补全方式
" 1 - 记住上次的补全方式, 直到用其他的补全命令改变它
" 2 - 记住上次的补全方式, 直到按ESC退出插入模式为止
let g:SuperTabRetainCompletionType=2

" 设置按下<Tab>后默认的补全方式为<C-X><C-O>, 默认为<C-P>
let g:SuperTabDefaultCompletionType="<C-X><C-O>"

"=======================================
" Grep config
"=======================================

nnoremap <silent> <F7> :Grep<CR>

References