Citre 是基于ctags 的Emacs 自动补全前端, 可以提供代码跳转和自动补全功能, 后端基于 ctags 或者 universal-ctags
由于在Emacs 中一直没有把 verilog 的 LSP 用起来, 之前用的是gtags, Citre 比gtags 定制性更好些, 而且速度更快
下载 Citre 到本地
1
2
|
cd ~/.doom.d/elisp/
git clone https://github.com/universal-ctags/citre.git
|
看 Citre 的Readme
Windows
到 https://github.com/universal-ctags/ctags-win32
下载最新的Ctags 解压后记住路径 配置Emacs 中用到
查看当前ctgas 支持多少种语言
ctags --list-languages | wc -l
Macos
1
|
brew install --HEAD universal-ctags/universal-ctags/universal-ctags
|
Linux
自行编译
配置Emacs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
(use-package! citre
:defer t
:load-path "~/.doom.d/elisp/citre"
:init
;; This is needed in `:init' block for lazy load to work.
(require 'citre-config)
;; Bind your frequently used commands. Alternatively, you can define them
;; in `citre-mode-map' so you can only use them when `citre-mode' is enabled.
:config
(map!
(:map verilog-mode-map
;; Navigation
"C-/" #'citre-peek
"M-]" #'citre-jump
"M-[" #'citre-jump-back
;; "M-<f12>" #'helm-gtags-find-rtag
;; "C-M-]" #'helm-gtags-find-tag
;; "C-M-t" #'helm-gtags-find-tag-other-window)
;; "C-c c" #'my/verilog-compile-only
"C-c c" #'my/run-vcs-with-compile
"C-c a" #'my/verilog-compile-download
"C-c d" #'my/verilog-download
"C-c l" 'my/find-vcs-sim-log-file
"C-c m" 'my/run-modelsim-nogui
"C-c M" 'my/run-modelsim-gui
"C-c s" 'my/run-vcs-with-nogui
"C-c S" 'my/run-vcs-with-gui
"C-c k" 'my/kill-vcs-modelsim-gui-process
"C-c A" 'my/open-anlogic-prj
"C-c q" 'my/open-quartus-prj
))
;; Set these if readtags/ctags is not in your path.
(cond ((file-exists-p "E:\\work\\tools\\ctags-p5.9.20210905.0-x64\\ctags.exe")
(setq
citre-readtags-program "E:\\work\\tools\\ctags-p5.9.20210905.0-x64\\readtags.exe"
citre-ctags-program "E:\\work\\tools\\ctags-p5.9.20210905.0-x64\\ctags.exe"))
((file-exists-p "/usr/local/bin/ctags")
(setq
citre-readtags-program "/usr/local/bin/readtags"
citre-ctags-program "/usr/local/bin/ctags"))
)
(setq
;; Set this if you use project management plugin like projectile. It's
;; used for things like displaying paths relatively, see its docstring.
citre-project-root-function #'projectile-project-root
;; Set this if you want to always use one location to create a tags file.
citre-default-create-tags-file-location 'global-cache
;; See the "Create tags file" section above to know these options
citre-use-project-root-when-creating-tags t
citre-prompt-language-for-ctags-command t
;; By default, when you open any file, and a tags file can be found for it,
;; `citre-mode' is automatically enabled. If you only want this to work for
;; certain modes (like `prog-mode'), set it like this.
citre-auto-enable-citre-mode-modes '(verilog-mode)
citre-edit-cmd-buf-default-cmd "ctags\n-o\n%TAGSFILE%\n--languages=[verilog,systemverilog]\n--kinds-all=*\n--fields=*\n--extras=*\n
;; exclude file or dir use --exclude= can use multi line
-R\n;; add dirs/files to scan here, one line per dir/file\n"
)
(defun my/citre-jump ()
"Jump to the definition of the symbol at point.
When there's multiple definitions, it lets you pick one using the
`completing-read' UI, or you could use your own UI by customizing
`citre-select-definition-function'.
append add goto keyword pos "
(interactive)
(let* ((marker (point-marker))
(symbol (citre-get-symbol))
(definitions
(citre-get-definitions-maybe-update-tags-file symbol))
(root (funcall citre-project-root-function)))
(when (null definitions)
(user-error "Can't find definition for %s" symbol))
(citre-jump-show symbol definitions marker root)
;; 跳到symbol 处
(beginning-of-line)
(search-forward symbol (line-end-position) t)
(backward-char)
(unless (citre-tags-file-path)
(setq citre--tags-file
(with-current-buffer (marker-buffer marker)
(citre-tags-file-path))))))
(advice-add #'citre-jump :override #'my/citre-jump))
|
简单用法
如果不知道具体的语言, 可以使用 citre-edit-cmd-buf-add-lang
查看
M-x: citre-edit-tags-file-recipe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
;; Edit the command line for creating the tags file
;;
;; Syntax:
;;
;; - One command line argument in one line
;; - Lines start with ;; are ignored
;; - Use %TAGSFILE% to refer to the tags file
;; - "%" (other than those in %TAGSFILE%) and "\" need escaping
;;
;; Commands:
;;
;; - C-c l: Insert a language (needs Universal Ctags)
;; - C-c f: Insert a dir or file
;; - C-c C-c: Commit
;; - C-c C-k: Cancel
ctags
-o
%TAGSFILE%
--languages=verilog,systemverilog
--kinds-all=*
--fields=*
--extras=*
--exclude=simulation/*
--exclude=src/spi/spi_ctrl_quad.v
--exclude=src/psram/*
-R
|
如果要排除掉一些文件 可以使用 –exclude 选项, 如果要排除多个目录需用多个 –exclude
更多参数配置参考 ctags --help
M-x: citre-update-this-tags-file
跳转到定义
M-]
citre-jump
跳转后返回
M-[
citre-back
不离当前文件查看定义
C-/
citre-peek
Citre 的一个BUG ( 打开verilog 文件导致Emacs 卡死 )
当打开某些含有很多`define 语句的 .svh 或者 .sv 文件时, 使用默认的配置的话, 很容易导致Emacs 卡死( C-g 都无解 )
最后通过二分法最终查到了 citre 的 citre-config.el 头上
解决办法
把 citre-config.el 里面的
1
|
(add-hook 'find-file-hook #'citre-auto-enable-citre-mode)
|
注释掉