Citre: 先进的 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。如果我误解了,请指正。

我以为 --append 是增量更新的?如果没有增量更新,我感觉会给大项目带来不便,因为每次重新生成 tags 文件耗时还是蛮久的,不过这种情况下,确实也没必要频繁更新 tags

--append 就是把扫描到的 tag 附加到已存在的 tags 文件里,并不是增量更新。

这个选项可能看起来比较鸡肋,但是也是实现增量更新所需要的。关于增量更新的讨论,参见 Proposal: A possible way of incrementally updating tags file · Issue #2697 · universal-ctags/ctags · GitHub

你说得对。这种就是「没有也能用,但有比没有好」的情况。

但我可以告诉你 masatake 自己是怎么做的。他用 crontab 之类的东西写了个定时任务,每天更新一次内核的 tags。

3 个赞

可以在 emacs-devel 发个投票帖问一下,还是非常期待能够进入 Emacs Core 的

1 个赞

Wow! Wow! 楼主也太强了吧,感谢楼主

如果用上 ctags+citre,还需要查找引用的需求,有什么建议呢?

我个人需要查引用的时候就直接 grep。

我想关键不是「我们要用什么工具来查引用」,而是「我们要通过查引用来做到什么」。你需要的工具是你的目的决定的。这楼是个很好的例子。

我一直觉得查引用除了在批量改名的时候好像就没什么用,所以用 grep 就够了。

如果你已经知道了自己的目的,我很想听听,这有助于我改进 Citre 或者设计新的工具。

2 个赞

用grep确实能完成查引用的功能,只是有时完成的不够好。

有时由于代码风格的问题,部分函数名会在已有的函数上加后缀,比如:function_a,function_a_for_arm,function_a_for_x86。有时log打印中也会有函数名的现象,用grep搜索function_a的引用的话,搜索结果不太好,需要一个个去识别。当然grep+正则可能能解决这类问题,但还是不如直接查找引用来的方便,准确。

单层的查引用 grep/rg 确实够用了。我自己使用引用主要是为了快速确定执行路径,此时建立多层的引用关系和过滤是最主要的功能。

这里两篇文章讲述了通过 calltree.pl 阅读代码。

2 个赞

这种搜索一个 function_a\s*\( 就好了,也不用每次都打一遍,你可以自己包装个命令嘛。我感觉这个还不至于让我觉得一定要一个查引用的工具。

那要针对这些语言写citre扩展吗? 我看到源码config只做了c语言的扩展