natebosch / vim-lsc

A vim plugin for communicating with a language server
BSD 3-Clause "New" or "Revised" License
692 stars 83 forks source link

For long completion lists, contemplate a hard cap with 'IsIncomplete=true' #303

Closed bluz71 closed 4 years ago

bluz71 commented 4 years ago

Another item spawned fro #291

The Dart Analysis Server that ships with Flutter 1.17 is sending upwards of 27,000 completion items to LSC's auto-completion engine.

Needless to say, VimScript and LSC is not handling that well (pauses and stutters whilst in Vim's insert mode).

A future version of the Dart Analysis Server should pare that back greatly via server-side prefix filtering. So it may not be a problem for Dart soon (to-be-determined).

However, the fundamental issue remains, how to deal with Language Servers that send thousands of completion items? Ideally we don't want LSC stuttering and pausing.

Question, does any other mainstream language server send huge completion lists? That is a research topic I will undertake, my plan is to investigate the servers for these languages:

If none of the above are bad actors then I would not bother with this, just resolve it.

If some LS do send very large completion lists then it may be worth exploring the possibility of hard capping completions to a reasonable number, say 1,000, and then implementing IsIncomplete=true-style completion; which would complicate LSC, and the benefits of which may not worth it.

For example I wonder if JSON decoding is taking up just as much times as list processing? I don't know.

I hope Dart's huge payload was a once off and that we don't need to think about this.

I will feed back my findings over the next week or so depending on my free time.

bluz71 commented 4 years ago

I managed to test a bunch of language servers.

Tests

Two tests were undertaken, counting the number of server-provided completion items when completing a language keyword and also when completing a library type.

Language Language Server Keyword Matches Type Matches
C++ clangd 100 100
Dart Analysis Server / Flutter 1.12 5,630 5,619
Dart Analysis Server / Flutter 1.17 26,789 26,777
Go gopls 4 4
JavaScript Microsoft TypeScript LS 1,449 1,203
JavaScript Sourcegraph JavaScript LS 1,083 1,083
Ruby Solargraph 4 3
Rust rust-analyzer 206 206
Swift SourceKit-LSP 33,216 33,216
TypeScript Microsoft TypeScript LS 1,371 1,106

Findings

Dart Analysis Server via Flutter 1.17 is towards the very upper end in providing too many completion items. A work in progress, since server-side prefix filtering is due eventually.

Swift Language Server is totally unusable, it is taking about 10 seconds to type anything. This is not just due to LSC, if anything it feels like a lot more time is spent in the server.

However, Go's language server is blazingly fast. LSC is popping up the completion menu instantly.

Microsoft's TypeScript language server, which can also be used for JavaScript as well, is also quite speedy.

Rust's language server feels slow even though the match list is small.

Performance is a combination of server-side performance and client-side handling. Slow servers exist. Likewise clients in pure VimScript, such as LSC, can be made slow if given too much content as Dart's Analysis Server is currently doing.

Recommendations for LSC

The best language servers are already fast and lean as evidenced by Go and to an extent the TypeScript language servers.

VimScript theoretically will also be getting faster in Vim9:

https://github.com/brammool/vim9/blob/master/README.md

For now, I would wait and see how Dart's upcoming Analysis Server changes impact LSC. If that trims the completion way back then I would be inclined to close the issue.

bluz71 commented 4 years ago

Dart Analysis Server performance issue now appears to be resolved.

Raw match counts of Dart Analysis Servers:

Language Language Server Keyword Matches Type Matches
Dart Analysis Server / Flutter 1.12 5,630 5,619
Dart Analysis Server / Flutter 1.17 26,789 26,777
Dart Analysis Server / Dev 2.9.0-19.0 863 572

Language servers that I find to work well with LSC (no lag): clangd (C++), solargraph (Ruby), gopls (Go), Dart Analysis Server (upcoming) and Microsoft TypeScript language server (for JS and TS). That's a pretty good collections of production ready language servers.

I now believe that it is not worth doing anything here. Hence I am closing this issue.

Basically, language Servers that are too verbose or slow should be improved just as Dart has been.