I've set up lsp mode with rust using https://robert.kra.hn/posts/rust-emacs-setup/ mostly successfully. I can create a new hello-world directory inside /tmp just fine. Opening up main.rs inside that new project directory gives helpful hints, popups, etc.

However, I found out that this stops working when there is not a .git directory right next to the Cargo.toml file in the generated project directory (EDIT: because I intentionally used cargo new --vcs none hello_world; see Reason for no local .git dir below). This happened when I stopped playing with rust inside /tmp but instead ran cargo new hello-world within my home directory. Turns out that either rust-analyzer, or Emacs rustic mode, or lsp, or something just stops generating helpful things that the rust-analyzer should provide because it couldn't find the project directory.

I tried to use the advice at this spot:


which is this:

Should you ever see an error such as LSP :: rust-analyzer failed to discover workspace when trying to open a .rs file, try invoking the lsp-workspace-folders-add manually and add the root project directory.

But that did not work.

Note that I do have this set in my emacs configuration:

(setq lsp-auto-guess-root t)

This is so that I don't get nagged with including the directory each time I open up a rust source file, as I want it to figure out all by itself, without prompting me, where the project is. (Reason for no local .git dir) And I do not want a separate .git directory for each rust project, because I have a .git in a parent directory, so as to track multiple rust projects within the same repo.

If I disable the above via:

(setq lsp-auto-guess-root nil)

Then of course things start working again, but then I get hassled with the prompt to import the directory every time.

So what is a way to avoid the hassles with manually importing the project every time?

Why I failed to use projectile:

db48x's answer may lead us in the right direction, but it unfortunately is not the full story here that I did not think I had to go into detail about in the original version of this question:

Long ago, I read those Elisp doc-strings mentioning "all of your projects are following projectile/project.el conventions" as mentioned in db48x's answer, and struggled with it majorly given the complexity of projectile. I tried to follow those conventions as well as I could understand them, but I failed to do so to the letter of their law. Months/years ago, when I first tried to just go along with the program, and simply install and use projectile to manage all of my projects through lsp-mode, I found, to my surprise and astonishment, that projectile was performing very expensive operations upon each and every single find-file operation: projectile would call locate-dominating-file for several VC's (source code control systems such as Git etc.). This brought my Emacs productivity to a crawl, because the directory structures I need to have some sort of project management upon are (a) have a HUGE amount of files underneath the VC-controlling file/directory, and (b) are on on NFS partitions shared with many, many others. I tried hooking into projectile functions and such, but there were other places where it would fail out and start using locate-dominating-file. My speculation is that the originators of that package live in a pristine world of local SSD harddrives under tiny source code bases, which is not my scenario and will not be my scenario until I no longer work on those large code basis. So, that is when I resorted to trying to bypass "those conventions" by disabling projectile completely (and in fact marking it as "disabled" in my use-package configuration with copious reminders in the comments as to why I couldn't use it).

  • I haven't tested it, and it's just as a suggestion, but you might be interested to just use eglot (which, from Emacs 29, comes with Emacs by default). You can find how to set it up for rust here. Oct 5, 2023 at 3:51

1 Answer 1


You should read the help for the variable with C-h v:

Automatically guess the project root using projectile/project.

Do *not* use this setting unless you are familiar with lsp-mode
internals and you are sure that all of your projects are
following projectile/project.el conventions.

Do you know what the conventions for projectile projects or project.el projects are? Then perhaps you should leave this variable nil. Or perhaps you should read up on those conventions!

Projectile has a variable projectile-project-root-functions which is a list of functions that determine where the project root is, or return nil if they don’t think the current file is in a project. The default value of this variable is '(projectile-root-local projectile-root-marked projectile-root-bottom-up projectile-root-top-down projectile-root-top-down-recurring).

projectile-root-local just compares against the variable projectile-project-root. You could set that as a file–local or directory–local variable and identify your projects that way.

projectile-root-marked does a bottom–up search of the current path to look for a file called .projectile. Thus you could make an empty file with that name wherever you want a project to exist.

projectile-root-bottom-up does a search for files with these names:

  '(".git"        ; Git VCS root dir
    ".hg"         ; Mercurial VCS root dir
    ".fslckout"   ; Fossil VCS root dir
    "_FOSSIL_"    ; Fossil VCS root DB on Windows
    ".bzr"        ; Bazaar VCS root dir
    "_darcs"      ; Darcs VCS root dir
    ".pijul"      ; Pijul VCS root dir

As the comments indicate, these come from various VCS systems. You could extend that list if you want; it is stored in the variable projectile-project-root-files-bottom-up.

projectile-root-top-down is a top–down search for these files:

    "GTAGS"              ; GNU Global tags
    "TAGS"               ; etags/ctags are usually in the root of project
    "configure.ac"       ; autoconf new style
    "configure.in"       ; autoconf old style
    "cscope.out"         ; cscope

Again, you could add to this list by customizing projectile-project-root-files.

projectile-root-top-down-recurring is more complex, but searches for these files:

  '(".svn" ; Svn VCS root dir
    "CVS"  ; Csv VCS root dir

As usual, you can customize this list by editing projectile-project-root-files-top-down-recurring.

I have much less information about project.el, but it appears to be a bit less involved, just looking for Git, Mercurial, or Bazaar repos or a .projectile file.

  • I added a section into my OP at Why I failed to use projectile to explain my predicament with projectile mode. IIRC, projectile-project-root-functions is most likely the very set of functions I tried to change and failed. I don't recall how it failed but it was so miserable, and my global Emacs productivity suffered so badly, that at the time I had no choice but to ditch it completely.
    – bgoodr
    May 7, 2023 at 16:20
  • Fun times. What I would do is re-enable projectile, but set projectile-project-root-functions to just '(projectile-root-marked). Because this is a bottom–up search it will be much faster than the other possibilities. You can then add a .projectile file to the root directory of each of your projects. Projectile has a cache that is supposed to ensure that it doesn’t need to repeat this search for every file in the project that you open, once it finds it the first time. If that’s not fast enough, then you might just have to live with the prompt.
    – db48x
    May 8, 2023 at 1:15
  • Yes, what I have been doing right now is just living with the prompt. I have resisted the temptation to re-enable projectile, because of my newfound personal bias against it given how badly it burned me. Or, rather, my ignorance, of how to use it properly, burned myself. I will reconsider that.
    – bgoodr
    May 9, 2023 at 14:51

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.