Closed VernonGrant closed 1 year ago
(Commit https://github.com/emacs-mirror/emacs/commit/b6a7b42b199d4e96312bf8147d36dddbcf14f4ea removes the intelephense support, I wonder why.)
You haven't attached the communication logs to your report. Without the logs, I'm just guessing, but they might show that Eglot sends the deleted directory the second time as well, which in turn, might be the result of the caching mechanisms of project.el.
Hi @nemethf, thanks for responding. I'm sure its not an issue with Intelephense as it works just fine in VSCode and I did also try PHPActor, and it has the exact same problem. So it seems we have the same issue in two different language servers, that both work in fine other tools. Where can I find the communication logs?
Eglot sends the deleted directory the second time as well, which in turn, might be the result of the caching mechanisms of project.el.
Let me look into this, thanks!
Where can I find the communication logs?
This page has that info. I suggest you visit it and study it briefly to make sure you give us everything mentioned there, including, for example, how you started Emacs.
https://joaotavora.github.io/eglot/#Troubleshooting-Eglot
When you say that visiting a file makes Eglot connect, I find that surprising, because a stock Eglot doesn't do that. So you must have some user config somewhere.
In fact, i think you found the events log already, but you called it the "error message". An error in Elisp would be something different, you normally see it and hear it.
When you say that visiting a file makes Eglot connect, I find that surprising, because a stock Eglot doesn't do that. So you must have some user config somewhere.
@joaotavora I apologize, I do have hooks configured through use-package
. But you can obviously just run M-x: eglot
in the buffer to connect to the LSP. I updated the issue statement with my Eglot config.
Let me take a look at the link, thanks!
@joaotavora Ok, I updated the issue statement with more information. Please take a look at the backtrace, it reports Directory does not exist for the folder I deleted in the example. It seems to be related to workspace/didChangeWatchedFiles
. Let me know if there's anything else you need.
I updated the issue statement with my Eglot config.
If you can reproduce it with a minimal configuration, as you said, then please I urge you provide that configuration, ideally that non-configuration. Else this is just going to take longer to analyze -- if if one ever picks it up. There's a inverse relation between the size of your config and the time it takes to solve a problem.
But fortunately, in the error backtrace you provided I'm starting to see glimpses of the cause for this. It has to do with the server asking Emacs/Eglot to watch files that don't exist anymore.
I still don't understand clearly what leads to this. There are instructions in "Reproducing the issue" and more instructions in "Backtrace". But when exactly does the error happen? I need to trace the steps you take exactly in my mind or in my reproduction of your experiment.
Please write the "steps taken:" like so:
M-x step-three
C-x C-f file-of-step-five
. Press enter.Ok, I updated the issue statement again. This video demonstration might also be helpful. Let me know if things are more clear now.
I'm still missing the full events buffer. It can't possible be just
[internal] Sun Apr 2 13:33:36 2023:
(:message "Connection state changed" :change "exited abnormally with code 1\n")
----------b---y---e---b---y---e----------
[stderr]
[stderr]
[stderr] nil
[stderr] nil
[stderr] Process EGLOT (WordPress-Starter-Theme/(php-mode phps-mode)) stderr finished
It also seems like a server bug to me. The server is asking to watch a directory that doesn't exist, and Emacs complains. But this shouldn't kill the connection. Maybe the server doesn't like the reply, but it shouldn't bail just because of that.
At least this is I can read in the minuscule portion of the Eglot events buffer that you posted. Can you post the full log for the second time you open Emacs? That's steps 8-10 in your recipe. Also please do consider not using eglot-ensure
, as recommended. It's just a matter of typing M-x eglot
after visiting the file, i.e. step 9.5 in that recipe would be "type M-x eglot".
eglot-ensure
is known to be problematic, so I'd like to rule out that class of problems, i.e. know for sure if the problem happens with M-x eglot
too.
@joaotavora Noted, I updated the events buffer portion in the issue statement with the full log. And I also removed all eglot-ensure
hooks from the config and updated the steps. I can confirm the same issue persists.
It also seems like a server bug to me. The server is asking to watch a directory that doesn't exist, and Emacs complains. But this shouldn't kill the connection. Maybe the server doesn't like the reply, but it shouldn't bail just because of that.
I see, but why does PHPactor, a different PHP LSP server have the exact same issue?
I see, but why does PHPactor, a different PHP LSP server have the exact same issue?
Maybe it uses the same logic? maybe one was inspired by the other, or maybe it uses the same code/library?
But after seeing the event log, I don't think the server is at fault here. It just asks to watch a "glob" and that is somewhat innocent. I think what happens is that the files that Emacs thinks are included in that glob isn't coming from the file system itself, but rather from project.el's idea of what the project files are.
So.... @nemethf was on to something from the beginning :-D
So.... @nemethf was on to something from the beginning :-D
I had problems with project.el in the past, but my guess this time wasn't perfect as the recipe restarts Emacs.
At any rate, if I read the source correctly, project.el in project--vc-list-files
collects the files of a project by basically executing git ls-files -c -o
, which is probably much faster than actually examining a large directory tree. However, that command includes deleted files that are not yet committed.
I'm no git expert, so I cannot suggest a substitute command, but git ls-files -d
lists the deleted files.
Maybe we can call @dgutov, maintainer of project.el
here and ask him if project-files
should return files that don't exist anymore.
If so, then a fix to Eglot is in order, and the matter seems easy to solve. Else, that fix can go in temporarily to eglot.el
, but then if and when project.el
fixes this, I don't know if the fix should stay, because theoretically we want Eglot to complain to the server if the file doesn't exist.
At any rate I think a server shouldn't do hara-kiri over an error report from the client, but that's another matter...
I've now fixed this in Emacs 29's Eglot, meaning it will make its way into GNU ELPA soon. In the meantime, @VernonGrant, you may try this patch:
commit 86cf9fd932c654cc502bedf634458a918ee5e9cb
Author: João Távora <joaotavora@gmail.com>
Date: Sun Apr 2 23:01:29 2023 +0100
Eglot: don't watch directories that don't exist
project-files isn't guaranteed to return existing files, so better
check if they exist because placing a watcher on them.
Originally reported at:
https://github.com/joaotavora/eglot/issues/1198
* lisp/progmodes/eglot.el (eglot-register-capability
workspace/didChangeWatchedFiles): Check if directories exist.
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 8f64f849d72..4a9209ab9b4 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -3433,8 +3433,9 @@ eglot-register-capability
(unwind-protect
(progn
(dolist (dir dirs-to-watch)
- (push (file-notify-add-watch dir '(change) #'handle-event)
- (gethash id (eglot--file-watches server))))
+ (when (file-readable-p dir)
+ (push (file-notify-add-watch dir '(change) #'handle-event)
+ (gethash id (eglot--file-watches server)))))
(setq
success
`(:message ,(format "OK, watching %s directories in %s watchers"
Thanks for the report! I'm closing this, but let me know if this doesn't fix it, in which case I'll reopen.
Maybe we can call @dgutov, maintainer of project.el here and ask him if project-files should return files that don't exist anymore.
In theory, it shouldn't. In practice, deletion detection might be pretty costly.
E.g., in a larger project over here, the difference between git ls-files -cot >/dev/null
and git ls-files -codt >/dev/null
, is about 2x, which would slow down the full project-files call by about 1.5x, not to mention the more difficult parsing of the output.
This is definitely something to consider, but let's maybe see if most problems with this behavior can be solved by easier methods, and whether this comes up frequently enough. IIUC, this is a problem only when the file has been rm
-d but not git rm
-d.
Let's keep this discussion open somewhere: maybe file it with M-x report-emacs-bug
.
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62633 is the Emacs bug report.
@joaotavora The patch is working just fine. Thanks for all the effort 🙏🏻
For me, executing project-forget-project
on problematic project and re-opening the project did work, but I assume it's a temporarily solution
This problem is fixed/worked around in Eglot 1.14. you can add more information about the project.el problem by sending email to the bug tracker, https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62633
I've been struggling with a strange bug the past two days. I think it's related to
Git
in some way. Let me briefly explain the issue:I would open up a PHP project and navigate to a source file in the project root. Eglot will successfully connect to the LSP server, in my case Intelephense (the same issue exists using
phpactor
). Everything works as expected, but once I delete any directory inside of the projects root folder. All future Eglot connections, meaning closing and reopening Emacs, or callingeglot-shutdown-all
and reconnecting, will just completely blow up and fail. No matter what I tried, Eglot refused to reconnect to the LSP server that was working before.Now here's the stange thing, once I commit the changes into version control or just revert back the deleted folder, Eglot reconnects and everything works again. So I'm thinking this might be related to a misuse of
git ls-files
or something.What I tried
Steps taken to reproducing this issue
Assuming you already have Intelephense installed (
npm i -g intelephense
) and you use this configuration:You can do the following:
git clone https://github.com/mattbanks/WordPress-Starter-Theme.git
cd ./WordPress-Starter-Theme && emacs ./
C-x C-f
and openfunctions.php
M-x eglot
and press enter and wait for Eglot to successfully connect to the LSP.rm -R ./lib
(in the same terminal window)emacs ./
C-x C-f
and openfunctions.php
M-x eglot
and press enter and now Eglot's connection to the LSP will now fail.Eglot events buffer output
Backtrace
I ran
toggle-debug-on-error
in Emacs. Open the sample repository and deleted the lib folder. Eglot failed to connect, resulting in:Emacs details
Installed packages
My system details:
@joaotavora Let me know if there's anything I can help with, I have some time available this week and know a little bit of Emacs lisp 🙏🏻