ChatGPT解决这个技术问题 Extra ChatGPT

Emacs 标签:etags、ebrowse、cscope、GNU Global 和 exuberant ctags 之间的关系

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

etags、ebrowse、exuberant ctags、cscope、GNU Global 和 GTags 之间有什么区别(例如在功能方面)?我需要做什么才能在 Emacs 中使用它们?如果我想使用标签来导航/自动完成符号,我是否需要语义/参议员 (CEDET)?在这些不同的标签实用程序之上,语义带来了什么?它如何与这些工具交互?

the trunk 来看,您链接到的 GTags 项目已经死了。如果有人在谈论gtags,他们可能指的是 GNU Global。
Universal Ctags(Exuberant Ctags 的维护分支)添加到组合中:) ggtags 是用于此目的的 Emacs 包。

B
Bozhidar Batsov

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

第 1 点:

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

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

把它们加起来:

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

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

转到符号的声明

显示对符号的所有引用的可选列表

搜索任何全局定义

函数调用的函数

函数调用函数

搜索文本字符串

搜索正则表达式模式

查找文件

查找包括文件在内的所有文件

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

第 2 点。

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

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

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

第 3 点。

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

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

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


这很棒。谢谢!你知道如何在 Emacs 中使用 cscope 吗?我在 EmacsWiki here 上阅读了有关 xcscope.el 的信息,但找不到该文件的链接。另外,您使用哪个 .el 文件通过 Emacs 获取 cscope
xcscope.el 位于 cscope/contrib/xcscope/(在分发包中)。这就是我使用的。
还有一个问题:semanticcscope 相比如何?在浏览源代码方面,语义是否提供了 cscope 没有的任何功能?你两个都用吗?
顺便说一句,我不相信 GNU Global 使用 etags。 IIRC 它维护和查询一个“适当的”数据库(而不是扫描一个平面文本文件),这对于查询和(尤其是)更新标签具有许多性能优势。
@BozhidarBatsov 当您说For languages where semantic is not enabled by default, you can add the following line to your major mode hook of choice ... <code>时。该代码片段究竟做了什么?
l
legends2k

我将尝试在 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 种语言。

祝你好运!


对于 Debian 和 Ubuntu 等衍生产品的用户:GNU GLOBAL 网页警告说,这些 Linux 发行版附带的 .deb 软件包已过时,不应使用。就我而言,GLOBAL 的版本为 5.7.1,我无法让 gtags.el、ggtags.el 或 helm-gtags.el 在 Emacs 24 上正常工作。从头开始编译 GNU GLOBAL 6.5,支持 Exuberant Ctags (我用了 5.8) 很好玩。 (感谢出色的指点,@shigio)。
W
Wilfred Hughes

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 文件来完成代码。例如,company's etags backend uses TAGS files

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

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

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

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

其他文件格式

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

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

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

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

另见this HN discussion comparing global and cscope

客户端/服务器项目

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

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

语义(CEDET)

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


T
TomRoche

[答案更新自 shigio 的]

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

它是什么?

Etags 生成一个 TAGS 文件,它是 Emacs 的标记文件格式。您可以将 Etags 文件与 etags.el 一起使用,它是 Emacs 的一部分。 Ctags 是任何可以生成标签文件的通用术语,它是 Vi 的原生标签文件格式。通用 Ctags(又名 UCtags,以前称为 Exuberant Ctags)也可以使用 -e 选项生成 Etags。 Cscope 是一个多合一的 C 源代码浏览工具(对 C++ 和 Java 的支持较少),具有自己的标签数据库(cscope.in.out、cscope.out、cscope.po.out)和 TUI。 Vim 内置了 Cscope 支持;您可以使用 xcscope.el 包从 Emacs 中使用 Cscope。还有基于 Cscope 的 GUI。 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 浏览器使用。

Gtags 通过 GLOBAL 包提供 gtags.el,但也有许多其他的 elisp 扩展,包括 xgtags.el、ggtags.el、anything-gtags.el、helm-gtags.el。

组合

通过将 Ctags 用作 GLOBAL plug-in parser,您可以将 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

祝你好运!


我读到:“再次注意,如果您使用 Ctags 作为 Gtags 的解析器,您将失去处理 Gtags 否则会提供的引用(例如,变量使用、函数调用)的能力。本质上,您将 Gtags 的引用跟踪用于Ctags 更强大的内置语言支持。”对于 Emacs 附带的旧 ctags 是否如此,或者对于 Universal Ctags 仍然如此?此外,我阅读了“结合 Universal Ctag 的丰富语言”,但在 shell 片段中它使用 --with-exuberant-ctags=...,而现在截至 2019 年有一个 --with-universal-ctags 选项。是否应该改为后者?
C
Clément B.

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

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

 (semanticdb-enable-cscope-databases)

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

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


这似乎在 Emacs 24.3.1 中不起作用,使用它附带的 vanilla CEDET 2.0(没有语义数据库启用 cscope 数据库方法)。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅