joaotavora / eglot

A client for Language Server Protocol servers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

eglot--connect: Symbol’s function definition is void: project-name

jaybarra opened this issue · comments

Environment

Emacs for Mac 28.2
eglot-1.13

Reproduction Steps

  1. Ensure the clangd LSP server is installed and available in path
  2. Delete or rename ~/.emacs.d
  3. Recreate ~/.emacs.d directory
  4. Recreate ~/.emacs.d/init.el with the following contents
;;; init.el --- Minimum eglot example
;;; Commentary:
;;; Code:

(unless (fboundp 'package-activate-all) (package-initialize))

;;; init.el ends here
  1. Open Emacs
  2. M-x package-install RET eglot RET
  3. M-x make-directory RET eglot-mre RET
  4. C-x C-f ~/eglot-mre/main.c RET
  5. Fill with the following
/* main.c */
int main(int argc, char *argv[]) {
  return 0;
}
  1. C-x C-s
  2. M-x eglot and receive this error in the *Messages* buffer
    eglot--connect: Symbol’s function definition is void: project-name

Reproduced. The problem goes away simply restarting Emacs.

I don't understand why project.el is being loaded as part of the package-install process of Eglot.

I don't understand why project.el is being loaded as part of the package-install process of Eglot.

Or rather, I do understand that, eglot.el has a (require 'project) which is run at compilation time.
But I don't understand why is it that, if project.el is a dependency of Eglot, and thus must be installed before, why it isn't in place already when this require happens.

Maybe @monnier can shed some light?

Is this [similar to] https://bugs.gnu.org/61048 ?

I.e. is Emacs 28.2 picking up the built-in project that lacks project-name, rather than the more recent version of project required by Eglot?

I.e. is Emacs 28.2 picking up the built-in project that lacks project-name, rather than the more recent version of project required by Eglot?

Yes. And this can happen if you have previously loaded the build in project.el before you issue M-x package-install RET eglot RET. But in this recipe, you'll notice that (featurep 'project) reports nil in the beginning. So at a certain point, the old built-in project.el is loaded, when, AFAICT only eglot.el 's compilation require s it. And by that time, the new version should have been installed already, becasue project.el is a dependency of eglot.el.

Is this [similar to] https://bugs.gnu.org/61048 ?

I'll have a look.

Is this [similar to] https://bugs.gnu.org/61048 ?

I don't think so. I think there the problem was the failure to pull in a transitive dependency right?

Here, it's -- I presume -- not having the right load-path setup by the time that the (require 'project) happens.

In the meantime, I think the best is for eglot to replace (require 'project) with (load "project") right? It's a bit unidiomatic, but I see no better way to protect users against this.

The problem can still happen very easily if you decide to M-x package-install RET eglot after doing some project.el things.

Unless we force the dependent libraries to be loaded after each package-install. Not pretty, but safer.

In theory that should not be necessary because package.el should
itself reload project.el after setting up the new path (if
project.el had been loaded earlier).

So can you follow Jay's reproduction recipe and find out why this
isn't happening?

João

Done, here's the report.

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62576

In the meaning, i think I'll put the load statements there.

In the meaning, i think I'll put the load statements there.

This is now in Eglot 1.14, I've just tested this recipe and it doesn't error anymore. Please test and report back here to reopen if it doesn'twork.

I just ran into this, and I had to explicitly (require 'eglot) before doing anything (I was originally using the autoloaded eglot function to load the library). I'm not sure if this can be fixed, or if it will just need to be mentioned as a workaround.

EDIT: A Minimum Reproducible Example is in the works, I apologize, I posted this hastily.
EDIT 2: I could not quite reproduce with a basic example, my guess is that my issue was dependent on my particular setup (the straight package manager, in particular). If anyone does run into this issue, where any of the project.el functions are being used from the built in version, rather than the version installed with eglot, just make sure to run (require 'eglot) somewhere so that the new version of project.el is used.

I just ran into this

Can you explain exactly how you ran into this? There are many possible ways to "run into this". Your require eglot doesn't make much sense.

So please, if you can, provide a Minimum Reproducible Example just like @jaybarra did.

For people using ELPACA (i am on Emacs 28.2), you need to install project first:

  (defun my-eglot-organize-imports () (interactive)
         (eglot-code-actions nil nil "source.organizeImports" t))

  (use-package project :demand t)
  
  (use-package eglot
    :demand t
    :after (project projectile)
    :hook (
           (scala-mode . eglot-ensure)
           (sh-mode . eglot-ensure)
           (python-mode . eglot-ensure)
           (java-mode . eglot-ensure)
           (yaml-mode . eglot-ensure)
           (haskell-mode . eglot-ensure)
           (go-mode . eglot-ensure)
           (dockerfile-mode . eglot-ensure)
           )
    :config
    (add-hook 'before-save-hook 'my-eglot-organize-imports nil t)
    (add-hook 'before-save-hook 'eglot-format-buffer)
    )