diff options
| author | João Távora | 2022-12-22 11:29:49 +0000 |
|---|---|---|
| committer | João Távora | 2022-12-22 11:30:19 +0000 |
| commit | bbe35c280c2bf9fb2fd9b6e33b2950b8fae67e2c (patch) | |
| tree | 0ec21ea308e79ede56484d8fc713b5d6f750b981 | |
| parent | 9bf13a3fb9e197dfa741625fb7089ee7924cc581 (diff) | |
| download | emacs-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.el | 9 |
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. |
| 1065 | This relies on `project-current' and thus on | 1068 | This relies on `project-current' and thus on |