bug#81538: 32.0.50; Eglot: Non-local exit during window/showDocument handling
Troy Brown via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <CABvCZ432uPPiEsHP1XkhvOBUX1iL-1buj9H1jLH8amYatK-AOQ@mail.gmail.com> |
On Thu, Aug 6, 2026 at 5:46 AM João Távora <[email protected]> wrote: > > OK, thanks. I think I understood what happens, and it can be summarized > in two lines. > > "Using Eglot with the Ada server and my own major mode. Typing 'M-x > foo' to jump to bar.ada mostly works, but bar.ada's Eglot is broken :-(" Yes, roughly that is a valid description. > > This modified ERT test for my major mode exhibits the problem on my > > machine quite often. > > Wait, but does it also happens interactively right? Or does it _only_ > happen in ERT tests? Yes, it absolutely happens interactively. The command is bound to C-c C-o in the major mode and interactive use is where the problem was discovered. I modified an existing test to try and create a reproducible scenario with larger files, enabled traces and output of the Eglot event log. > In other words, you seem to be describing these 5 events > > a1. -> adals/ff-thingy sync client request (eglot-execute-command, interactive, from user) > b1. <- window/showDocument server request > c. -> f-f-no-select, Eglot sends the large didOpen notification > b2. -> window/showDocument client response > a2. <- ada/ff-thingy server response > > And your description is that in certain situations ('a2' is sitting in > the pipes ready to go early and 'c' is reasonably large), 'a2' is > processed ahead of time, and the ensuing 'throw' causes important steps > near 'c' to be skipped. I agree that this would indeed be problematic. > But Eglot's method: > > (cl-defmethod eglot-handle-request (_server (_method (eql > window/showDocument)) > > has a provision to execute 'c' in a "run-with-timer 0". Put > differently, the intent here is "agree what to do, finish the > transaction, only then go to the thing"". So the intended sequence of > events should in theory, be: > > a1. -> adals/ff-thingy sync client request (eglot-execute-command, interactive, from user) > b1. <- window/showDocument server request > b2. -> window/showDocument client response > a2. <- ada/ff-thingy server response > c. -> f-f-no-select, Eglot sends the large didOpen notification > > Except, according to your observations, it is not.... I don't think `a2` arrives early, I think it is triggered by the server having received `b2` (which is transmitted prior to the processing of `c` as you've noted above). Looking at the Eglot event logs shows about 50ms between when `b2` is sent and when `a2` arrives. During this 50ms window is when I believe the timer which contains`c` starts to be processed by Emacs. > I will look into this some more from the jsonrpc.el side, but can you > try this silly patch and see if the problem goes away? > > @@ -2965,7 +2965,7 @@ eglot-handle-request > ;; "synchronous imenu" floated in bug#62116 presumably caused by > ;; which-func-mode. > (run-with-timer > - 0 nil > + 0.1 nil > (lambda () > (with-current-buffer (find-file-noselect filename) > (cond (takeFocus Yes, this patch does seem to fix the problem...at least I couldn't reproduce it after applying it. I believe the 100ms delay ensures that `a2` is received prior to starting to process `c`, at least on my machine. I think the interesting thing to note are the traces in the attached trace log in the original email. Looking at nested traced function call #15 (jsonrpc-connection-send) and #17 (jsonrpc-connection-receive) shows that there is a way to receive data while the transmission of data has not yet completed, which correlates to the reception of `a2` while in the middle of sending the large `c`. Troy.