joaotavora / eglot

A client for Language Server Protocol servers
GNU General Public License v3.0
2.25k stars 200 forks source link

eglot causes emacsclient to exit immediately on first load #1310

Closed asmeurer closed 11 months ago

asmeurer commented 11 months ago

I am using emacsclient with emacs 28.1, and ever since I installed eglot, when I first start a client, it immediately exits. If I run the command again it opens.

Here is a reproducer:

;; .emacs
(package-initialize)

(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))

;; my git clone of https://github.com/jwiegley/use-package
(add-to-list 'load-path "~/Documents/use-package")
(require 'use-package)

(setq use-package-always-ensure t)

(use-package eglot)
(add-hook 'prog-mode-hook 'eglot-ensure)
$ emacs -nw --daemon
$ emacsclient -nw somefile # exits
$ emacsclient -nw somefile # works

without eglot, the first emacsclient -nw somefile works.

joaotavora commented 11 months ago

Please answer the following (also reading https://joaotavora.github.io/eglot/#Troubleshooting-Eglot is recommended)

  1. What is somefile?
  2. What server are you using?
  3. Can you get rid of the line with eglot-ensure and first confirm that M-x eglot works?
  4. Can you post the contents of the Eglot events buffer?

I can't reproduce this with Emacs 29.1 with this much simpler recipe:

emacs -Q -nw --eval '(add-hook (quote prog-mode-hook) (quote eglot-ensure))' --daemon
emacsclient -nw /path/to/a/c++/file

Server is clangd.

Adding eglot-ensure to prog-mode-hook is a bad idea IMO. You should only use eglot-ensure when you yourself can ensure that Eglot can start cleanly for any file of a given major mode. It's very suspicious that you can make sure of this for basically almost every programming file visited in Emacs.

Please, as the instructions indicate, try to avoid use-package. Also avoid MELPA, Eglot is available from ELPA.

asmeurer commented 11 months ago

Happy to test this without use-package. Is there a oneliner that can be used to test it from emacs -Q?

I don't have easy access to emacs 29.1.

asmeurer commented 11 months ago

My goal with the prog-mode thing is just to use eglot whenever I can. I don't know what language servers I happen to have installed and I don't want to think about it for the rare cases when I open a file in some language other than the 2 or 3 I use day-to-day (case in point, I do have clangd installed, but I rarely open .c files).

joaotavora commented 11 months ago

Happy to test this without use-package. Is there a oneliner that can be used to test it from emacs -Q?

Use this

HOME=`mktemp -d` emacs --eval '(package-install (quote eglot))' -nw --eval '(add-hook (quote prog-mode-hook) (quote eglot-ensure))' --daemon
emacsclient -nw /path/to/a/c++/file

My goal with the prog-mode thing is just to use eglot whenever I can. I don't know what language servers I happen to have installed and I don't want to think about it for the rare cases when I open a file in some language other than the 2 or 3 I use day-to-day (case in point, I do have clangd installed, but I rarely open .c files).

Yes, but if you don't have a server installed for a given major mode, eglot-ensure will error. Emacsclient doesn't change that, but the error is probably making emacsclient bail when trying to visit a new file. The "ensure" part of it does not go so far as to figure out which server is needed and download it. Again, use of eglot-ensure is only viable/recommended once you yourself can ensure that it can start manually.

joaotavora commented 11 months ago

Closing this since I've now reproduced the problem by visiting a file of a major mode I don't have a server for. Make sparse use of eglot-ensure or don't use it at all. You can M-x eglot in a project and it will remember files in that project and activate itself automatically. If you feel like typing M-x is too much, you can bind it to a key.

asmeurer commented 11 months ago

There's a few things here, which are independent, but I think they are all valid:

Really this issue is about the second thing. I can open separate issues for the other two if you like.

joaotavora commented 11 months ago

eglot ought to have a way to just "enable when it can" without any user interaction. That's the best user experience.

M-x eglot already is that feature, in an amortized way at least. You usually do it once per project and forget about it. Asking for Eglot to enable itself in every possible file-visiting situation is asking for trouble since there are situations of projects containing other projects, files at the root of the file system where it may or may not make sense to enable LSP (sometimes with disastrous consequences in terms of system resources). So abusing M-x eglot-ensure is a bad idea.

An eglot error shouldn't kill emacsclient

It's an Emacs error, not an Eglot error. eglot-ensure is specified to error out if it can't find a server. If Emacsclient finds an error in the post-command-hook (as is the case) of a command issued from the Emacsclient, it bails you back to the shell. That's an Emacs behaviour, not an Eglot one.

Note that I am getting this error for files that I definitely have a server installed for. And as I noted, it works the second time I try to open the file, just not the first time.

You need to answer those four questions. I think I'm doing a bit too much guesswork for such an poorly-specified issue. I thought it was due to the daring "eglot-ensure in prog-mode" heroics, it might not be. That's the only way I can reproduce something vaguely similar to this.