From bbe35c280c2bf9fb2fd9b6e33b2950b8fae67e2c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Thu, 22 Dec 2022 11:29:49 +0000 Subject: [PATCH] Prevent stale servers when using eglot-extend-to-xref A weak-valued hash-table is not enough to guarantee that a reference to a zombie server in eglot--servers-by-xrefed-file variable won't survive long enough to confuse the next call to eglot--current-server in some buffers. So, before this fix it was common to get "Process EGLOT ... not running" errors if some xref-extended buffers (like system libraries) were open and M-x eglot-reconnect was issued. This should be prevented now. Note however, that even after this the eglot-extend-to-xref logic is still flawed. For example, if a buffer for the xref-extended buffer happens to be already visited by the time M-. is issued to navigate to it, Eglot won't be activated. A half-decent workaround is to kill the buffer and re-visit it. * lisp/progmodes/eglot.el (eglot--servers-by-xrefed-file): Move up. (eglot--on-shutdown): Make sure to cleanup eglot--servers-by-xrefed-file. --- lisp/progmodes/eglot.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 0f1bfd0447d..e7782ea8112 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -908,6 +908,9 @@ PRESERVE-BUFFERS as in `eglot-shutdown', which see." do (with-demoted-errors "[eglot] shutdown all: %s" (cl-loop for s in ss do (eglot-shutdown s nil nil preserve-buffers))))) +(defvar eglot--servers-by-xrefed-file + (make-hash-table :test 'equal :weakness 'value)) + (defun eglot--on-shutdown (server) "Called by jsonrpc.el when SERVER is already dead." ;; Turn off `eglot--managed-mode' where appropriate. @@ -926,6 +929,9 @@ PRESERVE-BUFFERS as in `eglot-shutdown', which see." (setf (gethash (eglot--project server) eglot--servers-by-project) (delq server (gethash (eglot--project server) eglot--servers-by-project))) + (maphash (lambda (f s) + (when (eq s server) (remhash f eglot--servers-by-xrefed-file))) + eglot--servers-by-xrefed-file) (cond ((eglot--shutdown-requested server) t) ((not (eglot--inhibit-autoreconnect server)) @@ -1057,9 +1063,6 @@ be guessed." (put 'eglot-lsp-context 'variable-documentation "Dynamically non-nil when searching for projects in LSP context.") -(defvar eglot--servers-by-xrefed-file - (make-hash-table :test 'equal :weakness 'value)) - (defun eglot--current-project () "Return a project object for Eglot's LSP purposes. This relies on `project-current' and thus on -- 2.39.2