eglot, "the Emacs LSP that stays out of your way" is usually pretty-good at figuring-out where you are and where your project is when you invoke it in a file you've opened. Occasionally, however, it gets confused. For instance, I have a personal project that contains code in Guile, bash, and Rust. When I opened a Rust file, eglot
complained that it couldn't find the project, leading me to dig into just how eglot finds the "current project".
It was a nice example of how to work the Emacs documentation system. I said "C-h f eglot" and was told "PROJECT is guessed from
‘project-find-functions’." Ok. I said "C-h v project-find-functions" and was told "…Its value is (project-projectile project-try-vc)" Alright, I guess project-try-vc
would find the root directory (i.e. where there's a directory named .git
), so let's take a look at project-projectile
. I followed the provided link and found:
(defun project-projectile (dir) "Return Projectile project of form ('projectile . root-dir) for DIR." (let ((root (projectile-project-root dir))) (when root (cons 'projectile root))))
I placed my cursor on "projectile-project-root" and said "M-." to find the definition. This function, in turn, works off of the variable projectile-project-root-functions
. Help again told me:
projectile-project-root-functions is a variable defined in ‘projectile.el’. Its value is (projectile-root-local projectile-root-marked projectile-root-bottom-up projectile-root-top-down projectile-root-top-down-recurring)
Ok. Function projectile-root-local
just works off the variable projectile-project-root
; I guessed this wouldn't work well– I'd need to set a directory-local variable in every directory containing project source files.
On to projectile-root-marked
: this works off the variable projectile-dirconfig-file
, which was set to ".projectile".
Ah, so: all I needed to do was touch a file named .projectile
in the root of my Rust project & eglot
was happy.