Subject: eglot sends first didOpen before didChangeConfiguration.

From: Stephen Leake <[email-masked]>
Date: Thu, 24 Nov 2022 17:24:56 -0800

I'm running emacs master, in Debian testing, with ada_language_server
version 23, and a development version of ada-mode.

In the simplest configuration, ada-mode starts eglot from a function on
ada-mode hook. That's how the tree-sitter and wisi parsers are started,
as well, when they are configured. The user just installs the Ada
language server, opens an Ada mode file, and expects to get eglot
services; they don't have to type M-x eglot.

As part of eglot startup, ada-mode binds eglot-workspace-configuration
with a parameter for ada_language_server (als) specifying the compiler
project file. That should be passed in initializationOptions, but the
current als doesn't support that (I've submitted an issue to als on
that).

Then eglot sends textDocument/didOpen before it sends
workspace/didChangeConfiguration, so the server reports errors when it
opens the document without the compiler project file. The attached log
shows the LSP messages, captured from the *EGLOT ada-mode...* buffer.

The sequence of lisp calls is this:

find-file runs ada-mode, which runs ada-mode-hook, which calls
ada-eglot-setup, which binds eglot-workspace-configuration and calls
eglot. That calls eglot-connect, which sends the initialize message, and
in effect queues the didChangeConfiguration message to be sent after the
initialize response is received.

ada-mode returns to find-file, which runs find-file-hook, which has
eglot--maybe-activate-editing-mode; that calls 
eglot--signal-textDocument/didOpen without checking if the server is
done processing initialize.

So the server gets the didOpen message before it gets the
didChangeConfiguration messages, and possibly before the initialize
response is sent, which would violate the LSP startup protocol
(https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize).

I can eliminate the errors by starting eglot via a wisi project before
any Ada files are opened, and waiting a short time. But the use case
presented above is typical for a newbie (not expected to use a wisi
project), and it is also how Eurocontrol expects things to work for
their complex projects, so I'd like to be able to eliminate the errors.

One way to fix this is for eglot--maybe-activate-editing-mode to check
if the server is initialized (maybe by checking if eglot--capabilities
is set?), and enqueue the didOpen message to be sent after the
initialize response is recieved if not. I did not look in jsonrpc for an
"enqueue" function; it would be similar to the :success-fn arg in
jsonrpc-async-request, so I assume there's a way to do it.

--
-- Stephe