microsoft / language-server-protocol

Defines a common protocol for language servers.
https://microsoft.github.io/language-server-protocol/
Creative Commons Attribution 4.0 International
11.22k stars 798 forks source link

support smart indentation in LSP #1326

Open heejaechang opened 3 years ago

heejaechang commented 3 years ago

can smart indenting capability added to LSP? I know that there is a concern on perf, but if LS chooses to take that perf hit for better indentation on vertical cursor move or enter, I think LSP should allow LS to do so.

many complex indentation requires parse tree and can't be done using regex alone. so, it feels like it should be LS's decision to take the perf hit or not.

with smart cancellation, (no cancel if "enter" + key typed, but cancel previous smart indentation request if cursor moved vertically and etc), a lot of perf concern, I feel like, can be mitigated.

thank you.

ex)

method( { 1: 'apple', 
                  * align caret to "1" on "arrow down" 
rcjsuen commented 3 years ago

I wonder if this can be solved by textDocument/onTypeFormatting? Also see #1001.

heejaechang commented 3 years ago

if either OnEnter or onTypeFormatting can put caret at certain position without putting real whitespaces before the caret, then probably we can use one of those as workaround for "enter" case. but it won't work for navigating using up/down arrow.

see how C# behaves when moving caret up and down in an editor in VS as an example.

dbaeumer commented 3 years ago

The problem is perf and async behavior and the unpredictability for the user on typing. This is why we stayed away from this.

Isn't your example even more complex. Usually smart indent is used when user creates a new line. In your example the line would already exist since you are arrowing down.

heejaechang commented 3 years ago

@dbaeumer we want the behavior of VS's smart indenter if possible. in VS, smart indenter is not enter only. when user arrows down to a blank line between, say, methods, it puts caret at right indentation without actually putting whitespaces before it. only when user actually type something, then whitespaces are added (virtual column).

also, it would be nice if vscode can use virtual column for enter case as well. when user hits enter, VS puts caret at right location without introducing whitespaces, vscode does so by putting right amount of whitespaces at the blank line. (so some corner case whitespaces can left out tangling there until formatter/prettier run)

Having proper indentation API might help to make user experiences better?

Anyway, shouldn't LS be able to participate in the decision? rather than dictated by protocol? if it is a capability for server, client and user (options), all participants should be able to decide whether they want to use/support the smart indentation or not. (like format on enter) and users who want the functionality over other concerns (which in practice won't happen to most (99%) of users) can choose to do so?

The problem is perf and async behavior and the unpredictability for the user on typing

dbaeumer commented 3 years ago

vscode does so by putting right amount of whitespaces at the blank line. (so some corner case whitespaces can left out tangling there until formatter/prettier run)

That is true, but the unnecessary white spaces are removed on save.

Anyway, shouldn't LS be able to participate in the decision? rather than dictated by protocol?

I agree. This is why I didn't close the issue :-)

It is absolutely OK if VS proposes such a protocol to LSP. It is also fine if an implementation only exist for VS.

heejaechang commented 3 years ago

@dbaeumer we want it on vscode actually, would that be okay?

dbaeumer commented 3 years ago

@heejaechang have you opened a issue about this against VS Code? We would need extension host API for this as well.

heejaechang commented 3 years ago

@dbaeumer opened.

DanTup commented 3 years ago

To avoid the perf concerns (at least for some cases), couldn't this be done by allowing the LSP server to provide some declarative rules during initialisation? I was recently thinking about the same thing for textmate grammars etc. - right now we have some things that live inside a VS Code extension that other editors would like to use (eg. to get faster basic highlighting when files are opened) and they're currently left entirely to the client editor/extension. It would be nice if an LSP server could provide some of these things statically during initialisation so they at least don't need to be replicated in each editors extensions.