Vim 适用于 C 程序员
典型的程序员例程包括编译和编辑程序,直到测试证明该程序正确地完成了它应该做的工作。任何减少此循环严格性的机制显然都会使程序员的生活更轻松。Vim 正是通过以这样一种方式将 make 与 Vim 集成,使您不必离开编辑器即可编译和测试程序。在 Vim 内部运行:make即可为您完成这项工作,前提是当前目录中存在 makefile。
您可以通过运行以下命令从 Vim 内部更改目录:cd。要验证您当前的位置,请使用:pwd。如果您正在使用 FreeBSD 并且想要从命令行调用 gmake 而不是 make,您只需输入:set makeprg=gmake。现在假设您想要给 make 一些参数。例如,如果您想提供 CC=gcc296
:set makeprg=gmake\ \CC=gcc296
即可完成这项工作。
现在开始检查错误、跳转到源文件中相应的行号并修复它们。如果您想在源文件中显示行号,:se nu会启用此选项,而:se nonu会禁用行号显示。
编译完成后,Vim 会自动将您带到导致错误的第一个行。要转到下一个错误,请使用:cn将您带到下一个导致错误的行号。:cfirst和:clast分别将您带到第一个错误和最后一个错误。修复错误后,您可以再次编译。如果您想再次检查错误列表,:clist会显示它。方便,不是吗?
如果您想在修复特定错误时读取其他源文件,例如 foo.c,只需键入:e foo.c.
Vim 提供的一个快捷方式是避免键入过多来切换回上一个文件,只需键入:e #而不是键入文件的完整路径。如果您想查看在任何时间点在 Vim 中打开的所有文件,您可以使用:ls或:buffers.
如果您遇到打开了太多文件并且想要关闭其中一些文件的情况,您可以发出:ls。它应该显示如下内容
2 # "newcachain.c" line 5 3 %a "cachain.c" line 1
如果您想关闭 newcachain.c,:bd 2或:bd newcachain.c即可完成这项工作。
在浏览 C 代码时,您可能会遇到想要快速跳过多个函数的情况。您可以在命令模式下使用 ]] 组合键。如果您想在文件中向后浏览,可以使用 [[ 。
您还可以使用标记来为某些光标位置添加书签。您可以使用任何小写字母字符作为标记。例如,假设您想要标记源文件的第 256 行并将其称为 b。只需转到该行,:256,然后键入mb在命令模式下。Vim 永远不会回显您在命令模式下键入的内容,但会静默地为您执行命令。
如果您想转到上一个位置,''(两个单引号)会将您带到那里。键入'a会将您带到标记 a,依此类推。
尤其是在编辑 Makefile 时,您可能想要弄清楚哪些空白是制表符。您可以键入:se list,并且显示为^I蓝色的就是制表符。另一种方法是使用/\t。这会以黄色突出显示制表符。
全局搜索和替换是程序员的常见任务,Vim 为两者都提供了良好的支持。只需在命令模式下键入/,您就会被带到搜索到的关键字。如果您喜欢增量搜索,à lá emacs,您可以指定:se incsearch在搜索之前。当您想要禁用它时,请键入:se nois.
搜索和替换是 Vim 中一个强大的工具。您只能在您使用 v 命令选择的区域、仅在某些行号之间或仅在使用 Ctrl-V 命令选择的矩形区域中执行它。
一旦您选择了区域或行号范围,例如使用:24,56选择第 24-56 行(包括两行),或者只选择您的区域并键入:<','>就会出现。现在键入s/foo/bar以将所有出现的字符串 foo 替换为 bar。
但是,此命令每行仅替换一个实例。如果您想每行执行多次出现,请键入s/foo/bar/g。如果您只想替换某些出现,您可以使用带有“confirm”选项的s/foo/bag/gc.
有时字符串包含的字符会作为其他关键字的子字符串出现。例如,假设您想替换变量“in”而不是 inta 中的“in”。要搜索整个单词,请键入/\<in\>/.
最常见的情况是,您将要执行全局替换,即给定文件中每个实例。您可以使用以下任一方法来完成此操作:1,$s/foo/bar/g或:%s/foo/bar/g。如果您随后想要在所有打开的文件中替换它,您可以输入:bufdo %s/foo/bar/g.
另一种搜索方式是转到关键字并在命令模式下键入 *。键盘现在将在文件中突出显示它出现的所有位置。向后搜索也很简单;搜索时键入 ? 而不是 /。
搜索结束后,Vim 会记住它,因此下次您搜索相同的关键字时,您只需键入 / 或 ?,而不是键入整个文本。
搜索的一个副作用是它会保持突出显示。这在编辑程序时可能会分散注意力。通过键入以下命令关闭突出显示:se nohlsearch, :nohlsearch或:nohl
您始终可以使用 Tab 键来完成您使用冒号给出的 Vim 命令。例如,您可以键入:nohl<Tab>,Vim 会为您完成它。这普遍适用,您可以按 Tab 键循环浏览 Vim 的命令,直到 Vim 找到唯一匹配项。
Exuberant ctags(请参阅在线资源)是一个外部程序,可以为 Vim 生成标签以导航源代码。如果您的所有源代码都只包含在一个目录中,只需转到 shell 中的目录并输入
$ ctags .
这将生成一个名为 tags 的标签文件。Vim 读取此文件以跳转到函数、枚举、#defines 和其他 C 构造。
如果源代码分布在多个目录中,ctags 必须相对于某个目录为所有目录生成标签。为此,请转到源代码的根目录并执行
$ ctags -R .
检查是否已生成 tags 文件。您还可以在 Vim 中打开和读取 tags 文件。
现在,让我们继续讨论使用标签导航源代码。使用 ctags 导航源代码是程序员拥有的最令人着迷的工具之一。您可以非常出色和快速地阅读代码,以至于您会怀疑如果没有 ctags 会是什么样子。
生成 tags 文件后,像往常一样在 Vim 中打开文件,但如果文件位于深层目录中,则从根目录打开它。例如,您的源代码组织如下
common | ----> gui --> wxpython | | | ------>Tk | ----> backend --> networking include user
如果您想编辑 common/backend/networking 目录下的 tcp.c,您应该像这样打开它
$ vim common/backend/networking/tcp.c
和
$ vim tcp.c
tags 文件位于 common 上方的目录中,Vim 会自动知道 tags 文件的位置。
或者,您可以使用上面提到的第二种方法打开文件,并从 Vim 内部执行此操作
:se tags=../../../tags
第一种方法更易于导航。打开文件后,您可以使用组合键 Ctrl-] 轻松地从一个函数定义跳转到另一个函数定义。
如果您想转到任何内容的定义,无论是函数、宏还是其他任何内容,只需将光标放在其上时按 Ctrl-] 即可。因此,从调用处,我们可以移动到定义处。它会将您带到那里,无论哪个文件包含它。假设我们从 tcp.c 调用 drawscreen(),它会自动将您带到那里,即使该文件包含在 common/gui 下。
如果您想返回到您正在阅读的内容,请按 Ctrl-T,您将返回到您离开的位置。您可以从那里再次按 Ctrl-] 跳转到另一个调用。您可以无限期地继续此过程,并且可以通过按 Ctrl-T 不断返回。
如果您只知道函数名称的一部分,另一种查找函数定义的方法是
:ta /function
如果存在多个匹配项,此命令会将您带到第一个匹配项。您可以使用以下命令转到下一个匹配项:tn.
如果存在多个定义并且您想在它们之间进行选择,您可以按 G Ctrl-] 或键入:tselect <tagname>。这样,您就可以通过使用标签进行导航来修改源代码,而无需知道哪个文件包含什么。
Cscope 是另一个强大的源代码导航工具,我们可以使用它执行各种搜索。以下是 Cscope 菜单的示例输出
Find this C symbol: Find this global definition: Find functions called by this function: Find functions calling this function: Find this text string: Change this text string: Find this egrep pattern: Find this file: Find files #including this file:
现在,Vim 已将 Cscope 集成到其功能库中,使程序员可以方便地从舒适的 Vim 中使用 Cscope 中的相同功能。您只需通过发出以下命令来建立 Cscope 连接:cs add cscope.out.
正如我们之前与 ctags 讨论的那样,Cscope 生成一个名为 cscope.out 的索引,可以使用 shell 命令生成
$ cscope -Rbq
这将生成文件 cscope.out。它要从源代码根目录执行,à lá Ctags。然后,您像以前一样相对于源代码根目录打开文件,并使用命令建立 Cscope 连接:cs add cscope.out。您可以通过键入以下命令来验证现有的 Cscope 连接:cs show.
。可以使用以下命令查看您可以从 Vim 内部搜索的内容:cs<CR>。例如,要转到特定文件或源文件的标头,只需键入:cs f f stdio.h以打开 stdio.h 或:cs f f foo.c.
要搜索由函数 foo.c 调用的函数,请键入:cs f d foo.c。这将列出由 foo.c 调用的函数。对于调用 foo.c 的函数,请键入:cs f c foo.c.
要搜索 egrep 模式,请键入:cs f e varName等等。有关可用选项的列表,请键入:cs。它会显示一系列可用选项。
现在,如果您同时拥有 ctags 和 Cscope,您可以键入:cstag /foo以搜索包含 foo 的函数或枚举或任何内容。
如果说 Vim 有一项功能比任何其他编辑器或 IDE 都更胜一筹,那就是功能齐全的语法高亮。Vim 中可用的颜色使处理源代码成为一种真正的乐趣。它不仅使您的生活丰富多彩,而且还可以轻松地在编译之前发现错误。代码中常见的错误,例如不匹配的 ),} 或 ],很容易看到。它还会提醒您是否留下了未以 " 或 ' 结尾的字符串。它会告诉您注释未以 */ 结尾,或者您正在嵌套注释。在 C 语法方面,语法高亮非常智能。
通常,您无需执行任何操作即可启用 Vim 的语法高亮;:sy on如果您的发行版默认未启用它,则此命令可以完成这项工作。与其他命令一样,您可以将其添加到您的 ~/.vimrc 文件中。
如果颜色仍然没有显示,则您的终端存在问题。首先修复它。:se filetype on是您可以尝试的另一件事,除了:sy enable.
让我们假设您的颜色显示正确。假设您不喜欢某种颜色,或者因为蓝色在深色背景中不可见,您无法阅读 C 注释。要解决第二个问题,一个简单的:se background=dark即可完成这项工作。如果您想禁用 C 注释的语法高亮,请键入:highlight clear comment.
要更改颜色,首先使用:syntax命令显示给定缓冲区的所有语法项。然后,确定您要更改的语法组。如果您希望字符串以亮白色显示,这在黑色背景下易于阅读,只需输入
:highlight String ctermfg=white
或者,对于 gvim 用户,键入
:highlight String guifg=white
您还可以更改任何组的语法颜色。典型的语法组有 Statement、Label、Conditional、Repeat、Todo 和 Special。您还可以更改高亮显示的属性,例如下划线和粗体。例如,如果您想用下划线显示 NOTE、FIXME、TODO 和 XXX,您可以使用
:highlight Todo cterm=underline
或者您可以同时添加粗体并更改颜色
:highlight Repeat ctermfg=yellow cterm=bold
您可以创建自己的一组高亮显示命令并将其保存在您的 ~/.vimrc 文件中,这样每次您编辑源代码时,都会显示您喜欢的颜色。
此外,Vim 还具有变量名补全功能。在键入时,只需在插入模式下按 Ctrl-N 或 Ctrl-P 即可。请记住,这仅在插入模式下有效。上面提到的所有其他命令都在命令模式下工作。您可以通过再次按 Ctrl-N 来循环浏览可能的补全。
这有助于我们避免在键入时出错,因为结构成员和函数名称经常会拼写错误。当 Vim 可以使用标签时,此功能效果最佳,因此请确保已安装 ctags 文件。
Vim 非常了解 C,能够自动缩进代码。默认缩进样式使用制表符,这可能不适合某些人。为了从源中完全删除制表符,请输入
:set expandtab :retab
这会将所有制表符转换为空格,以使缩进得以保留。在键入 C 文本时,Vim 会自动为您缩进。这有助于您找出匹配的大括号的位置。您可以使用命令模式下的 % 命令匹配大括号、)、] 和 }。只需将光标移动到大括号并按 %,即可将您带到相应的右括号或左括号。这适用于注释以及 #if、#ifdef 和 #endif。
在完成程序键入后,如果您想一次缩进整个文件,请在命令模式下键入gg=G。然后,如果您愿意,可以使用上述方法删除制表符。gq是缩进注释的命令序列。您也可以选择一个区域并使用 = 运算符对其进行缩进。
如果 Vim 的默认制表符缩进难以使用,您可以通过设置:se nocindent来禁用它。还有其他缩进选项可用。您可以缩进两个大括号之间和某些行号之间的代码。您可以通过键入以下命令了解更多信息:help indent.txt.
Vim 附带丰富的帮助文档。在 Vim 内部键入:help来浏览它。要转到特定主题,请在绿松石色的文本上按 Ctrl-]。Vim 的帮助文档使用了我们使用标签看到的导航机制。
Girish Venkatachalam 喜欢玩开源操作系统,例如 OpenBSD、FreeBSD 和 Debian GNU/Linux。在不进行黑客攻击时,他也喜欢去骑自行车。可以通过 girish1729@gmail.com 联系到他。