Subject: Re: bug#76683: [PATCH] Eglot: Implement additionalPropertiesSupport for showMessage

From: Felician Nemeth <[email-masked]>
Date: Sun, 02 Mar 2025 16:16:50 +0100

> * Why did you remove the gh#627 reference?  Not relevant anymore?

I think the note about gh#627 warned the reader that a "vector to list
conversion" was necessary.  However, mapcar can work with vectors, so
the reference is not relevant anymore.

> * Could eglot--lambda be used for simplicity (I know it wasn't used
> before)

I think it won't be simpler, but it might be easier to understand the
intent of the code.  However, I don't know how it is possible to rewrite
the lambda.  How can we access the original object from the body of
eglot--lambda?

The patch has this: (lambda (a) (cons (plist-get a :title) a))

It should be turned into something like this:

(eglot--lambda ((MessageActionItem) title)
   (cons title orignal-object))

> * Are you 100% we'll return an 'equal' object for servers that don't
> make use of this feature?

The specification says: "result: the selected MessageActionItem".  If
the server does not send additional properties, the new version will
return what the original one returns: an object with a single title
property.  So this patch should not cause any trouble to servers
following the specification.

Although, there is a corner case when the new version gives different
result.  The original version can return (:title "OK") for an empty
action list, which is not in line with the specification.  The updated
patch returns :null in this case.

> * In the original version it was obvious the structure returned, now
> not so much.   Maybe
> a very short comment showing what the typical object looks like.

I added a comment and extended the docstring.

> After evaluating this, and doing changes (if any), feel free to push.

After your last email, I requested inclusion for the emacs group at
savannah three weeks ago.  Nothing happened since then, which I
interpret as polite rejection.

I've attached the updated patch.

Thanks again,
Felicián

>From dbf47c6cb2be29842d0bcb6852f1365cd401a1e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felici=C3=A1n=20N=C3=A9meth?= <[email-masked]>
Date: Sun, 2 Mar 2025 14:18:48 +0100
Subject: [PATCH] Eglot: Implement additionalPropertiesSupport for showMessage

This feature was introduced in LSP v3.16.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#window_showMessageRequest

* lisp/progmodes/eglot.el (eglot-client-capabilities): Set
window/showMessage/messageActionItem/additionalPropertiesSupport to t.
(eglot-handle-request window/showMessageRequest): Return the whole
selected ActionItem, not just its title.
---
 lisp/progmodes/eglot.el | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 1920d835cc3..1fac26be302 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -1089,6 +1089,8 @@ eglot-client-capabilities
                                          [,@(mapcar
                                              #'car eglot--tag-faces)])))
             :window `(:showDocument (:support t)
+                      :showMessage (:messageActionItem
+                                    (:additionalPropertiesSupport t))
                       :workDoneProgress ,(if eglot-report-progress t :json-false))
             :general (list :positionEncodings ["utf-32" "utf-8" "utf-16"])
             :experimental eglot--{})))
@@ -2593,18 +2595,23 @@ eglot-handle-notification
 (cl-defmethod eglot-handle-request
   (_server (_method (eql window/showMessageRequest))
            &key type message actions &allow-other-keys)
-  "Handle server request window/showMessageRequest."
-  (let* ((actions (append actions nil)) ;; gh#627
+  "Handle server request window/showMessageRequest.
+Make the user select from a list of action items, and return the
+selected item to the server.
+"
+  ;; Argument `actions' is a list of MessageActionItems.  A
+  ;; MessageActionItem must have a :title property, but it can have
+  ;; additional properties as well.
+  (let* ((actions (mapcar (lambda (a) (cons (plist-get a :title) a)) actions))
          (label (completing-read
                  (concat
                   (format (propertize "[eglot] Server reports (type=%s): %s"
                                       'face (if (or (not type) (<= type 1)) 'error))
                           type message)
                   "\nChoose an option: ")
-                 (or (mapcar (lambda (obj) (plist-get obj :title)) actions)
-                     '("OK"))
-                 nil t (plist-get (elt actions 0) :title))))
-    (if label `(:title ,label) :null)))
+                 (or actions '("OK"))
+                 nil t (caar actions))))
+    (if label (or (cdr (assoc label actions)) :null) :null)))
 
 (cl-defmethod eglot-handle-notification
   (_server (_method (eql window/logMessage)) &key _type _message)
-- 
2.39.5

> João
>
> On Sun, Mar 2, 2025 at 1:40 PM Felician Nemeth
> <[email-masked]> wrote:
>>
>> Hi João,
>>
>> This small patch implements a harmless feature introduced in LSP version
>> 3.16:
>> https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#window_showMessageRequest
>>
>> It allows me to implement a rust-analyzer feautre in a simple, stateless
>> manner.
>>
>> Thank you,
>> Felicián
>>