lsp-find-definination 找不到头文件和函数的定义位置

大家好,我在使用lsp-mode,后端是clangd,项目代码结构如图所示。

我想问一下,这种结构下 lsp-find-definination 找不到头文件和函数的定义位置是正常现象吗?有办法配置吗?其中lsp-mode在启动时已经手动指明了项目的根目录。

我的lsp-mode配置如下:


(use-package lsp-mode
  :ensure t
  :defer t
  :hook
  (;;(prog-mode . (lambda ()
   ;;               ;; Ask lsp mode load
   ;;               (unless (derived-mode-p 'emacs-lisp-mode 'lisp-mode 'makefile-mode 'snippet-mode)
   ;;                 (lsp-deferred))))
   (lsp-mode . (lambda ()
                 ;; Intergrate `which-key'
                 (lsp-enable-which-key-intergration)

                 ;; Format and organize imports
                 (when (and leesin-lsp-format-on-save
                            (not (apply #'derived-mode-p leesin-lsp-format-on-save-ignore-modes)))
                   (add-hook 'before-save-hook #'lsp-format-buffer t t)
                   (add-hook 'before-save-hook #'lsp-organize-imports t t))))
   )
  :init
  (setq lsp-keymap-prefix "C-c l")
  (setq lsp-prefer-flymake nil)
  (setq lsp-prefer-capf t)
  (setq lsp-enable-snippet t)
  (setq lsp-enable-completion-at-point t)
  (setq lsp-keep-workspace-alive nil)
  (setq lsp-enable-file-watchers nil)
  (setq lsp-enable-semantic-highlighting nil)
  (setq lsp-enable-symbol-highlighting nil)
  (setq lsp-enable-text-document-color nil)
  (setq lsp-enable-folding nil)
  (setq lsp-enable-indentation nil)
  (setq lsp-enable-on-type-formatting nil)
  ;;Reset company backends
  ;;In this way can emacs show company-yasnippet
  ;;Refered from doom-emacs
  (add-hook 'lsp-completion-mode-hook (lambda ()
                                        (when lsp-completion-mode
                                          (set (make-local-variable 'company-backends)
                                               (remq 'company-capf company-backends)))))
  :commands (lsp lsp-deferred)
  )
1 个赞

compile_commands.json 这个文件有么?clangd需要它。

搞硬件的大哥!!
这种项目一般是借助 ctags 来实现跳转 定义的, 对于那些头文件缺失的 提示就不是很好解决了

谢谢,我了解了一下,目前生成compile_commands.json似乎是基于make或者cmake等的方式,由keil编译的项目我还不知道该怎么生成。

我试了counsel-etags 以及 citre,我总结了一下,目前情况是这样的:

  1. 它们都能直接跳转源文件所在的文件夹下的头文件,比如当 main.h 和 main.c 在一个文件夹下时可以直接跳转
  2. 像我项目中 /Core/Src 和 /Core/Inc 的形式,它们就不能完成源文件到头文件的直接跳转,也就是无法根据 #include "main.h" 跳转,只能通过各函数定义跳转(这应该是基于全局搜索的方式)。
  3. vscode 打开项目根目录之后,在代码文件中可以进行任何形式的跳转,即使源文件和头文件隔着两层目录,我不知道emacs中是否有这样的插件

把闭源代码截图出来不好吧?

citre/ctags可以自己加扫描symbol的正则

这不是 Emacs 的问题, 你能在 Vscode 跳转是因为你是用那个 C/C++ 插件, 而你将 Core/Inc 目录添加进了C/C++ 这个插件头文件列表当中自然就能跳转, 而 Emacs 的插件似乎并没有这个功能

如果你想在 Emacs 也能做到这样的跳转, 尝试添加头文件 include “…/Inc/xxx.h”
但是这样做就太麻烦了
这些项目确实挺难受的, 没 Makefile…
简单常用的就是 ctags(citre) 和 dumb-jump 了

1 个赞

我还没开始上班,这是用于学习的代码,不是公司的。 :joy:

感谢提示,我看看citre的正则。

我这边是c项目,是makefile的方式编译的,而且是在Windows,clangd官网提到的各种工具生成json方式我能试的都试过了,没用,输出空的json。

后来发现make命令可以输出详细的编译语句,然后自己写个Python脚本来提取转换成compile_command.json的内容格式,就一切都好了

1 个赞

这个听起来很有趣的尝试,可以的话,给我们share下你的导出工作流。

可以用bear来生成。

可以用global 的gtags试试。我印象中gtags的跳转是可以跳到其他目录的头文件中的。之前没遇到过这种问题。

标题修改建议:

- LSP Mode 跳转定义
+ lsp-find-definination 找不到头文件和函数的定义位置是正常现象吗?

好的,谢谢,我晚上试一下

已经改正,谢谢。

是的,chatgpt也向我推荐了bear,不过bear在windows上似乎不能运行 :sob:

安装 GNU global 和 ggtags 后,可以使用 ggtags-find-file 跳转。

好消息,Citre可以实现跳转,我首先在命令行测试是这样:

ctags --languages=C --kinds-all='*' --fields='*' --extras='*' -R . 生成的tags不包含file kind信息;

ctags --languages=C,C++ --kinds-all='*' --fields='*' --extras='*' -R . 生成的tags包含file kind信息。

所以当citre询问语言的时候,写C,C++就好了。

我之前粗读citre的手册还没有在上面找到有关这方面的描述,不过这应该是ctags方面的问题(我不确定算不算问题,也许是特性)