From: João Távora Date: Mon, 14 May 2018 18:19:12 +0000 (+0100) Subject: Proper server shutdown when jrpc.el is used X-Git-Tag: emacs-29.0.90~1616^2~524^2~4^2~489^2~27 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=35dae7034b96fe0f32bdd51377e9a2574adea374;p=emacs.git Proper server shutdown when jrpc.el is used The shutdown hook can't be a buffer-local thing, it has to be a server property. Also, on shutdown in eglot.el, remember to first unmanage buffers and only then affect eglot--processes-by-project. * eglot.el (eglot--on-shutdown): reverse order of first two sexps. (eglot--connect): Pass a shutdown function to jrpc-connect (eglot--managed-mode): Don't use jrpc-server-moribund-hook (eglot--buffer-managed-p): Simplify. Use eglot--find-current-process. --- diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 934270c43f1..f33a851eced 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -95,13 +95,14 @@ A list (ID WHAT DONE-P).") (defun eglot--on-shutdown (proc) ;; Turn off `eglot--managed-mode' where appropriate. - (setf (gethash (eglot--project proc) eglot--processes-by-project) - (delq proc - (gethash (eglot--project proc) eglot--processes-by-project))) (dolist (buffer (buffer-list)) (with-current-buffer buffer (when (eglot--buffer-managed-p proc) (eglot--managed-mode -1)))) + ;; Sever the project/process relationship for proc + (setf (gethash (eglot--project proc) eglot--processes-by-project) + (delq proc + (gethash (eglot--project proc) eglot--processes-by-project))) (cond ((eglot--moribund proc)) ((not (eglot--inhibit-autoreconnect proc)) (eglot--warn "Reconnecting unexpected server exit.") @@ -267,7 +268,7 @@ INTERACTIVE is t if called interactively." (defun eglot--connect (project managed-major-mode name command dont-inhibit) - (let ((proc (jrpc-connect name command "eglot--server-"))) + (let ((proc (jrpc-connect name command "eglot--server-" #'eglot--on-shutdown))) (setf (eglot--project proc) project) (setf (eglot--major-mode proc)managed-major-mode) (push proc (gethash project eglot--processes-by-project)) @@ -326,11 +327,11 @@ INTERACTIVE is t if called interactively." "Convert point POS to LSP position." (save-excursion (jrpc-obj :line - ;; F!@(#*&#$)CKING OFF-BY-ONE - (1- (line-number-at-pos pos t)) - :character - (- (goto-char (or pos (point))) - (line-beginning-position))))) + ;; F!@(#*&#$)CKING OFF-BY-ONE + (1- (line-number-at-pos pos t)) + :character + (- (goto-char (or pos (point))) + (line-beginning-position))))) (defun eglot--lsp-position-to-point (pos-plist) "Convert LSP position POS-PLIST to Emacs point." @@ -401,7 +402,6 @@ INTERACTIVE is t if called interactively." (eglot--managed-mode (add-hook 'jrpc-find-process-functions 'eglot--find-current-process nil t) (add-hook 'jrpc-ready-predicates 'eglot--server-ready-p nil t) - (add-hook 'jrpc-server-moribund-hook 'eglot--on-shutdown nil t) (add-hook 'after-change-functions 'eglot--after-change nil t) (add-hook 'before-change-functions 'eglot--before-change nil t) (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t) @@ -417,7 +417,6 @@ INTERACTIVE is t if called interactively." (t (remove-hook 'jrpc-find-process-functions 'eglot--find-current-process t) (remove-hook 'jrpc-ready-predicates 'eglot--server-ready-p t) - (remove-hook 'jrpc-server-moribund-hook 'eglot--on-shutdown t) (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t) (remove-hook 'after-change-functions 'eglot--after-change t) (remove-hook 'before-change-functions 'eglot--before-change t) @@ -439,11 +438,9 @@ INTERACTIVE is t if called interactively." (defun eglot--buffer-managed-p (&optional proc) "Tell if current buffer can be managed by PROC." - (and buffer-file-name - (cond ((null proc) (jrpc-current-process)) - (t (and (eq major-mode (eglot--major-mode proc)) - (let ((proj (project-current))) - (and proj (equal proj (eglot--project proc))))))))) + (and buffer-file-name (let ((cur (eglot--find-current-process))) + (or (and (null proc) cur) + (and proc (eq proc cur)))))) (defvar-local eglot--current-flymake-report-fn nil "Current flymake report function for this buffer") @@ -585,12 +582,12 @@ Uses THING, FACE, DEFS and PREPEND." _code source message) diag-spec (eglot--with-lsp-range (beg end) range - (flymake-make-diagnostic (current-buffer) - beg end - (cond ((<= severity 1) :error) - ((= severity 2) :warning) - (t :note)) - (concat source ": " message)))) + (flymake-make-diagnostic (current-buffer) + beg end + (cond ((<= severity 1) :error) + ((= severity 2) :warning) + (t :note)) + (concat source ": " message)))) into diags finally (cond (eglot--current-flymake-report-fn (funcall eglot--current-flymake-report-fn diags) @@ -657,18 +654,18 @@ Uses THING, FACE, DEFS and PREPEND." (append (eglot--VersionedTextDocumentIdentifier) (jrpc-obj :languageId - (if (string-match "\\(.*\\)-mode" (symbol-name major-mode)) - (match-string 1 (symbol-name major-mode)) - "unknown") - :text - (save-restriction - (widen) - (buffer-substring-no-properties (point-min) (point-max)))))) + (if (string-match "\\(.*\\)-mode" (symbol-name major-mode)) + (match-string 1 (symbol-name major-mode)) + "unknown") + :text + (save-restriction + (widen) + (buffer-substring-no-properties (point-min) (point-max)))))) (defun eglot--TextDocumentPositionParams () "Compute TextDocumentPositionParams." (jrpc-obj :textDocument (eglot--TextDocumentIdentifier) - :position (eglot--pos-to-lsp-position))) + :position (eglot--pos-to-lsp-position))) (defvar-local eglot--recent-changes nil "Recent buffer changes as collected by `eglot--before-change'.") @@ -931,7 +928,7 @@ DUMMY is ignored" (defun eglot--hover-info (contents &optional range) (concat (and range (eglot--with-lsp-range (beg end) range - (concat (buffer-substring beg end) ": "))) + (concat (buffer-substring beg end) ": "))) (mapconcat #'eglot--format-markup (append (cond ((vectorp contents)