emacs-31 83ec0fd8f33: Eglot: prevent showDocument disruption of sync requests (bug#81538)
João Távora <[email protected]>
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: emacs-31 commit 83ec0fd8f33e36672032201862cbf500e0063733 Author: João Távora <[email protected]> Commit: João Távora <[email protected]> Eglot: prevent showDocument disruption of sync requests (bug#81538) This couldn't be reproduced here, but seems nevertheless possible. The previous (run-at-time 0...) technique for the window/showDocument handling never really avoided the fact that that timer could kick during the accept-process-output of jsonrpc-request, thus happening before the response to the original request. Since the handling evolves a lot of output to send to the process, it could be interrupted by the 'throw' that's meant to exit abort 'accept-process-output' (and only that). This commit should ensure the sequence is always this one. a1. -> adals/ff-thingy sync client request b1. <- window/showDocument server request b2. -> window/showDocument client response (after scheduling 'c') a2. <- ada/ff-thingy server response c. -> f-f-no-select, Eglot sends the large didOpen notification * lisp/progmodes/eglot.el (eglot-handle-request): Maybe use "post command" once trick. --- lisp/progmodes/eglot.el | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 1f4f6abbd91..e53d2a08159 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -2962,19 +2962,22 @@ THINGS are either registrations or unregisterations (sic)." (cond ((eq external t) (browse-url uri)) ((file-readable-p (setq filename (eglot-uri-to-path uri))) - ;; Use run-with-timer to avoid nested client requests like the - ;; "synchronous imenu" floated in bug#62116 presumably caused by - ;; which-func-mode. - (run-with-timer - 0 nil - (lambda () - (with-current-buffer (find-file-noselect filename) - (cond (takeFocus - (pop-to-buffer (current-buffer)) - (select-frame-set-input-focus (selected-frame))) - ((display-buffer (current-buffer)))) - (when selection - (eglot--goto selection)))))) + ;; Really ensure this runs when it is safe to run it. + ;; run-with-timer avoid nested client requests like the + ;; "synchronous imenu" floated in bug#62116, while the + ;; "post-command once" trick is for bug#81538. + (cl-labels ((findit () + (remove-hook 'post-command-hook #'findit) + (with-current-buffer (find-file-noselect filename) + (cond (takeFocus + (pop-to-buffer (current-buffer)) + (select-frame-set-input-focus (selected-frame))) + ((display-buffer (current-buffer)))) + (when selection + (eglot--goto selection))))) + (if this-command + (add-hook 'post-command-hook #'findit) + (run-at-time 0 nil #'findit)))) (t (setq success :json-false))) `(:success ,success)))