Skip to content

Commit ca3ded8

Browse files
committed
Add support for workspace
1 parent 96bcae5 commit ca3ded8

10 files changed

+232
-111
lines changed

internal/ls/completions_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2172,7 +2172,7 @@ func assertIncludesItem(t *testing.T, actual *lsproto.CompletionList, expected *
21722172

21732173
func createLanguageService(ctx context.Context, fileName string, files map[string]any) (*ls.LanguageService, func()) {
21742174
projectService, _ := projecttestutil.Setup(files, nil)
2175-
projectService.OpenFile(fileName, files[fileName].(string), core.GetScriptKindFromFileName(fileName), "")
2175+
projectService.OpenFile(fileName, files[fileName].(string), core.GetScriptKindFromFileName(fileName))
21762176
project := projectService.Projects()[0]
21772177
return project.GetLanguageServiceForRequest(ctx)
21782178
}

internal/lsp/server.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ type Server struct {
141141

142142
initializeParams *lsproto.InitializeParams
143143
positionEncoding lsproto.PositionEncodingKind
144+
workspace *project.Workspace
144145

145146
watchEnabled bool
146147
watcherID atomic.Uint32
@@ -471,6 +472,8 @@ func (s *Server) handleRequestOrNotification(ctx context.Context, req *lsproto.R
471472
return s.handleDidClose(ctx, req)
472473
case *lsproto.DidChangeWatchedFilesParams:
473474
return s.handleDidChangeWatchedFiles(ctx, req)
475+
case *lsproto.DidChangeWorkspaceFoldersParams:
476+
return s.handleDidChangeWorkspaceFolders(ctx, req)
474477
case *lsproto.DocumentDiagnosticParams:
475478
return s.handleDocumentDiagnostic(ctx, req)
476479
case *lsproto.HoverParams:
@@ -566,6 +569,14 @@ func (s *Server) handleInitialize(req *lsproto.RequestMessage) {
566569
FirstTriggerCharacter: "{",
567570
MoreTriggerCharacter: &[]string{"}", ";", "\n"},
568571
},
572+
Workspace: &lsproto.WorkspaceOptions{
573+
WorkspaceFolders: &lsproto.WorkspaceFoldersServerCapabilities{
574+
Supported: ptrTo(true),
575+
ChangeNotifications: ptrTo(lsproto.StringOrBoolean{
576+
Boolean: ptrTo(true),
577+
}),
578+
},
579+
},
569580
},
570581
})
571582
}
@@ -591,12 +602,18 @@ func (s *Server) handleInitialized(ctx context.Context, req *lsproto.RequestMess
591602
s.projectService.SetCompilerOptionsForInferredProjects(s.compilerOptionsForInferredProjects)
592603
}
593604

605+
if !s.initializeParams.RootUri.Null {
606+
s.projectService.Workspace.SetRoot(ls.DocumentURIToFileName(s.initializeParams.RootUri.Value))
607+
}
608+
for _, folder := range s.initializeParams.WorkspaceFolders.Value {
609+
s.projectService.Workspace.AddFolder(ls.DocumentURIToFileName(lsproto.DocumentUri(folder.Uri)))
610+
}
594611
return nil
595612
}
596613

597614
func (s *Server) handleDidOpen(ctx context.Context, req *lsproto.RequestMessage) error {
598615
params := req.Params.(*lsproto.DidOpenTextDocumentParams)
599-
s.projectService.OpenFile(ls.DocumentURIToFileName(params.TextDocument.Uri), params.TextDocument.Text, ls.LanguageKindToScriptKind(params.TextDocument.LanguageId), "")
616+
s.projectService.OpenFile(ls.DocumentURIToFileName(params.TextDocument.Uri), params.TextDocument.Text, ls.LanguageKindToScriptKind(params.TextDocument.LanguageId))
600617
return nil
601618
}
602619

@@ -622,6 +639,19 @@ func (s *Server) handleDidChangeWatchedFiles(ctx context.Context, req *lsproto.R
622639
return s.projectService.OnWatchedFilesChanged(ctx, params.Changes)
623640
}
624641

642+
func (s *Server) handleDidChangeWorkspaceFolders(ctx context.Context, req *lsproto.RequestMessage) error {
643+
params := req.Params.(*lsproto.DidChangeWorkspaceFoldersParams)
644+
if params.Event != nil {
645+
for _, folder := range params.Event.Added {
646+
s.workspace.AddFolder(ls.DocumentURIToFileName(lsproto.DocumentUri(folder.Uri)))
647+
}
648+
for _, folder := range params.Event.Removed {
649+
s.workspace.RemoveFolder(ls.DocumentURIToFileName(lsproto.DocumentUri(folder.Uri)))
650+
}
651+
}
652+
return nil
653+
}
654+
625655
func (s *Server) handleDocumentDiagnostic(ctx context.Context, req *lsproto.RequestMessage) error {
626656
params := req.Params.(*lsproto.DocumentDiagnosticParams)
627657
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
@@ -827,7 +857,8 @@ func isBlockingMethod(method lsproto.Method) bool {
827857
lsproto.MethodTextDocumentDidChange,
828858
lsproto.MethodTextDocumentDidSave,
829859
lsproto.MethodTextDocumentDidClose,
830-
lsproto.MethodWorkspaceDidChangeWatchedFiles:
860+
lsproto.MethodWorkspaceDidChangeWatchedFiles,
861+
lsproto.MethodWorkspaceDidChangeWorkspaceFolders:
831862
return true
832863
}
833864
return false

internal/project/ata_test.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestAta(t *testing.T) {
3434
TypesRegistry: []string{"config"},
3535
},
3636
})
37-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
37+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
3838
assert.Equal(t, len(service.Projects()), 1)
3939
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
4040
assert.Equal(t, p.Kind(), project.KindConfigured)
@@ -70,7 +70,7 @@ func TestAta(t *testing.T) {
7070
},
7171
},
7272
})
73-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
73+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
7474
assert.Equal(t, len(service.Projects()), 1)
7575
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
7676
assert.Equal(t, p.Kind(), project.KindConfigured)
@@ -108,7 +108,7 @@ func TestAta(t *testing.T) {
108108
},
109109
},
110110
})
111-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
111+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
112112
assert.Equal(t, len(service.Projects()), 1)
113113
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
114114
assert.Equal(t, p.Kind(), project.KindInferred)
@@ -142,7 +142,7 @@ func TestAta(t *testing.T) {
142142
TypesRegistry: []string{"jquery"},
143143
},
144144
})
145-
service.OpenFile("/user/username/projects/project/jquery.js", files["/user/username/projects/project/jquery.js"].(string), core.ScriptKindJS, "")
145+
service.OpenFile("/user/username/projects/project/jquery.js", files["/user/username/projects/project/jquery.js"].(string), core.ScriptKindJS)
146146
assert.Equal(t, len(service.Projects()), 1)
147147
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/jquery.js")
148148
assert.Equal(t, p.Kind(), project.KindConfigured)
@@ -170,7 +170,7 @@ func TestAta(t *testing.T) {
170170
TypesRegistry: []string{"node"},
171171
},
172172
})
173-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
173+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
174174
assert.Equal(t, len(service.Projects()), 1)
175175
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
176176
assert.Equal(t, p.Kind(), project.KindConfigured)
@@ -210,8 +210,8 @@ func TestAta(t *testing.T) {
210210
},
211211
})
212212

213-
service.OpenFile("/user/username/projects/project1/app.js", files["/user/username/projects/project1/app.js"].(string), core.ScriptKindJS, "")
214-
service.OpenFile("/user/username/projects/project2/app.js", files["/user/username/projects/project2/app.js"].(string), core.ScriptKindJS, "")
213+
service.OpenFile("/user/username/projects/project1/app.js", files["/user/username/projects/project1/app.js"].(string), core.ScriptKindJS)
214+
service.OpenFile("/user/username/projects/project2/app.js", files["/user/username/projects/project2/app.js"].(string), core.ScriptKindJS)
215215
_, p1 := service.EnsureDefaultProjectForFile("/user/username/projects/project1/app.js")
216216
_, p2 := service.EnsureDefaultProjectForFile("/user/username/projects/project2/app.js")
217217
var installStatuses []project.TypingsInstallerStatus
@@ -271,8 +271,8 @@ func TestAta(t *testing.T) {
271271
}
272272
}
273273

274-
service.OpenFile("/user/username/projects/project1/app.js", files["/user/username/projects/project1/app.js"].(string), core.ScriptKindJS, "")
275-
service.OpenFile("/user/username/projects/project2/app.js", files["/user/username/projects/project2/app.js"].(string), core.ScriptKindJS, "")
274+
service.OpenFile("/user/username/projects/project1/app.js", files["/user/username/projects/project1/app.js"].(string), core.ScriptKindJS)
275+
service.OpenFile("/user/username/projects/project2/app.js", files["/user/username/projects/project2/app.js"].(string), core.ScriptKindJS)
276276
_, p1 := service.EnsureDefaultProjectForFile("/user/username/projects/project1/app.js")
277277
_, p2 := service.EnsureDefaultProjectForFile("/user/username/projects/project2/app.js")
278278
// Order is determinate since second install will run only after completing first one
@@ -310,7 +310,7 @@ func TestAta(t *testing.T) {
310310
},
311311
})
312312

313-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
313+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
314314
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
315315
// Order is determinate since second install will run only after completing first one
316316
status := <-host.ServiceOptions.InstallStatus
@@ -352,7 +352,7 @@ func TestAta(t *testing.T) {
352352
},
353353
})
354354

355-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
355+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
356356
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
357357
// Order is determinate since second install will run only after completing first one
358358
status := <-host.ServiceOptions.InstallStatus
@@ -394,7 +394,7 @@ func TestAta(t *testing.T) {
394394
},
395395
})
396396

397-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
397+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
398398
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
399399
// Order is determinate since second install will run only after completing first one
400400
status := <-host.ServiceOptions.InstallStatus
@@ -436,7 +436,7 @@ func TestAta(t *testing.T) {
436436
},
437437
})
438438

439-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
439+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
440440
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
441441
// Order is determinate since second install will run only after completing first one
442442
status := <-host.ServiceOptions.InstallStatus
@@ -463,7 +463,7 @@ func TestAta(t *testing.T) {
463463
},
464464
})
465465

466-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
466+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
467467
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
468468
// Order is determinate since second install will run only after completing first one
469469
status := <-host.ServiceOptions.InstallStatus
@@ -495,7 +495,7 @@ func TestAta(t *testing.T) {
495495
},
496496
})
497497

498-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
498+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
499499
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
500500
// Order is determinate since second install will run only after completing first one
501501
status := <-host.ServiceOptions.InstallStatus
@@ -522,7 +522,7 @@ func TestAta(t *testing.T) {
522522
},
523523
})
524524

525-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
525+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
526526
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
527527
// Order is determinate since second install will run only after completing first one
528528
status := <-host.ServiceOptions.InstallStatus
@@ -571,7 +571,7 @@ func TestAta(t *testing.T) {
571571
},
572572
})
573573

574-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
574+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
575575
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
576576
// Order is determinate since second install will run only after completing first one
577577
status := <-host.ServiceOptions.InstallStatus
@@ -602,7 +602,7 @@ func TestAta(t *testing.T) {
602602
},
603603
})
604604

605-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
605+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
606606
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
607607
// Order is determinate since second install will run only after completing first one
608608
status := <-host.ServiceOptions.InstallStatus
@@ -651,7 +651,7 @@ func TestAta(t *testing.T) {
651651
},
652652
})
653653

654-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
654+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
655655
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
656656
// Order is determinate since second install will run only after completing first one
657657
status := <-host.ServiceOptions.InstallStatus
@@ -697,7 +697,7 @@ func TestAta(t *testing.T) {
697697
},
698698
})
699699

700-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
700+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
701701
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
702702
// Order is determinate since second install will run only after completing first one
703703
status := <-host.ServiceOptions.InstallStatus
@@ -745,7 +745,7 @@ func TestAta(t *testing.T) {
745745
},
746746
})
747747

748-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
748+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
749749
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
750750
// Order is determinate since second install will run only after completing first one
751751
status := <-host.ServiceOptions.InstallStatus
@@ -791,7 +791,7 @@ func TestAta(t *testing.T) {
791791
},
792792
})
793793

794-
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS, "")
794+
service.OpenFile("/user/username/projects/project/app.js", files["/user/username/projects/project/app.js"].(string), core.ScriptKindJS)
795795
_, p := service.EnsureDefaultProjectForFile("/user/username/projects/project/app.js")
796796
// Order is determinate since second install will run only after completing first one
797797
status := <-host.ServiceOptions.InstallStatus

0 commit comments

Comments
 (0)