diff options
| author | João Távora | 2025-02-11 16:50:23 +0000 |
|---|---|---|
| committer | João Távora | 2025-02-11 23:38:30 +0000 |
| commit | 3fd0b802de20dc83b5d5236b6d458df73c9d4e77 (patch) | |
| tree | 2dc650cc9a18549e0d02cc72b5c2ac7b7ff14ae3 | |
| parent | e2991272f286af94f13d9d78ac609f08ad77183e (diff) | |
| download | emacs-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.el | 54 |
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. |
| 1961 | MARKUP is either an LSP MarkedString or MarkupContent object." | 1961 | MARKUP 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 | ;;; |