Replies: 9 comments 14 replies
|
This is reference implementation of getting text diffs using listener_add() |
|
What about combined approach? An official lsp plugin bundled with vim. With additional building blocks you mentioned in the last paragraph when and if needed. There would be quite a few global/local settings users would need to set up and exposing/using them via core c would be quite cumbersome compared to vimscript. |
|
Hi,
On Mon, Mar 9, 2026 at 5:15 PM mattn ***@***.***> wrote:
Today, many text editors and IDEs support the Language Server Protocol
(LSP). As you all know, LSP is a protocol that provides features such as
code completion, syntax highlighting, and error detection, supporting a
wide range of programming languages.
Vim will most likely still be alive ten years from now, and so will LSP.
There is more than enough merit in adding LSP support to Vim's core
functionality.
I would like to discuss and decide on Vim's direction now, while we have
the opportunity. There are broadly two approaches:
*Plan 1.* Vim core implements the LSP client itself
*Plan 2.* Vim core implements the building blocks needed for an LSP client
The first plan needs little explanation. Having Vim core implement the LSP
client directly is the most straightforward way to provide LSP support.
This would allow users to take advantage of LSP features simply by using
Vim.
The second plan is for Vim core to implement the building blocks needed
for an LSP client. This means Vim core would provide the foundation for LSP
client functionality. This would enable plugins such as vim-lsp and
yegappan/lsp to build fast and stable LSP clients by leveraging core
functionality.
I prefer the second option as that is more flexible and allows more custom
plugins to be developed.
As far as I know, the following are currently a burden for LSP clients
implemented as Vim plugins:
- Obtaining text diffs
- Applying TextEdits
The enhancements to the listener functionality in Vim 9.2 are supposed to
simplify the method to get the
changes. I haven't tried it out yet as I want the LSP plugin to work with
Vim 9.0.
I also added the diff() function to simplify getting the diff between a
cached version of a buffer and the
latest version.
When obtaining text diffs in Vim script, you would typically call getbufline(1,
'$'), but when the text is tens of thousands of lines long, this function
call becomes costly — for example, applying semantic highlights can take
several seconds. LSP clients should send only the changed portions to the
server.
As for applying TextEdits, anyone who has implemented an LSP client will
understand — applying TextEdits requires accurately and efficiently
reflecting changes to a buffer based on specified positions and lengths,
making it a complex and costly operation.
Implementing these in Vim script is extremely difficult, and performance
issues are likely to arise. If we choose Plan 2, I believe we need to
implement the following three building blocks in Vim core:
- fname_to_uri(), fname_from_uri()
- A way to obtain text diffs using listener_add(), or a getchanges()
function to get the current text diff
- applytextedits() to apply TextEdits to a buffer
We also need functions to better handle snippets with multiple variables.
Regards,
Yegappan
|
|
On Mon, Mar 9, 2026 at 8:59 PM Yegappan Lakshmanan ***@***.***> wrote:
Hi,
On Mon, Mar 9, 2026 at 5:15 PM mattn ***@***.***> wrote:
>
> Today, many text editors and IDEs support the Language Server Protocol (LSP). As you all know, LSP is a protocol that provides features such as code completion, syntax highlighting, and error detection, supporting a wide range of programming languages.
>
> Vim will most likely still be alive ten years from now, and so will LSP. There is more than enough merit in adding LSP support to Vim's core functionality.
>
> I would like to discuss and decide on Vim's direction now, while we have the opportunity. There are broadly two approaches:
>
> Plan 1. Vim core implements the LSP client itself
> Plan 2. Vim core implements the building blocks needed for an LSP client
>
> The first plan needs little explanation. Having Vim core implement the LSP client directly is the most straightforward way to provide LSP support. This would allow users to take advantage of LSP features simply by using Vim.
>
> The second plan is for Vim core to implement the building blocks needed for an LSP client. This means Vim core would provide the foundation for LSP client functionality. This would enable plugins such as vim-lsp and yegappan/lsp to build fast and stable LSP clients by leveraging core functionality.
I prefer the second option as that is more flexible and allows more custom plugins to be developed.
>
> As far as I know, the following are currently a burden for LSP clients implemented as Vim plugins:
>
> Obtaining text diffs
> Applying TextEdits
The enhancements to the listener functionality in Vim 9.2 are supposed to simplify the method to get the
changes. I haven't tried it out yet as I want the LSP plugin to work with Vim 9.0.
I also added the diff() function to simplify getting the diff between a cached version of a buffer and the
latest version.
>
> When obtaining text diffs in Vim script, you would typically call getbufline(1, '$'), but when the text is tens of thousands of lines long, this function call becomes costly — for example, applying semantic highlights can take several seconds. LSP clients should send only the changed portions to the server.
>
> As for applying TextEdits, anyone who has implemented an LSP client will understand — applying TextEdits requires accurately and efficiently reflecting changes to a buffer based on specified positions and lengths, making it a complex and costly operation.
>
> Implementing these in Vim script is extremely difficult, and performance issues are likely to arise. If we choose Plan 2, I believe we need to implement the following three building blocks in Vim core:
>
> fname_to_uri(), fname_from_uri()
> A way to obtain text diffs using listener_add(), or a getchanges() function to get the current text diff
> applytextedits() to apply TextEdits to a buffer
>
>
We also need functions to better handle snippets with multiple variables.
Another feature we need is support for string identifiers within the
Vim channel interface.
While the Language Server Protocol specification allows for both
numeric and string identifiers
in JSON-RPC messages, the Vim channel interface currently only
supports numeric ones.
Regards,
Yegappan
|
|
@mattn have you identified the slow parts of I can recommend valgrind + kcachegrind. just open |
|
Thanks mattn for starting this discussion! Being 2026, it sure seems as though Vim needs a good LSP Client! I've looked at the solution provided by prabirshrestha using listener_add(). While headed in the right direction (IMO), I believe a solution in vim9 is needed. I favor your plan #2 Plan 2. Vim core implements the building blocks needed for an LSP client I have one question regarding your two tasks: The goal is maintaining sync with Server. Are you thinking "Appying TextEdits" is relaying changes to the Server via |
|
I spent a few more hours digging into the LSP Server Incremental Synchronization Issue. This is for others who may come along investigating this issue. Its clear that even with the latest vim (9.2), this is a difficult (& ugly) nut to crack. The "listener fcn" set via listener_add() simply doesn't provide the necessary information to easily computer the The best route I can determine, which appears to be the route taken by prabirshrestha, is to keep two versions of any file being tracked by a LSP Server and then do a "diff" between them. The number of diffed lined can be minimized with information provided to the listener fcn but diffing is req'd none the less. So, for those working on vim's internal code, it would be great if listener_add(), or an improved version (get_changes() ?? as mattn suggests ??), that provides a [was/is] list would be great. Absent of that, the next best solution is a vim9 solution that performs the required diffs to format the req'd As far as I know, a vim9 solution doesn't exist. If anyone has developed this, please drop a comment here so those of us wanting a decent LSP Client can benefit. BTW: code folding is completely unworkable without vim9. |
|
Another feature that is needed in Vim is file and directory watcher to support https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWatchedFiles. |
|
May someone clarify what textdiffs are? Are they just more detailed change descriptions than the current listener callbacks? Thanks |
Uh oh!
There was an error while loading. Please reload this page.
Today, many text editors and IDEs support the Language Server Protocol (LSP). As you all know, LSP is a protocol that provides features such as code completion, syntax highlighting, and error detection, supporting a wide range of programming languages.
Vim will most likely still be alive ten years from now, and so will LSP. There is more than enough merit in adding LSP support to Vim's core functionality.
I would like to discuss and decide on Vim's direction now, while we have the opportunity. There are broadly two approaches:
Plan 1. Vim core implements the LSP client itself
Plan 2. Vim core implements the building blocks needed for an LSP client
The first plan needs little explanation. Having Vim core implement the LSP client directly is the most straightforward way to provide LSP support. This would allow users to take advantage of LSP features simply by using Vim.
The second plan is for Vim core to implement the building blocks needed for an LSP client. This means Vim core would provide the foundation for LSP client functionality. This would enable plugins such as vim-lsp and yegappan/lsp to build fast and stable LSP clients by leveraging core functionality.
As far as I know, the following are currently a burden for LSP clients implemented as Vim plugins:
When obtaining text diffs in Vim script, you would typically call
getbufline(1, '$'), but when the text is tens of thousands of lines long, this function call becomes costly — for example, applying semantic highlights can take several seconds. LSP clients should send only the changed portions to the server.As for applying TextEdits, anyone who has implemented an LSP client will understand — applying TextEdits requires accurately and efficiently reflecting changes to a buffer based on specified positions and lengths, making it a complex and costly operation.
Implementing these in Vim script is extremely difficult, and performance issues are likely to arise. If we choose Plan 2, I believe we need to implement the following three building blocks in Vim core:
fname_to_uri(),fname_from_uri()listener_add(), or agetchanges()function to get the current text diffapplytextedits()to apply TextEdits to a bufferAll reactions