1

Question

My would like to open up a .C file, position point (cursor) onto a symbol, type M-?, and show all references to that symbol under point, in all translation units in the project. But it does not do that, but only shows references in that buffer, or in other C++ files buffers (in the same projectile project) I have already opened in Emacs, files that are configured into the compile_commands.json file that is fed to clangd LSP server that is configured into the lsp-mode package in Emacs. This is Emacs version 27.2 running on a RHEL8 host.

I have ascertained (see Details section below) that, even after clangd has finished indexing all translation units, the M-? still does not show all of the references to symbol under point in all translation units.

So, is there something I can change or configure that forces lsp-mode (or clangd itself) to report all references to the symbol under point in all translation units, even if those source files have not yet been opened up in Emacs?

Details

I have lsp clangd server configured properly using the tips at Morten's Dev blog. M-? is bound by default by lsp-mode to xref-find-references because lsp-enable-xref is currently set to t. The compile_commands.json file that I have properly configured: It has one compile line per translation unit, for a total of ~11,000 files.

(use-package lsp-clangd
  :config
  ;; From https://www.mortens.dev/blog/emacs-and-the-language-server-protocol/#:~:text=setq%20lsp%2Dclients%2Dclangd%2Dargs
  ;;
  ;;   It tells clangd that it can use 4 concurrent jobs and to make a complete
  ;;   background index on disk. Without -background-index, it will only keep an
  ;;   in-memory index of the files that are active in Emacs buffers, but to be
  ;;   able to find references and symbols in any project file the background
  ;;   index is recommended. The background index, named “.clangd” by default,
  ;;   is placed at the root of the project.
  ;;
  (setq lsp-clients-clangd-args (append lsp-clients-clangd-args '(
                                                                  "-j=4"
                                                                  "-background-index"
                                                                  "-log=error" ;; Only show errors but comment this out if/when we desire to see what it is doing in detail
                                                                  ))))

When I comment out the "-log=error" line above, I do see it re-reading index files, and indexing files also dynamically. For instance, looking at the resulting .cache/clangd/index that clangd produces, sorted by modification timestamp, repeatedly, shows that those idx files are being generated:

/path/to/my/source/tree/.cache/clangd/index:
total used in directory 141060 available 789.5 GiB
drwxrwx--- 2 drunkard saloon 2236416 Mar 19 19:27 .
-rw-rw-r-- 1 drunkard saloon     352 Mar 19 19:27 some_file_1.cxx.DA6F8114A502DB9B.idx
-rw-rw-r-- 1 drunkard saloon     384 Mar 19 19:27 some_file_2.C.898F85D2653F3AC4.idx
-rw-rw-r-- 1 drunkard saloon     864 Mar 19 19:27 some_file_3.C.3D9D3F9DA5EE5E8D.idx
-rw-rw-r-- 1 drunkard saloon     738 Mar 19 19:27 some_file_4.C.7E32A213B7D4F758.idx

But, even when those files stop being updated (which I conclude that indexing has finished), M-? still does not reveal all references for the symbol that I know are there (via other slow means such as grep -R ... etc.).

1 Answer 1

1

Quoting from the answer to the question Why does clangd not return all references for a symbol?:

If you are sure all files are indexed and can be accessed: clangd limits the number of returned results to prevent UI freezes by default. If you have more than a 1000 symbols and you would like to get through all of them, please pass --limit-references=0 to clangd invocation.

3
  • Thanks. So, given that it seems as if clangd does support returning all of the references or at least 1,000 of them by default. Thus, this leads me to conclude that lsp-mode is not respecting or processing all of those references properly, limiting the amount of returned references only to those translation units corresponding to opened buffers in Emacs. Or, lsp-mode is not designed to return all of those references. Or, this is just user-error on my part, and I'm not configuring the mode properly in the first place.
    – bgoodr
    Commented Mar 25, 2022 at 0:48
  • 1
    I don't know your lsp configuration - Mortens-dev seems to be a little outdated, e.g. company-lsp is now part of lsp, not needed as separate package, helm-xref need to be added to the installation. Better see this page: emacs-lsp.github.io/lsp-mode/tutorials/CPP-guide. Although recommended , helm-lsp seems to have a similar issue - finding symbols fail (emacs 27), see this: github.com/emacs-lsp/helm-lsp/issues/19. In such cases, a good idea is to try another tool (e.g. vscode) - at least you can find out if the problem is clangd or emacs lsp.
    – Ian
    Commented Mar 25, 2022 at 9:33
  • Hmmm "try another tool (e.g., vscode)" : That is indeed an intriguing idea! Thank you. Yes, the Mortens-dev is a bit outdated for sure, and in fact, I'm using Ivy integration with lsp--mode and not Helm.
    – bgoodr
    Commented Mar 26, 2022 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.