You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When loading or updating the contents of a file (e.g. :e), vim-lsp correctly sends the full content to the file to the first LSP registered server, but erroneously tells subsequent servers that the file has had changes. This causes the subsequent LSP servers to have a warped view of what the file contents are.
In some cases the only effect will be an overloaded list of diagnostics, (e.g. when no code actions are requested). In other cases, like requesting :LspDocumentFormat, the server will return its own warped version of the file, leaving the user with a buffer containing multiple copies of the actual content.
A suggested fix is provided in an accompanying PR (#1548)
Setup
Tell vim-lsp to start both ruff and pyright servers:
The formatting step in the reproduction below will work only when ruff is assigned the second slot int he server list; however, the duplication of diagnostics should also show up for pyright if that is the one assigned the second slot.
Create a test file that will trigger some diagnostics for both servers. The following has unused imports (ruff fix), extra blank lines (ruff format) and unknown module (pyright):
importpandasimportnumpi
Reproduce
The initial opening of the file correctly identifies the issues of the simple file:
Executing :e on the file once causes ruff to start hallucinating, while pyright is doing well:
And this continues as we reload the file:
Asking for :LspDocumentFormat, which is executed by ruff, results in a very different buffer, caused by ruff imposing its perceived reality onto the developer:
Debug
The offending line can be found in the function s:text_changes(buf, server_name) in the following line:
When the second LSP server is being sent the data, the condition is met and the diff is sent. However, the check is not making the distinction of which LSP server is actually being updated, a distinction that should be meade given the expected content of s:file_content:
Summary
When loading or updating the contents of a file (e.g.
:e
),vim-lsp
correctly sends the full content to the file to the first LSP registered server, but erroneously tells subsequent servers that the file has had changes. This causes the subsequent LSP servers to have a warped view of what the file contents are.In some cases the only effect will be an overloaded list of diagnostics, (e.g. when no code actions are requested). In other cases, like requesting
:LspDocumentFormat
, the server will return its own warped version of the file, leaving the user with a buffer containing multiple copies of the actual content.A suggested fix is provided in an accompanying PR (#1548)
Setup
Tell
vim-lsp
to start bothruff
andpyright
servers:The formatting step in the reproduction below will work only when
ruff
is assigned the second slot int he server list; however, the duplication of diagnostics should also show up forpyright
if that is the one assigned the second slot.Create a test file that will trigger some diagnostics for both servers. The following has unused imports (
ruff fix
), extra blank lines (ruff format
) and unknown module (pyright
):Reproduce
The initial opening of the file correctly identifies the issues of the simple file:
Executing
:e
on the file once causesruff
to start hallucinating, whilepyright
is doing well:And this continues as we reload the file:
Asking for
:LspDocumentFormat
, which is executed byruff
, results in a very different buffer, caused byruff
imposing its perceived reality onto the developer:Debug
The offending line can be found in the function
s:text_changes(buf, server_name)
in the following line:vim-lsp/autoload/lsp.vim
Lines 752 to 754 in f7ccf00
When the first LSP server is being sent the data
s:file_content
does not have an entry for the buffer yet, and is correctly sent the full content:vim-lsp/autoload/lsp.vim
Lines 765 to 768 in f7ccf00
When the second LSP server is being sent the data, the condition is met and the diff is sent. However, the check is not making the distinction of which LSP server is actually being updated, a distinction that should be meade given the expected content of
s:file_content
:vim-lsp/autoload/lsp.vim
Lines 9 to 20 in f7ccf00
Fix
The fix seems to be simple, just add a statement to the condition statement to ensure the right server is being evaluated and updated, change:
vim-lsp/autoload/lsp.vim
Lines 752 to 754 in f7ccf00
to:
The text was updated successfully, but these errors were encountered: