111

我从事 C++ 项目,我浏览了 Alex Ott 的CEDET 指南和关于 StackOverflow 中标签的其他线程,但我仍然对 Emacs 如何与这些不同的标签系统接口以促进自动完成、查找定义、导航源感到困惑代码库或文档字符串的预览。

  1. etagsebrowseexuberant ctagscscopeGNU Global之间有什么区别(例如在特征方面) GTags?我需要做什么才能在Emacs中使用它们?

  2. 如果我想使用标签来导航/自动完成符号,我是否需要语义/参议员 (CEDET)?

  3. 在这些不同的标签实用程序之上,语义带来了什么?它如何与这些工具交互?

4

5 回答 5

73

这是我最近在这里读到的一个好问题,所以我将尝试更详细地解释差异:

第 1 点:

etags并且ctags两者都生成在源文件中找到的语言对象的索引(又名标签/标签)文件,允许文本编辑器或其他实用程序快速轻松地找到这些项目。标记表示可以使用索引条目的语言对象(或者,为该对象创建的索引条目)。ctags 生成的标签在元数据方面更丰富,但 Emacs 无论如何都无法解释额外的数据,因此您应该认为它们或多或少相同(主要优点ctags是它支持更多语言)。标签文件的主要用途是查找类/方法/函数/常量/等声明/定义。

cscope是更强大的野兽(至少就 C/C++ 和 Java 而言)。虽然它的工作原理或多或少相同(生成有用的元数据文件),但它允许您做一些更奇特的事情,例如查找对符号的所有引用,查看调用函数的位置等(您也可以找到定义) .

把它们加起来:

ctags一个允许您导航到符号声明/定义(有些人称之为单向查找)。ctags是适用于多种语言的通用工具。

另一方面(如项目页面所述)cscope允许您:

  • 转到符号的声明
  • 显示对符号的所有引用的可选列表
  • 搜索任何全局定义
  • 函数调用的函数
  • 函数调用函数
  • 搜索文本字符串
  • 搜索正则表达式模式
  • 查找文件
  • 查找包括文件在内的所有文件

在这一点上,任何人都不会感到惊讶,当我处理 C/C++ 项目时,我大量使用cscope并且很少关心ctags. 在处理其他语言时,情况显然会相反。

第 2 点。

要实现智能自动完成,您需要一个真正的源代码解析器(如语义),否则您将不知道应用程序中对象(例如)的类型以及可以在它们上调用的方法。您可以根据许多不同的来源进行自动补全,但要获得最佳结果,您最终需要一个解析器。语法高亮也是如此——目前 Emacs 主要模式中的语法高亮仅基于正则表达式,这非常脆弱且容易出错。希望通过在 Emacs 23.2 中包含语义(在此之前它曾经是一个外部包),我们将开始看到它的更多用途(比如使用它来分析缓冲区源代码以正确突出显示它)

由于 Emacs 24.1 语义可以从 Emacs 完成框架中使用。测试它的最简单方法是打开一个 C 源代码文件并键入M-TABorC-M-i并观察语义自动为您完成。对于默认情况下未启用语义的语言,您可以将以下行添加到您选择的主要模式挂钩中:

(add-to-list 'completion-at-point-functions 'semantic-completion-at-point-function)

第 3 点。

语义带来了真正的代码意识(对于它目前支持的少数语言)并缩小了 IDE 和 Emacs 之间的差距。它并没有真正与 和 之类的工具交互etagscscope但这并不意味着您不能将它们一起使用。

希望我的解释有意义,对你有用。

PS 我对 and 不太熟悉globalebrowse但如果没记错的话,他们使用了 etags。

于 2012-10-16T21:50:46.823 回答
46

我将尝试在 1 中添加一些解释。

它是什么?

  • Etags 是一个生成“TAGS”文件的命令,该文件是 Emacs 的标记文件。您可以将该文件与 etags.el 一起使用,它是 emacs 包的一部分。
  • Ctags 是一个生成“标签”文件的命令,它是 vi 的标签文件。Universal Ctags,Exuberant Ctags的继承者,可以通过-e选项生成'TAGS'文件,支持超过41种编程语言。
  • Cscope 是一个用于 C 语言的一体化源代码浏览工具。它拥有自己的精美 CUI(字符用户界面)和标签数据库(cscope.in.out、cscope.out、cscope.po.out)。您可以使用 Emacs 中的 cscope 使用 xcscope.el,它是 cscope 包的一部分。
  • GNU GLOBAL 是一个源代码标记系统。虽然它与上述工具相似,但它与它们的不同之处在于它依赖于任何编辑器,并且它除了命令行之外没有用户界面。Gtags 是为 GLOBAL(GTAGS、GRTAGS、GPATH)生成标签文件的命令。您可以使用 gtags.el 从 emacs 使用 GLOBAL,它是 GLOBAL 包的一部分。除此之外,还有许多 elisp 库(xgtags.el、ggtags.el、anything-gtags.el、helm-gtags.el 等)。

比较

  • Ctags 和 etags 只处理定义。Cscope 和 GNU GLOBAL 不仅处理定义,还处理引用。
  • Ctags 和 etags 使用纯文本标记文件。Cscope 和 GNU GLOBAL 使用键值标签数据库。
  • Cscope 和 GNU GLOBAL 具有类似 grep 的搜索引擎和标记文件的增量更新工具。

组合

通过将 ctags 用作 GLOBAL 的插件解析器,您可以将 Universal Ctags 的丰富语言支持和 GNU GLOBAL 的数据库工具结合起来。

尝试以下操作:(分别需要 GLOBAL-6.5.3+ 和 Universal Ctags)

构建 GNU GLOBAL:

$ ./configure --with-universal-ctags=/usr/local/bin/ctags
$ sudo make install

用法:

$ export GTAGSCONF=/usr/local/share/gtags/gtags.conf
$ export GTAGSLABEL=new-ctags
$ gtags                     # invokes Universal Ctags internally
$ emacs -f gtags-mode       # load gtags.el

(但是,您不能通过此方法处理引用,因为 ctags 不处理引用。)

您还可以将 cscope 用作 GNU GLOBAL 的客户端。GLOBAL 包包含一个名为“gtags-cscope”的命令,它是 cscope 的一个端口,也就是说,它是 cscope 本身,只是它使用 GLOBAL 作为搜索引擎而不是 cscope 的搜索引擎。

$ gtags-cscope          # this is GLOBAL version of cscope

通过这些组合,您可以将 cscope 用于 41 种语言。

祝你好运!

于 2013-03-02T01:18:17.063 回答
9

TAGS 文件包含定义

文件TAGS包含定义函数和类的列表。它通常放在项目的根目录中,如下所示:

^L
configure,3945
as_fn_success () { as_fn_return 0; }^?as_fn_success^A180,5465
as_fn_failure () { as_fn_return 1; }^?as_fn_failure^A181,5502
as_fn_ret_success () { return 0; }^?as_fn_ret_success^A182,5539
as_fn_ret_failure () { return 1; }^?as_fn_ret_failure^A183,5574

这使 Emacs 能够找到定义。基本导航是内置的find-tag,但etags-select在有多个匹配项时提供更好的 UI。

您还可以使用 TAGS 文件来完成代码。例如,公司的 etags 后端使用 TAGS 文件

TAGS文件可以通过不同的工具构建

ctags(以前称为 'universal ctags' 或 'exuberant ctags')可以生成 TAGS 文件并支持最广泛的语言。它在 github 上积极维护。

Emacs 附带了两个生成 TAGS 文件的程序,分别称为etagsctags. Emacsctagsetags通用 ctags 具有相同的 CLI 界面。为避免混淆,许多发行版重命名这些程序(例如ctags.emacs24在 Debian 上)。

还有用于生成 TAGS 文件的特定语言工具,例如jsctagshasktags.

其他文件格式

ebrowse是 Emacs 附带的 C 程序。它索引 C/C++ 代码并生成BROWSE文件。ebrowse.el 提供通常的查找定义和补全。您也可以BROWSE直接在 Emacs 中打开该文件,以获取定义代码库的类/函数的概览。

GNU Global有自己的数据库格式,由GTAGS,GRTAGSGPATH文件组成。gtags您可以使用解析 C/C++ 代码的命令生成这些文件。对于其他语言,GNU Global 可以读取由通用 ctags 生成的文件。

GNU Global 还提供了一个 CLI 界面来询问更复杂的问题,例如“这个符号在哪里提到?”。它附带一个 Emacs 包 gtags.el,但ggtags.el也很流行用于访问 GNU 全球数据库。

Cscope在精神上类似于 GNU Global:它将 C/C++ 解析为自己的数据库格式。它还可以回答诸如“查找此功能的所有调用者/被调用者”之类的问题。

另请参阅比较 global 和 cscope 的此 HN 讨论

客户端/服务器项目

rtags使用持久服务器解析和索引 C/C++。它使用 clang 解析器,因此它可以很好地处理 C++。它附带一个 Emacs 包来查询服务器。

google-gtags是一个将大型 TAGS 文件存储在服务器上的项目。当您查询服务器时,它会提供与您的搜索相关的 TAGS 文件子集。

语义(CEDET)

Semantic 是一个内置的 Emacs 包,其中包含 C/C++ 解析器,因此它也可以找到定义。它还可以从 TAGS 文件、csope 数据库和其他来源导入数据。CEDET 还包括使用此数据的 IDE 样式功能,例如生成类层次结构的 UML 图。

于 2016-03-05T14:36:25.833 回答
7

[答案从shigio更新]

我将尝试为问题的第 1 部分添加一些解释。

它是什么?

  1. Etags生成一个TAGS文件,该文件是 Emacs 的标记文件格式。您可以使用作为etags.elEmacs 一部分的 Etags 文件。
  2. Ctags是可以生成tags文件的任何东西的通用术语,它是 Vi 的原生标记文件格式。Universal Ctags(又名UCtags,以前的 Exuberant Ctags)也可以使用该-e选项生成 Etags。
  3. Cscope是一个多合一的 C 源代码浏览工具(对 C++ 和 Java 的支持较少),具有自己的标记数据库 ( cscope.in.out, cscope.out, cscope.po.out) 和TUI。Vim 内置了 Cscope 支持;您可以使用xcscope.el 包从 Emacs 中使用 Cscope 。还有基于 Cscope 的 GUI
  4. GNU GLOBAL(又名Gtags)是另一个源代码标记系统(有很大的不同——见下一节),因为它也生成标记文件。

比较

  • Ctags 和Etags 只处理定义(例如,变量和函数)。Cscope 和 Gtags 也处理引用。
  • Ctags 和 Etags 标记文件是平面的。Cscope 和 Gtags 标记文件是更强大的键值数据库,它允许(例如)增量更新。
  • Cscope 和 Gtags 有一个类似grep的搜索引擎。
  • Ctags 内置了对更多语言和数据格式的支持:请参阅通用 Ctags 解析器的当前存储库列表。UCtags 还记录了如何开发自己的解析器
  • Cscope 和 Gtags 是独立于编辑器的。
  • Gtags 不提供自己的用户界面,但目前(2016 年 10 月)可以从命令行 (CLI)、Emacs 和亲属、Vi 和亲属、less(pager)、Doxygen和任何 Web 浏览器使用。
  • Gtagsgtags.el通过 GLOBAL 包提供,但也有许多其他的 elisp 扩展,包括 xgtags.el、ggtags.el、anything-gtags.el、helm-gtags.el。

组合

通过将 Ctags 用作GLOBAL 插件解析器,您可以将 Universal Ctags 的丰富语言支持与 Gtags 的数据库工具和众多扩展相结合:

# build GNU GLOBAL
./configure --with-exuberant-ctags=/usr/local/bin/ctags
sudo make install

# use it
export GTAGSCONF=/usr/local/share/gtags/gtags.conf
export GTAGSLABEL=ctags
gtags                     # invokes Universal Ctags internally
emacs -f gtags-mode       # load gtags.el

再次注意,如果您使用 Ctags 作为 Gtags 的解析器,您将失去处理 Gtags 否则会提供的引用(例如,变量使用、函数调用)的能力。从本质上讲,您用 Gtags 的参考跟踪来换取 Ctags 更强大的内置语言支持。

您还可以将 Cscope 用作 Gtags 的客户端:gtags-cscope.

祝你好运!

于 2016-10-06T21:35:04.010 回答
3

我实际上没有检查过,但根据 CEDET 手册(http://www.randomsample.de/cedetdocs/common/cedet/CScope.html):

语义可以使用 CScope 作为数据库搜索的后端。要启用它,请使用:

 (semanticdb-enable-cscope-databases)

这将使 cscope 能够用于所有 C 和 C++ 缓冲区。

当预先存在的语义数据库搜索可能无法解析您的所有文件时,CScope 将作为备份用于项目范围的搜索。

于 2013-02-24T20:42:36.027 回答