[转载][译文]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        :2050行用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        :删除当前行的所有AEIO

你也可以再选择模式下使用!.选择一段文字后,按下!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>你还可以使用windowsrundll32.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:压缩空行在书签ab的所有行首加上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")

posted on 2012-06-15 10:07  kivan  阅读(70)  评论(0)    收藏  举报

导航