Citre: 先进的 Ctags 前端

我个人需要查引用的时候就直接 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语言的扩展

不需要。Citre 对 Ctags 支持的所有语言开箱即用,具体语言的扩展只是提供一些更贴心的小规则而已。

wow,这两天要玩一下了

1 个赞

我建立Tag的时候报这个错,这个是我ctags版本的问题吗?

应该是的。你用的是 Universal Ctags 吗?$ ctags --version 看一下?

我在Widnows 下用最新的 Universal Ctags 可以正常生成Python 的 tags。
版本信息如下:

~ >>> ctags --version
ctags (GNU Emacs 28.0.50) Copyright © 2021 Free Software Foundation, Inc. This program is distributed under the terms in ETAGS.README

删除Emacs ctags,重新安装 ctags 好了

1 个赞

我今天写了个补丁,已经从我自己的 Nox 切换到 Citre 来了,Python补全非常爽,比LSP那些后端好用多了,有几点反馈意见:

  1. Tags能否自动生成,比如project-root变化的时候,检测一下tags文件,没有就子进程新建tags
  2. Tags的语言可以根据 project-root下的文件类型自动添加,不用手动设置language
  3. Python的 Class 属性好像没有全部补全,有些属性可以有些不行,倒是 Class 的函数名补全的很Nice
  4. citre-peek 按了就会弹出一个类似 frame 的东西, citre-peek 怎么玩啊?没有搞懂

citre-jump 配合 selectrum 倒是非常舒服。

6 个赞

LSP/elgot/Nox 这种LSP后端的对库的补全比较好,比如Python的 os 库,可以补全 os.path.exists 这样的函数

citre 这种基于Tag的对当前项目已经Index的补全支持很好,也就是自己写的代码补全比较好(这方面LSP反而没法补全)

继续体验,citre确实很快很好用, 我个人倾向于用 citre,不用折腾那么多后端,如果配合自动生成tags的功能,其实大多数语言反而更好用。

1 个赞

谢谢,有牛逼的黑客喜欢我的工具是最开心的事 :wink:

这么做的话可能管得有点宽了,比方说用户可能不希望每一个工程都用 ctags。我正在实现一个生成 tags 的向导,生成一次之后用一个命令就可以更新:misctools, feat: generate and update tags file by AmaiKinono · Pull Request #62 · universal-ctags/citre · GitHub

这个可能也比较难。首先很多工程下面有 Makefile,但我们不一定需要 tag 它;另外就是子目录下的文件要不要搜索的问题。我在向导里面实现了一个手动添加语言的功能。

这个最有可能的是 ctags 没有 tag 部分属性,可以看一下 tags file 里面有没有。如果确实没有的话可以给 Ctags 报 bug。

citre-peek 其实超简单 :wink: 建议看一下这个文档,每一步都跟着操作一下,一会就搞懂了。

我在文档上还是花了很多精力的,建议从 README 开始都读一下,一定会有收获。

1 个赞

这方面我也有一些想法,但可能不是用自动补全的形式来实现。参见这一楼我的回复:

感谢大佬,体验非常滴好 :+1: 。目前我是 lsp 和 citre 一起用,有些地方 lsp 没法补全的时候(比如 java 里写 sql 的 query)可以用 citre 补,还可以用 citre-peek 边查看类、函数的信息边码代码。感觉好久没有碰上这么爽的插件了,哈哈。

3 个赞

希望你能一直用 Citre 一直开心 :wink:

可以告诉我这个功能大概是怎么配的吗?

像 golang 这种可以 --exclude $GOPATH/pkg/mod/… 来把第三方库的代码加到 tag 中,我试了一下 ok, 但是 python 这种我就不熟悉了。

这不对吧,你给的这个命令应该是排除这个目录才对。

我考虑到了添加第三方库的需求,在生成 tag 的向导中会允许选择多个要扫描的目录,包括当前工程外面的。

Edit: 其实我和 Masatake 讨论过让 Ctags 自己找到依赖的那些模块的路径,但是现在找不到那个 issue 了。感觉短期也不太可能有。

另外,如果有很大的依赖库被 tag 了,那么增量更新就更重要了。

Edit2: 我刚又看了一遍才理解你和懒猫的意思。你们意思是 ctags 只扫当前工程目录,所以没有外部库的符号。但我说的意思一直是「在 tag 了那些库的符号的情况下,怎么把它们挖掘出来」。

1 个赞