Citre: 先进的 Ctags 前端

其实我就是想有的时候看下第三方库的源码,可能和语言有关系,我现在用 go 可以很方便跳进源码,因为本地就有存。

Anyway, 我就是随口一说, ctags 目前我觉得已经挺完美的了

1 个赞

这个的问题是需要预设一个 ctags 命令,那肯定是要写一个对大多数情况适用的 universal ctags 命令(目前我是打算这么做)。这样用户对这个工程调整过的参数就不能反映了,或者如果使用 hasktags 之类其他的 ctags 程序也就不能用了。

我本来想到现在 tags 文件自带 recipe 了,可以直接从里面读命令,但是仔细想一下,被扫描的路径也是写在命令里面的,而且没有可靠的办法把它们分离出来(特别是使用其它 ctags 程序的情况),所以还是没用了。

1 个赞

能不能始终使用当前文件指向的 project (root) 的那个tags文件里的 recipe,只是把tagging 对象替换为当前文件、生成tags的存放位置移到/tmp(用个固定的文件名就好,反正很快,每次都刷了都不会慢)。

哦哦,我说的就是这个。不能可靠分离是指?ctags|-o|%TAGSFILE%|--languages=MatLab,|--kinds-all=*|--fields=*|--extras=*|-R,就是说这段可能会非常复杂,无法简单的用正则把这些arguments找出来?那就只找个--languages好了,其它您全局写死,留个变量给用户自己修改;也挺好。

哦,能跳进(标准库、第三方库的)源码有时确实是还蛮方便的。

如果是 uctags 的话就从最后面找就行。问题是用户使用其他的 ctags 程序怎么办(比如 hasktags,gotags)不过实际上设计合理的命令行界面肯定都是把扫描路径放最后的 :rofl: 所以我觉得好像也确实能这么干 :rofl:

language 也不用,反正就一个文件,ctags 会自动识别的 :rofl: 这个选项主要还是避免 tag 工程里的一些脚本和文档。

其实 ctags 眼里没有什么工程和库的差别,只要你 tag 了肯定就能跳,所以目前确实有需求的话,在 recipe 里把库的路径写进去就行了 :rofl:

1 个赞

@oracleyue 运行 imenu 时为当前文件创建临时 tags file 的功能已经实现(在 develop 分支),你可以测试一下吗?

详细请读 citre-imenu-create-tags-file-threshold 的文档。目前默认在使用的 tags file 大于 100 MiB 的时候创建临时 tags file。我也在内核代码里试了一下,还是很快的。

1 个赞

这个命令行可以搞一个local variable,默认设置一个通用的ctags的命令

这事早已解决了 :rofl: 看一下最新的文档(

赞!我搞个dev分支试下哈,现在用的是melpa上的正式版


测试归来,完美!32

1 个赞

好,晚上就推到 master :wink:

1 个赞

打开文件时报错: Error loading tags-file: (user-error File /Users/leewish/work/ceph/TAGS is not a valid tags table

生成tags的命令: ctags --languages=c,c++ --kinds-all=‘’ --fields='’ --extras=‘*’ -R

ctags 版本: ❯ ctags --version Universal Ctags 5.9.0(b5cd9f4e), Copyright (C) 2015 Universal Ctags Team Universal Ctags is derived from Exuberant Ctags. Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert Compiled: Jul 19 2021, 12:37:59 URL: https://ctags.io/ Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +json, +interactive, +yaml, +case-insensitive-filenames, +packcc, +optscript

应该是这个问题:GitHub - universal-ctags/citre: Ctags IDE on the True Editor

1 个赞

问个问题,我用citre-jump查询如果一个函数在tags文件中有多次命中(比如一次c一次h),在minibuffer里就只会显示函数名+冒号,需要再用上下来显示和选择命中的条目;这个地方挺不友好,我刚开始就以为没找到;能不能像ivy或helm一样把所有命中都直接显示出来让选择?如果能再加一个编号直接输入编号跳转就更好了; 不知道是不是有设置已经实现了,在这里问一下,多谢;

另外还有个问题,通过citre-jump查询的文件,如果是本文件,好像现在不是直接复用跳转而是再次打开(文件名后加一个<2>)是不是我有啥设置不对?每次查询都打开一遍,有点费内存啊;

感谢老哥的工作!Citre看上去很有吸引力!

ctags貌似不支持查看函数/变量的引用(reference),查看了citre和ctags的文档也没有看到这个功能。

请问ctags/Citre的确没有列出函数/变量引用的功能吗? :sweat_smile:

我这里没有这个问题:

$ cat code.c
int test () {
  return 0;
}

$ cat code.h
int test ();

$ cat .tags
...
test    code.c  /^int test () {$/;"     kind:function   line:1  language:C      typeref:typename:int  signature:()    roles:def       end:3
test    code.h  /^int test ();$/;"      kind:prototype  line:1  language:C++    typeref:typename:int  signature:()    roles:def       end:1

citre-jump 浏览 test 的定义时是这样的:

image

可以看到显示了 种类/类型 路径(行号): 行的内容。如果你只看到函数名和冒号,建议检查下 tags 文件是否记录了所需的信息。

这个我觉得应该是 minibuffer 补全框架操心的事情。citre-jump 用的就是标准的 completing-read 接口,completing-read 在用户那里长什么样不是 Citre 能管得了的。

这个问题我也测试过没有出现。建议用 $ emacs -Q 测一下是不是能复现,我个人怀疑你可能用了什么修改 buffer 或 window 行为的包。

短的回答:几乎没有。

长的回答:首先,Ctags 是有 reference tags 的。我在某个文档的角落还提了一嘴:

The mark `<R>` means the definition comes from a reference tag.

问题是 Ctags 的 reference tags 现在关注的只是模块的引用,详情我在这一楼已经介绍过。如果你在 dired 里面找一个头文件,然后用 Citre 查它的定义,应该能找到工程里所有引用了这个头文件的地方。

也就是说,并不是 Ctags 的架构不支持查引用,只是它对它支持的语言都还没有实现函数/类等的引用的索引。

如果你想不依赖别的工具查引用的话,建议两种方法:

  1. 自己写正则扩展 Ctags 的 parser,让 tags 文件记录你想 tag 的东西(我在这一楼给了一个例子)。
  2. grep,也是我目前在用的办法。
2 个赞

考虑用gtags实现引用吗,ctags+gtags组合

谢谢提供思路。

这个东西如果嵌到 CItre 底层,让上面的所有工具都可用的话,破坏性太大。但我想可以给 citre-peek 开发一个插件,提供一个命令 citre-peek-reference(当然也要有 citre-peek-through-reference),让它调 gtags 命令行,把结果转成 Citre 的 tag 数据结构,然后利用 citre-peek 的内部 API 来显示结果。

我不能保证会做这个东西。目前 Citre 自己就需要很多精力维护了,我对找引用暂时也没需求。

感谢!

lsp对于c++虚函数的效果不是很好,所以也经常用grep:sweat_smile:

用emacs -q试了一下,现象一样;可是我觉得好像也不是citre导致的,不知道为啥就是completing-read UI弹不出来。用tab键也能看到需要匹配的几条记录,只是没办法选择。不知道是不是有啥参数控制completing-read UI的表现呢?