Citre: 先进的 Ctags 前端

我想,是否有必要把行内容放在前面或者用户自定义?因为我每次对结果过滤的时候,我似乎更关注行内容;如果把行内容放在最前面,行内容就不会因为文件名长度不一致,导致行内容不对齐,肉眼过滤的时候眼睛焦点会左右来回飘……

你这个情况我建议用 citre-peek,不过 peek 目前不能做二次过滤 :rofl:

我对这个东西的排序就是按我想的重要程度排的。我觉得最前面那个 kind/type@scope 基本上就能概括那一行干了什么了。

请问 citre 不是递归检查 tags 的里面存的路径吗?我把我 emacs 的配置做了 tags ,但只有直接在路径下的才有,子目录就找不到了。

我的 .tags 文件前几行:

!_CITRE_CMD ctags|-o|%TAGSFILE%|--languages=EmacsLisp|--kinds-all=*|--fields=*|--extras=*|-R|/home/weiss/emacs/|/home/weiss/.emacs.d/emacs-config/|/home/weiss/.emacs.d/local-package/|local-package/snails/|/home/weiss/.emacs.d/straight/repos/snails-roam/|/home/weiss/.emacs.d/straight/repos/ /command line to generate this tags file/;" !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/;" extras:pseudo !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/;" extras:pseudo !_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/;" extras:pseudo !_TAG_OUTPUT_FILESEP slash /slash or backslash/;" extras:pseudo !_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/;" extras:pseudo !_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/;" extras:pseudo !_TAG_PROC_CWD /home/weiss/.emacs.d/ //;" extras:pseudo !_TAG_PROGRAM_AUTHOR Universal Ctags Team //;" extras:pseudo !_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/;" extras:pseudo !_TAG_PROGRAM_URL https://ctags.io/ /official site/;" extras:pseudo !_TAG_PROGRAM_VERSION 5.9.0 /b5cd9f4e/;" extras:pseudo

是递归的,并且测试过多次可以用。我不知道你为啥不行。。。

哦,确实是递归的。 我猜原因是我在 .emacs.d/emacs-config/xxx.el 中运行了创建 tag 的命令,然后设置 root 的时候没设置对?(照理说我设置的 root 是 .emacs.d 应该没问题才对)。总之我直接在 -R 后加上所有需要的路径就 ok 了。

哦,知道原因了,不是文件没有扫描到,而是 tags 不支持 with-eval-after-load 里面的东西 :rofl:

写了个支持 verilog 的 PR:Verilog, feat: add language support for (System) Verilog by AmaiKinono · Pull Request #79 · universal-ctags/citre · GitHub

希望你能帮我审一下。主要看这个行为是不是正确:

;; Language support for Verilog.  The features are:
;;
;; - Correctly grabbing the name of a macro reference.  When the symbol begins
;;   with a "`", it's dropped by Citre.
;; - When the symbol begins with a "`", tags of constant kind (which ctags uses
;;   to record macro definitions) are sorted above others.
1 个赞

测试过了,好用,好用……非常感谢!看了下代码,感觉我还是做伸手党比较合适 :joy:

2 个赞

你的代码写得挺不错的 :wink: 一般 elisper 成长得比自己想象的快

最近迫不得以要看 golang 的代码,用了 Citre!好用!

1 个赞

可以啊,也是一种方案

1 个赞

目前宏定义跳转还没有用到过, 不过你提出的想法和代码很好啊 虽然我也是不怎么会写elisp 但你帮助citre支持了verilog 谢谢你啊

最近发现好多同学喜欢只在 prog-mode 里自动启用 citre-mode,而如果 (require 'citre-config) 的话,会在所有模式里尝试自动启用 citre-mode。因此,只好不用 citre-config,这样就不能即时享受到上游对 citre-config 的更新(比如最近就添加了 verilog 支持)。

刚刚新加了一个用户选项,用法一目了然:

(citre-auto-enable-citre-mode-modes '(prog-mode))

这样就可以放心地 (require 'citre-config) 了,citre-mode 只会在 prog-mode 中自动打开。

FYI @seagle0128 @Youmu

6 个赞

赞!我刚把相关配置给推到 github 上。。

入坑占楼。 :grin: :grin:

已经实现了,现在 Citre 的 imenu 会给 qualified tags 和 reference tags 自己的分类。

1 个赞

求教一个奇怪的问题。我配置了ctags的exclude ccls cache rule https://github.com/ztlevi/dotty-config/blob/main/editor/emacs/.ctags.d/.ctags#L21.

但是本地生成的tags里面还是有ccls cache的东西,不知道为什么。我用的是这个sample project测试 GitHub - edumentab/cpp-project-example: Example of project structure for a C++ project with cmake

!_CITRE_CMD	ctags|-o|%TAGSFILE%|--languages=c++|--kinds-all=*|--fields=*|--extras=*|-R	/command line to generate this tags file/;"
!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/;"	extras:pseudo
!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/;"	extras:pseudo
!_TAG_OUTPUT_EXCMD	mixed	/number, pattern, mixed, or combineV2/;"	extras:pseudo
!_TAG_OUTPUT_FILESEP	slash	/slash or backslash/;"	extras:pseudo
!_TAG_OUTPUT_MODE	u-ctags	/u-ctags or e-ctags/;"	extras:pseudo
!_TAG_PATTERN_LENGTH_LIMIT	96	/0 for no limit/;"	extras:pseudo
!_TAG_PROC_CWD	/Users/ztlevi/dev/cpp-project-example/	//;"	extras:pseudo
!_TAG_PROGRAM_AUTHOR	Universal Ctags Team	//;"	extras:pseudo
!_TAG_PROGRAM_NAME	Universal Ctags	/Derived from Exuberant Ctags/;"	extras:pseudo
!_TAG_PROGRAM_URL	https://ctags.io/	/official site/;"	extras:pseudo
!_TAG_PROGRAM_VERSION	5.9.0	/p5.9.20210627.0/;"	extras:pseudo
01-general-executable@src@[email protected]	.ccls-cache/@Users@ztlevi@dev@cpp-project-example/01-general-executable@src@[email protected]	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:18	epoch:1628262431
::testing::internal2	01-general-executable/build/googletest-src/googletest/include/gtest/gtest-printers.h	/^  using namespace ::testing::internal2;  \/\/ NOLINT$/;"	kind:using	line:234	language:C++	scope:function:testing_internal::DefaultPrintNonContainerTo	roles:def
<<	01-general-executable/build/googletest-src/googletest/include/gtest/gtest-message.h	/^    using ::operator <<;$/;"	kind:name	line:130	language:C++	scope:function:testing::Message::operator <<	roles:def
<<	01-general-executable/build/googletest-src/googletest/include/gtest/gtest-message.h	/^    using ::operator <<;$/;"	kind:name	line:218	language:C++	scope:function:testing::Message::StreamHelper	roles:def
@[email protected]@Contents@Developer@[email protected]@usr@lib@[email protected]@[email protected]	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@[email protected]@Contents@Developer@[email protected]@usr@lib@[email protected]@[email protected]	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:35	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:483	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:4675	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@[email protected]	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:217	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@__wctype.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@__wctype.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:74	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@_ctermid.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@_ctermid.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:35	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@_ctype.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@_ctype.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:387	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@_locale.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@_locale.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:76	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@_stdio.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@_stdio.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:159	epoch:1628262431
@Library@Developer@CommandLineTools@[email protected]@usr@include@_types.h	.ccls-cache/@@Users@ztlevi@dev@cpp-project-example/@Library@Developer@CommandLineTools@[email protected]@usr@include@_types.h	1;"	kind:file	line:1	language:C++	roles:def	extras:inputFile	end:69	epoch:1628262431

把你的配置文件名字中 .ctags 改成 0.ctags 就可以了。

我也不知道 uctags 是不是会挑这个名字,但是手册里写了读取配置文件的顺序是按那个数字来的,所以我自己都是用 0.ctags1.ctags 这样的名字。你可以翻翻手册看究竟是咋回事。

PS:你这个配置是直接用 exuberant ctags 的吗?我肉眼看上去有几个小问题:

  • .git 之类的目录其实不用排除,uctags 会自动排除这类东西的。不过我不知道默认的排除规则是什么。

  • 如果你不是很在乎 tags 文件的体积的话,不需要指定开启的 fields 和 kinds,Citre 默认是全启用的,用起来体验肯定也最好。如果需要小一些的体积的话,Citre 的手册里讲了一些命令行的技巧。

  • --tag-relative 这个选项我从未见过。默认情况下 tag 的路径应该是相对于 ctags 程序运行时的 pwd 的,tags 文件里有个 TAG_PROC_CWD 的 ptag 记录这个 pwd,Citre 也是这么算绝对路径的(这是 uctags 作者提供的方案)。所以我看 --tag-relative 描述的行为感觉很不对。

  • 你这里大多数写了正则规则的语言 uctags 都已支持了。如果没有特殊需要建议不要自己写规则,要写的话也不应该用这种名字直接和支持的语言名字重合的写法(Citre 的手册里有示例)。

我觉得 uctags 不配置就很可能能满足你的需求。

改成了0.ctags还是有一堆ccls的东西啊

手册里说 exclude pattern 是匹配「目录名或文件名」的,不是路径,所以你应该把它改成

--exclude=.ccls-cache

Edit: 可以用 $ ctags --list-excludes 看看自带的 exclude pattern 怎么写的。

哦哦,搞定了,我看到官方repo里有个.ctags.d/exclusion.ctags, 还特地试了下--exclude=.ccls-cache,当时好像没生效,不知道为什么。

我现在把ctags config 清理了一下就行了。

多谢啦!

1 个赞