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:
Justin M. Keyes
2026-04-30 09:09:55 -04:00
committed by GitHub
parent d147d0434d
commit 4b424a06c5
20 changed files with 243 additions and 283 deletions

View File

@@ -308,15 +308,15 @@ M.properties = properties
--- @private
--- Configure the given buffer with options from an `.editorconfig` file
--- @param bufnr integer Buffer number to configure
function M.config(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
if not vim.api.nvim_buf_is_valid(bufnr) then
--- @param buf integer Buffer number to configure
function M.config(buf)
buf = buf or vim.api.nvim_get_current_buf()
if not vim.api.nvim_buf_is_valid(buf) then
return
end
local path = vim.fs.normalize(vim.api.nvim_buf_get_name(bufnr))
if vim.bo[bufnr].buftype ~= '' or not vim.bo[bufnr].modifiable or path == '' then
local path = vim.fs.normalize(vim.api.nvim_buf_get_name(buf))
if vim.bo[buf].buftype ~= '' or not vim.bo[buf].modifiable or path == '' then
return
end
@@ -339,7 +339,7 @@ function M.config(bufnr)
local func = M.properties[opt]
if func then
--- @type boolean, string?
local ok, err = pcall(func, bufnr, val, opts)
local ok, err = pcall(func, buf, val, opts)
if ok then
applied[opt] = val
else
@@ -349,7 +349,7 @@ function M.config(bufnr)
end
end
vim.b[bufnr].editorconfig = applied
vim.b[buf].editorconfig = applied
end
return M