Contents

Neovim Nightly: Native Inlay Hints with Virtual Text


I’ve been using Neovim for a while now, and there is ONE single feature that I’ve felt like I was missing out on since making the switch, and that is good inlay hints. I’m beyond excited that it’s finally here for us.

No Inlay Hints

Using the same code example from my previous post, here is what it looks like with no inlay hints:

Looks pretty plain!

rust-tools.nvim Inlay Hints

Here are the inlay hints provided by the rust-tools.nvim plugin:

This is a little better, but not great.

Let’s use the line numbered 12 as an example.

The inlay hint says <- (sep) => String

What’s this mean? It means the argument passed to the function items.join is named sep, and the type of items_skim is a String.

While this is helpful, it’s not as helpful as it could be. Additionally, the inlay hint comes at the end of the line, which just isn’t that visually pleasing.

If you use a different editor, you might be used to having hints in the line, mixed in with real text. Well until recently, Neovim had no support for virtual text in the middle of lines - only at the end of the lines.

Native LSP Inlay Hints with Virtual Text

That brings us to the present. Neovim recently merged in support for multiple pieces that bring proper inlay hints to our favorite editor.

Here is what it looks like:

Look back at line 12, or any line really. Isn’t the result much better?

How to Enable

As mentioned, you need to be (as of today) on Neovim nightly. The current build is v0.10.0-dev-e85e7fc. Anything after this should be good to go.

In a single buffer

If you just want to try it out, inside Neovim (in a buffer with an LSP that supports inlay hints running) run:

:lua vim.lsp.inlay_hint.enable(0, true)

This will enable it in the current buffer.

Globally

If you want it to be globally enabled on startup, you’ll have to add the setting to your configuration.

For me, that looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vim.api.nvim_create_autocmd("LspAttach", {
    group = vim.api.nvim_create_augroup("UserLspConfig", {}),
    callback = function(args)
        local client = vim.lsp.get_client_by_id(args.data.client_id)
        if client.server_capabilities.inlayHintProvider then
            vim.lsp.inlay_hint.enable(args.buf, true)
        end
        -- whatever other lsp config you want
    end
})

There you have it! Inlay hints in Neovim! Hope you all enjoy this update as much as I am.

Updates

2023-07-06

  • In the past few days there was a breaking API change in Neovim: vim.lsp.buf.inlay_hint was changed to vim.lsp.inlay_hint. I’ve updated the post to reflect this.
  • While tinkering with my config, I found that putting lsp settings in on_attach is no longer considered best practice. Instead you should use the LspAttach event in an autocommand.
  • In the original post I didn’t check if the LSP server supported inlay hints. I’ve updated the example code to check if the LSP server provides an inlay hint provider before enabling inlay hints for the buffer.

2023-12-07

  • In the last update inlay hints were toggled on with vim.lsp.inlay_hint(args.buf, true). Francisco Gonzalez in the comments pointed out that the API changed again, and I had not noticed (I didn’t update Neovim recently!). It is now vim.lsp.inlay_hint.enable(...) and the post has been updated to reflect this. Thank you, Francisco!