about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/user/README.md2
-rw-r--r--editors/emacs/ra-emacs-lsp.el42
2 files changed, 40 insertions, 4 deletions
diff --git a/docs/user/README.md b/docs/user/README.md
index d5633019281..8a576784928 100644
--- a/docs/user/README.md
+++ b/docs/user/README.md
@@ -86,7 +86,7 @@ Installation:
 [ra-emacs-lsp.el](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/editors/emacs/ra-emacs-lsp.el)
 to load path and require it in `init.el`
 * run `lsp` in a rust buffer
-* (Optionally) bind commands like `rust-analyzer-join-lines` or `rust-analyzer-extend-selection` to keys
+* (Optionally) bind commands like `rust-analyzer-join-lines` or `rust-analyzer-extend-selection` to keys, and enable `rust-analyzer-inlay-hints-mode` to get inline type hints
 
 
 ## Vim and NeoVim
diff --git a/editors/emacs/ra-emacs-lsp.el b/editors/emacs/ra-emacs-lsp.el
index 21a90c86b46..d7656476ef7 100644
--- a/editors/emacs/ra-emacs-lsp.el
+++ b/editors/emacs/ra-emacs-lsp.el
@@ -15,6 +15,7 @@
 ;;  - implements source changes (for code actions etc.), except for file system changes
 ;;  - implements joinLines (you need to bind rust-analyzer-join-lines to a key)
 ;;  - implements extendSelection (either bind rust-analyzer-extend-selection to a key, or use expand-region)
+;;  - provides rust-analyzer-inlay-hints-mode for inline type hints
 
 ;; What's missing:
 ;;  - file system changes in apply-source-change
@@ -22,7 +23,6 @@
 ;;  - onEnter, parentModule, findMatchingBrace
 ;;  - runnables
 ;;  - the debugging commands (syntaxTree and analyzerStatus)
-;;  - lsp-ui doesn't interpret the markdown we return currently and instead displays it raw (https://github.com/emacs-lsp/lsp-ui/issues/220 )
 ;;  - more
 
 ;; Also, there's a problem with company-lsp's caching being too eager, sometimes
@@ -225,10 +225,46 @@
           (with-current-buffer buf
             (let ((inhibit-read-only t))
               (erase-buffer)
-              (insert parse-result)) 
-            )
+              (insert parse-result)))
           (pop-to-buffer buf))))))
 
+;; inlay hints
+(defun rust-analyzer--update-inlay-hints ()
+  (lsp-send-request-async
+   (lsp-make-request "rust-analyzer/inlayHints"
+                     (list :textDocument (lsp--text-document-identifier)))
+   (lambda (res)
+     (remove-overlays (point-min) (point-max) 'rust-analyzer--inlay-hint t)
+     (dolist (hint res)
+       (-let* (((&hash "range" "label" "kind") hint)
+               ((beg . end) (lsp--range-to-region range))
+               (overlay (make-overlay beg end)))
+         (overlay-put overlay 'rust-analyzer--inlay-hint t)
+         (overlay-put overlay 'evaporate t)
+         (overlay-put overlay 'after-string (propertize (concat ": " label)
+                                                        'font-lock-face 'font-lock-comment-face)))))
+   'tick)
+  nil)
+
+(defvar-local rust-analyzer--inlay-hints-timer nil)
+
+(defun rust-analyzer--inlay-hints-change-handler (&rest rest)
+  (when rust-analyzer--inlay-hints-timer
+    (cancel-timer rust-analyzer--inlay-hints-timer))
+  (setq rust-analyzer--inlay-hints-timer
+        (run-with-idle-timer 0.1 nil #'rust-analyzer--update-inlay-hints)))
+
+(define-minor-mode rust-analyzer-inlay-hints-mode
+  "Mode for showing inlay hints."
+  nil nil nil
+  (cond
+   (rust-analyzer-inlay-hints-mode
+    (rust-analyzer--update-inlay-hints)
+    (add-hook 'after-change-functions #'rust-analyzer--inlay-hints-change-handler nil t))
+   (t
+    (remove-overlays (point-min) (point-max) 'rust-analyzer--inlay-hint t)
+    (remove-hook 'after-change-functions #'rust-analyzer--inlay-hints-change-handler t))))
+
 
 (provide 'ra-emacs-lsp)
 ;;; ra-emacs-lsp.el ends here