编程相关
欢呼吧,本节是文档的最后一节了(总结不算)。读者能读到这里不易啊,笔者写到这里也
是一把鼻涕一把泪啊。However, nevertheless, but, yet, the last one is the best
one, and the hardest one. (跩什么鸟文啊(- -#))。
该小节主要会介绍上面所没有涉及到的主题,包括常用命令、配置以及插件。如果没有这
些功能的话, Vim也只不过比其他的编辑器强大一点点而已,而不会成为神器级别的编辑
器。
不过这三个点都是大部头, 每个都可以单独写一个文档了,不信可以看看Vim的帮助有多
少。因此这里着重将三部分中和C语言代码编写相关的内容提取出来介绍。 如果没有这些
功能,使用Vim编写代码可以用喝白开水来形容,平淡无奇,Vim也不会被称为是为程序员
打造的编辑器。这样既可以介绍这三部分功能,让读者熟悉,又可以很好的和应用结合起
来,立即投入实践。下面就先用Vim打开一个C文件,一起来试试下面的操作吧^_^。
常用命令
这里介绍和代码编写相关的常用命令。 其实前面所介绍的set hls, set ic也属于这部分
内容。
系统交互
首先介绍一些和系统交互的命令。
:pwd
该命令用于查看当前的窗口的工作目录。
:cd your/path
该命令用于切换当前目录到指定的目录下。和shell中的cd一样可以使用tab自动补齐。
:lcd /your/path
和cd类似,但只设置当前窗口的当前目录,别的窗口的当前目录保持不变。
当前目录的作用在于,当需要对该当前目录下的文件或目录进行操作时,就不需要输入绝
对路径来访问,可以直接使用相对路径。另外,如果输入命令:
:e .
则会在Vim中打开当前目录,其中.就表示当前目录。 此时Vim就表现得像一个文件浏览器
了,只是功能比较简陋点。
如果需要在Vim中直接执行shell命令,例如mkdir来建立一个目录tmp,则可以输入:
:!mkdir tmp
即可在当前目录下新建一个tmp目录。 该命令是在要执行的shell命令前添加一个!。这个
和前面介绍过的强制执行类似,只不过强制执行是将!放在命令后面, 而且强制执行的命
令是Vim中的命令,而不是shell命令。
接下来介绍如何对Vim进行设置,调教开始!!
配色方案
Vim安装后的默认样子是十分土的,大部分使用者都是因为不能接受Vim的土包子样才弃用
它的。其实Vim是需要进行设置、调教才会变得强大的。 下面就一步一步介绍如何进行设
置,将Vim打造成程序员专用编辑器。
先从界面视觉上着手,其他IDE有的神马语法高亮、自动缩进一个都不能少。
首先选择一个配色方案。所谓配色方案就是在软件里背景色如何、前景色如何、出错信息
颜色如何、状态栏什么颜色等等。Vim安装后自带了很多配色方案在默认安装路径下:
/usr/local/share/vim/vim73/colors/
colors目录下看到很多配色文件,里面还有个README.txt,有详细的介绍。那么如何将这
些配色方案应用起来呢? 例如要使用koehler配色方案(笔者使用这个^_^),则在Vim中键
入如下命令:
:color koehler
即可,输入后是不是发现Vim整个大变样了。 也可以在键入color之后,可以使用tab键来
遍历系统自带的配色方案,然后进行选择。
Vim的可定制性是超强的。 如果你不满意系统自带的配色方案,完全可以自己编写一个配
色文件,然后放置到该路径下。不过推荐放到自己的目录下:
~/.vim/colors/
然后使用color命令导入。
语法高亮
代码编写中的语法高亮是十分有用到功能,可以让代码编写以及阅读起来更加高效。
配色方案只是全局的颜色搭配,而针对特定语言的语法高亮和配色方案不同。例如,在编
写C源文件时,输入static之后,static是关键字,因此需要将该单词高亮显示。 而不同
的语言有着不同的关键字集,且不同的语法高亮文件也有着不同的颜色搭配。要启用语法
高亮,输入命令:
:sy on
sy(不要想歪)是syntax的缩写,如果你直接输入:
:syntax on
是同样的效果,即Vim提供命令的简写。输入:
:sy off
则会关闭语法高亮显示。
Vim发行版里带了450多种语言的语法高亮,在其主页vim.org上还可以找到更多。而针对C
语言,你可以到如下网址上下载适合你审美观的语法高亮文件:
http://vimcolorschemetest.googlecode.com
将下载好的文件保存到:
~/.vim/syntax/
目录下,重命名为c.vim即可。 如果读者有兴趣,可以自己修改该文件打造自己风格的语
法高亮。
显示行号
在代码编写和查看中,显示代码的行号是非常实用的功能,代码都是以行为单位嘛。而在
程序开发调试过程中尤其有用:编译器报错打印行号,使用printf调试打印行号,assert
报错打印行号,gdb调试输出打印行号,执行一些组合操作需要行号。
要在Vim中显示行号,输入如下命令:
:set nu
之后,便会默认在窗口的左侧显示行号了。nu是number的缩写,两者等效。如果需要关闭
行号,输入:
:set nonu
即可。
代码缩进
代码缩进是代码风格中重要的一部分,也是体现程序员专业素质的一个重要指标。值得庆
幸的是,使用Vim来编写代码使得这个工作变得很轻松。
Vim默认对大部分的语言,包括C,都提供了自动缩进功能。如下命令使能自动缩进:
:filetype indent on
:set autoindent
之后,Vim会判断文件类型载入不同的缩进规则。
在编写代码过程中,Vim在每次回车之后,便会自动将光标缩进到合理位置。比如输入{自
动向右缩进一个tab字符(具体用什么缩进可以配置,下面会介绍),输入}自动回退缩进。
这样就不需要使用者自己输入tab键或者空格键来控制缩进了。更棒的是,Vim会智能地自
动判断缩进层次,这样就不需要自己来看那一层层的嵌套了。
如果是针对已有的代码,想要修改代码的缩进,比较笨的方法就是给每行不符合缩进要求
执行回车,让它回车后自动缩进(笔者曾经这么干过- -')。不过有更高效的方法。
修改缩进
<--------------------------->
, <, =
这三个命令一般会放在组合操作中的范围+操作命令里。 例如,如果你要将10行同一层次
的代码向右缩进一级,则可以使用可视行选择需要缩进的代码,然后键入>。 执行后,该
代码块便会向右缩进一级了。而<则是向左缩进一级。 >和<用以表示缩进方向也是十分形
象的吧^_^。
假如你要将10行代码缩进三级呢,那是不是要重复执行三次该操作序列呢?聪明的读者可
能会想要使用宏来完成,但是也必要麻烦。这里有更简单的方法。
重复修改
<--------------------------->
.
该快捷键会重复上次文本的改变。不过该快捷键只是用来重复简单的改变操作,而不能重
复命令行命令。可以将起看作是轻量级的重复,而宏则是完备的重量级重复。
还有=没有介绍呢。 上面介绍的<和>只能让代码(不管是不是同一层次)一起缩进相同的距
离,感觉没那么智能。例如,你面对的是这样的一个函数:
int bad_func(int i, int j)
{
if(i == 1){
return i++;
} else {
if(j == 1)
return 0;
else
return 1;
}
}
看着是不是很崩溃,完全搞不清逻辑。当然这是个极端的例子,但是平常还是会碰到一些
缩进层次混乱的代码。那么如何梳理呢,使用<和>是不可行的,要不就每行手动回车吧?
呵呵,高效的方法Vim当然是有的。那就是使用=。
首先移动到函数体定义开始处的{,切换到可视模式,然后键入%将整个函数体选中,之间
就键入=号,执行命令。 哈哈,代码一下子就很乖的各自回到了适当的缩进级别了,很神
奇吧。该函数正常的样子如下:
int bad_func(int i, int j)
{
if(i == 1){
return i++;
} else {
if(j == 1)
return 0;
else
return 1;
}
}
缩进的话题还没有结束。 不同的代码风格要求的缩进字符是不同的,例如Linux内核的代
码风格要求使用tab缩进,并且tab的宽度为8个字符。 这样做的解释是:可以防止程序员
写出嵌套太深的代码。 可以查看Linux内核源码树里Documentation目录的CodingStyle文
件。
那么如何应对不同的缩进要求呢,Vim提供如下设置命令:
:set expandtab
:set tabstop=4
:set shiftwidth=4
第一个命令使能了用空格代替tab,即使用空格来进行缩进。 默认情况下Vim是使用tab来
缩进的;第二个命令设置了一个tab代表的空格数;第三个命令设置tab键在文本显示时所
显示的宽度为多少字符数。更详细的可以help对应的参数来查看帮助。
映射
对于每天面对整屏整屏的代码、需要成天coding的码农来说,提高效率是十分重要的,而
快捷键便是其中一个重要的手段。
在前面的<基本编辑>中提到过,对于系统的复制粘帖指令,因为输入序列较长,可以自定
义快捷键将操作序列映射为单个按键。要实现该映射,输入的命令如下:
:map "+y
:map "+p
这样的设置,即将复制操作定义为了键,而粘帖操作定义为了键。
再例如,在C中经常要注释掉一行代码或者取消行注释。 这当然可以通过I//以及^xx来实
现,不过每次都需要输入不是很麻烦吗?输入如下命令:
:map I//
:map ^xx
:imap I//
:imap ^xx
便将定义为了行注释的快捷键,而定义为了去掉行注释的快捷键了。
那么命令中的imap是什么意思呢。imap表示定义在插入模式下的键映射。 即map所映射的
快捷键只能在普通模式下识别,而imap定义的快捷键则适用于插入模式。即然是插入模式
下,因此该操作序列就需要先执行Esc操作,回到普通模式下后再执行行注释。 这样,进
行行注释就可以不用管当下处于什么模式下,直接按下即可。除了map、imap,Vim
还提供了vmap, xmap等等。
键映射还可以有着十分复杂的设置,比如执行条件判断等等。如果读者有兴趣,可以尝试
实现一下如何进行块注释(/* */)。
自动补齐
Vim也是支持自动补齐的,不过自动补齐有两个版本。第一种为Vim自带的,自动补齐的候
补选项是文本中已出现的单词,即上下文相关补齐;第二种为通过外部插件来实现的,例
如supertab, neocomplcache等等,可以到Vim官网上查看,应该有很多的。
这里只介绍Vim自带的,因为最基础而且简单; 而对插件的选择则是因人而异,众口难调
啊(其实是写文档写到快崩溃了,一切从简吧- -')!
自动补齐
<--------------------------->
Ctrl+p, Ctrl+n
例如Vim中同时打开了两个源文件在进行编辑:main.c和login.c。在main.c中定义了变量
status和life,在login.c中定义了stop和list。
在main.c中输入st之后,需要进行自动补齐。此时光标位于st之后,并且仍然是处于插入
模式,键入Ctrl+p[previous]或者Ctrl+n[next],则会出现一个类似下拉列表的文本框,
列出了符合st开头的单词。这里列出的是status和stop,其中在stop之后会注明该变量是
定义在login.c中的。 再按下Ctrl+p或者Ctrl+n则用来向上或者向下选择所列出的候选变
量名,选择好之后空格即可。
同样的,在login.c中输入li之后,键入Ctrl+p或者Ctrl+n, 也会出现选择lift和list的
文本框。
该方法的缺点是:只有Vim中打开的文件,才会被纳入到搜索匹配补齐的范围之内, 而没
有被打开的文件则不会被搜索。这和跨文件查找一样,需要更强大的插件来完成。读者可
以去查找符合你自己要求的自动补齐插件。
语法折叠
<--------------------------->
zr, zR, zm, zM
关于语法折叠,笔者自己是不太喜欢的,不过习惯使用IDE的人可能会比较喜欢。 这可以
使得代码非常简洁,容易浏览代码。不过笔者的意见是, Vim已经提供了很强大的motion
指令,可以很方便地在各个代码块之间移动,那么比起需要频繁地使用折叠指令带来的繁
琐操作,笔者还是宁愿放弃使用语法折叠。
正是因为不怎么使用语法折叠,这里就不多做介绍了,有兴趣的读者可以使用如下的命令
查看帮助,了解更多:
:help cindent
:help autoindent
:help smartindent
下面再介绍两个小技巧类型的快捷键。
查看man
<--------------------------->
K
man手册是Linux中,无论是命令行使用还是编写程序,都会经常需要查看的手册,对程序
员十分友好。 使用Vim在编写代码过程中,如果对某个库函数或者系统调用不熟悉,需要
查看它的man手册时,可以直接将光标移动到该函数名上,然后键入K, Vim会自动将自己
隐藏,然后调用man程序显示该函数的手册了。
需要说明的是,该功能在终端下使用起来最方便和完美,如果是使用gvim的话,手册中会
出现乱码,影响查看。
查看ascii值
<--------------------------->
ga
该命令是查看光标下的字符的ascii码的值,信息会在信息区给出。这个命令可能对于写C
程序,特别是嵌入式的程序比较有用。读者可以尝试下。
项目管理
设想这么个场景:在今天的工作里, 你在Vim中已经打开了几个源文件进行编辑,而且还
使用分割窗口打开了其他目录下的参考文档,以便一边编程一边查看。但是要下班了,需
要关掉电脑,那是不是意味着,明天重新工作时需要再手动地将各个源文件和文档打开,
已恢复到昨天的工作状态呢?
很多IDE则不存在这个问题,它会记住每个工程在关闭时的状态: 打开了哪几个文件,每
个文件当前显示的位置等。
Vim也是提供这样功能的,只不过不是自动完成的,需要用户自行管理。 不过也可以编写
脚本来实现该功能的自动化。这里只介绍工程管理相关的命令。
在你要关闭Vim之前,并且执行了:wa之后,输入命令:
:mks
即可将当前编辑会话保存了。这个命令的完整形式是mksession,即“制作会话”。
会话是Linux中常用的一个名词,可以理解为一次工作场景、工作环境。例如登录到Linux
中便可认为是开启了一次会话,而logout便是结束一次会话。
mks会将本次会话信息写入一个Vim脚本,该脚本能够恢复当前的编辑会话。如果命令后面
为空,不提供文件名, 则默认使用"Session.vim"作为脚本名,会在当前目录下生成该文
件。如果当前目录下已有该文件,则需要包含!,来强制执行,将已有的文件覆盖。
保存了会话之后,在第二天需要载入时, 先确保当前目录是所保存Session.vim所在的目
录,然后执行命令:
:so Session.vim
来导入会话信息。so的完整命令是source,表示载入会话。 这时Vim便会立刻恢复当初保
存时的文件布局,甚至连当时做的书签标记、记录的宏都还有效。
自此, 对于如何设置Vim,使得代码编写简化和提高效率的介绍到此了。下面插件部分会
再介绍几个用于编程的插件。
配置
嗯,好了,看过了上面的介绍后, 你可以在Vim中输入各种设置命令,将语法高亮、自动
缩进、显示行号等等配置好了,使用后也觉得非常ok,心满意足的关闭Vim。 不过在下次
打开Vim写代码时,你发现—>悲剧了,Vim还是默认的那副土样,你上次辛辛苦苦输入的
各种设置命令已经浮云了。难道每次都要输入一堆设置命令吗…命令吗…令吗…吗?
(小月月体)
当然不用了,这时便是配置文件发挥作用的时候了。不过,你会感到奇怪,因为找不着菜
单中的“配置”选项来打开设置对话框啊,事实上,根本连菜单都没有!
大部分IDE或者编辑器都提供了设置对话框来对软件进行配置, 并将配置保存在配置文件
中,在每次打开时载入,保证软件如同你所期望的那样。只不过很少有用户会去打开配置
文件查看,甚至查看不了,因为你找不到,即便找到了也看不懂,因为可能使用的是二进
制保存的,而不是文本形式。
如果读者使用过Total Commander,并且还折腾过的话,应该会对它的配置比较了解。 除
了通过tc软件上的配置对话框来设置之外,你可以在其安装目录下很容易发现它的配置文
件,然后用文本编辑器打开就可以直接在里面编辑设置,因为它是文本形式的,而且注释
很详细。这种方式是十分舒服,在Windows下很少有软件做得这么贴心。
不过在Linux里,一切软件都是这样的,当然Vim也不例外了。 而且Vim的配置文件的修改
也十分、十分简单。
首先确认的一点是,个人的配置文件是放置在用户家目录下的,文件名为.vimrc,即:
~/.vimrc
它的编写很简单:将设置所需要输入的那些命令去掉开头的冒号,然后直接写在配置文件
中,一行一个命令即可。在每行前添加引号来注释。
Vim将在启动时,读取配置文件,将里面的每行配置当作命令输入来自动执行。 这样就不
需要每次手动输入命令来进行设置了,而是由Vim自动完成。是不是很easy、简单易懂?
对Vim的设置就只需要这么一个小文本文件就可以了。如果身边的人想要和你的Vim的配置
变得一样,却不愿花功夫去折腾,那么直接将你的配置文件拷给他,覆盖掉他的用户家目
录下的配置文件即可。
当然除了这个配置文件之外,还记得前面提到的存放各种语法高亮配置文件、缩进配置文
件的路径吗?即:
/usr/local/share/vim/vim73/
该目录是Vim安装后默认建立的,里面存放着Vim默认自带的配色方案、语法高亮、缩进规
则、帮助文档、插件、按键映射、拼写检查等等文件。这些是对系统上的所有用户都适用
的文件。而用户自己应该在自己的家目录下有这么个目录,即:
~/.vim/
来存放专用于自己的配色方案,语法高亮文件等等,特别是插件。关于插件在后面详细介
绍。
文件编码
对于Linux用户来说,需要应对各种编码的文件。 Windows统一使用的是gb18030编码,而
Linux下大部分使用的是utf8编码。因此需要设置Vim的编、解码来应对不同编码的文件。
这里直接给出笔者在配置文件中的配置:
" 文件保存编码 "
set fenc=utf-8
" 打开文件编码猜测 "
set fencs=utf-8,gb2312,ucs-bom,gb18030,gbk,cp936,big5
有两条设置命令。 第一个设置将Vim的默认保存的编码格式设置为utf8格式。第二个设置
则是设置在Vim打开一个文件时,对文件编码进行检查的种类和顺序。 即首先检查该文件
是否为utf8格式,是则直接打开,不是则继续下一个检查,检查是否为gb2312格式,如此
类推。如果都不符合的话,则会打开为乱码。
通过添加该命令后面的编码类型,可以让Vim支持多种编码格式的文件。
如果想要查看当前Vim都设置了哪些的话,可以输入命令:
:set
set命令后面不接任何参数,表示查看Vim中的设置,包括是否使能了自动缩进、是否使能
语法高亮、文件编码为什么等等。
当然,配置中还有许多话题这里没有提及, 例如利用Vim自身的脚本语言来条件执行命令
等,读者可以自行查看帮助。