Figuring out how to make Eglot work with nested projects in Emacs.
I have been using Eglot since it has been in core Emacs and I am generally very happy with it
for the C and Go projects I have been working on. But I recently started looking at a Go project
that has nested modules (directories with a go.mod
file):
cert-manager ├── go.mod └── cmd ├── acmesolver │ └── go.mod ├── cainjector │ └── go.mod ├── controller │ └── go.mod └── webhook └── go.mod
When I open a file in one of these sub-modules, I get the following warning message and related imports are also broken:
warning go list: This file is within module "cmd/controller", which is not included in your workspace. error compiler [BrokenImport]: could not import github.com/cert-manager/cert-manager/controller-binary/app (current file is not included in a workspace module)
After a bit of investigation, I found that Eglot uses the builtin project.el
to discover the
project root directory. It does this by evaluating (project-current)
which returns (vc Git
"/opt/cert-manager/")
in our example. project.el
in turn uses the project-find-functions
hook which, by default, looks for the version control root and uses that.
project-find-functions is a variable defined in ‘project.el’. Its value is (project-try-vc) Special hook to find the project containing a given directory. ...
Looking at project.el
I don't see any alternatives to project-try-vc
so I went looking
through Melpa and found project-rootfile offers an alternative based on rootfile detection.
With the following added to my .emacs
, I now have nested projects working very smoothly in
Eglot:
(add-to-list 'project-find-functions #'project-rootfile-try-detect)
Hopefully there are no downsides to this setup with any of my existing projects.
It feels to me like project-rootfile
should be part of the core project.el
functionality to
improve the out-of-the-box ergonomics of Eglot.