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

fix(lsp): workaround for inlay hint rendering + fix serverStatus handler #156

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- LSP: If inlay hints are enabled for a buffer, force Neovim
to redraw them when rust-analyzer has fully initialized.
This is a workaround for [neovim/26511](https://github.com/neovim/neovim/issues/26511).
- LSP: On client stop, reset the `experimental/serverStatus` handler's
internal state for the respective client, so that the handler can be
rerun on restart.

## [3.15.0] - 2024-01-11

### Added
Expand Down
9 changes: 8 additions & 1 deletion lua/rustaceanvim/lsp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local config = require('rustaceanvim.config.internal')
local compat = require('rustaceanvim.compat')
local types = require('rustaceanvim.types.internal')
local rust_analyzer = require('rustaceanvim.rust_analyzer')
local server_status = require('rustaceanvim.server_status')
local joinpath = compat.joinpath

local function override_apply_text_edits()
Expand Down Expand Up @@ -172,7 +173,7 @@ M.start = function(bufnr)
lsp_start_opts.capabilities = vim.tbl_deep_extend('force', capabilities, lsp_start_opts.capabilities or {})

local custom_handlers = {}
custom_handlers['experimental/serverStatus'] = require('rustaceanvim.server_status').handler
custom_handlers['experimental/serverStatus'] = server_status.handler

if config.tools.hover_actions.replace_builtin_hover then
custom_handlers['textDocument/hover'] = require('rustaceanvim.hover_actions').handler
Expand Down Expand Up @@ -221,6 +222,12 @@ M.stop = function(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
local clients = rust_analyzer.get_active_rustaceanvim_clients(bufnr)
vim.lsp.stop_client(clients)
if type(clients) == 'table' then
---@cast clients lsp.Client[]
for _, client in ipairs(clients) do
server_status.reset_client_state(client.id)
end
end
return clients
end

Expand Down
34 changes: 28 additions & 6 deletions lua/rustaceanvim/server_status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,38 @@ local config = require('rustaceanvim.config.internal')

local M = {}

local _ran_once = false
---@type { [integer]: boolean }
local _ran_once = {}

---@param result RustAnalyzerInitializedStatusInternal
function M.handler(_, result)
if result.quiescent and not _ran_once then
if config.tools.on_initialized then
config.tools.on_initialized(result)
function M.handler(_, result, ctx, _)
-- quiescent means the full set of results is ready.
if not result.quiescent or _ran_once[ctx.client_id] then
return
end
-- rust-analyzer may provide incomplete/empty inlay hints by the time Neovim
-- calls the `on_attach` callback.
-- [https://github.com/neovim/neovim/issues/26511]
-- This workaround forces Neovim to redraw inlay hints if they are enabled,
-- as soon as rust-analyzer has fully initialized.
if type(vim.lsp.inlay_hint) == 'table' then
for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do
if vim.lsp.inlay_hint.is_enabled(bufnr) then
vim.lsp.inlay_hint.enable(bufnr, false)
vim.lsp.inlay_hint.enable(bufnr, true)
end
end
_ran_once = true
end
-- Load user on_initialized
if config.tools.on_initialized then
config.tools.on_initialized(result)
end
_ran_once[ctx.client_id] = true
end

---@param client_id integer
function M.reset_client_state(client_id)
_ran_once[client_id] = false
end

return M