查看文章
 
[原创]Best of Vim Tips注释(1)
2008年08月12日 星期二 20:51

英文版见:http://www.rayninfo.co.uk/vimtips.html

中文翻译见:http://groups.google.com/group/Vim-cn/msg/f72fba0645955101

前面部分的注释见:http://blog.csdn.net/easwy (这是easwy在csdn的blog,分成了很多篇日志,因为最近csdn被和谐了,暂时无法给出具体的地址.)
08.08.20 CSDN终于恢复,给个具体点的地址: http://blog.csdn.net/easwy/category/234641.aspx

--------------------------------------------------------------------------------------------------------------------------------

因为easwy只注释了前面一部分,后面就没继续注释了,我觉得这篇tips写的非常好,但是解释太少,如果不注释一下,对VIM的新手来说,无异于天书,所以我决定在学习的同时,把我理解的都写下来,利人利己

我目前学习VIM也就两周不到的时间,可以说还是处于菜鸟阶段,所以解释的可能不太准确,如果有什么错误,希望留言指出

这篇文章是在vim里面写的,因为操作系统是Windows,所以我用的是GVIM,版本7.1

文件的扩展名是.tips,我写了一个语法高亮的文件,因为还仔细研究,只是用了一些简单的语法高亮,同时也没有按比较好的风格来写,但是如果你是一个初学VIM的人,我还是建议你按照下面的几个步骤操作,把这些内容保存成文件,然后用VIM查看(当然,如果你喜欢在网页上看,也是可以的,但是在VIM里面看,可以增加对VIM的熟悉程度)

步骤一:

将下面的内容复制,然后在$VIM\vim71\syntax\里面新建一个tips.vim的文件,粘贴进去,然后保存

下面是tips.vim的内容

syntax clear
syntax sync minlines=10 maxlines=500

syn match Help "^:h.*$" contained
syn region CommentHead matchgroup=ignore start=/^>/ end=/$/ oneline
syn region Comment start=/^>注释/ matchgroup=ignore end=/^<$/ contains=ALL keepend
syn region Note matchgroup=ignore start=/!!/ end=/!!/ contained oneline
syn region String matchgroup=ignore start=/\~/ end=/\~/ contained oneline
syn region String matchgroup=ignore start=*^\~\~* end=*$* oneline

hi Help guibg=#eeeeee
hi CommentHead guifg=red gui=bold
hi def link Note CommentHead

文件的内容我就不解释了,因为我自己对这种语法文件也没仔细研究,解释起来怕误导了大家,如果想看详细解释,可以用:h syntax:h 44查看,建议先看一遍44,再看一遍syntax,这样就能有个大概的了解了.

这第一个步骤干了什么?
VIM可以根据一些特定的语法进行着色,一些普遍的文件类型,都有高手帮我们写好了语法着色的文件,安装VIM的时候,这些文件都装好了,比如c语言的.c文件,可以在$VIM\vim71\syntax里面的c.vim看到语法文件的内容(我暂时是没能力看懂).
注意:这里的$VIM指VIM的安装路径,比如我是安装在C:\Program Files,而vim71\这个根据不同的版本可能不同.

虽然复杂的语法文件看不懂,但是看了上面两篇帮助,鼓捣了1个多小时后,我还是弄出了我的第一个语法文件,专门针对我的这篇文章,这样在vim里面看起来漂亮一点.将上面的文件保存为tips.vim,这个文件名是有讲究的,不要随便改,下一个步骤里面会有解释

步骤二: 在vimrc文件中添加以下内容

au BufRead,BufNewFile *.tips setfiletype tips

nmap
<F4> 0y$:<c-r>=GotoHelp(@0)<cr><cr>
function! GotoHelp(
cmd)
        let c=a:cmd
        
if
match(c,'^:h .\+$') != -1
                return
c
        else
                return "echo '当前行不是查询帮助的命令'"
        endif

endfunction

vimrc是什么我觉得就不需要我解释了,基本上任何VIM的教程都会讲,可以这么理解,这个文件是我们配置一个完全个性化的VIM的工具,VIM启动的时候,会执行这里的每一条指令,通过在这个文件中加入我们自己的习惯用法,就能慢慢发现,原来VIM可以这么好用.

稍微解释一下这些代码,

第一句大概的意思就是在打开*.tips文件的时候,设置文件类型为tips,为啥要这么设置呢,因为VIM会根据我们设置的文件类型,到syntax目录中找对应的语法文件,如果找到,就会帮我们进行代码着色.现在知道步骤一中为啥说文件名是有讲究的了吧?其实只要和文件类型一致就行.

第二句是定义了一个映射,有了这个映射之后,在普通模式下按<F4>键,就可以直接将光标所在行的帮助命令运行,我下面的注释中,基本每条注释前面都有几个相关的帮助命令(灰底黑字的内容),原本是需要手动输入(或者是手动复制在粘贴)到命令行,然后执行,才能看到帮助,感觉麻烦了点,后来先是想用tags文件,使得可以用Ctrl+]来定位到帮助,可惜不知道什么原因,定位到的帮助居然中文是乱码,估计是哪个地方需要转换一下编码才行.后来没办法,改成定义一个映射,经过1个小时的反复修改,才终于弄出来了,前面的0y$是先定位光标到行首,再复制到行尾,然后在命令行里面调用GotoHelp函数,这个函数的作用是判断刚才复制的内容是不是帮助命令,如果是的话,才能执行,不然会提示错误.其中的@0表示的是0寄存器的内容.最近一次复制的内容,都是默认放在0寄存器里面的(是数字0,不是字母)

下面的几行就是GotoHelp函数的定义了,用到了match函数,可以用:h match()查看

步骤三:下面的内容保存为任意路径下的Best.tips文件,用VIM打开,在VIM里面慢慢看,慢慢试

因为文件内容太长,百度空间一篇日志放不下,只能分开放,最好是把后面的所有内容(最底下有全部后续章节的链接)也都复制到Best.tips文件里面

前面的部分在easwy的blog中已经有解释,我就不重复劳动了

下面是Best.tips的内容

" new items marked *N* , corrected items marked *C*
" searching
/joe/e                       : cursor set to End of match
/joe/e+1                     : cursor set to End of match plus 1
/joe/s-2                     : cursor set to Start of match minus 2
/joe/+3                     : find joe move cursor 3 lines down
/^joe.*fred.*bill/           : find joe AND fred AND Bill (Joe at start of line)
/^[A-J]/                     : search for lines beginning with one or more A-J
/begin\_.*end               : search over possible multiple lines
/fred\_s*joe/               : any whitespace including newline *C*
/fred\|joe                   : Search for FRED OR JOE
/.*fred\&.*joe               : Search for FRED AND JOE in any ORDER!
/\<fred\>/                   : search for fred but not alfred or frederick *C*
/\<\d\d\d\d\>               : Search for exactly 4 digit numbers
/\D\d\d\d\d\D               : Search for exactly 4 digit numbers
/\<\d\{4}\>                 : same thing
/\([^0-9]\|^\)%.*%           : Search for absence of a digit or beginning of line
" finding empty lines
/^\n\{3}                     : find 3 empty lines
/^str.*\nstr                 : find 2 successive lines starting with str
/\(^str.*\n\)\{2}           : find 2 successive lines starting with str
" using rexexp memory in a search
/\(fred\).*\(joe\).*\2.*\1
" Repeating the Regexp (rather than what the Regexp finds)
/^\([^,]*,\)\{8}
" visual searching
:vmap // y/<C-R>"<CR>       : search for visually highlighted text
:vmap <silent> //     y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR> : with spec chars
" \zs and \ze regex delimiters :h /\zs
/<\zs[^>]*\ze>               : search for tag contents, ignoring chevrons
" zero-width :h /\@=
/<\@<=[^>]*>\@=             : search for tag contents, ignoring chevrons
/<\@<=\_[^>]*>\@=           : search for tags across possible multiple lines
" searching over multiple lines \_ means including newline
/<!--\_p\{-}-->                   : search for multiple line comments
/fred\_s*joe/                     : any whitespace including newline *C*
/bugs\(\_.\)*bunny                 : bugs followed by bunny anywhere in file
:h \_                             : help
" search for declaration of subroutine/function under cursor
:nmap gx yiw/^\(sub\<bar>function\)\s\+<C-R>"<CR>
" multiple file search
:bufdo /searchstr/                 : use :rewind to recommence search
>注释
bufdo 在所有缓冲区执行后面的命令,可以用|连接多个命令
:h bufdo
<
" multiple file search better but cheating
:bufdo %s/searchstr/&/gic   : say n and then a to stop
>注释
:h :s
这是用替换代替查找的方法,其中的~&~表示前面匹配的内容,也就是说,实际上是用自己替换自己,相当于没替换.那为什么要"多此一举"呢?因为后面的~gic~,这是三个选项,g表示替换所有找到的匹配,i表示忽略大小写,c表示每次替换都要经过确认.如果只是用查找,那不能用这三个选项.这样执行的话,就会把所有匹配的内容走一遍(按n再按a可以停止).
另外还有一个好处,替换是有计数的,结束的时候,会显示一共替换了多少次,其实也就是找到了多少个匹配.
<
" How to search for a URL without backslashing
?
http://www.vim.org/        : (first) search BACKWARDS!!! clever huh!
>注释
:h ?
用反向查找,避免输入太多反斜杆
如果用反斜杆来写,那要写成~/http:\/\/www.vim.org\/~看起来乱了点
<
" Specify what you are NOT searching for (vowels)
/\c\v([^aeiou]&\a){4}       : search for 4 consecutive consonants
>注释
:h /\c
:h /\v
:h /\&
:h /\a
:h /\{
查找4个连续的非元音字母,\c表示忽略大小写,\v是使后面的表达式中,除了字母数字下划线外,都认为是特殊符号,使得如+,&,|等不需要在前面加\转义.
括号中规定了两个必须同时满足的条件,~[^aeiou]~表示非元音字母的字符,~\a~表示所有字母,合起来就是非元音的字母,最后的~{4}~表示匹配四次
<
/\%>20l\%<30lgoat           : Search for goat between lines 20 and 30 *N*
>注释
:h \%l
在第20到30行中匹配后面的内容
<
/^.\{-}home.\{-}\zshome/e   : match only the 2nd occurence in a line of "home" *N*
>注释
:h /\{-
:h /\zs
匹配第二次出现的home,~\{-}~表示非贪婪匹配,~\zs~表示从这个位置开始匹配,这是个"零长度匹配"
<
:%s/home.\{-}\zshome/alone   : Substitute only the occurrence of home in any line *N*
>注释
:h :s
和上面一样,不过这次是替换,把第二个home替换为alone
<
" find str but not on lines containing tongue
^\(.*tongue.*\)\@!.*nose.*$
>注释
:h /\@!
~\@!~这个又是一个"零长度匹配",表示匹配不包含前面内容地方
整个句子的意思,是匹配所有不包括tongue,但是包括nose的行
<
\v^((tongue)@!.)*nose((tongue)@!.)*$
.*nose.*\&^\%(\%(tongue\)\@!.\)*$
>注释
:h /\%(\)
这两句都是和上面那句同样的功能,第三句有个特殊的用法~\%(~~\)~,这两个是配对的,和~\(\)~差不多,但是有%的不作为一个子表达式(也就是说,不能在后面用\1~\9来表示),速度也会快一点
<
:v/tongue/s/nose/&/gic
>注释
:h :v
:h :g
~:v~相当于~:g!~,就是对所有!!不满足!!后面的条件的行,执行命令
在本句中,条件是包含有tongue,命令是替换nose为nose(也就是不替换).
<
--------------------------------------------------------------------------------------------------------------------------------

下面是其他部分的链接

[原创]Best of Vim Tips注释(2)
[原创]Best of Vim Tips注释(3)

--------------------------------------------------------------------------------------------------------------------------------

本文是永夜的极光原创,首发于http://hi.baidu.com/newkedison/blog/item/bb8d6edda746e0325982ddd3.html

可随意转载,但不能用于商业用途


类别:Vim||添加到搜藏 |分享到i贴吧|浏览(1293)|评论 (0)
 
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu