mirror of
https://github.com/neovim/neovim.git
synced 2026-06-17 01:01:16 +00:00
backport fix(lsp): send didClose, didOpen when languageId changes (#39519)
fix(lsp): send didClose, didOpen when languageId changes
Problem:
If a buffer's filetype changes after the LSP client has already
attached (e.g. from json to jsonc via a modeline), but the client
supports both filetypes, it stays attached. It does not notify the
server of the new languageId, causing the server to incorrectly process
the file using the old languageId.
Solution:
Save the languageId used during textDocument/didOpen, and send
textDocument/didClose + textDocument/didOpen when buffer's languageId
changed.
Lsp spec:
0003fb53f1/_specifications/lsp/3.18/textDocument/didOpen.md (L5)
> If the language id of a document changes, the client
> needs to send a textDocument/didClose to the server followed by a
> textDocument/didOpen with the new language id if the server handles
> the new language id as well.
AI-assisted: Gemini 3.1 Pro
Co-authored-by: phanium <91544758+phanen@users.noreply.github.com>
This commit is contained in:
@@ -69,24 +69,20 @@ end
|
||||
|
||||
--- Create a new treesitter view.
|
||||
---
|
||||
---@param bufnr integer Source buffer number
|
||||
---@param buf integer Source buffer number
|
||||
---@param lang string|nil Language of source buffer
|
||||
---
|
||||
---@return vim.treesitter.dev.TSTreeView|nil
|
||||
---@return string|nil Error message, if any
|
||||
---
|
||||
---@package
|
||||
function TSTreeView:new(bufnr, lang)
|
||||
bufnr = bufnr or 0
|
||||
lang = lang or vim.treesitter.language.get_lang(vim.bo[bufnr].filetype)
|
||||
local parser = vim.treesitter.get_parser(bufnr, lang)
|
||||
function TSTreeView:new(buf, lang)
|
||||
buf = buf or 0
|
||||
lang = lang or vim.treesitter.language.get_lang(vim.bo[buf].filetype)
|
||||
local parser = vim.treesitter.get_parser(buf, lang)
|
||||
if not parser then
|
||||
return nil,
|
||||
string.format(
|
||||
'Failed to create TSTreeView for buffer %s: no parser for lang "%s"',
|
||||
bufnr,
|
||||
lang
|
||||
)
|
||||
string.format('Failed to create TSTreeView for buffer %s: no parser for lang "%s"', buf, lang)
|
||||
end
|
||||
|
||||
-- For each child tree (injected language), find the root of the tree and locate the node within
|
||||
@@ -232,10 +228,10 @@ end
|
||||
---
|
||||
--- Calling this function computes the text that is displayed for each node.
|
||||
---
|
||||
---@param bufnr integer Buffer number to write into.
|
||||
---@param buf integer Buffer number to write into.
|
||||
---@package
|
||||
function TSTreeView:draw(bufnr)
|
||||
vim.bo[bufnr].modifiable = true
|
||||
function TSTreeView:draw(buf)
|
||||
vim.bo[buf].modifiable = true
|
||||
local lines = {} ---@type string[]
|
||||
local lang_hl_marks = {} ---@type table[]
|
||||
|
||||
@@ -284,18 +280,18 @@ function TSTreeView:draw(bufnr)
|
||||
lines[i] = line
|
||||
end
|
||||
|
||||
api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||
|
||||
api.nvim_buf_clear_namespace(bufnr, decor_ns, 0, -1)
|
||||
api.nvim_buf_clear_namespace(buf, decor_ns, 0, -1)
|
||||
|
||||
for i, m in ipairs(lang_hl_marks) do
|
||||
api.nvim_buf_set_extmark(bufnr, decor_ns, i - 1, m.col, {
|
||||
api.nvim_buf_set_extmark(buf, decor_ns, i - 1, m.col, {
|
||||
hl_group = 'Title',
|
||||
end_col = m.end_col,
|
||||
})
|
||||
end
|
||||
|
||||
vim.bo[bufnr].modifiable = false
|
||||
vim.bo[buf].modifiable = false
|
||||
end
|
||||
|
||||
--- Get node {i} from this View.
|
||||
|
||||
Reference in New Issue
Block a user