]> git.eshelyaron.com Git - emacs.git/commitdiff
Eglot: more work on eglot--sig-info (bug#62687)
authorJoão Távora <joaotavora@gmail.com>
Sat, 8 Apr 2023 22:26:43 +0000 (23:26 +0100)
committerJoão Távora <joaotavora@gmail.com>
Sat, 8 Apr 2023 22:28:03 +0000 (23:28 +0100)
Simplify function and now also consider individual parameter
documentation strings, which typescript-language-server seems to
provide.

* lisp/progmodes/eglot.el (eglot--sig-info): Rework.

lisp/progmodes/eglot.el

index b10344a706bf4ac6df6590ade800e5922f0594ae..3f00281e15569866eec1990d96e9acd4a67d93e7 100644 (file)
@@ -3118,44 +3118,55 @@ for which LSP on-type-formatting should be requested."
   (mapconcat #'eglot--format-markup
              (if (vectorp contents) contents (list contents)) "\n"))
 
-(defun eglot--sig-info (sig &optional sig-help-active-param briefp)
-  (eglot--dbind ((SignatureInformation) label documentation parameters activeParameter)
+(defun eglot--sig-info (sig &optional sig-active briefp)
+  (eglot--dbind ((SignatureInformation)
+                 ((:label siglabel))
+                 ((:documentation sigdoc)) parameters activeParameter)
       sig
     (with-temp-buffer
-      (save-excursion (insert label))
-      (let ((active-param (or activeParameter sig-help-active-param))
-            (labeldoc (and (not briefp) documentation
-                           (eglot--format-markup documentation)))
-            params-start params-end)
-        ;; Ad-hoc attempt to parse label as <name>(<params>)
+      (save-excursion (insert siglabel))
+      ;; Ad-hoc attempt to parse label as <name>(<params>)
         (when (looking-at "\\([^(]*\\)(\\([^)]+\\))")
-          (setq params-start (match-beginning 2) params-end (match-end 2))
           (add-face-text-property (match-beginning 1) (match-end 1)
                                   'font-lock-function-name-face))
         ;; Add documentation, indented so we can distinguish multiple signatures
-        (when labeldoc
+        (when-let (doc (and (not briefp) sigdoc (eglot--format-markup sigdoc)))
           (goto-char (point-max))
-          (insert "\n" (replace-regexp-in-string "^" "  " labeldoc)))
-        ;; Decide what to do with the active parameter...
-        (when (and active-param (< -1 active-param (length parameters)))
-          (eglot--dbind ((ParameterInformation) label)
-              (aref parameters active-param)
-            ;; ...perhaps highlight it in the formals list
-            (when params-start
-              (goto-char params-start)
-              (pcase-let
-                  ((`(,beg ,end)
-                    (if (stringp label)
-                        (let ((case-fold-search nil))
-                          (and (re-search-forward
-                                (concat "\\<" (regexp-quote label) "\\>")
-                                params-end t)
-                               (list (match-beginning 0) (match-end 0))))
-                      (mapcar #'1+ (append label nil)))))
-                (if (and beg end)
-                    (add-face-text-property
-                     beg end
-                     'eldoc-highlight-function-argument)))))))
+          (insert "\n" (replace-regexp-in-string "^" "  " doc)))
+        ;; Now to the parameters
+        (cl-loop
+         with active-param = (or sig-active activeParameter)
+         for i from 0 for parameter across parameters do
+         (eglot--dbind ((ParameterInformation)
+                        ((:label parlabel))
+                        ((:documentation pardoc)))
+             parameter
+           ;; ...perhaps highlight it in the formals list
+           (when (and (eq i active-param))
+             (save-excursion
+               (goto-char (point-min))
+               (pcase-let
+                   ((`(,beg ,end)
+                     (if (stringp parlabel)
+                         (let ((case-fold-search nil))
+                           (and (search-forward parlabel (line-end-position) t)
+                                (list (match-beginning 0) (match-end 0))))
+                       (mapcar #'1+ (append parlabel nil)))))
+                 (if (and beg end)
+                     (add-face-text-property
+                      beg end
+                      'eldoc-highlight-function-argument)))))
+           ;; ...and/or maybe add its doc on a line by its own.
+           (let (fpardoc)
+             (when (and pardoc (not briefp)
+                        (not (string-empty-p
+                              (setq fpardoc (eglot--format-markup pardoc)))))
+               (insert "\n  "
+                       (propertize
+                        (if (stringp parlabel) parlabel
+                          (apply #'substring siglabel (mapcar #'1+ parlabel)))
+                        'face (and (eq i active-param) 'eldoc-highlight-function-argument))
+                       ": " fpardoc)))))
       (buffer-string))))
 
 (defun eglot-signature-eldoc-function (cb)
@@ -3167,7 +3178,7 @@ for which LSP on-type-formatting should be requested."
        :textDocument/signatureHelp (eglot--TextDocumentPositionParams)
        :success-fn
        (eglot--lambda ((SignatureHelp)
-                       signatures activeSignature activeParameter)
+                       signatures activeSignature (activeParameter 0))
          (eglot--when-buffer-window buf
            (let ((active-sig (and (cl-plusp (length signatures))
                                   (aref signatures (or activeSignature 0)))))