diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index e09e4fe637..b60bca8ae9 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -365,19 +365,24 @@ func sendRequest[Params, Resp any](t *testing.T, f *FourslashTest, info lsproto. // !!! remove if `config` is handled in initialization and there are no other server-initiated requests if resp.Kind == lsproto.MessageKindRequest { req := resp.AsRequest() - switch req.Method { - case lsproto.MethodWorkspaceConfiguration: - req := lsproto.ResponseMessage{ - ID: req.ID, - JSONRPC: req.JSONRPC, - Result: []any{f.userPreferences}, - } - f.writeMsg(t, req.Message()) - resp = f.readMsg(t) - default: - // other types of requests not yet used in fourslash; implement them if needed - t.Fatalf("Unexpected request received: %s", req.Method) + + assert.Equal(t, req.Method, lsproto.MethodWorkspaceConfiguration, "Unexpected request received: %s", req.Method) + res := lsproto.ResponseMessage{ + ID: req.ID, + JSONRPC: req.JSONRPC, + Result: []any{f.userPreferences}, } + f.writeMsg(t, res.Message()) + req = f.readMsg(t).AsRequest() + + assert.Equal(t, req.Method, lsproto.MethodClientRegisterCapability, "Unexpected request received: %s", req.Method) + res = lsproto.ResponseMessage{ + ID: req.ID, + JSONRPC: req.JSONRPC, + Result: lsproto.Null{}, + } + f.writeMsg(t, res.Message()) + resp = f.readMsg(t) } if resp == nil { @@ -413,9 +418,16 @@ func (f *FourslashTest) readMsg(t *testing.T) *lsproto.Message { } func (f *FourslashTest) Configure(t *testing.T, config *lsutil.UserPreferences) { + // !!! + // Callers to this function may need to consider + // sending a more specific configuration for 'javascript' + // or 'js/ts' as well. For now, we only send 'typescript', + // and most tests probably just want this. f.userPreferences = config sendNotification(t, f, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ - Settings: config, + Settings: map[string]any{ + "typescript": config, + }, }) } diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 29037f6c74..9bf70dcd37 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -742,9 +742,29 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali return err } s.session.InitializeWithConfig(userPreferences) + + _, err = s.sendRequest(ctx, lsproto.MethodClientRegisterCapability, &lsproto.RegistrationParams{ + Registrations: []*lsproto.Registration{ + { + Id: "typescript-config-watch-id", + Method: string(lsproto.MethodWorkspaceDidChangeConfiguration), + RegisterOptions: ptrTo(any(lsproto.DidChangeConfigurationRegistrationOptions{ + Section: &lsproto.StringOrStrings{ + // !!! Both the 'javascript' and 'js/ts' scopes need to be watched for settings as well. + Strings: &[]string{"typescript"}, + }, + })), + }, + }, + }) + if err != nil { + return fmt.Errorf("failed to register configuration change watcher: %w", err) + } } - // !!! temporary; remove when we have `handleDidChangeConfiguration`/implicit project config support + // !!! temporary. + // Remove when we have `handleDidChangeConfiguration`/implicit project config support + // derived from 'js/ts.implicitProjectConfig.*'. if s.compilerOptionsForInferredProjects != nil { s.session.DidChangeCompilerOptionsForInferredProjects(ctx, s.compilerOptionsForInferredProjects) } @@ -762,9 +782,14 @@ func (s *Server) handleExit(ctx context.Context, params any) error { } func (s *Server) handleDidChangeWorkspaceConfiguration(ctx context.Context, params *lsproto.DidChangeConfigurationParams) error { - // !!! only implemented because needed for fourslash + settings, ok := params.Settings.(map[string]any) + if !ok { + return nil + } + // !!! Both the 'javascript' and 'js/ts' scopes need to be checked for settings as well. + tsSettings := settings["typescript"] userPreferences := s.session.UserPreferences() - if parsed := userPreferences.Parse(params.Settings); parsed != nil { + if parsed := userPreferences.Parse(tsSettings); parsed != nil { userPreferences = parsed } s.session.Configure(userPreferences)