simrat39 / rust-tools.nvim

Tools for better development in rust using neovim's builtin lsp
MIT License
2.17k stars 159 forks source link

Correctly iterate over multiple clients #329

Closed mkeeter closed 1 year ago

mkeeter commented 1 year ago

I've been using rust-tools for a few months and it's been a great plugin!

However, I noticed that the inlay hints don't work correctly in the presence of multiple clients:

 Language client log: /Users/mjk/.local/state/nvim/lsp.log
 Detected filetype:   rust

 1 client(s) attached to this buffer: 

 Client: rust_analyzer (id: 2, bufnr: [12])
    filetypes:       rust
    autostart:       true
    root directory:  /Users/mjk/code/rust-tools-test/bar
    cmd:             rust-analyzer

 1 active client(s) not attached to this buffer: 

 Client: rust_analyzer (id: 1, bufnr: [1])
    filetypes:       rust
    autostart:       true
    root directory:  Running in single file mode.
    cmd:             rust-analyzer

 Configured servers list: rust_analyzer

This is because of cache_render:

 function M.cache_render(self, bufnr)
  local buffer = bufnr or vim.api.nvim_get_current_buf()

  for _, v in ipairs(vim.lsp.buf_get_clients(buffer)) do
    if rt.utils.is_ra_server(v) then
      v.request(
        "textDocument/inlayHint",
        get_params(v, buffer),
        -- ... etc

The ipairs documentation reads

Returns three values (an iterator function, the table t, and 0) so that the construction for i,v in ipairs(t) do body end will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first absent index.

Because buffer 12's client list starts at 2, ipairs sees a missing index at 1 and stops immediately. This means that inlay hints don't show up in this buffer!

Luckily, there's an easy fix: using pairs instead iterates over the whole table!