branch: externals/eglot
commit 1fb2bcbde95d89edd9df638869d679e42b416b4c
Author: João Távora <joaotav...@gmail.com>
Commit: João Távora <joaotav...@gmail.com>

    Ask server for textDocument/signatureHelp if it supports it
    
    * eglot.el (eglot--client-capabilities): Capable of signature Help.
    (eglot--sig-info): Helper for eglot-eldoc-function.
    (eglot-eldoc-function): Send textDocument/signatureHelp
    
    * README.md: Update to mention textDocument/signatureHelp
---
 README.md |  2 +-
 eglot.el  | 97 ++++++++++++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/README.md b/README.md
index 4dfe0a6..39ec752 100644
--- a/README.md
+++ b/README.md
@@ -103,7 +103,7 @@ either:
 - [x] textDocument/completion
 - [x] completionItem/resolve (works quite well with 
[company-mode][company-mode])
 - [x] textDocument/hover
-- [ ] textDocument/signatureHelp
+- [x] textDocument/signatureHelp (fancy stuff with Python's [pyls[pyls]])
 - [x] textDocument/definition
 - [ ] textDocument/typeDefinition (3.6.0)
 - [ ] textDocument/implementation (3.6.0)
diff --git a/eglot.el b/eglot.el
index f6eabe1..2e872dc 100644
--- a/eglot.el
+++ b/eglot.el
@@ -211,6 +211,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
                                     :didSave t)
                   :completion         `(:dynamicRegistration :json-false)
                   :hover              `(:dynamicRegistration :json-false)
+                  :signatureHelp      `(:dynamicRegistration :json-false)
                   :references         `(:dynamicRegistration :json-false)
                   :definition         `(:dynamicRegistration :json-false)
                   :documentSymbol     `(:dynamicRegistration :json-false)
@@ -1330,6 +1331,28 @@ DUMMY is ignored"
                             (contents
                              (list contents)))) "\n")))
 
+(defun eglot--sig-info (sigs active-sig active-param)
+  (cl-loop
+   for (sig . moresigs) on (append sigs nil) for i from 0
+   concat (cl-destructuring-bind (&key label _documentation parameters) sig
+            (let (active-doc)
+              (concat
+               (propertize (replace-regexp-in-string "(.*$" "(" label)
+                           'face 'font-lock-function-name-face)
+               (cl-loop
+                for (param . moreparams) on (append parameters nil) for j from 0
+                concat (cl-destructuring-bind (&key label documentation) param
+                         (when (and (eql j active-param) (eql i active-sig))
+                           (setq label (propertize
+                                        label
+                                        'face 
'eldoc-highlight-function-argument))
+                           (when documentation
+                             (setq active-doc (concat label ": " 
documentation))))
+                         label)
+                if moreparams concat ", " else concat ")")
+               (when active-doc (concat "\n" active-doc)))))
+   when moresigs concat "\n"))
+
 (defun eglot-help-at-point ()
   "Request \"hover\" information for the thing at point."
   (interactive)
@@ -1342,35 +1365,51 @@ DUMMY is ignored"
         (insert (eglot--hover-info contents range))))))
 
 (defun eglot-eldoc-function ()
-  "EGLOT's `eldoc-documentation-function' function."
-  (let ((buffer (current-buffer))
-        (proc (eglot--current-process-or-lose))
-        (position-params (eglot--TextDocumentPositionParams)))
-    (when (eglot--server-capable :hoverProvider)
-      (eglot--async-request
-       proc :textDocument/hover position-params
-       :success-fn (eglot--lambda (&key contents range)
-                     (when (get-buffer-window buffer)
-                       (with-current-buffer buffer
-                         (eldoc-message (eglot--hover-info contents range)))))
-       :deferred :textDocument/hover))
-    (when (eglot--server-capable :documentHighlightProvider)
-      (eglot--async-request
-       proc :textDocument/documentHighlight position-params
-       :success-fn (lambda (highlights)
-                     (mapc #'delete-overlay eglot--highlights)
-                     (setq eglot--highlights
-                           (when (get-buffer-window buffer)
-                             (with-current-buffer buffer
-                               (eglot--mapply
-                                (eglot--lambda (&key range _kind)
-                                  (eglot--with-lsp-range (beg end) range
-                                    (let ((ov (make-overlay beg end)))
-                                      (overlay-put ov 'face 'highlight)
-                                      (overlay-put ov 'evaporate t)
-                                      ov)))
-                                highlights)))))
-       :deferred :textDocument/documentHighlight)))
+  "EGLOT's `eldoc-documentation-function' function.
+If SKIP-SIGNATURE, don't try to send textDocument/signatureHelp."
+  (let* ((buffer (current-buffer))
+         (proc (eglot--current-process-or-lose))
+         (position-params (eglot--TextDocumentPositionParams))
+         sig-showing)
+    (cl-macrolet ((when-buffer-window
+                   (&body body) `(when (get-buffer-window buffer)
+                                   (with-current-buffer buffer ,@body))))
+      (when (eglot--server-capable :signatureHelpProvider)
+        (eglot--async-request
+         proc :textDocument/signatureHelp position-params
+         :success-fn (eglot--lambda (&key signatures activeSignature
+                                          activeParameter)
+                       (when-buffer-window
+                        (when (cl-plusp (length signatures))
+                          (setq sig-showing t)
+                          (eldoc-message (eglot--sig-info signatures
+                                                          activeSignature
+                                                          activeParameter)))))
+         :deferred :textDocument/signatureHelp))
+      (when (eglot--server-capable :hoverProvider)
+        (eglot--async-request
+         proc :textDocument/hover position-params
+         :success-fn (eglot--lambda (&key contents range)
+                       (unless sig-showing
+                         (when-buffer-window
+                          (eldoc-message (eglot--hover-info contents range)))))
+         :deferred :textDocument/hover))
+      (when (eglot--server-capable :documentHighlightProvider)
+        (eglot--async-request
+         proc :textDocument/documentHighlight position-params
+         :success-fn (lambda (highlights)
+                       (mapc #'delete-overlay eglot--highlights)
+                       (setq eglot--highlights
+                             (when-buffer-window
+                              (eglot--mapply
+                               (eglot--lambda (&key range _kind)
+                                 (eglot--with-lsp-range (beg end) range
+                                   (let ((ov (make-overlay beg end)))
+                                     (overlay-put ov 'face 'highlight)
+                                     (overlay-put ov 'evaporate t)
+                                     ov)))
+                               highlights))))
+         :deferred :textDocument/documentHighlight))))
   nil)
 
 (defun eglot-imenu (oldfun)

Reply via email to