求教Citre+Company的配合问题

我的相关配置如下

;; universal-ctags是自己编译的
(setq u-ctags-path (concat (getenv "HOME") "/u-ctags/bin"))
(setq modes-use-citre '(cmake-mode cmake-ts-mode makefile-mode asm-mode fortran-mode markdown-mode makefile-automake-mode))

(let ((tex-lsp (concat (getenv "HOME") "/texlab/target/release"))
          (lua-lsp (concat (getenv "HOME") "/lua-lsp-3.13.5/bin")))
  (progn
        (setenv "PATH" (concat py-bin-path ":" (getenv "PATH")))
        (setenv "PATH" (concat tex-lsp ":" (getenv "PATH")))
        (setenv "PATH" (concat lua-lsp ":" (getenv "PATH")))
        (setenv "PATH" (concat u-ctags-path ":" (getenv "PATH")))))
(use-package citre
  :ensure t
  :init
  (require 'citre-config)
  (add-hook 'prog-mode-hook #'citre-auto-enable-citre-mode)
  :bind(("C-x c j" . citre-jump)
                ("C-x c J" . citre-jump-back)
                ("C-x c p" . citre-ace-peek)
                ("C-x c u" . citre-update-this-tags-file))
  :config
  (setq citre-auto-enable-citre-mode-modes modes-use-citre)
  (setq-default citre-enable-capf-integration t)
  (setq citre-ctags-program (concat u-ctags-path "/ctags")
                citre-readtags-program (concat u-ctags-path "/readtags"))
  ;; always use one location to create a tags file
  (setq citre-default-create-tags-file-location 'global-cache)
  ;; use projectile find project root
  (setq citre-project-root-function #'projectile-project-root)
  (setq citre-edit-ctags-options-manually nil))
(use-package company
  :ensure t
  :init
  (add-hook 'text-mode-hook #'company-mode)
  (dolist (s modes-use-citre)
        (let ((mode-name (symbol-name s)))
          (let ((one-hook (intern (concat mode-name "-hook"))))
                (add-hook one-hook #'company-mode))))
  :config
  (setq company-minimum-prefix-length 1)
  (setq company-idle-delay 0.0)
  (setq company-tooltip-align-annotations t)
  (setq company-backends
                '(company-dabbrev company-dabbrev-code company-keywords company-files company-capf)))

这个配置可以生成tags文件,但是补全,跳转通通不行。

你对 citre-enable-capf-integration 和 company-backends 这两个变量以及 capf 的的作用没搞清楚。

capf 的逻辑是当这个 list 里有一个函数返回补全结果时,剩下的函数都将不再执行。因此如果你的 capf list 里还有别的函数位于 citre-capf 的顶上,那么 citre-capf 大概率根本就不会运行。

因此用 citre 补全我建议配合 cape 包使用。这样可以保证你的补全结果同时返回 citre 以及比如说 eglot 的结果。

另外 citre 其实需要的不是 ctags program,它需要的其实是 readtags program 来进行查询,这个通常都是和 universal-ctags 项目一起打包附带的。你如果定义跳转不通,可以看看是不是没有 readtags 程序。

company-backends 的逻辑和 capf 逻辑类似,当这个列表里有一个 entry 返回结果时,剩下的不再运行。但是 company 支持某一个 entry 是一个列表,这样每次运行时就会运行这个 entry 里的每一个 subentry。因此你的配置里,你把 company-capf 的优先级放到了最后,那么自然 company-capf 永远不会返回结果。你应该把你常用的 source 都包在一个列表里。

以下是一个 citre 和 company 的参考配置 (假设你配合 citre 和 eglot 一起使用)

(defalias #'mg-eglot-citre-capf
    (cape-capf-super #'eglot-completion-at-point #'citre-completion-at-point))

;;;###autoload
(defun mg-toggle-citre-eglot-capf ()
    (if (eglot-managed-p)
            (add-to-list 'completion-at-point-functions #'mg-eglot-citre-capf)
        (setq-local completion-at-point-functions
                    (delq #'mg-eglot-citre-capf completion-at-point-functions))))

    (mg-setq-on-hook text-mode-hook
                     company-backends
                     '((company-files company-yasnippet company-capf :separate company-dabbrev)))

    (setq eglot-stay-out-of '(company))

    (add-hook
     'eglot-managed-mode-hook #'mg-toggle-citre-eglot-capf)

试试我写的company-ctags, company的ctags后端