-
-
Notifications
You must be signed in to change notification settings - Fork 895
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
Conversation
I believe that this is no longer actually rust-analyzer-specific and instead will work with any LSP backend that supports the draft inlay hint feature, but I have no other backend to try with. Fixes emacs-lsp#3403
clients/lsp-rust.el
Outdated
(overlay (make-overlay start end nil 'front-advance 'end-advance))) | ||
(-let* (((&rust-analyzer:InlayHint :position :label :kind) hint) | ||
(pos (lsp--position-to-point position)) | ||
(overlay (make-overlay pos (+ pos 1) nil 'front-advance 'end-advance))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not actually sure what that second parameter should be; pos
doesn't work, but the position we get doesn't really have an end per se.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My guess would be that pos
doesn't work because we set evaporate
, which makes Emacs remove the hints when they have length 0. I don't know if that's necessary, since we also remove the overlays manually when we update them. Maybe @yyoncho knows more here
lsp-protocol.el
Outdated
(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-chaining-hint nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This nil
seems like it's a bug in rust-analyzer? It feels like it should be 3
but it definitely isn't on my machine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so not a bug but an extension to the draft spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in rust-lang/rust-analyzer#11720
So remove the formatting configuration options for them and the codepath that handled rendering them separately. Also, ask rust-analyzer not to pre-format the hints on its end so that the formatting options on the elisp side are actually useful.
This week's r-a added a bunch of new inlay hint options. I'll take a look at adding support for turning them on to this PR sometime tonight. |
* Lifetime elision hints * Reborrow hints * Closure return type hints The way rust-analyzer is evolving, the emacs-side formatting looks like it will become less and less useful, as these new hint types (and indeed the already-existing chaining hint type) are not distinguished in a way that the mode can determine; right now, I've left the support in, but I've disabled it by default in preference to letting the server format them. In that case, the server provides a small amount of formatting info (in particular, whether the inlay should be formatted with padding on the left and/or right).
As I mentioned in that latest commit message, the emacs-side formatting of hints looks like it'll become less useful over time. The new inlay hint protocol doesn't appear to be expressive enough to tell us what these hints are (being restricted to "parameter" and "type") and indeed the new hints once again provide a null kind. What it does do is tell us about what padding should appear. So anyway, I've undone the change where I asked rust-analyzer to never format the hints itself and made that configurable (defaulting to on). When it is on, the formatting and spacing stuff is all ignored - the code assumes that the I'm not super happy with it, to be honest, but I thought I'd put it out there and see what other people have to say. My current inclination is to remove the elisp formatting code altogether, always have rust-analyzer format it, and use the |
@flodiebold @brotzeit willing to take a look? |
Oof, @Veykril can we use parameter/parameter/type for those three? Lifetimes are parameters too. |
That sounds wrong to me, those kinds are solely meant for styling, with null falling back to the default styling the user chooses. I'm not sure what the problem here is though, It's a classic case of the LSP being limited to only a few known things and not allowing custom kinds though which I believe is a serious flaw in the spec :/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM mostly. I agree that letting rust-analyzer format the hints is probably the way forward.
@@ -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 |
There was a problem hiding this comment.
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 :/
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
clients/lsp-rust.el
Outdated
:chainingHints ,(lsp-json-bool lsp-rust-analyzer-display-chaining-hints) | ||
:closureReturnTypeHints ,(lsp-json-bool lsp-rust-analyzer-display-closure-return-type-hints) | ||
:lifetimeElisionHints ,lsp-rust-analyzer-display-lifetime-elision-hints |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the structure of this setting might change again soon (right, @Veykril ?), so maybe it's best to just leave it out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you're right, that's rust-lang/rust-analyzer#11778. Hasn't actually happened yet, but I'm aware it almost certainly will.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that will change, I'll do that later today and let you know here again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and changed one of the configs here https://github.com/rust-analyzer/rust-analyzer/pull/11789/files
Note that r-a might have to change a bunch of configs in the future for consistency ( we dug ourselves a bad hole here rust-lang/rust-analyzer#11790 )
clients/lsp-rust.el
Outdated
(overlay (make-overlay start end nil 'front-advance 'end-advance))) | ||
(-let* (((&rust-analyzer:InlayHint :position :label :kind) hint) | ||
(pos (lsp--position-to-point position)) | ||
(overlay (make-overlay pos (+ pos 1) nil 'front-advance 'end-advance))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My guess would be that pos
doesn't work because we set evaporate
, which makes Emacs remove the hints when they have length 0. I don't know if that's necessary, since we also remove the overlays manually when we update them. Maybe @yyoncho knows more here
Ah ok, that makes more sense. Looking at it in that light, I think I can make it a fair bit less scattered-feeling today, then I'll consider the PR "done". |
Now we always rely on rust-analyzer for spacing info, but allow the formatting within the label proper to be overridden emacs-side.
Ok, I'm pretty happy with the PR as it is now. I incorporated most of the feedback above, specifically:
|
AFAIK it shouldn't make a difference if we don't change |
Thank you @rjmac, very much appreciated! |
I believe that this is no longer actually rust-analyzer-specific and
instead will work with any LSP backend that supports the draft inlay
hint feature, but I have no other backend to try with.
Fixes #3403