[/home/brimmer/src]$ ctags -R
"-R"表示递归创建,也就包括源代码根目录下的所有子目录下的源程序。"tags"文件中包括这些对象的列表:
l 用#define定义的宏
l 枚举型变量的值
l 函数的定义、原型和声明
l 名字空间(namespace)
l 类型定义(typedefs)
l 变量(包括定义和声明)
l 类(class)、结构(struct)、枚举类型(enum)和联合(union)
l 类、结构和联合中成员变量或函数
VIM用这个"tags"文件来定位上面这些做了标记的对象,下面介绍一下定位这些对象的方法:
1) 用命令行。在运行vim的时候加上"-t"参数,例如:
[/home/brimmer/src]$ vim -t foo_bar
这个命令将打开定义"foo_bar"(变量或函数或其它)的文件,并把光标定位到这一行。
2) 在vim编辑器内用":ta"命令,例如:
:ta foo_bar
3) 最方便的方法是把光标移到变量名或函数名上,然后按下"Ctrl-]"。用"Ctrl-o"退回原来的地方。
注意:运行vim的时候,必须在"tags"文件所在的目录下运行。否则,运行vim的时候还要用":set tags="命令设定"tags"文件的路径,这样vim才能找到"tags"文件。
在函数中移动光标
[{ 转到上一个位于第一列的"{"
}] 转到下一个位于第一列的"{"
{ 转到上一个空行
} 转到下一个空行
gd 转到当前光标所指的局部变量的定义
* 转到当前光标所指的单词下一次出现的地方
# 转到当前光标所指的单词上一次出现的地方
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 tagname
Vim 会为你展示一个选择列表:
# 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_" 的标签名也会被找到。类似
地,"___FCKpd___0quot; 指定标签名结尾处的匹配。
标 签 浏 览 器
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_char
Vim 会打开一个窗口,跳转到 "write_char" 标签。然后它会回到原来的位置。这样你可
以继续输入而不必使用 CTRL-W 命令。
如果函数名出现在文本中,你可以用下面的命令在预览窗口中得到其定义:
CTRL-W }
有一个脚本可以自动显示光标处的标签定义。请参考 |CursorHold-example| 。
用下面的命令关闭预览窗口:
:pclose
要在预览窗口中编辑一个指定的文件,用 ":pedit" 。这在编辑头文件时很有用,比如:
:pedit defs.h
最后, "psearch" 可用来查找当前文件和任何包含文件中的单词并在预览窗口中显示匹
配。这在使用没有标签文件的库函数时十分有用。例如:
:psearch popen
这会在预览窗口中显示含有 popen() 原型的 "stdio.h" 文件:
FILE *popen __P((const char *, const char *));
你可以用 'previewheight' 选项指定预览窗口打开时的高度。
*29.3* 在代码间移动
因为程序代码是结构化的,Vim 可以识别其中的有关项目。一些特定的命令可用来完成相
关的移动。
C 程序中经常包含类似下面的代码:
#ifdef USE_POPEN
fd = popen("ls", "r")
#else
fd = fopen("tmp", "w")
#endif
有时会更长,也许还有套嵌。将光标置于 "#ifdef" 处按 %。Vim 会跳转到"#else"。继
续按 % 会跳转到 "#endif"。再次按下 % 又回到原来的 "#ifdef"。
当代码套嵌时,Vim 会找到相匹配的项目。这是检查你是否忘记了一个 "#endif" 的
好办法。
当你在一个 "#ifdef" - "#endif" 块内的某个位置,你可以用下面的命令回到开始
处:
[#
如果你的位置不是在 "#if" 或 "#ifdef" 之后, Vim 会鸣音。用下面命令可以跳转到下
一个 "#else" 或 "#endif":
]#
这两个命令会跳过它所经过的 "#if" - "#endif" 块。
例如:
#if defined(HAS_INC_H)
a = a + inc();
# ifdef USE_THEME
a += 3;
# endif
set_width(a);
如果光标在最后一行,"[#" 会移动到第一行。中间的 "#ifdef" - "#endif" 块被跳过。
在 代 码 块 内 移 动
C 代码块包含在 {} 中,有时一个代码会很长。要跳转到外部代码块的开始处,用 "[["
命令。用 "][" 找到结尾处。(前提是 "{" 和 "}" 都在第一列。)
"[{" 命令跳转到当前代码块的开始处。它会跳过同一级别的 {} 对。"]}" 跳转到结尾。
一点概述:
function(int a)
+-> {
| if (a)
| +-> {
[[ | | for (;;) --+
| | +-> { |
| [{ | | foo(32); | --+
| | [{ | if (bar(a)) --+ | ]} |
+-- | +-- break; | ]} | |
| } <-+ | | ][
+-- foobar(a) | |
} <-+ |
} <-+
当编写 C++ 或 Java 代码时,外部代码块是类,而下一级的 {} 是方法。在类内部用
"[m" 可以找到前一个方法的开始。"]m" 会找到下一个方法的开始。
另外,"[]" 向后移动到一个函数的结尾,"]]" 向前移动到一个函数的结尾。函数的结尾
指的是处在第一列的 "}"。
int func1(void)
{
return 1;
+----------> }
|
[] | int func2(void)
| +-> {
| [[ | if (flag)
start +-- +-- return flag;
| ][ | return 2;
| +-> }
]] |
| int func3(void)
+----------> {
return 3;
}
不要忘了你还可以用 "%" 在匹配的 (), {} 和 [] 间移动。这在它们相距很多行时仍然
适用。
在 括 号 内 移 动
"[(" 和 "])" 命令"[}" 和 "]}" 类似,只不过它们适用于 () 对而不是 {} 对。
[(
<--------------------------------
<-------
if (a == b && (c == d || (e > f)) && x > y)
-------------->
-------------------------------->
])
在 注 释 间 移 动
移动到一个注释的开始用 "[/";向前移动到注释的结尾用 "]/"。这只对 /* - */ 注释
有效。
+-> +-> /*
| [/ | * A comment about --+
[/ | +-- * wonderful life. | ]/
| */ <-+
|
+-- foo = bar * 3; --+
| ]/
/* a short comment */ <-+
*29.4* 查找全局标识符
你在编辑一个 C 程序,想要知道一个变量是被声明为 "int" 还是 "unsigned"。一个快
速的方法是使用 "[I" 命令来查找。
假设光标在单词 "column" 处。输入:
[I
Vim 会列出它所找出的匹配行,不仅在当前文件内查找,还会在所有的包含文件中查找。
结果如下所示:
structs.h
1: 29 unsigned column; /* column number */
相对使用标签文件或预览窗口的好处是包含文件也被搜索。大多数情况下都能找到正确
的声明。即使标签文件已经过期或者你没有为包含文件建立标签也不会影响结果。
但是一些准备工作是必要的,否则 "[I" 就没法工作。首先,'include' 选项必须指
定文件是如何被包含的。省缺值适用于 C 和 C++。对其它的语言,你需要自己设定。
定 位 包 含 文 件
Vim 会找到 'path' 选项指定路径中的包含文件。如果缺少某个目录,一些包含文件
将不会被找到。你可以用这个命令来查看:
:checkpath
它会列出不能找到的包含文件,以及被找到的包含文件。一个输出样例:
--- Included files not found in path ---
<io.h>
vim.h -->
<functions.h>
<clib/exec_protos.h>
文件 "io.h" 被当前文件包含但无法找到。"vim.h" 可以找到,这样 ":checkpath" 跟进
这个文件并检查其中的包含文件。结果显示无法找到 "vim.h" 包含的 "functions.h" 和
"clib/exec_protos.h" 文件。
Note:
Vim 不是一个编译器。它无法识别 "#ifdef" 语句。这就是说所有的
"#include" 语句都会被使用,即使它在 "#if NEVER" 之后。
给 'path' 选项增加一个目录可以修正无法找到文件的错误。一个好得参考是 Makefile。
注意那些包括 "-I" 的条目,比如 "-I/usr/local/X11"。要增加这个目录,用:
:set path+=/usr/local/X11
如果有很多的子目录,你可以用 "*" 通配符。例如:
:set path+=/usr/*/include
这会找到 "/usr/local/include" 以及 "/usr/X11/include" 目录下的文件。
如果你的工程项目的包含文件都在一个套嵌的目录树下,"**" 就非常有用。它会搜索所
有的子目录。例如:
:set path+=/projects/invent/**/include
这会找到这些目录下的文件:
/projects/invent/include
/projects/invent/main/include
/projects/invent/main/os/include
etc.
还有其它的可能性。更多信息,请查看 'path' 选项。
如果你想查看找到的包含文件,用这个命令:
:checkpath!
你会得到一个(很长)的包含文件列表。为使它更短些,Vim 会对已经找到的文件显示
"(Already listed)" 而不再重新显示一遍。
相关推荐
**vim插件ctags安装详解** vim作为一款强大的文本编辑器,因其高度可定制性和高效的操作方式深受程序员喜爱。在日常开发中,尤其对于大型项目,快速定位代码和跳转到函数定义是必不可少的功能。这就是ctags插件发挥...
linux下面vim+ctags+cscope的使用方法,功能非常强大 linux下面vim+ctags+cscope的使用方法,功能非常强大
Vim是一款强大的文本编辑器,深受程序员喜爱,而`ctags`则是一个非常实用的工具,它能够为源代码文件创建一个索引,方便在Vim中进行快速跳转和查找。`ctags.exe`是Windows系统下的ctags可执行文件,用于生成这些索引...
自己的vim配置文件, 内含: 1. _vimrc 2. plugin: TagList, SuperTab, OmniCppComplete, Code_Complete 3. tags for glibc, C++(stl,stream), Unix98 system, glib-2.0 4. ftplugin for Pro*C/C++
Vim+ctags+taglist+cscope 打造文本模式下的 Kscope Kscope 作为一个功能强大的文本模式下的代码浏览器,具有代码 navigation、代码搜索、代码分析等功能。但是,使用 Kscope 需要图形化界面,然而,在 Linux 系统...
vim+ctags 使用 Vim 是一个功能强大且灵活的文本编辑器,而 ctags 是一个源代码阅读工具,两者结合使用可以大大提高代码编写的效率。以下是 vim+ctags 的使用方法和应用。 ctags 应用 ctags 是一个源代码阅读...
vim+ctags+cscope一键安装(使用)
但是有时候又需要使用到windows下面的一些应用,所以开始折腾怎么在windows下使用vim+ctags+git,下面是我整理的记录。 windows使用vim,好多人推荐安装vim工具,但是我用了一下随着windows版本的升级,比如win8,...
在这个“vim插件ctags58+taglist_45+omnicppcomplete-0.41”的组合中,我们主要探讨的是三个关键的Vim插件:ctags、Taglist和OmniCppComplete,它们极大地提升了C++开发的效率和便利性。 1. **ctags**:这是一个源...
【vim ctags安装和使用】 CTags是一款强大的源代码导航工具,它能够遍历源代码文件,生成tags文件,帮助开发者快速定位代码中的符号,如变量、函数等。这对于大型项目或者频繁查阅代码的开发环境尤其有用。Taglist...
以 Ubuntu 系统为例,可以通过以下命令安装 ctags: ```bash sudo apt-get install ctags ``` #### 四、创建 tags 文件 假设我们有一个需要索引的目录 `/home/hjw951/arm/linux-2.6.12`,可以在该目录下运行 `...
"linux-tools:vim73 cscope ctags .vimrc" 提到的是一组工具和配置,旨在提升使用Vim编辑器的体验。下面我们将详细探讨这些工具及其在编程工作中的应用。 **Vim73**: Vim73指的是Vim编辑器的第7.3版本。Vim(Vi ...
"vim + ctags + cscope + nerdtree + taglist + vundle"的组合,是Vim高效开发环境的经典搭建方案,尤其适合进行大型代码库的管理和调试。 首先,`Vim` 是一个高度可配置的文本编辑器,它支持命令行模式,提供丰富...
vim ctags taglist winmanger安装示例
Vim标签Vim-Tags版本0.1.0 Vim的Ctags生成器版权所有(c)2012-2014 Szymon Wrozynski和贡献者关于Ctags支持是Vim的一项重要功能。 一种使用Ctags的方法是Tim Pope的插件方式。 例如,在Rails项目中,当Bundler运行...
自己的vim配置文件 1. .vimrc 2. plugins: TagList, SuperTab, OmniCppComplete, Code_Complete DoxygenToolkit, proc 3. glibc, C++(stl,stream), Unix98 system, glib-2.0 的tags文件 4. ftplugin for Pro*C/C++ 5...
自己的vim配置文件 1. .vimrc 2. plugins: TagList, SuperTab, OmniCppComplete, Code_Complete DoxygenToolkit, proc 3. c89, GNU libc, C++(stl,stream), IEEE Std 1003.1-2008, glib-2.0 的tags文件 4. ftplugin ...
这里提到的"ctags", "cscope", "taglist.vim" 和 "cscope_maps.vim" 是针对Windows环境下Vim编辑器的几个强大插件,它们极大地提升了程序员的工作效率。下面将详细阐述这些工具的功能和使用方法。 1. **ctags**:...