lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

Neovim: using the builtin formatter erases virtual lines

Open paveloom opened this issue 1 year ago • 2 comments

How are you using the lua-language-server?

NeoVim

Which OS are you using?

Linux

What is the issue affecting?

Formatting

Expected Behaviour

Virtual lines should be preserved. Here is an example (by @whynothugo) with using StyLua as a formatter instead.

Actual Behaviour

Virtual lines get erased. The diagnostics are still there, though. Here is an example of how it looks.

Reproduction steps

  1. Setup the nvim-lspconfig and lsp_lines plugins
  2. Make sure you see the virtual lines, then format the code
  3. Are the virtual lines still there?

Additional Notes

Both examples are demonstrated by using @WhyNotHugo's lsp_lines Neovim plugin. There is a downstream issue.

Log File

No response

paveloom avatar Aug 15 '22 07:08 paveloom

@CppCXY

sumneko avatar Aug 17 '22 10:08 sumneko

I don't know how virtual lines is implemented, I just respond to requests according to standard lsp, maybe you can try formatting with cli to see if it will cause the same problem.

CppCXY avatar Aug 17 '22 11:08 CppCXY

Any updates on if the cli helped? I would really love to see this issue resolved. All folds in my buffer get reset when saving in lua files and I believe it is this same issue.

ribru17 avatar Sep 09 '23 16:09 ribru17

Can't reproduce the original issue anymore.

paveloom avatar Sep 09 '23 16:09 paveloom

I am still having this issue very much, I think you no longer experience it because you disabled lua_ls formatting and switched to stylua based on your dotfiles.

ribru17 avatar Sep 09 '23 22:09 ribru17

Oh, right, completely forgot about it. Still an issue, then. Thanks, Riley. I can reproduce it with the mentioned CLI, too.

paveloom avatar Sep 10 '23 08:09 paveloom

Although I haven't used nvim myself, I believe the reason is that the code diagnostics are not triggered again. As far as I know, "virtual lines" rely on the current code diagnostic information. However, the formatting behavior itself clears the diagnostics of the current buffer. Since there is no change before and after formatting, nvim does not initiate a text update protocol, which results in luals not pushing the diagnostics information again and causing a lack of refresh in the "virtual lines". Other plugins like Stylelua do not cause this issue because their frontend plugins, such as null.nvim, check for changes before updating.

CppCXY avatar Sep 11 '23 02:09 CppCXY

Thanks for looking into this, that makes sense. I also noticed that the Lua LSP updates the file ranging from AST start to end, rather than creating a range of just the changed lines. I believe this is the reason the folds are always reset. I noticed with the typescript LSP the returned format response is not one change with all the edits ranging over the entire file, but rather an array of text changes with their own isolated line ranges, allowing the editor to update just those lines.

ribru17 avatar Sep 11 '23 15:09 ribru17

Thanks for looking into this, that makes sense. I also noticed that the Lua LSP updates the file ranging from AST start to end, rather than creating a range of just the changed lines. I believe this is the reason the folds are always reset. I noticed with the typescript LSP the returned format response is not one change with all the edits ranging over the entire file, but rather an array of text changes with their own isolated line ranges, allowing the editor to update just those lines.

I think this diff should be implemented by the editor, at least so that all features can work correctly on VS Code. According to the LSP protocol, if multiple small textEdits need to be generated, there is a state relationship between different textEdits. This means that the next textEdit must be based on the ending state of the previous textEdit, which becomes too complicated. On the other hand, it seems that nvim is not willing to do the diff because it affects performance, causing some features like code undo to not work well.

CppCXY avatar Sep 12 '23 03:09 CppCXY

Do you think there is an easy way to do this from the LSP side? For example check the line differences between the reformatted text and the original and only include those ranges

ribru17 avatar Sep 12 '23 04:09 ribru17

Do you think there is an easy way to do this from the LSP side? For example check the line differences between the reformatted text and the original and only include those ranges

This is a feasible solution, but I don't have the energy to implement it. Moreover, even if I make these modifications, I'm not sure if it would be helpful for the objective since I can't test it. I believe this is an issue with nvim and virtual lines themselves, and I don't feel motivated enough to fix it for them. If you're interested, you can try implementing it yourself, but please avoid implementing it in Lua as it would affect performance.

CppCXY avatar Sep 12 '23 04:09 CppCXY