linux中ctags的使用方法 您所在的位置:网站首页 没有扩展名 linux中ctags的使用方法

linux中ctags的使用方法

#linux中ctags的使用方法| 来源: 网络整理| 查看: 265

tags文件(标签文件)是由ctags程序产生的一个索引文件, ctags程序其是叫"Exuberant Ctags", 是Unix上面ctags程序的替代品, 并且比它功能强大, 是大多数Linux发行版上默认的ctags程序. 那么tags文件是做什么用的呢? 如果你在读程序时看了一个函数调用, 或者一个变量, 或者一个宏等等, 你想知道它们的定义在哪儿, 怎么办呢? 用grep? 那会搜出很多不相干的地方. 现在流行用是的"Ctrl+]", 谁用谁知道呀, 当光标在某个函数或变量上时, 按下"Ctrl+]", 光标会自动跳转到其定义处。

常规的标记命令为 ctags -R。"-R"表示递归创建,也就包括源代码根目录下的所有子目录下的源程序。 绝大多数Unix系统上都会预装这个程序。 ctags的功能:扫描指定的源文件,找出其中所包含的语法元素,并将找到的相关内容记录下来。

1.ctags可以识别哪些语言,是如何识别的

ctags识别很多语言,可以用如下命令来查看(注记:下图没截全): ctags --list-languages

2. ctags是可以根据文件的扩展名以及文件名的形式来确定该文件中是何种语言,从而使用正确的分析器。可以使用如下命令来查看默认哪些扩展名对应哪些语言:

ctags --list-maps

3.ctags可以识别和记录哪些语法元素

可以用如下命令查看ctags可以识别的语法元素: ctags --list-kinds 或者单独查看可以识别的c++的语法元素 ctags --list-kinds=c++

主要使用的选项:

1. -R

表示扫描当前目录及所有子目录(递归向下)中的源文件。并不是所有文件ctags都会扫描,如果用户没有特别指明,则ctags根据文件的扩展名来决定是否要扫描该文件——如果ctags可以根据文件的扩展名可以判断出该文件所使用的语言,则ctags会扫描该文件。

默认对当前目录进行递归遍历,符号链接也会递归进去遍历。可以使用L参数来指定文件列表。

2. -–languages=c++

只扫描文件内容判定为c++的文件——即ctags观察文件扩展名,如果扩展名对应c++,则扫描该文件。反之如果某个文件叫aaa.py(python文件),则该文件不会被扫描。

指定生成标记的语言,列表包含逗号分隔的语言名称列表(不区分大小写;内置的或用户自定义语言类型)。 如果列表的第一种语言没有以“ +”或“-”开头,则将在添加或删除列表中的语言之前清除当前列表。在遇到“-”之前,列表中的每种语言都将添加到当前列表中。由于在列表中遇到“ +”或“-”时,其后的语言将被添加到当前列表中或从当前列表中删除。因此,用新列表替换当前列表,或从当前列表中添加或删除语言变得很简单。 因此–languages=c++为先把当前列表清空,然后添加c++进当前列表

将要生成标签的文件的实际列表取决于有效的语言扩展名映射(请参见–langmap选项)。 因为是先根据选中的语言类型,决定有那些文件后缀 如–languages=c++有如下后缀,再根据这些后缀决定哪些文件用来生成tags

注意,除非使用此选项明确禁用某些语言,否则将启用所有语言,包括用户定义的语言。列表中包含的语言名称可以是任何内置语言,也可以是以前使用–langdef定义的一种语言。默认值为“ all”,也被接受为有效参数。 有关内置语言名称的完整列表,请参见–list-languages选项。

3. --c+±kinds=+px

ctags识别很多元素,但未必全都记录,例如“函数声明”这一语法元素默认是不记录的,可以控制ctags记录的语法元素的种类。如下命令要求ctags记录c++文件中的函数声明和各种外部和前向声明: 一个例子 ctags -R --languages=c++ --langmap=c++:+.inl -h +.inl --c+±kinds=+px --fields=+aiKSz --extra=+q --exclude=lex.yy.cc --exclude=copy_lex.yy.cc

请注意,可以省略长格式选项(以“-”开头并带有“ [= yes | no]”参数的布尔值)的布尔参数,在这种情况下,意味着“ = yes”。 (例如–sort等价于–sort = yes)。 还要注意,“ = 1”和“ = on”被认为是“= yes”的同义词,而“ = 0”和“ = off”被认为是“ = no”的同义词。如-R(–recurse)参数。

有些选项仅在以etags模式运行时使用时才被忽略或有用(请参阅-e选项)。 这些选项将被注意。

大多数选项可能会出现在命令行的任何位置,仅影响该选项后的那些文件。 但是,一些选项必须出现在第一个文件名之前,并且将这样指出。带有语言名称的选项将接受大小写的名称。有关内置语言名称的完整列表,请参见–list-languages选项。

4. –-langmap=c++:+.inl

告知ctags,以inl为扩展名的文件是c++语言写的,在加之上述2中的选项,即要求ctags以c++语法扫描以inl为扩展名的文件。

控制文件名如何映射到语言(请参见–list-maps选项)。每个逗号分隔的映射均由语言名称(内置或用户自定义的语言),冒号以及文件扩展名和/或文件名pattern的列表组成。通过在扩展名前加句点(例如“ .c”)来指定文件扩展名。通过将文件名pattern放在括号中来指定文件名模式,例如 ([Mm] akefile) 。 如果C编译器的运行时库(runtime library)提供了适当的支持,则文件名模式可能包含Unix上常见的常规Shell通配符,在传递给ctags之前,一定要把参数用双引号括起来(quote the option parameter)以保护通配符不被shell展开。 您可以通过检查–version选项的输出来确定shell通配符在您的平台上是否可用,该选项在已编译的功能列表中将包括“ +通配符”;否则,使用简单的文本比较将文件名模式与文件名进行匹配。

使用该选项映射文件扩展名到语言时,将首先将其与任何其他语言解除映射。

如果映射中的第一个字符是加号,则该映射中的扩展名和文件名模式将附加到该语言的当前映射中;例如,要指定仅将扩展名为.c和.x的文件视为C语言文件,请使用 --langmap = c:.c.x ;还要将扩展名为.j的文件添加为Java语言文件,请指定 --langmap = c:.c.x,java:+.j。

要将生成文件(例如,文件名为Makefile、makefile或扩展名为.mak的文件映射到一种名为make的语言,请指定 --langmap = make:([[Mm]akefile).mak。 要映射没有扩展名的文件,请指定一个句点,该句点后不能紧跟非句点字符,例如".", “…x”,".x." 要清除特定语言的映射(从而禁止自动生成该语言的标记),请指定一个空的扩展名列表(例如 --langmap = fortran:)。 要恢复所有特定语言的默认语言映射,请为映射提供关键字“默认”。要指定恢复所有语言的默认语言映射,请指定 --langmap = default。 请注意,在推断文件的语言时,文件扩展名会先于文件名模式进行测试。

5. -h +.inl

告知ctags,把以inl为扩展名的文件看作是头文件的一种(inl文件中放的是inline函数的定义,本来就是为了被include的)。这样ctags在扫描inl文件时,就算里面有static的全局变量,ctags在记录时也不会标明说该变量是局限于本文件的(见第一节描述)。

指定以句点分隔的文件扩展名列表,这些文件扩展名将被解释为include文件或header文件。要表示没有扩展名的文件,请使用不带非句点字符的句点(例如".", “…x”, “.x.”)。

此选项仅影响特定类型标记的作用域的解释方式(即,是否将它们视为全局可见或仅在定义它们的文件中可见);它不会将扩展名映射到任何特定语言。位于非包含文件中并且无法从另一个文件中看到(例如链接到)的任何标签都被认为具有文件限制范围。包含文件中出现的任何标记都不会被视为具有文件限制范围。

如果列表中的第一个字符是加号,则列表中的扩展名将附加到当前列表中;否则,列表中的扩展名将附加到当前列表中。否则,该列表将替换当前列表。 另请参见–file-scope选项。默认列表是".h.H.hh.hpp.hxx.h++.inc.def"。要恢复默认列表,请指定-h default。 请注意,如果此选项提供的扩展名尚未映射到特定语言,则还需要使用–langmap或–language-force选项。

6. –c+±kinds=+px

记录类型为函数声明和前向声明的语法元素。

指定将哪些类型的tag包含在输出文件中(不同语言有不同类型的tag) 其中不区分大小写,并且是内置语言名称之一(请参阅–list- 语言选项以获取完整列表)。 参数kinds是一组单字母标志,用于指定要包括在输出中或从输出中排除的各种标记(特定于语言)。可以使用–list-kinds选项列出每种语言可识别的特定标志集,其含义和默认值。 有off提示的tag类型默认为不输出,否则默认是输出。

因此–c+±kinds=+px为添加显示p和x两种类型tag,即函数声明和外部声明、前向变量声明的语法元素 字母或字母组前置’+‘来添加到默认集合中,也可以前置’-'将其从默认集合中删除。如下例 in order to add prototypes and external variable declarations to the default set of tag kinds, but exclude macros, use --c-kinds=+px-d;

在没有任何前置的’+‘或’-'符号的情况下,只有明确列出的种类才会包含在输出中,即清空默认集合。 如下例 to include only tags for functions,use --c-kinds=f.

7. –fields=+aiKSz

控制每行tag entries的字段内容

指定将包含在tag文件包含在每一行中的字段(有关更多信息,请参见下面的TAGFILE FORMAT)。 参数flags是一组单字母标志,每个标志代表要包括的一种扩展字段(除非另有说明,否则默认禁用)。 前置加减号的语法跟前面几个参数一样。

8. –extra=+q

让ctags额外记录一些tag entries。 指定是否为某些类型的信息添加额外的tag entries。 参数标记是一组单字母标记,每个标记代表一种要包括在标记文件中的额外标记条目。还是使用前置 +、- 符号。 每个标志的含义如下:

f 包括每个源文件(例如“ example.c”)的基本文件名的条目,该条目指向文件的第一行。 ctags除了记录上述的各种内容之外,还可以在tags文件中记录本次扫描的各个文件,一个文件名对应一个tag entry。默认是不记录的,要强制记录可以使用如下命令: ctags –R --extra=+f

q 为属于类的每个标签包括一个额外的类限定tag entry(对于提取该信息的语言;当前为C ++,Eiffel和Java)。 合格标签的实际形式取决于标签所源自的语言(使用对于语言中指定合格呼叫的方式最自然的形式)。 对于C ++,它的形式为“ class :: member”; 对于Eiffel和Java,格式为“ class.member”。 当在tag文件中多次出现标签名称时,这可以允许更容易地定位特定标签。 但是请注意,这可能使得标记文件变为两倍以上。

如果某个语法元素是类的一个成员,当然ctags默认会给其记录一个tag entry(说白了就是在tags文件里写一行),可以要求ctags对同一个语法元素再记一行。举一个例子来说明:假设语法元素是一个成员函数,ctags默认记录的tag entry中的tag的名字就是该函数的名字(不包括类名作为前缀),而我们强制要求ctags多记的那个tag entry的tag的名字是包含了类名作为前缀的函数的全路径名。这样做有什么好处见下文分析。强制ctags给类的成员函数多记一行的命令为: ctags -R --extra=+q

估计vi是这样使用tags文件的:我们使用vi来定位某个tag时,vi根据我们输入的tag的名字在tags文件中一行行查找,判断每一行tag entry的tag名字(即每行的开头)是否和用户给出的相同,如果相同就认为找到一条记录,最后vi显示所有找到的记录,或者根据这些记录直接跳转到对应文件的特定位置。 考虑到ctags记录的内容和方式,出现同名的tag entry是很常见的现象,例如函数声明和函数定义的tag名字是一样的,重载函数的tag名字是一样的等等。vi只是使用tag名字来搜索,还没智能到可以根据函数的signature来选择相应的tag entry。vi只能简单的显示tag entry的内容给user,让user自行选择。 ctags在记录成员函数时默认是把函数的名字(仅仅是函数的名字,不带任何类名和namespace作为前缀)作为tag的名字的,这样就导致很多不同类但同名的函数所对应的tag entry的名字都是一样的,这样user在vi中使用函数名来定位时就会出现暴多选择,挑选起来十分麻烦。user可能会想在vi中用函数的全路径名来进行定位,但这样做会失败,因为tags文件中没有对应名字的tag entry。要满足用户的这种心思,就要求ctags在记录时针对类的成员多记录一条tag entry,该tag entry和已有的tag entry的内容都相同,除了tag的名字不同,该tag entry的名字是类的成员的全路径名(包括了命名空间和类名)。这就解释了ctags的–extra=+q这样一条命令行选项

–exclude=lex.yy.cc --exclude=copy_lex.yy.cc 告知ctags不要扫描名字是这样的文件。还可以控制ctags不要扫描指定目录,这里就不细说了。

ctags -R //递归记录 --languages=c++ //只扫描文件内容判定为c++的文件 --c+±kinds=+px //记录c++文件中的函数声明和各种外部和前向声明 --langmap=c++:+.inl //以inl为扩展名的文件是c++文件 -h +.inl //以inl为扩展名的文件看作是头文件的一种 --fields=+aiKSz --extra=+q --exclude=lex.yy.cc --exclude=copy_lex.yy.cc

使用ctags仅需记住下面几条命令: 1. ctags –R * 2. vi –t tag (请把tag替换为您欲查找的变量或函数名) 3. Ctrl + ] (跳转到要找的目标) 4. Ctrl + T (回跳) 5. set tag=/path/tags(vi 底行模式下设置目标tags) 命令说明:

“$ ctags –R ”:“-R”表示递归创建,也就包括源代码根目录(当前目录)下的所有子目录。“”表示所有文件。这条命令会在当前目录下产生一个“tags”文件Tags文件中包括这些对象的列表: 用#define定义的宏 枚举型变量的值 函数的定义、原型和声明名 类型定义(typedefs) 变量(包括定义和声明) 类(class)、结构(struct)、枚举类型(enum)和联合(union) 类、结构和联合中成员变量或函数 VIM用这个“tags”文件来定位上面这些做了标记的对象。

使用实例: 1.进入/usr/include目录下 2.ctags –R *(等待生成tags,之后可以发现目录中多了tags文件) 3.vi –t termios(termios是我们要找的结构体) 4.这是你可以试试 Ctrl + ] Ctrl + T 还可以这样用: 比如我在我的工程文件中生成tags 1.ctags –R * 2. 在底行模式下:set tag=/path/tags,/path2/tags(同时制定多个文件中的tags) 使用Ctrl + ] Ctrl + T这样的话就可以查找当前文件中的一些函数,也可以tselect name(需要找的函数名)来查看



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有