godot
godot copied to clipboard
Very slow LSP diagnostics
Tested versions
- Reproducible in: 4.2.1.stable.arch_linux
System information
Godot v4.2.1.stable unknown - Arch Linux #1 SMP PREEMPT_DYNAMIC Thu, 21 Dec 2023 19:01:01 +0000 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 (nvidia; 545.29.06) - AMD Ryzen 5 5600X 6-Core Processor (12 Threads)
Issue description
This is similar to #69914, but for diagnostics rather than completions.
I'm using the helix editor with the Godot language server.
When typing, diagnostics show up very slowly:
I enabled "Use Thread" in the language server options. This significantly improved it, but it is still noticeably slow on large files:
One potential issue is that Godot uses Full
TextDocumentSync:
https://github.com/godotengine/godot/blob/master/modules/gdscript/language_server/godot_lsp.h#L567
This means that every time you hit a key, the entire text of the document is sent from the client to the server.
Using Incremental
sync could help here.
Another issue is that Godot sends diagnostics on every change.
For example, as I type var thread := Thread.new()
, Godot sends the following diagnostics:
"Expected variable name after \"var\"."
"Expected variable name after \"var\"."
"(UNUSED_VARIABLE): The local variable \"t\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"th\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"thr\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"thre\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"threa\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"thread\" is declared but never used in the block. If this is intended
"(UNUSED_VARIABLE): The local variable \"thread\" is declared but never used in the block. If this is intended
"Expected type after \":\""
"Expected expression for variable initial value after \"=\"."
"Expected expression for variable initial value after \"=\"."
Not only does this bog the editor down, it isn't helpful. When I'm in the middle of typing, I know my code is in an invalid state. Maybe we should have an option to only send diagnostics on save.
Steps to reproduce
- Configure an external editor with the LSP
- Clone https://github.com/oniksan/godobuf
- Edit https://github.com/oniksan/godobuf/tree/master/addons/protobuf/parser.gd
- Notice slow diagnostics when editing the file
Minimal reproduction project (MRP)
https://github.com/oniksan/godobuf
I experimented with only sending diagnostics on save here: https://github.com/rcorre/godot/commit/4ebe61a434d7b20ff09b23a4ab36e923695d71fa
It does improve performance significantly, but I'm not sure it's the best solution
Hey, I tried to reproduce this using Neovim and Godot 4.2.1.stable and I wasn't able to reproduce it. What I saw is the LSP didn't show any diagnostic while I'm editing, only when I finished editing and changed from insert mode to normal mode, that's when I got the first diagnostics. Even when I edited using only normal mode, I did see the diagnostics been shown more frequently, but the speed was pretty normal. Maybe it's something more related to the client you are using? I'm not sure.
@bkerz does the neovim client you're using send didChange
notifications as you type? Are you able to get logs of the messages to/from the LSP server? Have you tried with a large file like https://github.com/oniksan/godobuf/tree/master/addons/protobuf/parser.gd?
@rcorre Hey, sorrry, to be honest I didn't know how to get the logs from the LSP, but I do tried the file you mentioned and as I said, it worked nice. I'll try to get the info from the LSP logs and show it to you. The only case the LSP seems to have issues is when I either restart Godot or when I start Godot while having Neovim opened listening at the Godot port.
@bkerz no worries! Based on https://neovim.discourse.group/t/where-do-language-server-logs-go/1303/3, you can call :lua vim.lsp.set_log_level('debug')
and find logs at .cache/nvim/lsp.log
.
My guess is that neovim is batching changes while you type, whereas helix is sending a change every time you press a key.
#89284 might fix this, could one of you test it to confirm?
Assuming fixed by #89284. Please let us know if it isn't the case.
Yes, #89284 fixes this, thanks @mihe! This is a huge quality-of-life improvement.