aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2025-02-11 16:50:23 +0000
committerJoão Távora2025-02-11 23:38:30 +0000
commit3fd0b802de20dc83b5d5236b6d458df73c9d4e77 (patch)
tree2dc650cc9a18549e0d02cc72b5c2ac7b7ff14ae3
parente2991272f286af94f13d9d78ac609f08ad77183e (diff)
downloademacs-3fd0b802de20dc83b5d5236b6d458df73c9d4e77.tar.gz
emacs-3fd0b802de20dc83b5d5236b6d458df73c9d4e77.zip
Eglot: use Eldoc in eglot-hierarchy-mode
Use it to show details of the thing at point, like the full signature and the locus of the definition. * lisp/progmodes/eglot.el: Add optional arg MODE. (eglot--hierarchy-source-major-mode): New defvar. (eglot--hierarchy-1): Adjust. (eglot-hierarchy-mode): Set eldoc stuff. (eglot-hierarchy-center-on-node): Cosmetic fix. (eglot-hierarchy-detail-eldoc-function) (eglot-hierarchy-locus-eldoc-function): New eldoc functions.
-rw-r--r--lisp/progmodes/eglot.el54
1 files changed, 41 insertions, 13 deletions
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 2deeef9bce1..dbdb45d08cd 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -1956,32 +1956,34 @@ Doubles as an indicator of snippet support."
1956 (unless (bound-and-true-p yas-minor-mode) (yas-minor-mode 1)) 1956 (unless (bound-and-true-p yas-minor-mode) (yas-minor-mode 1))
1957 (apply #'yas-expand-snippet args))))) 1957 (apply #'yas-expand-snippet args)))))
1958 1958
1959 (defun eglot--format-markup (markup) 1959 (defun eglot--format-markup (markup &optional mode)
1960 "Format MARKUP according to LSP's spec. 1960 "Format MARKUP according to LSP's spec.
1961MARKUP is either an LSP MarkedString or MarkupContent object." 1961MARKUP is either an LSP MarkedString or MarkupContent object."
1962 (let (string mode language) 1962 (let (string render-mode language)
1963 (cond ((stringp markup) 1963 (cond ((stringp markup)
1964 (setq string markup 1964 (setq string markup
1965 mode 'gfm-view-mode)) 1965 render-mode (or mode 'gfm-view-mode)))
1966 ((setq language (plist-get markup :language)) 1966 ((setq language (plist-get markup :language))
1967 ;; Deprecated MarkedString 1967 ;; Deprecated MarkedString
1968 (setq string (concat "```" language "\n" 1968 (setq string (concat "```" language "\n"
1969 (plist-get markup :value) "\n```") 1969 (plist-get markup :value) "\n```")
1970 mode 'gfm-view-mode)) 1970 render-mode (or mode 'gfm-view-mode)))
1971 (t 1971 (t
1972 ;; MarkupContent 1972 ;; MarkupContent
1973 (setq string (plist-get markup :value) 1973 (setq string (plist-get markup :value)
1974 mode (pcase (plist-get markup :kind) 1974 render-mode
1975 ("markdown" 'gfm-view-mode) 1975 (or mode
1976 ("plaintext" 'text-mode) 1976 (pcase (plist-get markup :kind)
1977 (_ major-mode))))) 1977 ("markdown" 'gfm-view-mode)
1978 ("plaintext" 'text-mode)
1979 (_ major-mode))))))
1978 (with-temp-buffer 1980 (with-temp-buffer
1979 (setq-local markdown-fontify-code-blocks-natively t) 1981 (setq-local markdown-fontify-code-blocks-natively t)
1980 (insert string) 1982 (insert string)
1981 (let ((inhibit-message t) 1983 (let ((inhibit-message t)
1982 (message-log-max nil) 1984 (message-log-max nil)
1983 match) 1985 match)
1984 (ignore-errors (delay-mode-hooks (funcall mode))) 1986 (ignore-errors (delay-mode-hooks (funcall render-mode)))
1985 (font-lock-ensure) 1987 (font-lock-ensure)
1986 (goto-char (point-min)) 1988 (goto-char (point-min))
1987 (let ((inhibit-read-only t)) 1989 (let ((inhibit-read-only t))
@@ -3488,8 +3490,7 @@ for which LSP on-type-formatting should be requested."
3488 (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy)) 3490 (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy))
3489 :detail))) 3491 :detail)))
3490 (when (and (stringp detail) (not (string= detail ""))) 3492 (when (and (stringp detail) (not (string= detail "")))
3491 ;; Forces major-mode based fontification 3493 (eglot--format-markup detail major-mode))))
3492 (eglot--format-markup (list :value detail)))))
3493 :company-doc-buffer 3494 :company-doc-buffer
3494 (lambda (proxy) 3495 (lambda (proxy)
3495 (let* ((resolved 3496 (let* ((resolved
@@ -4457,6 +4458,7 @@ If NOERROR, return predicate, else erroring function."
4457 4458
4458(defvar-local eglot--hierarchy-roots nil) 4459(defvar-local eglot--hierarchy-roots nil)
4459(defvar-local eglot--hierarchy-specs nil) 4460(defvar-local eglot--hierarchy-specs nil)
4461(defvar-local eglot--hierarchy-source-major-mode nil)
4460 4462
4461(defun eglot--hierarchy-children (node) 4463(defun eglot--hierarchy-children (node)
4462 (cl-flet ((get-them (method node) 4464 (cl-flet ((get-them (method node)
@@ -4528,6 +4530,7 @@ If NOERROR, return predicate, else erroring function."
4528(defun eglot--hierarchy-1 (name provider preparer specs) 4530(defun eglot--hierarchy-1 (name provider preparer specs)
4529 (eglot-server-capable-or-lose provider) 4531 (eglot-server-capable-or-lose provider)
4530 (let* ((server (eglot-current-server)) 4532 (let* ((server (eglot-current-server))
4533 (mode major-mode)
4531 (roots (jsonrpc-request 4534 (roots (jsonrpc-request
4532 server 4535 server
4533 preparer 4536 preparer
@@ -4540,6 +4543,7 @@ If NOERROR, return predicate, else erroring function."
4540 eglot--hierarchy-roots roots 4543 eglot--hierarchy-roots roots
4541 eglot--hierarchy-specs specs 4544 eglot--hierarchy-specs specs
4542 eglot--cached-server server 4545 eglot--cached-server server
4546 eglot--hierarchy-source-major-mode mode
4543 buffer-read-only t 4547 buffer-read-only t
4544 revert-buffer-function 4548 revert-buffer-function
4545 (lambda (&rest _ignore) 4549 (lambda (&rest _ignore)
@@ -4577,16 +4581,40 @@ If NOERROR, return predicate, else erroring function."
4577(define-derived-mode eglot-hierarchy-mode special-mode 4581(define-derived-mode eglot-hierarchy-mode special-mode
4578 "Eglot special" "Eglot mode for viewing hierarchies. 4582 "Eglot special" "Eglot mode for viewing hierarchies.
4579\\{eglot-hierarchy-mode-map}" 4583\\{eglot-hierarchy-mode-map}"
4580 :interactive nil) 4584 :interactive nil
4585 (setq eldoc-documentation-strategy
4586 #'eldoc-documentation-compose)
4587 (add-hook 'eldoc-documentation-functions
4588 #'eglot-hierarchy-detail-eldoc-function
4589 nil t)
4590 (add-hook 'eldoc-documentation-functions
4591 #'eglot-hierarchy-locus-eldoc-function
4592 t t))
4581 4593
4582(defun eglot-hierarchy-center-on-node () 4594(defun eglot-hierarchy-center-on-node ()
4583 "Refresh hierarchy, centering on node at point." 4595 "Refresh hierarchy, centering on node at point."
4584 (interactive) 4596 (interactive)
4585 (setq-local eglot--hierarchy-roots 4597 (setq-local eglot--hierarchy-roots
4586 (list (get-text-property (point) 4598 (list (get-text-property (point)
4587 'eglot--hierarchy-node))) 4599 'eglot--hierarchy-node)))
4588 (eglot--hierarchy-2)) 4600 (eglot--hierarchy-2))
4589 4601
4602(defun eglot-hierarchy-detail-eldoc-function (_cb &rest _ignored)
4603 (when-let* ((detail
4604 (plist-get (get-text-property (point) 'eglot--hierarchy-node)
4605 :detail)))
4606 (eglot--format-markup detail eglot--hierarchy-source-major-mode)))
4607
4608(defun eglot-hierarchy-locus-eldoc-function (_cb &rest _ignored)
4609 (let* ((node (get-text-property (point) 'eglot--hierarchy-node))
4610 (uri (plist-get node :uri))
4611 (loc (plist-get (plist-get node :range) :start)))
4612 (and uri loc
4613 ;; maybe use `file-relative-name'?
4614 (format "%s:%s:%s" (eglot-uri-to-path uri)
4615 (1+ (plist-get loc :line))
4616 (plist-get loc :character)))))
4617
4590 4618
4591;;; Hacks 4619;;; Hacks
4592;;; 4620;;;