Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _extension/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
readNativePreviewConfig,
} from "./util";
import { getLanguageForUri } from "./util";
import { workspaceSymbolSendRequestMiddleware } from "./workspaceSymbolMiddleware";

export class Client implements vscode.Disposable {
private outputChannel: vscode.LogOutputChannel;
Expand Down Expand Up @@ -97,6 +98,7 @@ export class Client implements vscode.Disposable {
},
},
sendNotification: sendNotificationMiddleware,
sendRequest: workspaceSymbolSendRequestMiddleware,
provideHover: () => undefined,
},
diagnosticCollectionName: "typescript-push",
Expand Down
41 changes: 41 additions & 0 deletions _extension/src/workspaceSymbolMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as vscode from "vscode";
import type { CancellationToken } from "vscode";
import type { MessageSignature } from "vscode-languageserver-protocol";
import { isSupportedLanguageMode } from "./util";

const supportedSchemes = new Set(["file", "untitled"]);

function isSupportedDocument(document: vscode.TextDocument): boolean {
return isSupportedLanguageMode(document) && supportedSchemes.has(document.uri.scheme);
}

function getDocument(): vscode.TextDocument | undefined {
const activeDocument = vscode.window.activeTextEditor?.document;
if (activeDocument && isSupportedDocument(activeDocument)) {
return activeDocument;
}

return vscode.workspace.textDocuments.find(isSupportedDocument);
}

export function workspaceSymbolSendRequestMiddleware<P, R>(
type: string | MessageSignature,
params: P | undefined,
token: CancellationToken | undefined,
next: (type: string | MessageSignature, params?: P, token?: CancellationToken) => Promise<R>,
): Promise<R> {
const method = typeof type === "string" ? type : type.method;
if (method !== "workspace/symbol") {
return next(type, params, token);
}

const document = getDocument();
if (!document) {
return next(type, params, token);
}

return next(type, {
...params,
textDocument: { uri: document.uri.toString() },
} as P, token);
}
7 changes: 6 additions & 1 deletion internal/fourslash/fourslash.go
Original file line number Diff line number Diff line change
Expand Up @@ -5591,7 +5591,12 @@ func (f *FourslashTest) VerifyWorkspaceSymbol(t *testing.T, cases []*VerifyWorks
preferences = new(lsutil.NewDefaultUserPreferences())
}
f.Configure(t, *preferences)
result := sendRequest(t, f, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{Query: testCase.Pattern})
result := sendRequest(t, f, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{
Query: testCase.Pattern,
TextDocument: &lsproto.TextDocumentIdentifier{
Uri: lsconv.FileNameToDocumentURI(f.activeFilename),
},
})
if result.SymbolInformations == nil {
t.Fatalf("Expected non-nil symbol information array from workspace symbol request")
}
Expand Down
65 changes: 65 additions & 0 deletions internal/fourslash/tests/workspaceSymbolCurrentProject_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestWorkspaceSymbolCurrentProject(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `
// @Filename: /home/projects/a/tsconfig.json
{}

// @Filename: /home/projects/a/index.ts
export function [|fromA|]() {}

// @Filename: /home/projects/b/tsconfig.json
{}

// @Filename: /home/projects/b/index.ts
export function [|fromB|]() {}
`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToFile(t, "/home/projects/a/index.ts")

allOpenProjects := lsutil.NewDefaultUserPreferences()
currentProject := lsutil.NewDefaultUserPreferences()
currentProject.WorkspaceSymbolsScope = lsutil.WorkspaceSymbolsScopeCurrentProject

f.VerifyWorkspaceSymbol(t, []*fourslash.VerifyWorkspaceSymbolCase{
{
Pattern: "from",
Preferences: &allOpenProjects,
Exact: new([]*lsproto.SymbolInformation{
{
Name: "fromA",
Kind: lsproto.SymbolKindFunction,
Location: f.Ranges()[0].LSLocation(),
},
{
Name: "fromB",
Kind: lsproto.SymbolKindFunction,
Location: f.Ranges()[1].LSLocation(),
},
}),
},
{
Pattern: "from",
Preferences: &currentProject,
Exact: new([]*lsproto.SymbolInformation{
{
Name: "fromA",
Kind: lsproto.SymbolKindFunction,
Location: f.Ranges()[0].LSLocation(),
},
}),
},
})
}
11 changes: 10 additions & 1 deletion internal/ls/lsutil/userpreferences.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func NewDefaultUserPreferences() UserPreferences {
ReportStyleChecksAsWarnings: core.TSTrue,

ExcludeLibrarySymbolsInNavTo: core.TSTrue,
WorkspaceSymbolsScope: WorkspaceSymbolsScopeAllOpenProjects,
}
}

Expand Down Expand Up @@ -167,7 +168,8 @@ type UserPreferences struct {

// ------- Symbols -------

ExcludeLibrarySymbolsInNavTo core.Tristate `raw:"excludeLibrarySymbolsInNavTo" config:"workspaceSymbols.excludeLibrarySymbols"`
ExcludeLibrarySymbolsInNavTo core.Tristate `raw:"excludeLibrarySymbolsInNavTo" config:"workspaceSymbols.excludeLibrarySymbols"`
WorkspaceSymbolsScope WorkspaceSymbolsScope `config:"workspaceSymbols.scope"`

// ------- Misc -------

Expand Down Expand Up @@ -227,6 +229,13 @@ type CodeLensUserPreferences struct {

type QuotePreference string

type WorkspaceSymbolsScope string

const (
WorkspaceSymbolsScopeAllOpenProjects WorkspaceSymbolsScope = "allOpenProjects"
WorkspaceSymbolsScopeCurrentProject WorkspaceSymbolsScope = "currentProject"
)

const (
QuotePreferenceUnknown QuotePreference = ""
QuotePreferenceAuto QuotePreference = "auto"
Expand Down
4 changes: 3 additions & 1 deletion internal/ls/lsutil/userpreferences_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,15 @@ func TestUserPreferencesParseUnstable(t *testing.T) {
"importModuleSpecifier": "relative"
},
"workspaceSymbols": {
"excludeLibrarySymbols": true
"excludeLibrarySymbols": true,
"scope": "currentProject"
}
}`,
expected: UserPreferences{
DisplayPartsForJSDoc: core.TSTrue,
ImportModuleSpecifierPreference: modulespecifiers.ImportModuleSpecifierPreferenceRelative,
ExcludeLibrarySymbolsInNavTo: core.TSTrue,
WorkspaceSymbolsScope: WorkspaceSymbolsScopeCurrentProject,
},
},
{
Expand Down
11 changes: 11 additions & 0 deletions internal/lsp/lsproto/_generate/generate.mts
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,17 @@ function patchAndPreprocessModel() {
});
}

// Patch WorkspaceSymbolParams to optionally scope the search to projects
// containing a document, matching Strada's currentProject mode.
if (structure.name === "WorkspaceSymbolParams") {
structure.properties.push({
name: "textDocument",
type: { kind: "reference", name: "TextDocumentIdentifier" },
optional: true,
documentation: "Scopes the workspace symbol search to projects containing this document.",
});
}

// Patch Hover to add canIncreaseVerbosity
if (structure.name === "Hover") {
structure.properties.push(
Expand Down
3 changes: 3 additions & 0 deletions internal/lsp/lsproto/lsp_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1704,17 +1704,28 @@ func (s *Server) handleDocumentOnTypeFormat(ctx context.Context, ls *ls.Language
func (s *Server) handleWorkspaceSymbol(ctx context.Context, params *lsproto.WorkspaceSymbolParams, reqMsg *lsproto.RequestMessage) (lsproto.WorkspaceSymbolResponse, error) {
var resp lsproto.WorkspaceSymbolResponse
var lsErr error
s.session.WithSnapshotLoadingProjectTree(ctx, nil, func(snapshot *project.Snapshot) {
provideSymbols := func(snapshot *project.Snapshot, programs []*compiler.Program) {
defer s.recover(reqMsg)
programs := core.Map(snapshot.ProjectCollection.Projects(), (*project.Project).GetProgram)
resp, lsErr = ls.ProvideWorkspaceSymbols(
ctx,
programs,
snapshot.Converters(),
snapshot.UserPreferences(),
params.Query,
)
})
}
if params.TextDocument != nil && s.session.Config().WorkspaceSymbolsScope == lsutil.WorkspaceSymbolsScopeCurrentProject {
uri := params.TextDocument.Uri
s.session.WithSnapshotForDocument(ctx, uri, func(snapshot *project.Snapshot) {
programs := core.Map(snapshot.GetProjectsContainingFile(uri), ls.Project.GetProgram)
provideSymbols(snapshot, programs)
})
} else {
s.session.WithSnapshotLoadingProjectTree(ctx, nil, func(snapshot *project.Snapshot) {
programs := core.Map(snapshot.ProjectCollection.Projects(), (*project.Project).GetProgram)
provideSymbols(snapshot, programs)
})
}
return resp, lsErr
}

Expand Down
14 changes: 14 additions & 0 deletions internal/project/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,20 @@ func (s *Session) WithSnapshotLoadingProjectTree(
fn(snapshot)
}

func (s *Session) WithSnapshotForDocument(
ctx context.Context,
uri lsproto.DocumentUri,
fn func(*Snapshot),
) {
snapshot := s.getSnapshot(
ctx,
ResourceRequest{Documents: []lsproto.DocumentUri{uri}},
true, /*callerRef*/
)
defer snapshot.Deref(s)
fn(snapshot)
}

// GetCurrentLanguageServiceWithAutoImports flushes pending file changes, clones the
// current snapshot with auto-import preparation for the given URI, then returns a
// LanguageService for the default project. Use this only outside of request handling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,8 @@ Config::
"enabled": true
},
"workspaceSymbols": {
"excludeLibrarySymbols": true
"excludeLibrarySymbols": true,
"scope": "allOpenProjects"
}
}
}
Expand Down