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

Inlay Hints not drawn once they are provided #26511

Closed
jalil-salame opened this issue Dec 10, 2023 · 14 comments
Closed

Inlay Hints not drawn once they are provided #26511

jalil-salame opened this issue Dec 10, 2023 · 14 comments
Labels
Milestone

Comments

@jalil-salame
Copy link

Problem

When enabling inlay_hints on LspAttach, the hints are not shown on text already on screen. Scrolling and revealing more text does show inlay hints in the "new" text. Toggling inlay hints on and off fixes the "stuck" lines and show inlay hints there too. If the file is small enough and you scroll through all of it/can see all of it, no inlay hints will be displayed.

Basically any text seen between LspAttach being fired and the lsp server being ready to provide hints causes the "seen" text to not show inlay hints until they are toggled. My assumption is that some caching is being done, but before the lsp is ready to send hints it says there are no hints. Then, once it is ready, this cache is not invalidated.

Steps to reproduce

minimal_init.lua
local pattern = 'rust'
local cmd = {'rust-analyzer'}
local root_markers = {'.git', '.editorconfig', 'Cargo.toml'}
local settings = vim.empty_dict()


vim.api.nvim_create_autocmd("LspAttach", {
  callback = function(args)
    local bufnr = args.buf
    local client = vim.lsp.get_client_by_id(args.data.client_id)
    if client.server_capabilities.inlayHintProvider then
      vim.lsp.inlay_hint.enable(bufnr, true)
    end
  end,
})


vim.api.nvim_create_autocmd('FileType', {
  pattern = pattern,
  callback = function(args)
    local match = vim.fs.find(root_markers, { path = args.file, upward = true })[1]
    local root_dir = match and vim.fn.fnamemodify(match, ':p:h') or nil
    vim.lsp.start({
      name = 'bugged-ls',
      cmd = cmd,
      root_dir = root_dir,
      settings = settings
    })
  end
})
Asciicast recording of the bug

asciicast of bug report

  1. Open a rust project (may work with other servers providing inlay hints?) using minimal_init.lua (nvim --clean -u minimal_init.lua src/main.rs)
  2. Wait for rust-analyzer to finish starting
  3. Verify that everything on screen which should have inlay hints doesn't
  4. Scroll down to see that uncovered text does have inlay hints
  5. Toggle inlay hints (:lua vim.lsp.inlay_hint.enable(0, false), :lua vim.lsp.inlay_hint.enable(0, true))
  6. Verify that inlay hints are now properly shown

Expected behavior

Inlay hints should be drawn on displayed text once they become available.

My guess is that the same event that causes the syntax highlighting to be redrawn (see asciicast recording at 18s), should also be used to re-request inlay hints (invalidate hint cache(?)).

Neovim version (nvim -v)

NVIM v0.10.0-dev-096211a

Vim (not Nvim) behaves the same?

not applicable

Operating system/version

NixOS 24.05.20231204.2c7f3c0

Terminal name/version

wezterm 20230712-072601-f4abf8fd

$TERM environment variable

xterm-256color

Installation

nix nix-community/neovim-nightly-overlay

@jalil-salame jalil-salame added the bug issues reporting wrong behavior label Dec 10, 2023
@zeertzjq zeertzjq added the lsp label Dec 10, 2023
@snaggen
Copy link

snaggen commented Jan 4, 2024

Tested with todays nightly and it is still there.

This issue creates a quite confusing behavior, basically rendering it unusable for rust development where inlay hints are quite important.

@Spxg
Copy link

Spxg commented Jan 9, 2024

Try this: rust show inlay hint with native lsp. I've been using it for months

@snaggen
Copy link

snaggen commented Jan 9, 2024

Nice trick, but not sure how to hook that in to the rustaceanvim plugin, so I will probably wait until they fix this issue properly.

@snaggen
Copy link

snaggen commented Jan 10, 2024

Ok, until this bug is fixed, the workaround, adapted for rustaceanvim is as follows (using lazy):

    {
        'mrcjkb/rustaceanvim',
        version = '^3', -- Recommended
        ft = { 'rust' },
        config = function()
            local M = {}

            vim.g.rustaceanvim = function()
                return {
                    server = {
                        handlers = {
                            ["experimental/serverStatus"] = function(_, result, ctx, _)
                                if result.quiescent and not M.ran_once then
                                    for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do
                                        vim.lsp.inlay_hint.enable(bufnr, false);
                                        vim.lsp.inlay_hint.enable(bufnr, true);
                                    end
                                    M.ran_once = true
                                end
                            end,
                        }
                    }
                }
            end
        end
    },

@glepnir
Copy link
Member

glepnir commented Jan 10, 2024

I add this request in lspconfig before see neovim/nvim-lspconfig#2658 so you can create a handler to check rust analyzer status then enable inalyhint. nothing to fix here.

@justinmk justinmk added this to the unplanned milestone Jan 14, 2024
@justinmk justinmk removed the bug issues reporting wrong behavior label Jan 14, 2024
@justinmk
Copy link
Member

is this server-specific?

@justinmk justinmk closed this as not planned Won't fix, can't repro, duplicate, stale Jan 14, 2024
@jalil-salame
Copy link
Author

is this server-specific?

I don't know, I only have experience with rust's and latex's lsp, and latex has other issues.

@snaggen
Copy link

snaggen commented Jan 14, 2024

No, it's not server specific. Had to apply same workaround for jdtls.

@snaggen
Copy link

snaggen commented Jan 14, 2024

What I don't get is that this is closed with , not planned, but the lsp-config issue doesn't really aim to solve this, it seems to be about just enabling this workaround.
So, are we happy with this broken behavior by default? Needing to add this workaround to any lsp that needs it, and first experience this bug, and google it to figure out that the wo is needed.

I don't know where in the stack the responsibility for this really belongs, but it feels wrong to close this bug without an issue somewhere to fix this default behavior.

@glepnir
Copy link
Member

glepnir commented Jan 14, 2024

Each server's initialization preparation time is different. There is a known issue rust-lang/rust-analyzer#14258 that rust-analyzer starts slowly. Because it requires a lot of preparation. For some fast-start servers, the server is already ready when on_attach is called. lsp spec has no server status request. I once raised an issue microsoft/language-server-protocol#1764 hoping to add a standard to send a reminder to the client when the server is ready. But Microsoft wants clients to wait. This is kind of bad because you need to constantly poll the server status. Fortunately, some servers provide custom status notify such as rust anaylyzer. lspconfig is just a basic server configuration collector.I don't know if you are satisfied with this answer.

Thanks for your time . happy coding with neovim

@jalil-salame
Copy link
Author

Thanks for clarifying this c:

@snaggen
Copy link

snaggen commented Jan 14, 2024

But then, wouldn't the real fix be to add a status event, to Neovim, then have lsp-config hook that up for servers that have support for status events (both rust-analyzer and jdtls have that).
Then if server status done is sent after On Attach, re-initialize stuff like inlay hints.

@glepnir
Copy link
Member

glepnir commented Jan 14, 2024

We don't know when the server will be ready. Like I said unless the client keeps polling the server status and then calls on_attach it is expensive. currently some servers support sending status notify. I think it's enough.

@clason
Copy link
Member

clason commented Jan 14, 2024

I don't know where in the stack the responsibility for this really belongs

In this case, rustacean.nvim. The core LSP client is -- very intentionally -- server agnostic, so there will be no special treatments. This is different for a server-specific plugin that can handle all manner of off-spec idiosyncrasies. This includes unusually slow startup.

It is very much a design goal for the builtin client to handle the lowest common denominator only ("90% at 10% cost"), while allowing users and plugins to build on top of that to get the remaining 10%, exactly how they want it.

(We're not MSFT; we have to choose our battles carefully.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants