From cf6d44d82d39ccfd70925c02154893597ab92862 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 5 Apr 2024 16:03:47 -0400 Subject: [PATCH] fix(rust): lsp-mode: produce better hover info The caching of rust-analyzer (RA) is too aggressive and leads to bad results. RA does not give a protocol-compliant way to extract 1 line information from the hover response, so `lsp-mode` displays the first line of the result, which currently is the byte alignment of the data Fix: #6951 Close: #7754 Co-authored-by: gagbo Co-authored-by: scturtle --- modules/lang/rust/config.el | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/lang/rust/config.el b/modules/lang/rust/config.el index 9ed0483e3..1418ff530 100644 --- a/modules/lang/rust/config.el +++ b/modules/lang/rust/config.el @@ -48,7 +48,36 @@ (if (modulep! :tools lsp +eglot) 'eglot 'lsp-mode)) - (add-hook 'rustic-mode-local-vars-hook #'rustic-setup-lsp 'append)) + (add-hook 'rustic-mode-local-vars-hook #'rustic-setup-lsp 'append) + + ;; HACK: Add @scturtle fix for signatures on hover on LSP mode. This code + ;; has not been upstreamed because it depends on the exact format of the + ;; response of Rust Analyzer, which is not stable enough for `lsp-mode' + ;; maintainers (see emacs-lsp/lsp-mode#1740). + (unless (modulep! :tools lsp +eglot) + (defadvice! +rust--dont-cache-results-from-ra-a (fn &rest args) + :after #'lsp-eldoc-function + (when (derived-mode-p 'rust-mode 'rust-ts-mode) + (setq lsp--hover-saved-bounds nil))) + + ;; extract and show short signature for rust-analyzer + (cl-defmethod lsp-clients-extract-signature-on-hover (contents (_server-id (eql rust-analyzer))) + (let* ((value (if lsp-use-plists (plist-get contents :value) (gethash "value" contents))) + (groups (--partition-by (s-blank? it) (s-lines (s-trim value)))) + (mod-group (cond ((s-equals? "```rust" (car (-fifth-item groups))) (-third-item groups)) + ((s-equals? "```rust" (car (-third-item groups))) (-first-item groups)) + (t nil))) + (cmt (if (null mod-group) "" (concat " // " (cadr mod-group)))) + (sig-group (cond ((s-equals? "```rust" (car (-fifth-item groups))) (-fifth-item groups)) + ((s-equals? "```rust" (car (-third-item groups))) (-third-item groups)) + (t (-first-item groups)))) + (sig (->> sig-group + (--drop-while (s-equals? "```rust" it)) + (--take-while (not (s-equals? "```" it))) + (--map (s-replace-regexp "//.*" "" it)) + (--map (s-trim it)) + (s-join " ")))) + (lsp--render-element (concat "```rust\n" sig cmt "\n```")))))) (when (modulep! +tree-sitter) (add-hook 'rustic-mode-local-vars-hook #'tree-sitter! 'append))