📄 usr_29.cnx
字号:
*usr_29.txt* For Vim version 6.3. 最近更新:2004年6月 VIM 用户手册 - by Bram Moolenaar (译者:wandys http://vimcdoc.sf.net) 在代码间移动Vim 的创造者是一名计算机程序员,因此这就不奇怪 Vim 中有许多帮助编写程序的功能:跳转到标识符被定义和使用的地方;在另一个窗口中预览有关的声明等等。在下一章中还会介绍更多的功能。|29.1| 使用标签|29.2| 预览窗口|29.3| 在代码间移动|29.4| 查找全局标识符|29.5| 查找局部标识符 下一章:|usr_30.txt| 编辑程序 前一章:|usr_28.txt| 折叠 目录:|usr_toc.txt|==============================================================================*29.1* 使用标签什么是标签?标签就是一个标识符被定义的地方。一个例子就是 C 或者 C++ 程序中的函数定义。标签列表可以保存在一个标签文件中。Vim 可以通过它来从任何地方跳转到该标签,也就是一个标识符被定义的地方。 在当前目录下为所有的 C 文件生成标签文件,使用下面的这个命令: > ctags *.c"ctags" 是一个独立的程序。大多数 Unix 系统上都已经安装了它。如果你还没有安装,可以在这里找到 "Exuberant ctags": http://ctags.sf.net ~现在你可以使用下面的命令跳转到一个函数定义的地方: > :tag startlist这个命令会找到函数 "startlist",即使该函数是在另一个文件中。 CTRL-] 命令会跳转到当前光标下单词的标签。这样浏览毫无头绪的 C 代码会变得更容些易。举个例子,假设你在函数 "write_block" 中。你可以看到它调用了函数 "write_line"。但 "write_line" 做了什么呢?将光标置于调用 "write_line" 的地方然后按 CTRL-],你就跳转到了这个函数的定义的地方了。 "write_line" 函数调用了 "write_char"。你需要知道它做了什么。将光标定位到调用 "write_char" 的地方然后按 CTRL-],你就到了定义"write_char" 的地方。 +-------------------------------------+ |void write_block(char **s; int cnt) | |{ | | int i; | | for (i = 0; i < cnt; ++i) | | write_line(s[i]); | |} | | +-----------|-------------------------+ | CTRL-] | | +----------------------------+ +--> |void write_line(char *s) | |{ | | while (*s != 0) | | write_char(*s++); | |} | | +--------|-------------------+ | CTRL-] | | +------------------------------------+ +--> |void write_char(char c) | |{ | | putchar((int)(unsigned char)c); | |} | +------------------------------------+":tags" 命令显示你经过的标签列表: :tags # TO tag FROM line in file/text ~ 1 1 write_line 8 write_block.c ~ 2 1 write_char 7 write_line.c ~ > ~>现在介绍向回跳转。 CTRL-T 命令跳转到上一个标签。在上例中,你会回到 "write_line"函数调用 "write_char" 的地方。 这个命令接受一个计数参数,用来表示跳转回去的标签个数。你已经向前跳转,现在又跳转了回去。现在我们再一次向前跳转。下面的命令跳转到标签列表中最上面的标签:> :tag<你可以在前面加上要向前跳转的标签个数。比如:":3tag"。 CTRL-T 同样可以加上一个计数参数。 通过这些命令,你可以用 CTRL-] 延着调用树向前跳转, 用 CTRL-T 向回跳转,用 ":tags" 命令显示当前位置。分 割 窗 口":tag" 命令会将当前窗口的文件替换为包含新函数的文件。怎样才能同时查看两个文件呢?你可以使用 ":split" 命令将窗口分开然后再用 ":tag" 命令。Vim 有个缩写命令可以做到这些: > :stag tagname使用下面的命令可以分割当前窗口并跳转到光标下的标签: > CTRL-W ]如果指定了计数参数,新窗口将包含指定的那么多行。多 个 标 记 文 件如果在多个目录中都有文件,你可以在每一个目录下创建一个标签文件。Vim 只能跳转到那个目录下的标签。 通过设定 'tags' 选项,你可以使用多个相关的标签文件。 比如: > :set tags=./tags,./../tags,./*/tags这会使 Vim 找到当前文件所在目录及其父目录和所有子目录下的标签文件。 这已经是不少的标签文件了,但也许仍不够。比如,当编辑 "~/proj/src" 目录下的一个文件时,你无法找到 "~/proj/sub/tags" 目录下的标签文件。对这种情况,Vim提供了一个查找整个目录树下标签文件的方法,比如: > :set tags=~/proj/**/tags单 个 标 记 文 件当 Vim 在多个地方查找标签文件时,你会听到硬盘在格格作响。这样会有点慢。在这种情况下,你最好将这些时间花在生成一个大的标签文件上。你可以要等一会儿。 这得借助上面提到的 "Exuberant ctags" 程序。它有一个选项可以搜索整个目录树: > cd ~/proj ctags -R .这样做的好处是 "Exuberant ctags" 可以识别多种文件类型,它不仅适用于 C 和 C++程序,还适用于 Eiffel 甚至 Vim 脚本。请参考 ctags 文档进行调整所用参数。 现在你只需要告诉 Vim 你的标签文件在何处: > :set tags=~/proj/tags多 个 匹 配当一个函数(或类中的方法)被定义多次, ":tags" 命令会跳转到第一处。如果在当前文件中存在匹配,那它将会被首先使用。 你现在可以跳转到同一个标签的其它匹配处: > :tnext重复执行这个命令可以找到更多的匹配。如果存在很多匹配,你可以选择要跳转到哪一个: > :tselect tagnameVim 会为你展示一个选择列表: # pri kind tag file ~ 1 F f mch_init os_amiga.c ~ mch_init() ~ 2 F f mch_init os_mac.c ~ mch_init() ~ 3 F f mch_init os_msdos.c ~ mch_init(void) ~ 4 F f mch_init os_riscos.c ~ mch_init() ~ Enter nr of choice (<CR> to abort): ~你现在可以输入要跳转到的匹配代号(在第一列)。其它列的信息可以让你知道匹配在何处被定义。可以用这些命令在各匹配的标签间移动: :tfirst 到第一个匹配 :[count]tprevious 向前 [count] 个匹配 :[count]tnext 向后 [count] 个匹配 :tlast 到最后一个匹配如果没有指定,[count] 省缺为一。猜 测 标 签 名命令行补全是避免输入长标签名的好办法。只需输入开始的一部分然后按 <Tab>: > :tag write_<Tab>你会得到第一个匹配。如果这不是你想要的,重复输入 <Tab> 直到你找到正确的匹配。 有时你只知道一个函数名的一部分,或是你有很多以相同字符串开头而结尾不同的标记。这时你可以告诉 Vim 使用一个模式来查找标签。 假设你要跳转到一个包含 "block" 的标签。首先输入: > :tag /block现在再利用命令行补全功能:输入 <Tab>。Vim 会找到所有包含 "block" 的标签并使用第一个匹配。 标签名前面的 "/" 告诉 Vim 这不是一个确定的标签名而是一个模式。你可以利用有关查找模式的所有特性。举个列子,假设你要选择所有以 "write_" 开头的标签: > :tselect /^write_"^" 指定标签以 "write_" 开头,否则在中间含有 "write_" 的标签名也会被找到。类似地,"$" 指定标签名结尾处的匹配。标 签 浏 览 器CTRL-] 可以让你跳转到光标所在标识符的定义处,因此你可以利用标识符的列表来形成一个目录。这里给出一个例子。 首先生成一个标识符列表(需要 Exuberant ctags): > ctags --c-types=f -f functions *.c现在打开 Vim 并在一个垂直分割窗口中编辑这个文件: > vim :vsplit functions窗口中包含一个所有函数的列表。其它的东西可以被忽略。用 ":setlocal ts=99" 命令使其显示得更清晰些。 在这个窗口中,定义一个 mapping: > :nnoremap <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR>移动光标至要跳转到函数的所在行,输入 <Enter>。Vim 会在另一个窗口中跳转到所选择的函数定义处。相 关 杂 项你可以设定 'ignorecase' 选项来忽略标签名里的大小写。'tagbsearch' 选项标明标签文件是否经过排序。省缺是假定为标签文件已排序,这样会使查找更快,但如果文件没有被排序是无法工作的。'taglength' 选项可用来告诉 Vim 一个标签的有效字符个数。当你使用 SNiFF+ 程序时,你可以利用 Vim 的有关接口 |sniff| 。SNiFF+ 是一个商业软件。Cscope 是一个自由软件。它不仅可以找到一个标识符被声明的地方,还可以找到标识符被使用的地方。 请参考 |cscope|。==============================================================================*29.2* 预览窗口当编辑含有函数调用的代码时,你需要使用正确的调用参数。要获知所要传递的值,你可以查看这个函数是如何定义的。标签机制对此十分适用。如果定义可在另一个窗口内显示那就更好了。对此我们可以利用预览窗口。 打开一个预览窗口来显示函数 "write_char": > :ptag write_charVim 会打开一个窗口,跳转到 "write_char" 标签。然后它会回到原来的位置。这样你可以继续输入而不必使用 CTRL-W 命令。 如果函数名出现在文本中,你可以用下面的命令在预览窗口中得到其定义: > CTRL-W }有一个脚本可以自动显示光标处的标签定义。请参考 |CursorHold-example| 。用下面的命令关闭预览窗口: > :pclose要在预览窗口中编辑一个指定的文件,用 ":pedit" 。这在编辑头文件时很有用,比如: > :pedit defs.h最后, "psearch" 可用来查找当前文件和任何包含文件中的单词并在预览窗口中显示匹配。这在使用没有标签文件的库函数时十分有用。例如: > :psearch popen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -