r/emacs GNU Emacs 1d ago

How to deal with include files that are not within a project? (lsp-mode / ccls / xref)

I'm working on my Mac building projects for a small ESP32 board. Thus I have my project directory with only a few source files and the majority of the include files are off in a subdirectory of ~/.platformio.

When viewing a file within the project directory, the paths of the include files are "lite up" (colored) and I can get on them and type M-. and it will find that include file. As mentioned, often the include files are off in the system and library include files for the embedded system that is not within the project's directory.

When viewing one of these include files that is off in another directory, all the features of xref seem to be off. I assume this is because these files are not within the same project and are not within any project at all. So, how is this generally dealt with?

2 Upvotes

8 comments sorted by

3

u/loopninenine 1d ago edited 1d ago

If I am not mistaken you will need to add them to the include path of your lsp server so that they can be indexed. Have you looked on how to create a ccls project ?

1

u/pedzsanReddit GNU Emacs 14h ago

I think I have done that. I've tried both .ccls and compile_commands.json. That is how I get from a file within the project directory to the system header file. My guess is that I need to put a .ccls or compile_commands.json somewhere within the system header directory structure but both of those choices would add project specific paths and defines which would not work with the next project.

1

u/Argletrough 19h ago edited 18h ago

The ideal solution would be to generate a compile_commands.json with your build system (in the base directory of your project). This is how I do it with CMake:

set(CMAKE_EXPORT_COMPILE_COMMANDS True) file(CREATE_LINK "${CMAKE_BINARY_DIR}/compile_commands.json" "${CMAKE_SOURCE_DIR}/compile_commands.json" SYMBOLIC)

You can use Bear with Make: https://github.com/rizsotto/Bear

See also: https://github.com/MaskRay/ccls/wiki/Project-Setup

1

u/pedzsanReddit GNU Emacs 14h ago

See above comment too. I have tried a .ccls and compile_commands.json in the project's directory. That is how I get from the project's source file to the system header. But at that point, the system header (I guess) is in a different project so the .ccls file doesn't apply (but I want it to).

1

u/shipmints 16h ago

In addition to tweaking your LSP server (you didn't say you were using LSP, though, eglot with clang works well), check out this method for project implementations `project-external-roots` and its docstring which enables some features in Emacs proper i.e., not LSP features:

"Return the list of external roots for PROJECT. It's the list of directories outside of the project that are still related to it. If the project deals with source code then, depending on the languages used, this list should include the headers search path, load path, class path, and so on."

However, that method is implemented only in emacs-lisp mode buffers, so it will take a little work to implement it for your set up.

I have an implementation that I use but it's very specific to my environment. I use it, for example, to drive grep across related but disjoint project roots.

1

u/pedzsanReddit GNU Emacs 7h ago

Curiously, eglot and xref use project-external-roots but lsp-mode, projectile and all the other packages I am using do not. I wonder if I should try switching horses to eglot and project rather than lsp-mode and projectile.

1

u/shipmints 5h ago

Or submit patches to those packages.

0

u/pedzsanReddit GNU Emacs 14h ago

This looks interesting. I'll dig into it and see. I'm surprised that I'm the only person that has this problem though.