[转载][译文]Vim最佳实践
原文链接:http://wifeng.cn/?r=blog&a=view&id=51
英文链接:http://vim.wikia.com/wiki/Best_Vim_Tips
本打算翻译原来的8个vim文章,但逛了一圈www.vim.org,才发现真正实用的文章都在vim的官方网站,尤其是这个wiki。提高一下自己的vim使用技能,花点时间翻译一下。
翻译文字比较生硬。有时间再优化一下语句。
基本使用
<Esc> 是最常用的退出键,用于切换到正常(normal)模式,或者使用<ctrl>[,也常写作<C-[>
vimtutor : 打开VIM并编辑教程文档"vimtutor"的一个副本 - 非常棒
i : 进入编辑模式,接着打字就可以在文件中添加文字了
<Esc> : 从编辑模式中退出到正常模式,你就可以进行快速的文件跳转、使用编辑命令了。(停止选择文字)
h j k l : 移动光标 ( h: ← j: ↓ k: ↑ l: → )
A : 行尾插入
u : 撤销最后一次命令,可以连续撤销
x : 删除光标下的文字
dw : 删除光标下的单词(and put it into the default register)
dd : 删除整行(and put it into the default register)
p : 粘贴
/myname : 向后搜索单词"myname"
:wq : 保存并退出
:w filename : 保存正在编辑的文件为filename
:q! : 不保存修改强制退出
:help : 显示帮助
<Tab> : 使用tab键补全敲入的命令
仍然是基本功
复制、粘贴(用于上面提到的被删除的部分,比如dd剪切掉的一行)
v :选择模式-通过移动光标或鼠标选择
y :复制被选中的文字<Esc>:退出到普通模式^ w e $ :更快的移动,行首、单词、单词结尾、行尾模式:普通、插入和选择模式,但是还有一些其他模式<Esc>:进入普通模式在命令前加上数字来重复命令,比如;10w:让光标前进10个单词10dd:删除10行命令是区分大小写的:
c :开始替换命令
C :替换到至行尾(同c$)
ce :替换至单词的结尾
非常有用
www.vim.org :要经常逛逛
comp.editors :Vim新闻组*# g* g# : 查找光标下的单词(向后/向前)%:匹配{}[]()
matchit.vim :Vim插件,现在支持让%匹配<tr><td><script>等等<C-N><C-P>:插入模式下,文本的自动补全<C-X><C-L>:整行补全,非常有用!/<C-R><C-W>:将当前的单词出现在搜索/命令行中:set ignorecase :忽略大小写,你可能需要这个:set smartcase :如果搜索模式包含大写字符,不使用 ignorecase 选项:syntax on :在Perl,HTML,PHP等等文件中开启语法高亮:h slash<C-D>:使用Ctrl-D列出所有名称包含slash的帮助文档(ps.你也可以使用tab键补全)
轻松编辑、更新vimrc
:nmap <Leader>s :source $MYVIMRC
:nmap <Leader>v :e $MYVIMRC
(<Leader>默认是\键,所以你可以用\v和\s调用上面的命令)
选择模式下的映射
:vmap sb "zdi<b><C-R>z</b><Esc> : 将选中的文本用<b></b>标签围起来
:vmap st "zdi<?=<C-R>z ?><Esc>:将选中的文本用<?=?>标签围起来
资源管理
:Ex:浏览当前文件所在的目录
\be :显示浏览缓冲区(需要插件支持):ls :列出缓冲区:cd ..:移动到上一级目录
相当好的
guu :将当前行变成小写
gUU :将当前行变成大写~:切换光标下字符大小写
gf :跳转到光标下的文件名(超级赞)
ga :显示光标下字符的十六进制
g8 :显示光标下字符的utf-8对应16进制编码
ggg?G :使用Rot13对整个文件进行编码
xp :剪切光标下字符放到下个字符后,即交换相邻字符位置
CTRL-A,CTRL-X :递增、递减光标下的数字
CTRL-R=5*5:插入模式下,插入25=:缩进当前行或选中区域(强烈推荐)如果你想使用Ctrl-V组合键实现粘贴,你可能需要先取消Ctrl-A映射复活节菜彩蛋,请自己尝试敲下命令:help 42:help holy-grail
:help!:help map-modes (see comment below the table about :nunmap):help UserGettingBored:help spoon
:help showmatch (read the note):Ni!
书签功能及其跳转
'. : 跳到最近修改过的行首(推荐)
`. : 跳到最近修改的行的具体位置
<C-O> : 移动到上次光标移动的位置
<C-I> : 向后移动光标停留的位置
:ju(mps) : 列出最近所有的光标移动位置 {{help|jump-motions}}
:history : 列出所有最近使用的命令
简写和映射
:map <F7>:'a,'bw file " 将书签a和书签b的所有行写入到文件file中
:map <F8> :.w file<CR> "将当前行写入到文件file中:map <F9>:r file " 读取文件file插入到当前行下
:map <F10> :w<CR>:!php %<CR> "保存文件并调用php运行此文件:ab php " 列出所有php开头的缩写
:map \ "列出所有以\开头的映射
映射中使用的特殊字符
<CR> : 回车键
<Esc> : Escape键
<Leader> : 通常是 \
<Bar> : | 通道
列出寄存器
:reg :显示所有寄存器内容"1p : 从寄存器1中粘贴
从缓冲区内容中执行命令
"ayy@a : 将当前行作为一个vim命令来执行(即先复制当前行到寄存器a,然后执行寄存器a中命令)
yy@":同上
捕获shell命令输出
:r!ls :读入ls命令的结果(Windows上是dir):r !grep "^ebay" file.txt :读入grep结果:20,25!rot13 :将20至50行用rot13编码:r!date :插入日期(Windows上使用 date /T )
使用外部sort排序
使用外部sort排序:%!sort -u :排序当前文件,并去掉重复行:'v,'w!sort :排序书签v和书签w之间的内容:g/^$/;,/^$/-1!sort : sort each block (note the crucial ;)!1} sort :排序段落普通模式下连续键入!!相当于执行命令:.!将当前行替换为命令行输出!!date :替换当前行内容为日期!!which command :替换当前行为commdand命令的绝对路径信息!!tr -d AEIO :删除当前行的所有A、E、I、O
你也可以再选择模式下使用!.选择一段文字后,按下!command使用命令command来处理选择的文字。即相当于:'<,'>!command
比如在选择一段文字后,使用下面的命令:!sort :排序选中的行!grep word :匹配选择区域中匹配word的行
多文件处理
:wn :保存当前文件并开始编辑下一个:bd :从缓冲区里删除:sav php.html :将正在编辑的文件另存为php.html
:sp fred.txt :分隔一个新窗口编辑fred.txt
:e!:返回到编辑之前状态:w /some/path/%:r :将文件保存到另一个目录,使用当前的文件名:e # : 编辑另一个文件。(在编辑两个文件时方便来回跳转):args :显示参数列表,当前文件以方括号表示:n :跳转到参数列表中的下一个文件:prev :跳转到参数列表中的前一个文件:rew :编辑参数列表中的第一个文件:ls :显示缓冲区列表:bn :下一个缓冲区:bp :前一个缓冲区:brew :到缓冲区的第一个文件:tabe :打开一个新标签页(Ctrl-PgUp,Ctrl-PgDown跳转到上一个/下一个):tabm n :移动当前标签到第n位置(0=最左边)
记录
qq :记录操作保存到寄存器q中你的命令操作
q :退出记录@q:执行刚才寄存器q中记录的操作@@:再重复一次# 编辑寄存器/记录"qp
<将寄存器q中的内容粘贴到这个地方>
"add :删除当前行并保存到寄存器a中@a:执行寄存器a中的内容,即刚才删除的一行:%normal @q# 将寄存器q中的内容作为命令作用于整个文件#或者针对选中的文本进行命令操作:normal @q
vimrc 点睛
:set incsearch :在敲入搜索词时即跳转到搜索到的单词(有点儿讨厌但是个相当好的功能):set wildignore=*.o,*.obj,*.bak,*.exe :文件路径补全时忽略这些文件:syntax on :开始语法高亮(对于一些文件可能需要额外的插件)
Windows下快速启动应用程序
下面是windows平台上启动程序的一些选项这里举得例子,根据文件的扩展名调用对应的程序打开文件。It also restores the paste buffer to its original value:" 这个命令用来执行一个文件,比如对于一个html文件,那么将是
" start c:\absolute\filename.html
nnoremap <silent><C-F6>:let old_reg=@"<CR>:let @"=substitute(expand("%:p"),"/","\\","g")<CR>:silent!!cmd /cstart <C-R><C-R>"<CR><CR>:let @"=old_reg<CR>你还可以使用windows的rundll32.exe来实现其他的一些选项:" vmap <silent> <C-F5> :<C-U>let old_reg=@"<CR>gvy:silent!!start rundll32.exe url.dll,FileProtocolHandler<C-R><C-R>"<CR><CR>:let @"=old_reg<CR>另外,你可以直接这样调用IE浏览器打开当前文件和光标下的文件名:nmap <Leader>f :update<CR>:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p<CR>:nmap <Leader>i :update<CR>:!start c:\progra~1\intern~1\iexplore.exe <cWORD><CR>
Vim中的FTP操作
cmap <Leader>r :Nread ftp://209.51.134.122/public_html/index.html
cmap <Leader>w :Nwrite ftp://209.51.134.122/public_html/index.html
gvim ftp://209.51.134.122/public_html/index.html:在你的.vimrc配置文件中设置使用ascii文件传输
let g:netrw_ftpmode="ascii"
向寄存器添加内容
# 先复制5行到寄存器a中,然后再向下移动10行,复制5行添加到寄存器a中"a5yy
10j
"A5yy
[I :显示匹配光标下单词的所有行<cword>表示光标下的单词
快速缩进文本
:'a,'b>># 选择模式下缩进:vnoremap <<gv
:vnoremap >>gv
搜索
/^fred.*joe.*bill : 行首以fred开头,后面含有joe和bill
/^[A-J]:以A-J之前的字母开头/^[A-J][a-z]\+\s : A-J的字母开头,后面至少一个小写字母,然后是空格或是制表符/fred\_.\{-}joe : fred开头,然后任意字符,再后面到joe (可跨行匹配)/fred\_s\{-}joe : fred开头,然后任意空白,(可以跨行)再后joe
/fred\|joe : fred 或 joe
查找替换
:%s/fred/joe/igc :一般的替换命令:%s/\r//g : 删除DOS下的换行(即经常看到的^M):'a,'bg/fred/s/dick/joe/gc :先匹配行然后替换(非常有用!):s/\(.*\):\(.*\)/\2 : \1/:将用冒号:分隔的文本交换位置# 非贪婪匹配 \{-}:%s/^.\{-}pdf/new.pdf/:至第一个pdf
:s/fred/<c-r>a/g :将fred替换为寄存器a中的文本:%s/^\(.*\)\n\1/\1$/:删除重复行:help /\{ :多次匹配,具体请查看帮助# 多重命令#下面的命令先匹配所有的gif图片地址,然后删除不匹配的行,再将gif替换为jpg:%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d |%s/gif/jpg/:%s/suck\|buck/loopy/gc :或,可以自己试验一下。|往往作为管道,所以需要加个\
:s/__date__/\=strftime("%c")/:替换时间将十六进制的'01'字符替换为^'01'是十六进制的FIX protocol delimiter(FIX协议定界符?),你可以把光标移动一个字符上按ga查看其对应的十六进制数:%s/\%x01/^/g
全局命令
:g/one\|two/:列出所有包含"one"或"two"的行:g/^\s*$/d :删除所有空行:g/green/d :删除所有包含"green"的行:v/green/d :删除所有不包含"green"的行:g/one/,/two/d :删除包括匹配行的之前行:v/./.,/./-1join:压缩空行在书签a到b的所有行首加上Error,保存到文件:'a,'b g/^Error/.w >> errors.txt
删除包含"green"但是不包含"red"或"pink"的行,命令:g/^/匹配所有行,将当前行放到变量 x 中,如果x匹配(大小写敏感)"green"而且不匹配"red"和"pink",则删除行,将# 替换为 ? 则是大小写不敏感的:g/^/let x=getline('.')|if x=~#'green' && x!~#'red' && x!~#'pink' | d | endif
剪贴板寄存器 *
:redir @*:重定向命令到剪贴板:redir END:结束消息重定向"*yy : 复制到剪贴板
"*p :插入剪贴板的内容
排版文本
gq<CR>
gqap :排版当前段落
多文件操作命令
:argdo %s/foo/bar/:bufdo %s/foo/bar/:windo %s/foo/bar/:tabdo %s/foo/bar/
命令行窍门
gvim -h
ls | gvim -:编辑管道输出!# vg.ksh (shell script) [不懂,汗..]# 先grep当前目录下包含 $1 的所有文件,使用gvim打开,然后执行 /$1 ,即跳转到$1
gvim.exe -c "/$1" $(grep -isl "$1"*)&
使用浏览器打开文件
#添加到你的 .vimrc 中::!firefox %<CR>:使用firefox打开当前文件#如果你使用的是windows,需要把firefox所在路径加到环境变量中
Vim技巧
在正则表达式中,需要使用反斜杠 \ 对+(匹配一个或多个)进行转意./fred\+/:匹配fred/freddy但不匹配free
\v (很神奇)可以减少转义符/codes\(\n\|\s\)*where:正常写法/\vcodes(\n|\s)*where:神奇吧?可以省去两处转义符
更多技巧
将文本放到命令行或搜索行(相当实用)
CTRL-R CTRL-W :将光标下的单词放到命令行或搜索栏
CTRL-R CTRL-A :将光标下的单词(包括标点符号)放到命令行或搜索栏
CTRL-R -:寄存器-下的内容
CTRL-R [0-9a-z]:指定的寄存器内容
CTRL-R %:当前的文件名(同理,#也可以,打开的另一个文件)
操作寄存器
map <F11>"qyy:let @q=@q."zzz"
选项
:verbose set history :显示历史操作,比如写入文件并通过一个外部程序执行文件的细节
map <F9>:w<CR>:!php %<CR>
插入回车 (TODO replace with \r)
:%s/nubian/<C-V><C-M>&/g : that's what you type
:%s/nubian/<C-Q><C-M>&/g : for Win32
:%s/nubian/^M&/g : ^M是一个字符,表示换行
在命令行相关技巧:
在命令行拷贝粘贴上次的命令<C-R>:将上次的搜索词放到命令行<C-R>/
多行搜索: _ 表示可以跨行
/<!--\_p\{-}--> : 搜索多行html注释
/fred\_s*joe/i :包括空行的任意空白/bugs\_.*bunny :文件中任意地方出现bugs后面跟着bunny
:h \_ :打开帮助
更多自动补全
<C-X><C-F> : 补全当前目录的文件名
打开帮助
:h visual<C-D><Tab>:或得所有包含visual的帮助主题列表:按 tab 键补全:h ctrl<C-D>:列出所有与ctrl键相关的帮助:h :r :打开:ex 命令:h CTRL-R :正常模式:h \r :正则中 \r 表示什么:h i_CTRL-R :编辑模式下CTRL-R的帮助:h c_CTRL-R :命令行下的CTRL-R帮助:h v_CTRL-V :选择模式:h 'ai : 配置选项 'autoindent' 的帮助
为内容增加行号
试试下面的命令:
:%! nl -ba
:%!cat -n
显示当前编辑的文件有多少行,按ctrl-g(或者先按g然后再按ctrl-g查看更多信息)
删除连续相同的行
:%s/^\(.*\)\n\(\1\n\)*/\1\r/
改变显示状态
一般可以使用:
:map <F12>:set number!<CR>
但这样似乎更好:
map <F12>:set number!<Bar>set number?<CR>
类似的,可以增加下面快捷键:
map <F11>:set hls!<Bar>set hls?<CR>
map <F10>:set paste!<Bar>set paste?<CR>
map <F9>:set wrap!<Bar>set wrap?<CR>
取消windows下快捷键
如果你想去掉windows下默认的键盘映射,可以在_vimrc文件中增加下面一行:
noremap <C-kPlus><C-A>
这样,你就可以使用Ctrl-A来递增光标下的数字了。
超长行文件上下移动光标
当编辑的文本,某行非常长时,试用j k键会跑到下面一行,而不是在当前行的下一行。可以增加下面映射:
noremap <C-J> gj
noremap <C-K> gk
或是直接:
noremap <Up> gk
noremap <Down> gj
这样,直接把上下键映射为屏幕文字上下移动。
替换文件名
将文件中FILE替换为文件名,可以用下面命令:
:%s/FILE/\=expand("%:t")
浙公网安备 33010602011771号