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
feat(lsp)!: vim.lsp.inlay_hint.get()
#25512
Conversation
Here's the sample plugin using this API: https://github.com/llllvvuu/interactive-inlay.nvim I looked at how others are doing interactive inlay hints, and noticed that @MariaSolOs authored the |
Dumping some more notes: Edge cases where inlay hint tooltip/click is more efficient than regular hover / go to type definition:
In theory, language servers could include these info/prompts in regular hover docs too. The efficiency difference is probably smaller in Neovim because everything is fast in Neovim. |
I think clickable should just be clickable, instead of "querying" a hint |
For TUI, mouse click/hover may not be feasible, in which case the question one has to figure out is how to "DWIM" based on a key press. Range query would be the most general tool that plugins could use to do that. (also users might just prefer to use keyboard) How hard would it be to make virtual text clickable? Like setting the "cursor: pointer" and everything? |
OSC 8 is what you need to communicate "clickability" to the terminal, but even that is just for hyperlinks. I don't think it's possible to make an OSC 8 link do something like write text back to the running application. There might be some way to do something hacky here. Maybe using an empty "link" so that the terminal still gives you the pointer cursor, but the click event still goes through to Nvim. No idea if that'd work, I'm just brainstorming. |
Very interesting, seems worth looking into. For handling the click event itself, I played around with Then on the plugin side, I could add mappings for EDIT: The mouse handler does need to be Neovim core if the clickability indicator is in core (which it has to be, I think) TODO: I haven't thought through how this all plays with GUI frontends like Neovide |
Some research on mouse hover: #9534 |
regarding api/locationPart of the motivation for a dedicated module for This should be a regarding resolveI think ideally we'd handle this transparently, without users of higher level APIs knowing anything about it.
They do not have code actions, but can contain textEdits that one can apply (I think the intention here is to persist the inlay hint into actual text). This could be exposed via a The label can also contain a command. I have no idea what the intention here is. Do language servers use this? If so, what for? I wonder if neovim should have a more generic tooltip mechanism? |
vim.lsp.buf.inlay_hints()
vim.lsp.inlay_hint.get()
3325810
to
032ab9d
Compare
Thanks, that's exactly the kind of advice I'm looking for regarding the conventions (I'm not familiar with what's the "old way" vs "new way"). GitHub is being slow to update PRs, but I just updated the branch to make it this way. The only awkward thing is that
I wanted to keep initial drafts conservative by only doing trivial low-level stuff first, but if y'all are open to it we can also add these additional utilities as a next step.
Related to your comment on Matrix about I was going to try using |
032ab9d
to
2d0fcf7
Compare
Good call 👍 I didn't mean to imply that we should do that now/at the same time. Just as a rough outline of what we could do later.
I didn't have anything concrete in mind - that was just thinking out loud. |
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.
The only awkward thing is that __call does not show up in generated vimdoc. It works perfectly in LSP hover docs though.
We'll need some way to bring back the vim.lsp.inlay_hint()
docs, but no idea how.
Indeed, now that I think about it, it does seem correct to have Neovim handle the text edits / commands part given that we already have So the only complexity outsourced to plugins would be triggering the inlay hint w/o mouse |
@llllvvuu Might not be relevant but do note that when using inlay hints as a "go to definition", there could be multiple definitions and so one needs to consider how to handle that. In VS Code for example, when control-clicking on an inlay hints that has multiple definitions, the "Peek definition" hover window is displayed to show all the results. In Neovim this could mean hooking up to Just a heads-up because this might not be immediately obvious from the specification of label parts. |
848f826
to
d5dd4ed
Compare
I figured out a janky way to keep the vimdoc intact for the
It's very relevant! Currently I'm tracking all the UI stuff in my plugin roadmap, and starting with headless stuff here. If the UI stuff gets good reception downstream then I'll start proposing to upstream.
So maybe core UI (if it exists) can be
Thinking about this a bit. If we want to do resolution instead of the user doing it, we need to figure out what the right trigger for it is. Do we automatically resolve everything that we return from In any case, it looks like manual resolving is already possible without any extra work from our part (by calling |
8c04a5c
to
ac8bd8d
Compare
7fb8172
to
0cae26e
Compare
Sorry for the delay (haven't had Wi-fi for a while), made changes:
|
b876959
to
7a5327d
Compare
Enable/disable/toggle inlay hints for a buffer | ||
|
||
Parameters: ~ | ||
• {bufnr} (integer|nil) Buffer handle, or 0 or nil for current |
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.
Typo? Isn't nil
for using all buffers?
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.
For .get()
yes, but .enable()
, no
refactor!: `vim.lsp.inlay_hint()` -> `vim.lsp.inlay_hint.enable()` Problem --- The LSP specification allows inlay hints to include tooltips, clickable label parts, and code actions; but Neovim provides no API to query for these. Solution --- Add minimal viable extension point from which plugins can query for inlay hints in a range, in order to build functionality on top of. Possible Next Steps --- - Add `virt_text_idx` field to `vim.fn.getmousepos()` return value, for usage in mappings of `<LeftMouse>`, `<C-LeftMouse>`, etc
7a5327d
to
ed31745
Compare
Neovim merged [a breaking PR][1] that modified `vim.lsp.inlay_hints` into a module with functions. This required a config update to fix inlay hints. [1]: neovim/neovim#25512
Neovim merged [a breaking PR][1] that modified `vim.lsp.inlay_hints` Neovim merged [a breaking PR](neovim/neovim#25512) that modified `vim.lsp.inlay_hints` into a module with functions. This required a config update to fix inlay hints. [1]: neovim/neovim#25512
Neovim merged [a breaking PR][1] that modified `vim.lsp.inlay_hints` into a module with functions. This required a config update to fix inlay hints. [1]: neovim/neovim#25512
Neovim merged [a breaking PR][1] that modified `vim.lsp.inlay_hints` into a module with functions. This required a config update to fix inlay hints. [1]: neovim/neovim#25512
It doesn't since 448907f (neovim#25512).
It doesn't since 448907f (neovim#25512).
It doesn't since 448907f (neovim#25512).
Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see neovim#25512 (review) As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable`
Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see neovim#25512 (review) As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable`
Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see neovim#25512 (review) As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable`
Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see neovim#25512 (review) As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable`
Problem: `vim.diagnostic.is_disabled` and `vim.diagnostic.disable` are unnecessary and inconsistent with the "toggle" pattern (established starting with `vim.lsp.inlay_hint`, see neovim#25512 (review) As a reminder, the rationale is: - we always need `enable()` - we always end up needing `is_enabled()` - "toggle" can be achieved via `enable(not is_enabled())` - therefore, - `toggle()` and `disable()` are redundant - `is_disabled()` is a needless inconsistency Solution: - Introduce `vim.diagnostic.is_enabled`, and `vim.diagnostic.enable(…, enable:boolean)` - Note: Future improvement would be to add an `enable()` overload `enable(enable:boolean, opts: table)`. - Deprecate `vim.diagnostic.is_disabled`, `vim.diagnostic.disable`
resolves #25069
refactor!:
vim.lsp.inlay_hint()
->vim.lsp.inlay_hint.enable()
Problem
The LSP specification allows inlay hints to include tooltips, clickable label parts, and code actions; but Neovim provides no API to query for these.
Solution
Add minimal viable extension point from which plugins can query for inlay hints in a range, in order to build functionality on top of.
Possible Next Steps
virt_text_idx
field tovim.fn.getmousepos()
return value, for usage in mappings of<LeftMouse>
,<C-LeftMouse>
, etc