yioneko / vtsls

LSP wrapper for typescript extension of vscode
Other
486 stars 7 forks source link

Find a way to convey server-initiated configuration changes back to client #139

Open bradymadden97 opened 7 months ago

bradymadden97 commented 7 months ago

Hello! I've been testing out the workspace/didRenameFiles notification using vtsls and seem to mostly understand how to get it working. It required:

  1. Client sends workspace/didRenameFiles notification
  2. Client waits for a window/showMessageRequest, if it has not provided a configuration setting for [javascript/typescript].updateImportsOnFileMove.enabled. The request will look something like this:
    
    {
    "type": 3,
    "message": "Update imports for 'MyDefaultExport8.ts'?",
    "actions": [
        {
            "title": "No",
            "tsId": 1
        },
        {
            "title": "Yes",
            "tsId": 2
        },
        {
            "title": "Always",
            "tsId": 3
        },
        {
            "title": "Never",
            "tsId": 4
        }
    ]
    }
3. Client sends a response to `window/showMessageRequest` - in this example, let's assume they respond with 

{ "title": "Always", "tsId": 3 }


4. Internally, vtsls updates its "shim configuration service" to mock a "client configuration update", then sends `workspace/applyEdit` request
5. In subsequent notifications to `workspace/didRenameFiles`, vscode reads the configuration setting from vtsls's shim service and (potentially - in the case of 'always' or 'never' being previously selected) does not send `window/showMessageRequest` - in this example, it would automatically go ahead and send `workspace/applyEdit` request to apply the updates to imports, as the setting would say "always".

^^^ This all works pretty great!

However, the missing piece is vtsls notifying the client of its "internal" updates to the configuration, so that these configurations can be persisted, and provided on subsequent sessions. In the current state, if we restart the langauge server, it will not have configuration set, and will again prompt on the first run, which is not a great experience.

There seems to be no support that I can find in the spec for a **server sending a client an update to configuration**, so I'm proposing this as a workaround:

1. vtsls defines a [custom $ notification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#dollarRequests), which is supported by the spec, to tell the client that configuration has been updated. Something like `$/configurationUpdated`, with a body `LSPAny` that contains the updated configuration key-value pairs.
2. When vtsls updates its internal configuration shim, it sends a `$/configurationUpdated` notification to the client with the changes.
3. The client can persist these changes, and then provide them on subsequent server restarts

let me know what you think!