Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update support for rust-analyzer's inlay hints #3404

Merged
merged 6 commits into from
Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.org
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Add [[https://github.com/idris-community/idris2-lsp][idris2-lsp]]
* Add [[https://github.com/aca/emmet-ls][emmet-ls]]
* Support all ~initializationOptions~ in ~typescript-language-server~
* Update rust-analyzer's inlay hint protocol support.
** Release 8.0.0
* Add ~lsp-clients-angular-node-get-prefix-command~ to get the Angular server from another location which is still has ~/lib/node_modules~ in it.
* Set ~lsp-clients-angular-language-server-command~ after the first connection to speed up subsequent connections.
Expand Down
138 changes: 77 additions & 61 deletions clients/lsp-rust.el
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,13 @@ PARAMS progress report notification data."
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "6.2"))

(defcustom lsp-rust-analyzer-server-format-inlay-hints t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in general I'd prefer if the defcustoms mirror the naming of the options in rust-analyzer, but I recognize it's too late here :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left that on the wrong line, it was referring to lsp-rust-analyzer-display-lifetime-elision-hints etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add defvaralias for those options and update the names to reflect the rust-analyzer options. It would certainly make things less confusing for users.

"Whether to ask rust-analyzer to format inlay hints itself. If
active, the various inlay format settings are not used."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-rust-analyzer-server-display-inlay-hints nil
"Show inlay hints."
:type 'boolean
Expand All @@ -354,17 +361,48 @@ PARAMS progress report notification data."
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "6.2.2"))

(defcustom lsp-rust-analyzer-display-chaining-hints nil
"Whether to show inlay type hints for method chains. These
hints will be formatted with the type hint formatting options, if
the mode is not configured to ask the server to format them."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "6.2.2"))

(defcustom lsp-rust-analyzer-display-lifetime-elision-hints-enable "never"
"Whether to show elided lifetime inlay hints."
:type '(choice
(const "never")
(const "always")
(const "skip_trivial"))
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil
"When showing elided lifetime inlay hints, whether to use
parameter names or numeric placeholder names for the lifetimes."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-rust-analyzer-display-closure-return-type-hints nil
"Whether to show closure return type inlay hints for closures
with block bodies."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-rust-analyzer-display-parameter-hints nil
"Whether to show function parameter name inlay hints at the call site."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "6.2.2"))

(defcustom lsp-rust-analyzer-display-chaining-hints nil
"Whether to show inlay type hints for method chains."
(defcustom lsp-rust-analyzer-display-reborrow-hints nil
"Whether to show reborrowing inlay hints."
:type 'boolean
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "6.2.2"))
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-rust-analyzer-lru-capacity nil
"Number of syntax trees rust-analyzer keeps in memory."
Expand Down Expand Up @@ -665,9 +703,14 @@ https://rust-analyzer.github.io/manual.html#auto-import.
:unsetTest ,lsp-rust-analyzer-cargo-unset-test)
:rustfmt (:extraArgs ,lsp-rust-analyzer-rustfmt-extra-args
:overrideCommand ,lsp-rust-analyzer-rustfmt-override-command)
:inlayHints (:typeHints ,(lsp-json-bool lsp-rust-analyzer-server-display-inlay-hints)
:inlayHints (:renderColons ,(lsp-json-bool lsp-rust-analyzer-server-format-inlay-hints)
:typeHints ,(lsp-json-bool lsp-rust-analyzer-server-display-inlay-hints)
:chainingHints ,(lsp-json-bool lsp-rust-analyzer-display-chaining-hints)
:closureReturnTypeHints ,(lsp-json-bool lsp-rust-analyzer-display-closure-return-type-hints)
:lifetimeElisionHints (:enable ,lsp-rust-analyzer-display-lifetime-elision-hints-enable
:useParameterNames ,(lsp-json-bool lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names))
:parameterHints ,(lsp-json-bool lsp-rust-analyzer-display-parameter-hints)
:reborrowHints ,(lsp-json-bool lsp-rust-analyzer-display-reborrow-hints)
:maxLength ,lsp-rust-analyzer-max-inlay-hint-length)
:completion (:addCallParenthesis ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-parenthesis)
:addCallArgumentSnippets ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-argument-snippets)
Expand Down Expand Up @@ -843,15 +886,10 @@ https://rust-analyzer.github.io/manual.html#auto-import.
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-type-space-format "%s"
"Format string for spacing around variable inlays
\(not part of the inlay face)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-type-format ": %s"
"Format string for variable inlays (part of the inlay face)."
"Format string for variable inlays (part of the inlay face,
used only if lsp-rust-analyzer-server-format-inlay-hints is
non-nil)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))
Expand All @@ -862,33 +900,10 @@ https://rust-analyzer.github.io/manual.html#auto-import.
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-param-space-format "%s "
"Format string for spacing around parameter inlays
\(not part of the inlay face)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-param-format "%s:"
"Format string for parameter inlays (part of the inlay face)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defface lsp-rust-analyzer-inlay-chain-face
'((t :inherit lsp-rust-analyzer-inlay-face))
"Face for inlay chaining hints (e.g. inferred chain intermediate types)."
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-chain-space-format "%s"
"Format string for spacing around chain inlays (not part of the inlay face)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))

(defcustom lsp-rust-analyzer-inlay-chain-format ": %s"
"Format string for chain inlays (part of the inlay face)."
"Format string for parameter inlays (part of the inlay face,
used only if lsp-rust-analyzer-server-format-inlay-hints is
non-nil)."
:type '(string :tag "String")
:group 'lsp-rust-analyzer
:package-version '(lsp-mode . "8.0.0"))
Expand All @@ -910,38 +925,39 @@ meaning."
(if (and (lsp-rust-analyzer-initialized?)
(eq buffer (current-buffer)))
(lsp-request-async
"rust-analyzer/inlayHints"
"experimental/inlayHints"
(lsp-make-rust-analyzer-inlay-hints-params
:text-document (lsp--text-document-identifier))
(lambda (res)
(remove-overlays (point-min) (point-max) 'lsp-rust-analyzer-inlay-hint t)
(dolist (hint res)
(-let* (((&rust-analyzer:InlayHint :range :label :kind) hint)
((&RangeToPoint :start :end) range)
(overlay (make-overlay start end nil 'front-advance 'end-advance)))
(-let* (((&rust-analyzer:InlayHint :position :label :kind :padding-left :padding-right) hint)
(pos (lsp--position-to-point position))
(overlay (make-overlay pos pos nil 'front-advance 'end-advance)))
(overlay-put overlay 'lsp-rust-analyzer-inlay-hint t)
(overlay-put overlay 'evaporate t)
(cond
((equal kind lsp/rust-analyzer-inlay-hint-kind-type-hint)
(overlay-put overlay 'after-string
(format lsp-rust-analyzer-inlay-type-space-format
(propertize (format lsp-rust-analyzer-inlay-type-format label)
'font-lock-face 'lsp-rust-analyzer-inlay-type-face))))

((equal kind lsp/rust-analyzer-inlay-hint-kind-param-hint)
(overlay-put overlay 'before-string
(format lsp-rust-analyzer-inlay-param-space-format
(propertize (format lsp-rust-analyzer-inlay-param-format label)
'font-lock-face 'lsp-rust-analyzer-inlay-param-face))))

((equal kind lsp/rust-analyzer-inlay-hint-kind-chaining-hint)
(overlay-put overlay 'after-string
(format lsp-rust-analyzer-inlay-chain-space-format
(propertize (format lsp-rust-analyzer-inlay-chain-format label)
'font-lock-face 'lsp-rust-analyzer-inlay-chain-face))))))))
(overlay-put overlay 'before-string
(format "%s%s%s"
(if padding-left " " "")
(propertize (lsp-rust-analyzer-format-inlay label kind)
'font-lock-face (lsp-rust-analyzer-face-for-inlay kind))
(if padding-right " " ""))))))
:mode 'tick))
nil)

(defun lsp-rust-analyzer-format-inlay (label kind)
(if lsp-rust-analyzer-server-format-inlay-hints
label
(cond
((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) (format lsp-rust-analyzer-inlay-type-format label))
((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) (format lsp-rust-analyzer-inlay-param-format label))
(t label))))

(defun lsp-rust-analyzer-face-for-inlay (kind)
(cond
((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) 'lsp-rust-analyzer-inlay-type-face)
((eql kind lsp/rust-analyzer-inlay-hint-kind-type-hint) 'lsp-rust-analyzer-inlay-param-face)
(t 'lsp-rust-analyzer-inlay-face)))

(defun lsp-rust-analyzer-initialized? ()
(when-let ((workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name))))
(eq 'initialized (lsp--workspace-status workspace))))
Expand Down
8 changes: 4 additions & 4 deletions lsp-protocol.el
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,9 @@ See `-let' for a description of the destructuring mechanism."

(lsp-interface (rls:Cmd (:args :binary :env :cwd) nil))

(defconst lsp/rust-analyzer-inlay-hint-kind-type-hint "TypeHint")
(defconst lsp/rust-analyzer-inlay-hint-kind-param-hint "ParameterHint")
(defconst lsp/rust-analyzer-inlay-hint-kind-chaining-hint "ChainingHint")
(defconst lsp/rust-analyzer-inlay-hint-kind-type-hint 1)
(defconst lsp/rust-analyzer-inlay-hint-kind-param-hint 2)
(defconst lsp/rust-analyzer-inlay-hint-kind-nonstandard-hint nil)
(lsp-interface (rust-analyzer:AnalyzerStatusParams (:textDocument))
(rust-analyzer:SyntaxTreeParams (:textDocument) (:range))
(rust-analyzer:ExpandMacroParams (:textDocument :position) nil)
Expand All @@ -415,7 +415,7 @@ See `-let' for a description of the destructuring mechanism."
(rust-analyzer:RunnableArgs (:cargoArgs :executableArgs) (:workspaceRoot))
(rust-analyzer:RelatedTestsParams (:textDocument :position) nil)
(rust-analyzer:RelatedTests (:runnable) nil)
(rust-analyzer:InlayHint (:range :label :kind) nil)
(rust-analyzer:InlayHint (:position :label :kind :paddingLeft :paddingRight) nil)
(rust-analyzer:InlayHintsParams (:textDocument) nil)
(rust-analyzer:SsrParams (:query :parseOnly) nil)
(rust-analyzer:CommandLink (:title :command) (:arguments :tooltip))
Expand Down