aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2022-12-22 11:29:49 +0000
committerJoão Távora2022-12-22 11:30:19 +0000
commitbbe35c280c2bf9fb2fd9b6e33b2950b8fae67e2c (patch)
tree0ec21ea308e79ede56484d8fc713b5d6f750b981
parent9bf13a3fb9e197dfa741625fb7089ee7924cc581 (diff)
downloademacs-bbe35c280c2bf9fb2fd9b6e33b2950b8fae67e2c.tar.gz
emacs-bbe35c280c2bf9fb2fd9b6e33b2950b8fae67e2c.zip
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.
-rw-r--r--lisp/progmodes/eglot.el9
1 files 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."
908 do (with-demoted-errors "[eglot] shutdown all: %s" 908 do (with-demoted-errors "[eglot] shutdown all: %s"
909 (cl-loop for s in ss do (eglot-shutdown s nil nil preserve-buffers))))) 909 (cl-loop for s in ss do (eglot-shutdown s nil nil preserve-buffers)))))
910 910
911(defvar eglot--servers-by-xrefed-file
912 (make-hash-table :test 'equal :weakness 'value))
913
911(defun eglot--on-shutdown (server) 914(defun eglot--on-shutdown (server)
912 "Called by jsonrpc.el when SERVER is already dead." 915 "Called by jsonrpc.el when SERVER is already dead."
913 ;; Turn off `eglot--managed-mode' where appropriate. 916 ;; Turn off `eglot--managed-mode' where appropriate.
@@ -926,6 +929,9 @@ PRESERVE-BUFFERS as in `eglot-shutdown', which see."
926 (setf (gethash (eglot--project server) eglot--servers-by-project) 929 (setf (gethash (eglot--project server) eglot--servers-by-project)
927 (delq server 930 (delq server
928 (gethash (eglot--project server) eglot--servers-by-project))) 931 (gethash (eglot--project server) eglot--servers-by-project)))
932 (maphash (lambda (f s)
933 (when (eq s server) (remhash f eglot--servers-by-xrefed-file)))
934 eglot--servers-by-xrefed-file)
929 (cond ((eglot--shutdown-requested server) 935 (cond ((eglot--shutdown-requested server)
930 t) 936 t)
931 ((not (eglot--inhibit-autoreconnect server)) 937 ((not (eglot--inhibit-autoreconnect server))
@@ -1057,9 +1063,6 @@ be guessed."
1057(put 'eglot-lsp-context 'variable-documentation 1063(put 'eglot-lsp-context 'variable-documentation
1058 "Dynamically non-nil when searching for projects in LSP context.") 1064 "Dynamically non-nil when searching for projects in LSP context.")
1059 1065
1060(defvar eglot--servers-by-xrefed-file
1061 (make-hash-table :test 'equal :weakness 'value))
1062
1063(defun eglot--current-project () 1066(defun eglot--current-project ()
1064 "Return a project object for Eglot's LSP purposes. 1067 "Return a project object for Eglot's LSP purposes.
1065This relies on `project-current' and thus on 1068This relies on `project-current' and thus on