lvimuser / lsp-inlayhints.nvim

Apache License 2.0
423 stars 23 forks source link

Support inline virtual text #46

Open tom-anders opened 1 year ago

tom-anders commented 1 year ago

Inline virtual text will soon be merged into master: https://github.com/neovim/neovim/pull/23426

This Plugin is of course the perfect candidate for implementing this feature.

lvimuser commented 1 year ago

Testers needed for the anticonceal branch.

TODO yield every 5ms on the main 'render' loop. Ref https://github.com/neovim/neovim/commit/edf05b005f34f59dd40468c36cc139e217345a71 (l104-120)

ecosse3 commented 1 year ago

@lvimuser I would like to test it. Do you mind sharing instructions on how to apply the patch on neovim master branch?

In neovim repo directory I do:

$ wget https://patch-diff.githubusercontent.com/raw/neovim/neovim/pull/23426.patch && git apply 23426.patch --allow-overlap --reject --whitespace=fix
$ make CMAKE_BUILD_TYPE=RelWithDebInfo

Fails with error:

mkdir -p build
touch build/.ran-deps-cmake
ninja  -C .deps
ninja: Entering directory `.deps'
[4/10] Performing download step (download, verify and extract) for 'libuv'
FAILED: build/src/libuv-stamp/libuv-download /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src/libuv-stamp/libuv-download
cd /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src && /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -P /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src/libuv-stamp/download-libuv.cmake && /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -P /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src/libuv-stamp/verify-libuv.cmake && /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -P /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src/libuv-stamp/extract-libuv.cmake && /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -E touch /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/src/libuv-stamp/libuv-download
-- Downloading...
   dst='/Users/lukasz.kurpiewski/Projects/neovim/.deps/build/downloads/libuv/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz'
   timeout='none'
   inactivity timeout='none'
-- Using src='https://github.com/libuv/libuv/archive/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz'
-- verifying file...
       file='/Users/lukasz.kurpiewski/Projects/neovim/.deps/build/downloads/libuv/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz'
-- SHA256 hash of
    /Users/lukasz.kurpiewski/Projects/neovim/.deps/build/downloads/libuv/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz
  does not match expected value
    expected: 'cd97aff8e7073fb128aef7a45e9183264ccaf07945a6cb430053070bd03ff200'
      actual: 'c7e89137da65a1cb550ba96b892dfeeabea982bf33b9237bcf9bbcd90f2e70a1'
-- Hash mismatch, removing...

(...)

If I just apply the patch without --allow-overlap --reject --whitespace=fix I get:

2023-05-11 15:10:52 (1.35 MB/s) - ‘23426.patch’ saved [137917]

error: patch failed: runtime/doc/news.txt:52
error: runtime/doc/news.txt: patch does not apply
lvimuser commented 1 year ago

@lvimuser I would like to test it. Do you mind sharing instructions on how to apply the patch on neovim master branch?

In neovim repo directory I do:

$ wget https://patch-diff.githubusercontent.com/raw/neovim/neovim/pull/23426.patch && git apply 23426.patch --allow-overlap --reject --whitespace=fix

git am 23426.patch worked without any issues.

KostkaBrukowa commented 1 year ago

Hey! Thanks for your work on this plugin. In majority of cases that I've tested it works really well. I've been testing this for a while and I found two things:

  1. One thing is that inlay hints does not render on the first line of the buffer:

https://github.com/lvimuser/lsp-inlayhints.nvim/assets/35625949/74f1becb-5d79-4fc1-b77c-f3b56d3db92c

  1. Don't know if it's possible but when we have set set cursorline and on the line that our cursor is at the moment there is a hint with paddingLeft or paddingRight, this padding has different background than the cursorline background. I think it would be nice to have this background the same color as the cursorline: image
lvimuser commented 1 year ago
1. One thing is that inlay hints does not render on the first line of the buffer:

I've pushed a commit, could you try it out?

3. Don't know if it's possible but when we have set `set cursorline` and on the line that our cursor is at the moment there is a hint with `paddingLeft` or `paddingRight`,  this padding has different background than the `cursorline` background. I think it would be nice to have this background the same color as the cursorline:

Try to experiment with different values of highlight in the formatter function, perhaps "None"

virt_text_formatter = function(label, hint, opts, client_name)
  ...
  local vt = {}
  vt[#vt + 1] = hint.paddingLeft and { " ", "Normal" } or nil
  vt[#vt + 1] = { label, opts.highlight }
  vt[#vt + 1] = hint.paddingRight and { " ", "Normal" } or nil
  return vt
end,

if not, then it's probably https://github.com/lvimuser/lsp-inlayhints.nvim/commit/aa1fee3469f70842fecb0e915fa0d1e5c6784501#diff-35ff978c429cae2ed9217298ef4810beb45307b1baee86f83eb7233f60109fbaL132

KostkaBrukowa commented 1 year ago

I've checked the newest commit and now it works well. About the 3. you were right:

  vt[#vt + 1] = hint.paddingLeft and { " ", "None" } or nil
  vt[#vt + 1] = { label, opts.highlight }
  vt[#vt + 1] = hint.paddingRight and { " ", "None" } or nil

or even

  vt[#vt + 1] = hint.paddingLeft and { " " } or nil
  vt[#vt + 1] = { label, opts.highlight }
  vt[#vt + 1] = hint.paddingRight and { " " } or nil

works just as intended. Thanks and that all from my side

schizophrenical commented 1 year ago

Hello, I was trying to test this out with neovim built from 23426.

Is there a config that I need to set or some settings I need to update? Or I also need the patch from anticonceal branch?

I am seeing the inlay hints but they are all appended at the end of the line. Below are examples:

Screenshot_2023-05-13-20-18-17_3440x1440

Screenshot_2023-05-13-20-12-08_3440x1440

KostkaBrukowa commented 1 year ago

If you have hints at the end of a line, it means that you have this plugin version from "main" branch and you need version from "anticonceal" branch. Packer has "brach" option you can add in your config to install plugin version from branch ("lazy" should have something similar)

schizophrenical commented 1 year ago

thanks for the info @KostkaBrukowa! Works now.

bnjmnt4n commented 1 year ago

This seems to work great, with one issue: calling .toggle() hides the inlay hints, but calling it again doesn't re-display the inlay hints.

quantum-booty commented 1 year ago

The anticonceal feature has been merged to master https://github.com/neovim/neovim/pull/20130

theHamsta commented 1 year ago

Seems to work very fine. An edge case seems to be when the inlay hints are racing with LSP semantic token highlighting. If the inlay hints resolve first: image

If the semantic tokens resolve first and inlay hints appear after the LSP semantic highlighting they seem to inherit from the LSP highlighting (or is this something else?) image

AndreM222 commented 1 year ago

woo I am excited for this update

SleepySwords commented 1 year ago

If you didn't know, you could use the right_gravity option when placing virtual text. This would, if right_gravity was set to false, when inserting, place the inserted text to the right of the virtual text rather than the left. I found this particularly nice for the parameter type of some LSPs. For example with rust-analyzer

andrevmatos commented 1 year ago

Very nice plugin, thank you. only_current_line is broken though, it shows on current line when buffer is entered, but not when cursor is moved to another line.

Edit: workaround: autocmd CursorHold * silent! lua require('lsp-inlinehints').show(nil, 5)

A-Lamia commented 1 year ago

Tested and works with lua, cpp, TS with anticonceal, was not successful with rust, anyone else got it working ?

EDIT: should probably state the issue, nothing is showing at all with the anticonceal branch everything works fine on master.

perrin4869 commented 1 year ago

Tested on TS also and had no issues, super thanks!

lvimuser commented 1 year ago

Seems to work very fine. An edge case seems to be when the inlay hints are racing with LSP semantic token highlighting. If the inlay hints resolve first: image

If the semantic tokens resolve first and inlay hints appear after the LSP semantic highlighting they seem to inherit from the LSP highlighting (or is this something else?) image

Thanks for the report. I have no idea what's going on there...

lvimuser commented 1 year ago

If you didn't know, you could use the right_gravity option when placing virtual text. This would, if right_gravity was set to false, when inserting, place the inserted text to the right of the virtual text rather than the left. I found this particularly nice for the parameter type of some LSPs. For example with rust-analyzer

Thanks, it's way better.

Tested and works with lua, cpp, TS with anticonceal, was not successful with rust, anyone else got it working ?

EDIT: should probably state the issue, nothing is showing at all with the anticonceal branch everything works fine on master.

Not sure... I'll look into it on the weekend.

tom-anders commented 1 year ago

Seems to work very fine. An edge case seems to be when the inlay hints are racing with LSP semantic token highlighting. If the inlay hints resolve first: image

If the semantic tokens resolve first and inlay hints appear after the LSP semantic highlighting they seem to inherit from the LSP highlighting (or is this something else?) image

I wonder if this also happens with https://github.com/neovim/neovim/pull/23736...? If so, it's probably a bug in core

IndianBoy42 commented 1 year ago

was not successful with rust, anyone else got it working ?

EDIT: should probably state the issue, nothing is showing at all with the anticonceal branch everything works fine on master.

It seems like the hints only show up after making some change to the file. but then they update normally

EDIT: does it have something to do with the fact that when inlayhints tries to render initially, rust_analyzer is probably still stuck indexing, so it fails, and then only updates on edit. is there a change related to that in the anticonceal branch?

A-Lamia commented 1 year ago

@IndianBoy42 Yes you are correct, editing the file does resolve the problem, interesting.

junnplus commented 1 year ago

@A-Lamia You can try https://github.com/junnplus/lsp-setup.nvim#inlay-hints, I have tested it on Rust and it should work.

calops commented 1 year ago

Things are working pretty well, but with a few caveats:

IndianBoy42 commented 1 year ago

It might also be worth it to think about the future of this plugin when this pr exists

A-Lamia commented 1 year ago

@A-Lamia You can try junnplus/lsp-setup.nvim#inlay-hints, I have tested it on Rust and it should work.

Seem to not have any luck with I'm guessing the rust configuration, still the same problem where you need to edit to get things to show up.

lvimuser commented 1 year ago

@ rust-analyzer. Does it happen only on the first buffer, or on each new buffer?

IndianBoy42 commented 1 year ago

Huh, I dont know what happened but now it just works from the first buffer

kothavade commented 1 year ago

Using anticonceal branch on nightly (NVIM v0.10.0-dev-411+g9dd48f783), rust-analyzer inlay hints don't seem to work until rust-analyzer is stopped and started again. Anyone experience something similar, or have a fix?

Config:

{
    "lvimuser/lsp-inlayhints.nvim",
    event = "LspAttach",
    branch = "anticonceal",
    opts = {},
    config = function(_, opts)
      require("lsp-inlayhints").setup(opts)
      vim.api.nvim_create_autocmd("LspAttach", {
        group = vim.api.nvim_create_augroup("LspAttach_inlayhints", {}),
        callback = function(args)
          if not (args.data and args.data.client_id) then
            return
          end
          local client = vim.lsp.get_client_by_id(args.data.client_id)
          require("lsp-inlayhints").on_attach(client, args.buf)
        end,
      })
    end,
  },
lvimuser commented 1 year ago

Using anticonceal branch on nightly (NVIM v0.10.0-dev-411+g9dd48f783), rust-analyzer inlay hints don't seem to work until rust-analyzer is stopped and started again.

You're creating the autocommand after the LspAttach event, so it'll only trigger on subsequent events... Think about the loading order. You can

  1. set lazy = true and remove the event key; or
  2. use setup init instead of config.
Details

```lua { "lvimuser/lsp-inlayhints.nvim", branch = "anticonceal", opts = {}, lazy = true, init = function() vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("LspAttach_inlayhints", {}), callback = function(args) if not (args.data and args.data.client_id) then return end local client = vim.lsp.get_client_by_id(args.data.client_id) require("lsp-inlayhints").on_attach(client, args.buf) end, }) end, } ```

IndianBoy42 commented 1 year ago

for lazy.nvim you want init not setup

AndreM222 commented 1 year ago

this is still not supported yet right? as well what neovim version am I required for the inline virtual text?

kothavade commented 1 year ago

Thanks @lvimuser and @IndianBoy42, this worked:

Details ```lua { "lvimuser/lsp-inlayhints.nvim", event = "LspAttach", branch = "anticonceal", opts = {}, init = function() vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("LspAttach_inlayhints", {}), callback = function(args) if not (args.data and args.data.client_id) then return end local client = vim.lsp.get_client_by_id(args.data.client_id) require("lsp-inlayhints").on_attach(client, args.buf) end, }) end, }, ```
lvimuser commented 1 year ago

this is still not supported yet right?

depends on what you consider supported

what neovim version am I required for the inline virtual text?

nightly

AndreM222 commented 1 year ago

this is still not supported yet right?

depends on what you consider supported

I mean if it will work like vscode, jetbrains, visual studion, etc. if I implement this now to my nvim to have the inlay hints right inside where the parameters go instead of being outside.

IndianBoy42 commented 1 year ago

Have you tried the anticonceal branch mentioned in the second comment?

GustavoKatel commented 1 year ago

would this plugin/branch still be necessary after https://github.com/neovim/neovim/pull/23984 ?

No. The core implementation is miles better than this plugin. I'll archive this repo.

litoj commented 1 year ago

I'm curious what other feature will this plugin add that core does not have?

The feature I looked for is displaying inlay hints for current line only. And that is not possible with neovim core yet.

Edit: Neither does it allow to change the placement of hints.

nicos68 commented 8 months ago

Tested and works with lua, cpp, TS with anticonceal, was not successful with rust, anyone else got it working ?

EDIT: should probably state the issue, nothing is showing at all with the anticonceal branch everything works fine on master.

Same issue with https://github.com/mrcjkb/rustaceanvim : image

with the main branch, I only get hints at the end of the line. With anticonceal, I get nothing, even when I modify the file.

See my dotfiles here, my plugin config here and my rust config here.

TinusgragLin commented 8 months ago

@nicos68 You can try the recently-added vim.lsp.inlay_hint feature in nightly (0.10 dev) neovim. As 0.10 is coming soon (possibly April), this project will likely be archived before long. For reference, you can use this to enable the feature automatically:

vim.api.nvim_create_autocmd('LspAttach', {
    group = vim.api.nvim_create_augroup('UserLspConfig', {}),
    callback = function(ev)
        local client = vim.lsp.get_client_by_id(ev.data.client_id)
        if client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
            vim.lsp.inlay_hint.enable(ev.buf, true)
        end
    end,
)
nicos68 commented 8 months ago

@nicos68 You can try the recently-added vim.lsp.inlay_hint feature in nightly (0.10 dev) neovim. As 0.10 is coming soon (possibly April), this project will likely be archived before long. For reference, you can use this to enable the feature automatically:

vim.api.nvim_create_autocmd('LspAttach', {
    group = vim.api.nvim_create_augroup('UserLspConfig', {}),
    callback = function(ev)
        local client = vim.lsp.get_client_by_id(ev.data.client_id)
        if client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
            vim.lsp.inlay_hint.enable(ev.buf, true)
        end
    end,
)

Yeah I know I can switch to 0.10 where inlay hints have been added, but I’m using this plugin precisely because I don’t want to bother building neovim myself, I thought the goal of this plugin was to bring inlay hints for pre-0.10 neovim, is it not the case ?

TinusgragLin commented 8 months ago

because I don’t want to bother building neovim myself

Yeah, that's exactly my thought when I first saw this feature being developed in nightly versions and couldn't wait to try it out, but then I found that they release a development build every day using github actions! I am actually using the appimage I downloaded a few month ago.

I thought the goal of this plugin was to bring inlay hints for pre-0.10 neovim, is it not the case ?

Exactly! It's just that, from my experience, trying nightly is the easiest way to get this fantastic feature!