microsoft / vscode-languageserver-node

Language server protocol implementation for VSCode. This allows implementing language services in JS/TS running on node.js
MIT License
1.41k stars 320 forks source link

Question about the order of LSP requests and notifications (didChange and semanticTokens) #1495

Closed He1pa closed 3 weeks ago

He1pa commented 3 weeks ago

I am a developer of the lsp language extension. I noticed that under normal circumstances, when a user enters code in vscode, lsp will: 1 Send a notification of file changes (Notification { method: "textDocument/didChange"}) 2 Request new semantic highlighting (Request { method: "textDocument/semanticTokens})

But I found that when inputting continuously and quickly (such as typing two Enter or other keys), sometimes semantic highlighting will be requested first, and then file changes will be notified.

I'm not sure if this is a problem with my lsp client implementation, or a special design of vscode, or a configurable option of vscode

here is my language extension: client: https://github.com/kcl-lang/vscode-kcl server: https://github.com/kcl-lang/kcl/tree/main/kclvm/tools/src/LSP

also reported in https://github.com/microsoft/vscode-discussions/discussions/1219

Version: 1.89.1 (Universal) Commit: dc96b837cf6bb4af9cd736aa3af08cf8279f7685 Date: 2024-05-07T05:14:24.611Z Electron: 28.2.8 ElectronBuildId: 27744544 Chromium: 120.0.6099.291 Node.js: 18.18.2 V8: 12.0.267.19-electron.0 OS: Darwin arm64 21.5.0

dbaeumer commented 3 weeks ago

This behavior is absolutely fine. The server should in this situation compute the semantic tokens on the state of files it knows. If then some additional typing happens on the client, the client should either

Hope that explains it,

He1pa commented 3 weeks ago

I don't fully understand. Let me describe the problem I encountered in more detail. At first, my code was like this.

schema Data:
    name: str
    version?: str

I typed Enter twice at the beginning of the file,


schema Data:
    name: str
    version?: str

I got the log of lsp server

Notification(Notification { method: "textDocument/didChange", params: Object {"contentChanges": Array [Object {"text": String("\nschema Data:\n    name: str\n    version?: str\n")}], "textDocument": Object {"uri": String("file:///Users/zz/code/test/a.k"), "version": Number(35)}} })

Notification(Notification { method: "textDocument/didChange", params: Object {"contentChanges": Array [Object {"text": String("\n\nschema Data:\n    name: str\n    version?: str\n")}], "textDocument": Object {"uri": String("file:///Users/zz/code/test/a.k"), "version": Number(36)}} })

Request(Request { id: RequestId(I32(132)), method: "textDocument/semanticTokens/full", params: Object {"textDocument": Object {"uri": String("file:///Users/zz/code/test/a.k")}} })

For each didChanged notification, a \n is added to the text

But if I typed delete twice

schema Data:
    name: str
    version?: str

I got the log of lsp server

Request(Request { id: RequestId(I32(138)), method: "textDocument/semanticTokens/full", params: Object {"textDocument": Object {"uri": String("file:///Users/zz/code/test/a.k")}} })

Notification(Notification { method: "textDocument/didChange", params: Object {"contentChanges": Array [Object {"text": String("schema Data:\n    name: str\n    version?: str\n")}], "textDocument": Object {"uri": String("file:///Users/zz/code/test/a.k"), "version": Number(38)}} })

The semanticTokens request occurs before didChange, and the didChange notification is only the second time

dbaeumer commented 3 weeks ago

Ah, now I understand. This got fix in the latest versions of the client (e.g. 9.x)