vim实用技术(1)
下面首先对Vim做一下最基本的介绍,并给出一些参考信息,以方便对Vim不熟悉的读者也能够理解并自己查阅进一步信息。
与大部分其它编辑器不同,进入Vim后,缺省状态下键入的字符并不会插入到所编辑的文件之中。Vim的模式(mode,可以简单地理解为"状态")概念非常重要。需要知道,Vim有以下几个模式:
- 正常(normal)模式,缺省的编辑模式;下面如果不加特殊说明,提到的命令都直接在正常模式下输入;任何其它模式中都可以通过键盘上的Esc键回到正常模式。
- 命令(command)模式,用于执行较长、较复杂的命令;在正常模式下输入":"(一般命令)、"/"(正向搜索)或"?"(反向搜索)即可进入该模式;命令模式下的命令要输入回车键(Enter)才算完成。
- 插入(insert)模式,输入文本时使用;在正常模式下键入"i"(insert)或"a"(append)即可进入插入模式(也有另外一些命令,如"c",也可以进入插入模式,但这些命令有其它的作用)。
- 可视(visual)模式,用于选定文本块;可以在正常模式下输入"v"(小写)来按字符选定,输入"V"(大写)来按行选定,或输入"Ctrl-V"来按方块选定。
- 选择(select)模式,与普通的Windows编辑器较为接近的选择文本块的方式;在以可视模式和选择模式之一选定文本块之后,可以使用"Ctrl-G"切换到另一模式--该模式很少在Linux上使用,本文中就不再介绍了。
Vim带有完整的帮助文档。在当前的Vim 6.4的标准发布中,有一百多章、近六十万英文词的帮助文件,进入Vim后输入":help"(命令模式中输入的命令要敲回车键才结束输入,下面不再说明 这一点)即可访问。本文在介绍特性时,对文档中已经说明得很详细的内容只会提纲挈领地加以简短说明和提供应用范例,并提供访问相应的Vim文档的命令。
一般的发布版中还常常带有一个简单的30分钟的Vim教程,新手在操作系统的命令行上输入"vimtutor" 命令即可开始学习。除上面的简单说明外,本文并不介绍最基本的Vim命令,Vim的新手应该先通过教程熟悉一下Vim,再继续往下阅读。
建议所有的Vim用户经常访问Vim的主站点[1]。上面除了基本的发布、安装、下载等信息外,最有用的内容是用户可以上传自己写的Vim脚本 (script)和撰写自己认为有用的提示(tip),供其他Vim用户使用。在写这一段的时候,Vim站点上已有一千三百多个脚本,提示数刚好超过了一 千。对于序号为nn的脚本,直接访问的URL是http://www.vim.org/scripts/script.php?script_id= nn;对于序号为nn的提示,直接访问的URL是http://www.vim.org/tips/tip.php?tip_id=nn。
不另加说明的话,本文讨论的内容适用于Vim版本6(即从6.0到6.4)。建议认真的Vim用户升级到Vim 6.4,最好是自己编译升级所有的补丁包。相关信息网站上都有,此处不再赘述。
Vim支持世界上的主要语言,当然也包括中文。如果你用Vim编辑中文,而中文不能正确显示,那有两种可能性:一是使用的Vim不完整,不含多字节语言支持(multi_byte特性);二是某个配置出了问题。
说到多语言支持,最基本的概念有两个:一是文件的语言编码,而是环境的内部编码。在较老的操作系统中,不管Linux还是Windows,这两个编 码都是一样的,也就意味着,一次只能处理一种编码的文件:要么只能处理西文编码(Latin1,即ISO-8859-1 [5]),要么只能处理中文编码(GB2312 [2])。而在新的操作系统中,这两者可以是不一样的。在Linux上,常见的情况是环境的内部编码使用UTF-8 [6],而UTF-8可以同任何一种语言编码作无损转换,这就保证了系统的多语言处理能力。Vim这方面秉承了Unix/Linux的传统,在内部编码使 UTF-8的时候,可以同时处理不同意语言编码的文件。以下列出了和语言编码的相关的设置:
- 环境变量LANG(使用的语言);
- 环境变量LC_CTYPE(使用的内部编码);
- Vim选项encoding(Vim的内部编码);
- Vim选项termencoding(Vim在与屏幕/键盘交互时使用的编码);
- Vim选项fileencoding(Vim当前编辑的文件在存储时的编码);
- Vim选项fileencodings(Vim打开文件时的尝试使用的编码);
- Vim选项ambiwidth(对"不明宽度"字符的处理方式;Vim 6.1.455后引入)。
如果你的环境只需要处理简体中文的话,那么,最简单的方式就是所有的设定全部使用简体中文。只需要:设定LANG=zh_CN.GB2312,不设 定LC_CTYPE(默认跟LANG一样),不设定与编码相关的Vim选项(默认由LANG和LC_CTYPE决定),也无需设定Vim选项 ambiwidth。也就是说,我们把语言设定为中国(CN)使用的中文(zh),编码为GB2312(注意:Vim内部并不识别国标GB18030 [3],所以此处只能设GB2312;参看下面关于UTF-8的讨论)。
不过,如果按照目前Linux下的惯例,内部编码一律使用UTF-8的话,会有一些额外的好处,其中之一就是在这种情况下Vim支持同时编辑多种不 同编码的文件,如简体中文和繁体中文(见下图);另外,此时Vim也可以通过编码转换支持GBK [4]和GB18030了。这样,众多关于语言编码的Vim选项就有了用武之地了。下面进一步说明一下这些选项和推荐设定(如果适用的话):
![](http://3.bp.blogspot.com/_EGsewCBJBq4/SiTbGqFeD3I/AAAAAAAAASs/k0AWrryOkTc/s400/1.png)
- encoding=utf-8:不管文件的编码如何,不管如何显示和输入,Vim内部使用的编码是UTF-8;这是国际化支持的基础。
- termencoding:取决于实际的终端或X Window的设定。举例来说,如果选择语言简体中文登录到X Window,或者正在使用CXTERM [10]的话,那么该选项应被设为GB2312;如果使用缺省的语言(LANG=en_US.UTF-8)登录到X Window,或者使用PuTTY [11]远程访问Linux机器、并且设定里的字符编码(配置中Window-Translation)设为UTF-8的话,该选项就应该设为utf- 8。从Windows下使用PuTTY远程连接Linux的请特别注意,测试表明,仅在使用UTF-8的情况下,PuTTY才能可靠地支持中文的显示和输 入(显示字体必须设成中文字体)。
- fileencoding:文件载入时,该选项被置为Vim认定的文件编码,因此,存储时文件的编码不会改变。此处和下面 fileencodings可使用的编码为libiconv支持的所有几百种编码(如果编译时包含了iconv特性的话),与中文相关的有gb2312、 gbk、gb18030、hz-gb-2312、iso-2022-cn、big5、cp936、cp950等。如果创建新文件,你又不希望使用UTF- 8作为文件编码时,那么,你可能需要手工设定该选项,如":set fileencoding=gb2312"。需要注意的一点是,使用"set"来设定该选项的话会改变以后新建文件的缺省编码,而使用 "setlocal"的话则只影响当前文件(参考":help setlocal")。 fileencodings=ucs-bom,utf-8,chinese:Vim会首先判断文件的开头是否是一个Unicode [7]的BOM(byte order mark)字符[8],是的话则把文件的其余内容解释成相应的Unicode序列;否的话再试图把文件内容解释成UTF-8的序列;再失败的话,则把文件 解释为简体中文(chinese是一个跨平台的简体中文字符集的别名,Linux下相当于gb2312和euc-cn;此处也可以根据需要以 gb2312、gbk或gb18030等编码替代)。需要注意的是,该顺序不能颠倒,并且在后面再添加其它编码如big5、latin1也是没有意义的, 因为Vim不能识别8比特编码中的错误,因此这些编码后列的编码永远不会被用到。
- ambiwidth=double:把所有的"不明宽度"字符[9]--指的是在Unicode字符集中某些同时在东西方语言中使 用的字符,如省略号、破折号、书名号和全角引号,在西方文字中通常字符宽度等同于普通ASCII字符,而在东方文字中通常字符宽度等同于两倍的普通 ASCII字符,因而其宽度"不明"--的宽度置为双倍字符宽度(中文字符宽度)。此数值只在encoding设为utf-8或某一Unicode编码时 才有效。需要额外注意的是,如果你通过终端使用Vim的话,需要令终端也将这些字符显示为双宽度。比如,XTERM [12]的情况下应该使用选项"-cjk",即使用命令"uxterm -cjk"来启动使用双宽度显示这些字符的Unicode X终端;使用PuTTY远程连接的话则应在配置的Window-Translation中选中"Treat CJK ambiguous characters as wide"(参见下图)。
|
在使用内部编码UTF-8的情况下,如需编辑fileencodings之外(其不能自动识别)的文件,则可以使用以下命令:":e ++enc=编码 文件名"。详情可参考":help ++enc"。
不管是文本界面还是图形界面的Vim,都支持鼠标。不过,在文本界面中,鼠标支持缺省没有被激活;这就意味着,在终端上使用鼠标,所有的功能仍和没 有使用Vim时相同,并不受Vim影响。要激活文本界面中的鼠标支持也很容易,只需要执行一句 ":set mouse=a"即可。
启用了鼠标支持之后,Vim主要支持的鼠标操作有:
- 单击移动光标到点击的位置;
- 在帮助的关键字上双击显示该关键字相关的帮助信息;
- 在普通文本上双击选中点击位置的单词;
- 拖动鼠标选中文本;
- 使用鼠标滚轮滚动当前缓冲区中的文本;
- 多窗口编辑时可以拖动窗口分栏的位置。
进一步的信息可参看":help 'mouse'"、":help mouse-using"和":help scroll-mouse-wheel"。
特别需要值得一提的是,在远程访问Linux系统时也是可以使用鼠标的。如果使用X Window系统,自然不必说;而使用SSH远程连接时,大部分Linux下的终端客户程序,如XTERM、GNOME-Terminal [13]、较新版本的Konsole [14],以及Windows下的PuTTY,支持鼠标的使用:你只需简单地启动Vim、执行一句":set mouse=a"就可以了(当然,也可以把上面的语句去掉起始的冒号放到.vimrc文件中)。
对于编写代码,缩进是最基本的概念之一。至于缩进是使用空格还是制表符(Tab),或者缩进是否正好使用一个制表符来表示,很多程序员,特别是 Windows开发出身的程序员,很容易混淆。幸好,Vim对于这些概念有非常完整的支持,足以应付各种复杂的情况。以下是相关的主要Vim选项:
- shiftwidth(缩进的空格数);
- tabstop(制表符的宽度);
- expandtab(是否在缩进和遇到Tab键时使用空格替代;使用noexpandtab取消设置);
- softtabstop(软制表符宽度,设置为非零数值后使用Tab键和Backspace时光标移动的格数等于该数值,但实际插入的字符仍受tabstop和expandtab控制);
- autoindent(自动缩进,即每行的缩进值与上一行相等;使用noautoindent取消设置);
- cindent(使用C语言的缩进方式,根据特殊字符如"{"、"}"、":"和语句是否结束等信息自动调整缩进;在编辑C/C++等类型文件时会自动设定;使用nocindent取消设置);
- cinoptions(C语言缩进的具体方式,请参考":help cinoptions-values");
- paste(粘贴模式,会取消所有上述选项的影响来保证后面的操作--通常是从剪贴板粘贴代码--保持原有代码的风格;使用nopaste取消设置)。
下面给出一些常用的组合:
- shiftwidth=4 tabstop=4:很多Windows出身的程序员会习惯这样的设置,让缩进等于制表符宽度。
- shiftwidth=4 tabstop=8:很多Unix程序员的设置,仍使用较常用的4格缩进,但制表符宽度为标准的8。
- cinoptions=>4,n-2,{2,^-2,:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 shiftwidth=2 tabstop=8:标准的GNU编码风格的设置,对Vim缺省的C缩进风格作了很多微调,比如,if语句下的"{"、"}"要在"if"后缩进两格,但 函数定义部分"{"、"}"仍和函数名一行对齐。开源软件经常使用该种缩进风格。
在编辑代码时一个很有用的命令是调整代码缩进,可以很方便地增加(或减少)若干级缩进,并自动根据选项设定使用正确的空格或制表符。只需要使用 "V"选中你要调整的代码行,然后键入"<"(或">")即可增加(或减少)一级缩进;在键入"<"(或">")之前键入数字则 可以指定增加(或减少)的缩进级数。
我们要讨论的最后一个相关的命令是":retab"。在设定了expandtab选项时,该选项会把所有的制表符转换成空格。在没有设定 expandtab选项时,使用":retab!"可把空白字符转换成制表符(可能误转换,慎用),使用":retab n"可以把tabstop重置为n,并转换含制表符的连续空白字符为适当的制表符和空格的组合以保证含制表符的行看起来没有任何变化。详细信息请参看": help :retab"。
没人愿意每次都手工输入一大堆的Tab和缩进设定。可是,放在.vimrc文件中似乎也不是个好主意:如果我编辑的代码不止一种风格呢?--考虑一 下,如果你参加开源软件项目,你能保证你参加的所有项目,还有你公司里的软件项目,代码风格都一样吗?--Vim是我用过的第一个支持在文件中记录代码风 格设定的编辑器。这个特性在Vim中叫做模式行,实际上,它所做的是在打开文件时根据文件中的Vim指令设定相关的Vim选项。下面就是一个嵌在C源代码 中的模式行:
|
这种方式非常简单,功能也非常强大。另外请注意,出于安全的考虑,模式行中的选项只影响当前文件(":help modeline-local"),也不能做任何设置选项以外的工作。