From e33c0a549153fa3894f3b5e9c5e42ce07a1a68c7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Sat, 8 Apr 2023 23:26:43 +0100 Subject: [PATCH] Eglot: more work on eglot--sig-info (bug#62687) 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 | 75 +++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index b10344a706b..3f00281e155 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -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 () + (save-excursion (insert siglabel)) + ;; Ad-hoc attempt to parse label as () (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))))) -- 2.39.2