vim命令速查
2016年05月13日

/joe/e 把光标定位在匹配单词最后一个字母处
/joe/e+1 把光标定位在匹配单词最后一个字母的下一个字母处
/joe/s-2把光标定位在匹配单词第一个字母往前数两个字母的位置
/^joe.*fred.*bill/标准的正则表达式
/^[A-J]\+/查找以一个或多个 A-J 中的字母开头的行
/begin\_.*end查找在 begin 和 end 两个单词之间尽可能多的行
/fred\_s*joe/i查找在 fred 和 joe 两个单词之间任意多的空格,包括新行
/fred\|joe查找 fred 或 joe
/\([^0-9]\|^\)%.*%搜索非数字开头或者整行
/.*fred\&.*joe查找同时包含 fred 和 joe 的行,不分前后顺序
/\<fred\>/i查找 fred, 而不是 alfred 或者 frederick,也就是全字匹配
/\<\d\d\d\d\>查找4个数字的全字匹配
/\D\d\d\d\d\D查找4个数字的全字匹配
/\<\d\{4}\>同上,查找4个数字的全字匹配
/^\n\{3}查找 3 行空行
/\c\v([^aeiou]&\a){4}搜索不要查找什么,连续4次
/\(fred\).*\(joe\).*\2.*\1在查找中使用正则表达式存储
/^\([^,]*,\)\{8}重复正则表达式
:vmap // y/<C-R>”<CR>可视模式下的查找
:vmap <silent> // y/<C-R>=escape(@”, ‘\\/.*$^~[]‘)<CR><CR> 查找被高亮显示的文本
/<!–\_p\{-}–>查找多行。_ 表示包括新行
/fred\_s*joe/i查找在 fred 和 joe 两个单词之间任意多的空格,包括新行
/bugs\(\_.\)*bunnybugs 后任意位置含有 bunny 单词的多个行
:h \_帮助
:nmap gx yiw/^\(sub\<bar>function\)\s\+<C-R>”<CR>查找光标下子程序/函数的声明
:bufdo /searchstr在多个文件中查找
:argdo /searchstr在多个文件中查找

如何不使用反斜线查找 URL
?http://www.vim.org/向后搜索

替换
:%s/fred/joe/igc普通替换命令
:%s/\r//g删除 DOS 回车符 ^M

你的文本文件是否乱七八糟的排成一行?使用如下命令
:%s/\r/\r/g转换 DOS 回车符 ^M 为真正的回车符
:%s= *$==删除行尾空格
:%s= \+$==同上,珊瑚行尾空格
:%s#\s*\r\?$##删除行尾空格和 DOS 回车符
:%s#\s*\r*$##删除行尾空格和 DOS 回车符

删除空行
:%s/^\n\{3}//删除三行空行
:%s/^\n\+/\r/压缩多行空行为一行

如果你只想明白一件事情
:’a,’bg/fred/s/dick/joe/igc非常有用

复制列
:%s= [^ ]\+$=&&=复制最后一列
:%s= \f\+$=&&=同上
:%s= \S\+$=&&同上
记忆,或叫引用
:s/\(.*\):\(.*\)/\2 : \1/反转以 : 分隔的字段
:%s/^\(.*\)\n\1/\1$/删除重复的行

非贪婪匹配 {-}
:%s/^.\{-}pdf/new.pdf/只删除到第一个 pdf

使用可选的原子 ?
:%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc lowercase with optional leading characters

匹配尽可能多的行
:%s/<!–\_.\{-}–>//删除尽可能多的注释
:help /\{-}非贪婪匹配的帮助

使用寄存器替换
:s/fred/<c-r>a/g用"a"寄存器里的内容替换"fred"
:s/fred/\=@a/g更好的方法,不用显示寄存器内容

写在一行里的复杂命令
:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/

ORing
:%s/suck\|buck/loopy/gc ORing (must break pipe)

:s/__date__/\=strftime(“%c”)/调用 Vim 函数,插入日期
:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:处理列,替换所有在第三列中的 str1

:%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:交换第一列和最后一列 (共4列)

:redir @*|sil exec ‘g#<\(input\|select\|textarea\|/\=form\)\>#p’|redir END把所有的form元素(就是html里面的form啦)放到register里
:nmap ,z :redir @*<Bar>sil exec
‘g@<\(input\<Bar>select\<Bar>textarea\<Bar>/\=form\)\>@p’<Bar>redir END<CR>

:g/loc\|function/s/\d/\=submatch(0)+6/increment numbers by 6 on certain lines only
:%s#txtdev\zs\d#\=submatch(0)+1#g更好的方法
:h /\zs
:%s/\(gg\)\@<=\d\+/\=submatch(0)+6/increment only numbers gg\d\d by 6 (another way)
:h zero-width

:%s/”\([^.]\+\).*\zsxx/\1/查找需替换的文本,保存,然后使用 \zs 命令简单替换
:nmap <leader>z :%s#\<<c-r>=expand(“<cword>”)<cr>\># Pull word under cursor into LHS of a substitute
:vmap <leader>z :<C-U>%s/\<<c-r>*\>/ Pull Visually Highlighted text into LHS of a substitute

all following performing similar task, substitute within substitution
Multiple single character substitution in a portion of line only

:%s,\(all/.*\)\@<=/,_,g replace all / with _ AFTER “all/”

:s#all/\zs.*#\=substitute(submatch(0), ‘/’, ‘_’, ‘g’)#同上

:s#all/#&^M#|s#/#_#g|-j!Substitute by splitting line, then re-joining

:%s/.*/\=’cp ‘.submatch(0).’ all/’.substitute(submatch(0),’/’,'_’,'g’)/Substitute inside substitute

全局命令显示(参见 tip 227)
:g/fred.*joe.*dick/显示所有包含fred,joe 和 dick 的行
:g/\<fred\>/显示所有全字匹配 fred 的行
:g/<pattern>/z#.5显示上下文
:g/<pattern>/z#.5|echo “==========”显示得很漂亮
:g/^\s*$/d删除所有的空行
:g!/^dd/d删除所有行首不是 dd 的行
:v/^dd/d同上
:g/fred/,/joe/d并不基于行(非常强大)
:g/{/ ,/}/- s/\n\+/\r/g删除在 {…} 只见的空行
:v/./.,/./-1join压缩空行
:g/^$/,/./-j压缩空行
:g/<input\|<form/p ORing
:g/^/pu _把文件中空行增加一倍
:g/^/m0翻转文件
:g/fred/t$把匹配 fred 的行拷贝到文件最后
:g/stage/t’a把匹配 stage 的行做标记a
:%norm jdd隔一行删除一行

incrementing numbers (type as 5 characters)
:.,$g/^\d/exe “norm! \<c-a>”增加每行行首的数字
:’a,’bg/\d\+/norm! ^A增加标记 a 到标记 b 只见每行行首的数字

保存全局命令的结果 (注意必须使用添加模式)
:g/fred/y A添加所有为fred所匹配的行到register a
:’a,’b g/^Error/ . w >> errors.txt
:g/./yank|put|-1s/’/”/g|s/.*/Print ‘&’/复制每一行,然后在复制出来的每一行两侧加上一个 print ‘复制出来的内容’
:g/^MARK$/r tmp.ex | -d 用文件中的内容替换字符串,-d 表示删除“标记”

全局命令和替换命令联姻 (强大的编辑能力)
:’a,’bg/fred/s/joe/susan/gic可以使用反向引用来匹配
:g/fred/,/joe/s/fred/joe/gic non-line based (ultra)
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC先找fred,然后找joe

基础

* # g* g#寻找光标处的狭义单词() (前向/后向)
%括号配对寻找 {}[]()
.重复最后一次修改

matchit.vim 使得 % 能够配对标记<tr><td><script> <?php等等
<C-N><C-P>插入模式下的单词自动完成
<C-X><C-L>行自动完成(超级有用)
/<C-R><C-W>把狭义单词 写到 搜索命令行
/<C-R><C-A>把广义单词 写到 搜索命令行
:set ignorecase搜索时忽略大小写
:syntax on在 Perl,HTML,PHP 等中进行语法着色
:h regexp<C-D>按下 control-D 键即可得到包含有 regexp 的帮助主题的列表
(使用TAB可以实现帮助的自动补齐)

:nmap ,s :source $VIM/_vimrc使更新 _vimrc 更容易
nmap 是绑定一个在normal模式下的快捷键

:nmap ,v :e $VIM/_vimrc在normal模式下,先后按下 ,s 两个键执行_vimrc,而 ,v 则是编辑_vimrc

visual 模式 (例子是:轻松添加其他的 HTML Tags)
:vmap sb “zdi<b><C-R>z</b><ESC>在visual模式下选中的文字前后分别加上
:vmap st “zdi<?= <C-R>z ?><ESC>在visual模式下选中的文字前后分别加上

文件浏览
:Exp(lore)开启目录浏览器,注意首字母E是大写的
:Sex(plore)在一个分割的窗口中开启目录浏览器
:ls显示当前buffer的情况
:cd ..进入父目录
:args显示目前打开的文件
:lcd %:p:h更改到当前文件所在的目录

:autocmd BufEnter * lcd %:p:h 自动更改到当前文件所在的目录 (放到 _vimrc)

缓冲区(buffer)浏览器 (第三方的一个最流行的脚本)
需要下载 bufexplorer.vim
\be 在缓冲区浏览器中打开缓冲区列表
\bs以分割窗口的形式打开缓冲区浏览器

guu行小写
gUU行大写
Vu行小写
VU行大写
g~~行翻转
vEU字大写(狭义字)
vE~字翻转(狭义字)
ggguG把整个文章全部小写

Titlise Visually Selected Text (map for .vimrc)
vmap ,c :s/\<\(.\)\(\k*\)\>/\u\1\L\2/g<CR>

:%s/[.!?]\_s\+\a/\U&\E/g大写所有句子的第一个字母

gf取当前光标处的广义字作为文件名,然后试图打开它!
ga显示光标处字符的ascii,hex,oct,…
ggVGg?用rot13编码整个文件
ggg?G用rot13编码整个文件(对大文件更快一些)
:8 | normal VGg?从第8行开始,用rot13编码后面的文本
:normal 10GVGg?从第8行开始,用rot13编码后面的文本

【关于rot13——谁让英文是偶数个字母啊】
ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码的算法相同,仅仅交换字母的这两个部分,即:[a…m] –> [n…z] 和 [n…z]–> [a…m] 。 ROT13 用简易的手段使得信件不能直接被识别和阅读,也不会被搜索匹配程序用通常的方法直接找到。经常用于 USENET 中发表一些攻击性或令人不快的言论或有简单保密需要的文章。由于 ROT13 是自逆算法,所以,解码和编码是同一个过程。

<C-A>,<C-X>增加,减少 光标处的狭义字所表示的数字
Win32的用户可能需要重新定义一下Ctrl-A
<C-R>=5*5插入25 (一个迷你计算器)

Makes all other tips superfluous
:h 42 also http://www.google.com/search?q=42
:h holy-grail
:h !

标记和移动
'.跳到最后修改的那一行 (超级有用)

`. 不仅跳到最后修改的那一行,还要定位到修改点

g;循环跳转修改点(从最老的修改点开始) (vim6.3中新增)
g,反向循环跳转修改点 (vim6.3中新增)

:changes
:h changelist help for above
<C-O>依次沿着你的跳转记录向回跳 (从最近的一次开始)
<C-I>依次沿着你的跳转记录向前跳
:ju(mps)列出你跳转的足迹
:help jump-motions
:history列出历史命令记录
:his c命令行命令历史
:his s搜索命令历史
q/搜索命令历史的窗口
q:命令行命令历史的窗口
:<C-F>历史命令记录的窗口
缩写和键盘映射
:map <f7> :’a,’bw! c:/aaa/x
map是映射一个normal模式下的键
这里是把F7键映射成把标记a到标记b中间的内容另存为一个文件/aaa/x标记(mark)的方法:把光标移动到需要标记的地方,输入m,然后输入标记名,例如a
引用标记的方法:’a ,即:单引号加标记名

:map <f8> :r c:/aaa/x把F8键映射成在当前位置插入文件/aaa/x的内容
:map <f11> :.w! c:/aaa/xr<CR>
.(点号)表示当前行
所以F11就是把当前行存为/aaa/xr最后的表示一个回车

:map <f12> :r c:/aaa/xr<CR>
:ab php列出php表示的缩写
定义一个缩写使用::iab hm hmisty
一个有趣的现象是,它列出的会是php和它的前子串开头的缩写,例如,有这么几个缩写:h => hmisty1 , hm => hmisty2 , hmi => hmisty3, m => hmisty4
那么使用 :ab hm会显示这么几个缩写:hm 和 h,而不是你想象中的 hm 和 hmi

:map ,列出以逗号开始的键盘映射

允许 F10 的映射用法 (win32)
set wak=no参见 :h winaltkeys

在键盘映射中常用的表示
<CR>回车
<ESC>ESC
<LEADER>转义符号
<BAR>管道符号
<BACKSPACE>退格符号

:nmap <leader>c :hi Normal guibg=#<c-r>=expand(“<cword>”)<cr><cr>显示光标下数值的 RGB 颜色 例如 #445588

:let @m=":’a,’bs/"
:let @s=":%!sort -u"
Using a register as a map (preload registers in .vimrc)

列出寄存器(Registers)
:reg显示所有寄存器的内容
:reg a显示 a 寄存器的内容
"1p…. retrieve numeric registers one by one
:let @y='yy@"' pre-loading registers (put in .vimrc)

有用的窍门
"ayy@a把当前行作为一个Vim命令来执行
yy@"同上,不过是用匿名寄存器
u@.只执行键入的命令

从其他程序获取输出 (需要外部程序)
:r!ls.exe读取ls的输出到当前位置
!!date读取date的输出 (但是会替换当前行的内容)
其实你输入了!!后,vim就自动转换到 :.! 等待你继续输入

使用外部程序sort进行排序(sort是Unix标准命令,ls,date也是)
:%!sort -u使用sort程序排序整个文件(用结果重写文件)
%表示整个文件的所有行
!sort表示执行外部命令sort
-u是sort的参数,man sort看看,这个参数的意义是合并相同的行
u就是unique,如果两行内容相同,则结果中只保留一行的说

:’a,’b!sort -u对mark a 到mark b中间的内容进行排序
!1} sort -u排序当前段落 (只能在normal模式下使用!!)
!表示使用filter,1}表示filter的对象是从当前行开始向后数一段
段落指到空行处结束,不包括空行,其实你一旦输入 !1},vim就自动计算当前段落应该到那一行(eg.+5),然后生成
:.,.+5! 等待之后输入sort -u,回车,完成操作
.表示当前行,.+5当然就是当前行向后数5行

多文档操作 (基础)
:bn跳转到下一个buffer
:bp跳转到上一个buffer
:wn存盘当前文件并跳转到下一个
:wp存盘当前文件并跳转到上一个
:bd把这个文件从buffer列表中做掉
:bun卸掉buffer (关闭这个buffer的窗口但是不把它从列表中做掉)
:badd file.c把文件file.c添加到buffer列表
:b 3跳到第3个buffer
:b main跳到一个名字中包含main的buffer,例如main.c
:sav php.html把当前文件存为php.html并打开php.html
:sav! %<.bak换一个后缀保存
:sav! %:r.cfm Save Current file to alternative extension

:e!返回到修改之前的文件(修改之后没有存盘)
:w c:/aaa/%把文件存到一个地儿
:e #编辑标记为#的buffer(这个buffer必须含有一个可编辑的文件)

用ls命令就能看到哪一个buffer
有%a表示当前正在编辑的buffer
u 表示不能编辑或者已经被做掉的buffer

:rew回到第一个可编辑的文件
:brew回到第一个buffer
:sp fred.txt在一个水平分割的窗口中打开文件fred.txt
:vs fred.txt可以实现垂直分割
:sball,:sb把当前所有含有可编辑文件的buffer显示到一个分割窗口中
:scrollbind in each split window
:map <F5> :ls<CR>:e #在normal模式下按F5键,则会显示所有含有一个
可编辑文件的buffer,然后提示你输入buffer的序号,
输入后回车,则编辑这个buffer

:set hidden
允许不保存buffer而切换buffer (w/o=without)

在分割窗口中快速切换
:map <C-J> <C-W>j<C-W>_这是一个键盘绑定,把Ctrl-J定义成切换到下一个窗口并最大化

:map <C-K> <C-W>k<C-W>_这是一个键盘绑定,把Ctrl-K定义成切换到上一个窗口并最大化

命令录制 (最佳技巧)
qq录制到q
开始输入一系列复杂的指令
q按q停止录制
@q执行q中存储的指令
@@重复执行
5@@重复执行5遍

编辑寄存器/录制
"qp显示寄存器 q 的内容 (普通模式)
<ctrl-R>q显示寄存器 q 的内容 (插入模式)

你现在可以看到记录内容,随便编辑
"qddput changed contacts back into q
@q执行记录/寄存器 q

在可视块中运行记录

  1. 定义记录/寄存器
    qq:s/ to/ from/g^Mq
  2. 定义可视块
    V}
  3. 键入 : 将显示下面信息
    :’<,’>
  4. 完成如下操作
    :’<,’>norm @q
    可视模式是最新也通常是最好的编辑模式
    可视模式基础
    v进入可视模式
    V整行的可视模式
    <C-V>进入可视块模式
    gv重新选取最新的可视区域
    o浏览可视区域
    "*y复制可视区域到剪贴板
    V% visualise what you match
    V}J连接可视块

0<c-v>10j2ld删除连续10行中每行的头2个字符

如何用可视块拷贝几列
可视块(并非通常的 v 命令)
<C-V>然后通过移动命令选择列 (win32 )
然后执行 c,d,y,r等命令

_vimrc基础
:set incsearch实时匹配你输入的内容
:set wildignore=*.o,*.obj,*.bak,*.exetab键的自动完成现在会忽略这些
:set shiftwidth=3自动缩进设为4个字符
一个tab位通常是8个字符,所以我们还要设定 :set tabstop=4,这样,所有的缩进都是4字符了
:set vb t_vb=".沉默方式(不要叫beep!)
:set browsedir=buffer设置 GUI 版本文件打开时,使用当前路径

加载 IE 浏览器
:nmap ,f :update<CR>:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p<CR>
:nmap ,i :update<CR>: !start c:\progra~1\intern~1\iexplore.exe <cWORD><CR>
nmap是做一个normal模式下的键盘绑定
这里绑定了一个逗号命令 ,f
:update是写这个文件,与:w不同,它只有当文件被修改了的时候才写
:silent别让弹出窗口报告执行结果
!…后面就是执行windows命令了

用 VIM 通过 ftp 编辑文件
:cmap ,r :Nread ftp://209.51.134.122/public_html/index.html
:cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html
gvim ftp://209.51.134.122/public_html/index.html
cmap是命令(command)模式绑定

附加到一个register (用大写的register名字)
"a5yy复制5行到a中
10j下移10行
"A5yy再添加5行到a中

[I显示光标处的狭义字可以匹配的行(高级指令)
可以全文查找与光标处的狭义字相匹配的字,这在查找函数原型和实现,或者变量使用的时候很有用

常规缩进
:'a,'b>> 把mark a到mark b之间的内容缩进两次

在visual模式下缩进 (无限可重复)
:vnoremap < <gv
:vnoremap 重定义了visual模式下 < 符号的含义
把它定义成 <gv 即先<向外缩进,然后gv重新选择上一次选择了的区域
这样在visual模式下就可以实现连续按<而连续缩进了

:vnoremap > >gv同里,内缩

块缩进
>i{
>a{
also
>% and <%
重定向到剪贴板和从剪贴板粘贴
:redir @*重定向命令的输出结果(最下方命令行上的结果)
:redir END结束重定向
:redir >> out.txt重定向到一个文件

操作剪贴板
"*yy复制到剪贴板中
"*p从剪贴板中粘贴

拷贝到剪贴板 (ex 模式)
:'a,'by*把标记a到标记b见的内容拷贝到剪贴板
:%y*把整个文件拷贝到剪贴板
:nmap <leader>p :let @* = substitute(@*,'[^[:print:]]’,’‘,’g')<cr>”*p从剪贴板上过滤非可打印字符,当从一些 GUI 程序粘贴时会有用处

重新格式化文本
gq}格式化一个段落
ggVGgq重新格式化整个文件
Vgq格式化当前行
:s/.\{,69\};\s*\|.\{,69\}\s\+/&\r/g在70列的时候换行

对多个文档实施命令
:argdo %s/foo/bar/e对所有:args列表中的文档执行命令
:bufdo %s/foo/bar/e
:windo %s/foo/bar/e
:argdo exe '%!sort'|w!使用外部命令
:bufdo /foo/

命令行上的技巧
gvim -h启动帮助
ls | gvim –编辑一个数据流
cat xx | gvim – -c "v/^\d\d\|^[3-9]/d " filter a stream
gvim -o file1 file2以分割窗口打开两个文件
gvim.exe -c "/main" joe.c指出打开之后执行的命令;跳转到main
vim -c "%s/ABC/DEF/ge | update" file1.c对一个文件执行多个命令
vim -c “argdo %s/ABC/DEF/ge | update” *.c 对一组文件执行多个命令
vim -c "argdo /begin/+1,/end/-1g/^/d | update" *.c 从一组文件中删除文本块

vim -s "convert.vim" file.c自动编辑文件 (编辑命令序列Ex commands已经包含在convert.vim中了)

gvim -u NONE -U NONE -N不要加载.vimrc和任何plugins (启动一个干净的VIM)

gvim -c 'normal ggdG"*p' c:/aaa/xp 读取剪贴板内容 (放到脚本或批处理文件中)

gvim -c 's/^/\=@*/|hardcopy!|q!'把剪贴板内容打印到默认打印机

gvim -d file1 file2vimdiff (比较不同)
dp把光标处的不同放到另一个文件
do在光标处从另一个文件取得不同

Vim陷阱
In regular expressions you must backslash + (match 1 or more)
In regular expressions you must backslash | (or)
In regular expressions you must backslash ( (group)
In regular expressions you must backslash { (count)
在vim的正则表达式中, + | ( { 前都必须加转义符
/fred\+/匹配fred或freddy但是不匹配free
/\(fred\)\{2,3}/ note what you have to break
\v ,或叫做very magic (通常都是这么叫)可以取消转义符
/codes\(\n\|\s\)*where普通的正则表达式
/\vcodes(\n|\s)*wherevery magic

把东西送到命令行/搜索行 (SUPER)
<C-R><C-W>送一个狭义词
<C-R><C-A>送一个广义词
<C-R>-送一个小型寄存器 (插入模式下也有效)
<C-R>[0-9a-z]送一个命名寄存器 (插入模式下也有效)
<C-R>%送文件名过去 (#也行) (插入模式下也有效)

操作寄存器
:let @a=@_清空寄存器a
:let @a=""同上
:let @*=@a拷贝寄存器 a 的内容到剪贴板
map <f11> "qyy:let @q=@q."zzz"

关于帮助的帮助
:h quickrefVIM 快速参考手册 (ultra)
:h tipsVim自己的tips
:h visual<C-D><tab>得到一个关于visual关键字的帮助列表,然后用tab键去选择
:h ctrl<C-D>显示所有关于Ctrl的帮助
:h CTRL-R普通模式命令
:h /\r\r在正则表达式中是什么意思呢?
:h \\zs double up backslash to find \zs in help
:h i_CTRL-Rinsert模式下的Ctrl-R
:h c_CTRL-R命令行(command-line)模式下的Ctrl-R
:h v_CTRL-Vvisual模式下的Ctrl-V
:h tutorVIM 指南
<C-[>, <C-T>在帮助历史中,向前/后移动
gvim -h关于 VIM 命令的帮助

选项设置在哪里?
:scriptnames列出所有加载的 plugins, _vimrcs
:verbose set history?显示history的值并指出设置文件的位置
:function列出所有函数
:func SearchCompl列出指定的函数

制作你自己的VIM帮助
:helptags /vim/vim63/doc重建 /doc 中所有的 *.txt 帮助文件
:help add-local-help

用外部程序来运行程序 (例如 php)
map <f9> :w<CR>:!c:/php/php.exe %<CR>
map <f2> :w<CR>:!perl -c %<CR>

在另一个buffer中,捕捉当前脚本的输出
:new | r!perl #新建一个buffer,从另一个buffer中读入结果
:new! x.out | r!perl #同上,并指定一个新文件名

插入DOS换行符
:%s/nubian/<C-V><C-M>&/g that’s what you type
:%s/nubian/<C-Q><C-M>&/g对于Win32应该这样
dn_...@yahoo.ca
:%s/nubian/^M&/g你看到的^M是一个字符c-v,c-m --> ^M
:%s/nubian/\r&/g更好的办法

自动删除行尾 Dos回车符和空格
autocmd BufRead * silent! %s/[\r \t]\+$//
autocmd BufEnter *.php :%s/[ \t\r]\+$//e

对指定文件或文件类型执行某个动作
autocmd VimEnter c:/intranet/note011.txt normal! ggVGg?
autocmd FileType *.pl exec(‘set fileformats=unix’)

i<c-r>:把最后一个命令贴到当前位置

i<c-r>/把最后一个搜索指令贴到当前位置
译释:i是进入insert模式,
Ctrl-r是开启插入模式下register的引用
:和/分别引用了两个register的内容

更多的完成功能
<C-X><C-F>插入当前目录下的一个文件名到当前位置
在insert模式下使用,然后用 Ctrl-P/Ctrl-N 翻页

替换一个visual区域
选择一个区域,然后输入 :s/Emacs/Vim/ 等等,vim会自动进入:模式
:’<,’>s/Emacs/Vim/g前面的’<,’>是vim自动添加的
gv重新选择前一个可视区域 (ULTRA)

在文件中插入行号
:g/^/exec “s/^/”.strpart(line(".")." ", 0, 4)
:%s/^/\=strpart(line(".")." ", 0, 5)
:%s/^/\=line('.'). ' '

用VIM的方式来编号行
:set number显示行号
:map <F12> :set number!<CR> Show linenumbers flip-flop
:%s/^/\=strpart(line('.')." ",0,&ts)

从任意行开始编号(需要perl)
:'a,'b!perl -pne 'BEGIN{$a=223} substr($_,2,0)=$a++'

qqmnYPn^Aqin recording q repeat with @q:.,$g/^\d/exe “normal! <c-a>”` 递增已存在数字到文件末

高级递增,参见:http://vim.sourceforge.net/tip_view.php?tip_id=150

高级递增 真的很有用
把下面几句放到 _vimrc #vimrc脚本用 " 做行注释符

let g:I=0
function! INC(increment)
    let g:I =g:I + a:increment
    return g:I
endfunction
" 例如从mark a 到mark b 递增,从223开始,步长为5
:let I=223
:'a,'bs/^/\=INC(5)/
" create a map for INC
cab viminc :let I=223 \| 'a,'bs/$/\=INC(5)/

在当前插入模式下编辑/移动 (真得很有用)
<C-U>删除全部
<C-W>删除最后一个单词
<HOME><END>移动到行首/行尾
<C-LEFTARROW><C-RIGHTARROW>向前/后移动一个单词
<C-X><C-E>,<C-X><C-Y> scroll while staying put in insert

加密(小心使用,不要忘了密码)
:Xvim会提示你输入密码
:h :X

模式行 (使文件只读等),必须在前/后 5行内
// vim:noai:ts=2:sw=4:readonly:
vim:ft=html:使用 HTML 语法高亮
:h modeline

建立你自己的菜单项
amenu Modeline.Insert\ a\ VIM\ modeline <Esc><Esc>ggOvim:ff=unix ts=4
ss=4<CR>vim60:fdm=marker<esc>gg

一个保存当前光标下的狭义字到一个文件的函数

function! SaveWord()
    normal yiw
    exe ':!echo '.@0.' >> word.txt'
endfunction
map ,p :call SaveWord()

删除重复行的函数

function! Del()
    if getline(".") == getline(line(".") – 1)
        norm dd
    endif
endfunction

:g/^/ call Del()使用该函数的一个例子

双字节编码 (non alpha-numerics)
:digraphs显示编码表
:h dig帮助
i<C-K>e’输入 é
i<C-V>233输入 � (Unix)
i<C-Q>233输入 é (Win32)
ga查看字符的hex值

删除非 ascii 字符
:%s/[<C-V>128-<C-V>255]//gi where you have to type the Control-V
:%s/[€-�]//gi Should see a black square & a dotted y
:%s/[<C-V>128-<C-V>255<C-V>01-<C-V>31]//gi All pesky non-asciis
:exec "norm /[\x00-\x1f\x80-\xff]/"同上
yl/<C-R>"Pull a non-ascii character onto search bar

文件名自动完成 (例如 main_c.c)
:e main_<tab>tab 键完成
gf打开光标处广义字命名的文件 (normal模式)
main_<C-X><C-F>文件名自动完成(insert模式)

Vim复杂使用

:%s/\<\(on\|off\)\>/\=strpart("offon", 3 * ("off" == submatch(0)), 3)/g交换两个单词

:vnoremap `."gvP"P 交换两个单词

把text文件转换成html文件(oh,ft)
:runtime! syntax/2html.vim转换 txt 成 html
:h 2html

VIM 有一个内部自带的 grep 命令
:grep some_keyword *.c得到一个包含some_keyword的c文件名列表
:cn去下一个出现的位置
:set syntax=perl强制无扩展名的文件的语法着色方式
:set syntax off取消语法着色 (很有用)

:colorscheme blue改变色彩主题 (在~vim/vim??/colors中的任何文件)

通过使用模式行强迫使用 HTML 语法高亮
vim:ft=html:
:set noma (non modifiable)防止修改
:set ro (Read Only)只读保护

对话 (打开一堆文件)
gvim file1.c file2.c lib/lib.h lib/lib2.h在"对话"中加载这些文件
:mksession生成一个Session文件 (默认是Session.vim)
:q
gvim -S Session.vim重新加载所有文件

标记(tags) (跳转到子程序/函数)
taglist.vim很流行的插件
:Tlist显示标记 (函数列表)
<C-]>跳转到光标处的函数

columnise a csv file for display only as may crop wide columns
:let width = 20
:let fill=’ ‘ | while strlen(fill) < width | let fill=fill.fill | endwhile
:%s/\([^;]*\);\=/\=strpart(submatch(1).fill, 0, width)/ge
:%s/\s\+$//ge

Highlight a particular csv column (put in .vimrc)

function! CSVH(x)
    execute 'match Keyword /^\([^,]*,\)\{‘.a:x.’}\zs[^,]*/'
    execute 'normal ^'.a:x.'f,'
endfunction
command! -nargs=1 Csv :call CSVH(<args>)

call with
:Csv 5 highlight fith column

折叠:隐藏某些片断,是查看更容易
zf}使用动作命令折叠一个段落
v}zf使用可视模式折叠一个段落
zf’a折叠到一个标记上
zo打开折叠
zc重新关闭折叠

显示"不可见字符"
:set list
:h listchars

:norm qqy$jq如何在不进入插入模式的情况下粘贴"普通模式的命令"

处理文件名
:h filename-modifiers帮助
:w %写入当前文件
:w %:r.cfm改变文件扩展名为 .cfm
:!echo %:p显示完整路径和文件名
:!echo %:p:h只显示完整路径
<C-R>%插入文件名 (插入模式)
"%p插入文件名 (普通模式)
/<C-R>%在文本中查找文件名

删除,但不破坏 buffer 内容
"_d你一直想要的东西
"_dw例如:删除一个单词 (使用黑洞???)

送完整的路径名到剪贴板,用于邮件附件等
nnoremap <F2> :let @*=expand("%:p")<cr> :unix
nnoremap <F2> :let @*=substitute(expand("%:p"), "/", "\\", "g")<cr> :win32

不用离开 Vim 就能修改文件名的简单脚本

:r! ls *.c
:%s/\(.*\).c/mv & \1.bla
:w !sh
:q!

g<C-G>在一个文本里计算单词数

你自己设置高亮显示的例子
:syn match DoubleSpace " "
:hi def DoubleSpace guibg=#e0e0e0

根据文件类型映射快捷键
:autocmd bufenter *.tex map <F1> :!latex %<CR>
:autocmd bufenter *.tex map <F2> :!xdvi -hush %<.dvi&<CR>

读取 MS-Word 文档,需要 antiword
:autocmd BufReadPre *.doc set ro
:autocmd BufReadPre *.doc set hlsearch!
:autocmd BufReadPost *.doc %!antiword "%"

Just Another Vim Hacker JAVH
vim -c ":%s%s*%Cyrnfr)fcbafbe[Oenz(Zbbyranne%|:%s)[[()])-)Ig|norm Vg?"
在启动vim的时候执行了一个命令,先写入了 Just Another Vim Hacker 的rot13编码,然后再解码