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

我在C ++项目上工作,我经历了Alex Ott的CEDET指南以及其他有关StackOverflow中标签的主题,但是我仍然对Emacs如何与这些不同的标签系统进行交互以简化自动完成,查找定义,源代码导航代码库或预览文档string。

  1. etagsebrowseexuberant ctagscscopeGNU GlobalGTags之间有什么区别(例如特征)? 我需要做些什么来在Emacs中使用它们?

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

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

这是我最近在这里阅读的一个很好的问题,所以我会尝试更详细地解释它们之间的区别:

要点1:

etagsctags都会生成源文件中find的语言对象的索引(aka tag / TAGS)文件,这些文件允许通过文本编辑器或其他实用程序快速方便地定位这些项目。 标记表示可用索引条目的语言对象(或者,为该对象创build的索引条目)。 由ctags生成的标签在元数据方面更丰富,但Emacs无法解释额外的数据,所以你应该考虑它们差不多( ctags的主要优势在于它支持更多的语言)。 标签文件的主要用途是查找类/方法/函数/常量/等声明/定义。

cscope是更强大的野兽(至less就C / C ++和Java而言)。 虽然它或多或less地运行相同的原理(生成一个有用的元数据文件),但它允许你做一些更有趣的事情,比如find一个符号的所有引用,查看函数被调用的地方等等(你也可以find定义) 。

把它们加起来:

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

另一方面(如项目页面中提到的) cscope允许您:

  • 去一个符号的声明
  • 显示一个符号的所有引用的可选列表
  • search任何全局定义
  • 函数调用的函数
  • 调用函数的函数
  • search文本string
  • search正则expression式模式
  • find一个文件
  • 查找包括文件的所有文件

在这一点上,任何人都不应该感到惊讶的是,当我处理C / C ++项目时,我大量使用cscope并且对ctags关心很less。 在处理其他语言时,情况显然会被扭转。

第2点

要有智能的自动完成,你需要一个真正的源代码parsing器 (比如语义),否则你将不会知道你的应用程序中的对象types(例如)以及可以调用的方法。 你可以有一个基于许多不同来源的自动完成,但为了得到最好的结果,你最终需要一个parsing器。 语法突出同样如此 – 当前Emacs主要模式中的语法突出显示仅基于正则expression式,而且非常脆弱且容易出错。 希望在Emacs 23.2中包含语义(之前曾经是一个外部包),我们将开始看到更多的用法(比如使用它来分析缓冲区源代码以正确地突出显示它)

由于Emacs 24.1语义在Emacs完成框架中可用。 testing它的最简单的方法是打开一个C源代码文件并inputM-TABCMi,然后以语义自动完成。 对于缺省情况下未启用语义的语言,可以将以下行添加到主要模式的select钩子:

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

第3点

语义带来了真正的代码意识(对于目前支持的几种语言),并缩小了IDE和Emacs之间的差距。 它并不真正与etagscscope等工具接口,但这并不意味着你不能一起使用它们。

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

PS我不是很熟悉globalebrowse ,但如果记忆为我服务,他们使用etags。

我会尝试添加一些解释1。

它是什么?

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

对照

  • Ctags和etags只处理定义。 Cscope和GNU GLOBAL不仅要处理定义,而且要处理引用。
  • 标签和etags使用一个扁平的文本标签文件。 Cscope和GNU GLOBAL使用键值标记数据库。
  • Cscope和GNU GLOBAL有一个类似grep的search引擎和标签文件的增量更新function。

组合

您可以使用ctags作为GLOBAL的插件parsing器,将Exuberant Ctags丰富的语言支持和GNU GLOBAL的数据库设施结合起来。

尝试以下操作:(需要GLOBAL-6.0,Exuberant Ctags-5.5或更高版本)

构buildGNU GLOBAL:

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

用法:

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

(但是,你不能用这个方法来处理引用,因为ctags不会处理引用。)

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

 $ gtags-cscope # this is GLOBAL version of cscope 

有了这些组合,你可以使用41种语言的cscope。

祝你好运!

标签文件包含定义

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

 ^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定义。 基本导航内置了find-tag ,但etags-select在有多个匹配时提供了更好的UI。

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

标签文件可以由不同的工具build立

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

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

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

其他文件格式

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

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

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

Cscope在精神上与GNU Global相似:它将C / C ++分析成自己的数据库格式。 它也可以回答“find所有这个function的来电者/被调用者”的问题。

另请参阅HN讨论比较全球和cscope 。

客户端/服务器项目

rtags使用持久服务器parsing和索引C / C ++。 它使用了clangparsing器,所以它很好地处理了C ++。 它附带一个Emacs包来查询服务器。

谷歌gtags是一个大型标签文件将存储在服务器上的项目。 当您查询服务器时,它将提供与您的search相关的TAGS文件的子集。

语义(CEDET)

语义是一个内置的Emacs包,它包含一个C / C ++parsing器,所以它也可以find定义。 它也可以从TAGS文件,csope数据库和其他来源导入数据。 CEDET还包含使用此数据的IDE样式function,例如生成类层次结构的UML图。

[从shigio的更新]

我会试着在问题的第一部分加上一些解释。

它是什么?

  1. Etags生成一个TAGS文件,这是Emacs的标签文件格式 。 您可以使用Etags文件和etags.el ,它是Emacs的一部分。
  2. Ctags是任何可以生成tags文件的通用术语,它是Vi的本地标签文件格式。 通用Ctags (又名UCtags ,以前的UCtags Ctags)也可以用-e选项生成Etags。
  3. Cscope是C语言的全function源代码浏览工具(具有较less的C ++和Java支持),具有自己的标签数据库( cscope.in.outcscope.outcscope.po.out )和TUI 。 Vim内置了Cscope支持; 您可以使用xcscope.el包使用Emacs中的Cscope。 还有基于Cscope的GUI 。
  4. GNU GLOBAL (又名Gtags )是另一个源代码标记系统(具有显着差异 – 请参见下一节),因为它也生成标记文件。

对照

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

组合

通过使用Ctags作为GLOBAL插件parsing器,您可以将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的parsing器,那么你将失去处理引用的能力(例如,variables的使用,函数调用),否则Gtags会提供这种能力。 从本质上讲,您可以将Gtags的参考追踪与Ctags更大的内置语言支持进行权衡。

您也可以使用Cscope作为Gtags的客户端: gtags-cscope

祝你好运!

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

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

  (semanticdb-enable-cscope-databases) 

这将使所有C和C ++缓冲区都可以使用cscope。

当预先存在的语义数据库search可能没有parsing所有文件时,CScope将用于项目范围的search作为备份。

Interesting Posts