Citre: 先进的 Ctags 前端

我试用了一下,就算在 LLVM 这种大项目下速度也还是非常快。LZ 不考虑给 Emacs 28 贡献一下嘛,例如把这个功能实现成一个 ctags.el,这样就能把以前 Emacs 自带的那个 etags 给废弃了。

感觉回复,这个问题解决了

还没试用。

既然支持编辑相关的功能(自动补全),那是不是考虑支持自动更新tags文件?大概看了下代码,没发现有这功能。

祝你用得开心 :wink:

关于进 Emacs 这件事,其实我也考虑过。我想做的是把 citre-core.el 分离出来,作为一个 readtags 抽象层并入 Emacs(masatake 也和我说过这个想法)。这样别人也可以基于这个东西开发各种各样的工具。但 readtags 并不是像 grep 那样流行的程序,我想 Emacs 很可能不会想要这个东西。

而且 Citre 要求使用 Universal Ctags 的 readtags。Exuberant Ctags 其实也带一个 readtags,但缺少利用类 Scheme 表达式进行过滤和排序的关键特性。考虑到仍然有很多人使用 Exuberant Ctags,如果我被要求支持这个 readtags 的话,很多事情就没法做了。

其他的做法,像是做一个利用 Emacs 自带功能读 tags 文件的东西,或者做一个 xref 的 ctags 后端,我觉得意义不大,不如直接用 Citre。

ctags-e选项保证生成的TAGS文件和etags是兼容的。我建议不要再使用etags了。etags生成的TAGS文件的行可能有两种格式。一种通用的格式是ctags也会生成的。另一种老的格式ctags不会生成。麻烦在于emacs插件为了兼容老的格式,导致搜索速度慢4倍。

2 个赞

我认为这个没有必要。

利用 tags 文件,可以基于行号和 search pattern 来定位 tag 所在位置。search pattern 保证了即使文件被编辑过,我们仍然能找到需要的那一行。Citre 甚至会尝试在这一行本身被编辑过的情况下找到它。

我在使用中的感觉也是,基本上文件编辑过以后也不影响跳转的准确性。

我建议在项目的 Makefile(或者自己再新建一个 makefile 并在版本管理系统中排除)中添加一个生成 tags 的 target,然后包装一个命令来运行它。需要的时候手动升级就好。

如果你认为自动更新很重要的话,我想听听你的理由 :wink:

1 个赞

Yes. 其实 tags 格式相比 TAGS 格式有相当多的优势,请参考这一楼:Citre: 先进的 Ctags 前端 - #24,来自 kinono

主要是为了方便。

编辑可能会删/增/改,一是会导致已有的tag失效,二是新增/被修改的tag不能及时反映到自动补全/跳转中。我的理解是这两点是你说的“基于行号和search pattern”无能为力的。

当然,因为有你说的利用makefile或者直接执行命令来更新tags,所以在Citre里添加支持的必要性和急迫性都不高。

这种情况确实需要更新 tags。但一般一个项目大到需要索引的程度的时候,改一会也不会造成显著的准确性失效。注意到出问题的时候,执行一个命令更新一下也不麻烦。

赞一个,日常偶尔也会需要阅读c代码。不过我是使用gtags+ggtags。不知道跟ctags哪个好用点?

我不熟悉 gtags,就随便说说我自己的认识,有错误请多包涵

Ctags 的优势:

  • 最重要的一点仍然是信息丰富,请参考这一楼。就我所知,gtags 格式内含的信息应该和 TAGS 格式差不多。
  • 基于上一点,Citre 可以利用 readtags 通过各种条件来过滤 tags,因此 Citre 能够设计出更有利于我们理解代码的工具。gtags 的命令行界面与 readtags 相比很简陋,不能支持 Citre 这种级别的工具。
  • Ctags 现在还在活跃开发,支持的语言更多(不过据我所知 Ctags 可以作为 gtags 的插件使用,所以这一点不要紧)
  • Citre 有 citre-peek 这个小神器 :wink: 我觉得这个就足够作为转用 Ctags 的理由了。

gtags 的优势:

另外,gtags 的索引是二进制格式,tags 文件是纯文本,但可以做二分搜索。我也不太清楚二者搜索起来哪种比较快,但我个人的经验(还有楼上的体验)是 ctags 在巨型项目里是足够快的。

3 个赞

可以提供一些命令方便用户操作,projectile就有 projectile-regenerate-tags

1 个赞

试了一下,不知道怎么让自动补全工作?jump是可以的,LZ真的强啊

自动补全用的是标准的 completion-at-point 界面。按 C-M-i(就是 completion-at-point 命令)或者用 company 的 capf 后端都是可以的。

PS:citre-jump 是给已经熟悉类似界面然后懒得改的人用的,我更推荐 citre-peek

ctags只能用c语言吗?像python和javascript支持吗?

支持,还支持你爱用的 Ruby、Elisp 和 Haskell :wink:

最新的 Universal Ctags 支持 134 种语言:

$ ctags --list-languages | wc -l
134

当然里面不少是标记语言,还有 diff,SVG 之类的一些东西。我目测编程语言应该在四十种以上,流行的语言肯定都包含了。

Universal Ctags 的开发很活跃,今年还加了 Julia 支持。

2 个赞

感觉可以入坑了,lsp这玩意儿真是太复杂了,核心的功能不好用,不想要的功能一大堆。

2 个赞

欢迎!:partying_face: 希望 Citre 能让你开心 :wink:

另外,Ctags 这个项目并不复杂,我不熟悉 C,但也给 Julia 的 Parser 提交过比较重要的 Patch。如果你来玩的话,我估计想让 Ctags 支持什么语言都可以办到 :wink:

projectile 提供了生成 tag 的功能(projectile-regenerate-tags),而且 ctags 有增量更新的选项,可以在文档里补充一下 :+1:

我看了这个实现,感觉不是很好。它直接用一个变量来存储 Ctags 命令,但实际上 Ctags 命令要根据工程的需要来调整。我已经知道大家想要这么个工具了,会做的 :wink:

据我所知是没有。我知道部分 vim 插件提供了这个功能,但那个是它们自己的 Hack。如果我误解了,请指正。