Skip to content

Commit 291b484

Browse files
authored
feat: workspace symbols support (#2769)
#2375. Adding support in the Svelte language server so that you don't need to open ts/js files to use this feature. You can trigger this feature with Ctrl + T and search for symbol names. Some of the handling is also synced to the typescript-plugin so that it's more consistent, which also means vscode can better deduplicate the results from both tsserver and Svelte language server.
1 parent 5493844 commit 291b484

File tree

14 files changed

+496
-15
lines changed

14 files changed

+496
-15
lines changed

packages/language-server/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ Enable signature help (parameter hints) for JS/TS. _Default_: `true`
135135

136136
Enable semantic tokens (semantic highlight) for TypeScript. _Default_: `true`
137137

138+
#### `svelte.plugin.typescript.workspaceSymbols.enable`
139+
140+
Enable workspace symbols for TypeScript. You can disable this if the language server client you're using doesn't deduplicate results from the TSServer. _Default_: `true`.
141+
138142
##### `svelte.plugin.css.enable`
139143

140144
Enable the CSS plugin. _Default_: `true`

packages/language-server/src/ls-config.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const defaultLSConfig: LSConfig = {
2121
codeActions: { enable: true },
2222
selectionRange: { enable: true },
2323
signatureHelp: { enable: true },
24-
semanticTokens: { enable: true }
24+
semanticTokens: { enable: true },
25+
workspaceSymbols: { enable: true }
2526
},
2627
css: {
2728
enable: true,
@@ -105,6 +106,9 @@ export interface LSTypescriptConfig {
105106
semanticTokens: {
106107
enable: boolean;
107108
};
109+
workspaceSymbols: {
110+
enable: boolean;
111+
};
108112
}
109113

110114
export interface LSCSSConfig {
@@ -205,6 +209,7 @@ export interface TSUserConfig {
205209
inlayHints?: TsInlayHintsConfig;
206210
referencesCodeLens?: TsReferenceCodeLensConfig;
207211
implementationsCodeLens?: TsImplementationCodeLensConfig;
212+
workspaceSymbols?: TsWorkspaceSymbolsConfig;
208213
}
209214

210215
/**
@@ -280,6 +285,10 @@ export interface TsImplementationCodeLensConfig {
280285
showOnInterfaceMethods?: boolean | undefined;
281286
}
282287

288+
export interface TsWorkspaceSymbolsConfig {
289+
excludeLibrarySymbols?: boolean;
290+
}
291+
283292
export type TsUserConfigLang = 'typescript' | 'javascript';
284293

285294
/**
@@ -509,7 +518,9 @@ export class LSConfigManager {
509518
organizeImportsTypeOrder: this.withDefaultAsUndefined(
510519
config.preferences?.organizeImports?.typeOrder,
511520
'auto'
512-
)
521+
),
522+
523+
excludeLibrarySymbolsInNavTo: config.workspaceSymbols?.excludeLibrarySymbols ?? true
513524
};
514525
}
515526

packages/language-server/src/plugins/PluginHost.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
TextDocumentIdentifier,
3535
TextEdit,
3636
WorkspaceEdit,
37-
InlayHint
37+
InlayHint,
38+
WorkspaceSymbol
3839
} from 'vscode-languageserver';
3940
import { DocumentManager, getNodeIfIsInHTMLStartTag } from '../lib/documents';
4041
import { Logger } from '../logger';
@@ -697,6 +698,18 @@ export class PluginHost implements LSProvider, OnWatchFileChanges {
697698
);
698699
}
699700

701+
async getWorkspaceSymbols(
702+
query: string,
703+
token: CancellationToken
704+
): Promise<WorkspaceSymbol[] | null> {
705+
return await this.execute<WorkspaceSymbol[]>(
706+
'getWorkspaceSymbols',
707+
[query, token],
708+
ExecuteMode.FirstNonNull,
709+
'high'
710+
);
711+
}
712+
700713
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesPara[]): void {
701714
for (const support of this.plugins) {
702715
support.onWatchFileChanges?.(onWatchFileChangesParas);

packages/language-server/src/plugins/interfaces.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ import {
3535
SymbolInformation,
3636
TextDocumentIdentifier,
3737
TextEdit,
38-
WorkspaceEdit
38+
WorkspaceEdit,
39+
WorkspaceSymbol
3940
} from 'vscode-languageserver-types';
4041
import { Document } from '../lib/documents';
4142

@@ -251,6 +252,13 @@ export interface DocumentHighlightProvider {
251252
): Resolvable<DocumentHighlight[] | null>;
252253
}
253254

255+
export interface WorkspaceSymbolsProvider {
256+
getWorkspaceSymbols(
257+
query: string,
258+
cancellationToken?: CancellationToken
259+
): Resolvable<WorkspaceSymbol[] | null>;
260+
}
261+
254262
export interface OnWatchFileChanges {
255263
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesPara[]): void;
256264
}
@@ -282,7 +290,8 @@ type ProviderBase = DiagnosticsProvider &
282290
CallHierarchyProvider &
283291
FoldingRangeProvider &
284292
CodeLensProvider &
285-
DocumentHighlightProvider;
293+
DocumentHighlightProvider &
294+
WorkspaceSymbolsProvider;
286295

287296
export type LSProvider = ProviderBase & BackwardsCompatibleDefinitionsProvider;
288297

packages/language-server/src/plugins/typescript/SnapshotManager.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ export class SnapshotManager {
290290
}
291291
}
292292

293+
allFilesAreJsOrDts() {
294+
for (const doc of this.documents.values()) {
295+
if (doc.scriptKind === ts.ScriptKind.TS || doc.scriptKind === ts.ScriptKind.TSX) {
296+
return false;
297+
}
298+
}
299+
300+
return true;
301+
}
302+
293303
dispose() {
294304
this.globalSnapshotsManager.removeChangeListener(this.onSnapshotChange);
295305
}

packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import {
2828
SymbolInformation,
2929
SymbolKind,
3030
TextDocumentContentChangeEvent,
31-
WorkspaceEdit
31+
WorkspaceEdit,
32+
WorkspaceSymbol
3233
} from 'vscode-languageserver';
3334
import {
3435
Document,
@@ -65,7 +66,8 @@ import {
6566
SignatureHelpProvider,
6667
TypeDefinitionProvider,
6768
UpdateImportsProvider,
68-
UpdateTsOrJsFile
69+
UpdateTsOrJsFile,
70+
WorkspaceSymbolsProvider
6971
} from '../interfaces';
7072
import { LSAndTSDocResolver } from './LSAndTSDocResolver';
7173
import { ignoredBuildDirectories } from './SnapshotManager';
@@ -103,6 +105,7 @@ import {
103105
} from './utils';
104106
import { CallHierarchyProviderImpl } from './features/CallHierarchyProvider';
105107
import { CodeLensProviderImpl } from './features/CodeLensProvider';
108+
import { WorkspaceSymbolsProviderImpl } from './features/WorkspaceSymbolProvider';
106109

107110
export class TypeScriptPlugin
108111
implements
@@ -126,6 +129,7 @@ export class TypeScriptPlugin
126129
CallHierarchyProvider,
127130
FoldingRangeProvider,
128131
CodeLensProvider,
132+
WorkspaceSymbolsProvider,
129133
OnWatchFileChanges,
130134
CompletionsProvider<CompletionResolveInfo>,
131135
UpdateTsOrJsFile
@@ -154,6 +158,7 @@ export class TypeScriptPlugin
154158
private readonly callHierarchyProvider: CallHierarchyProviderImpl;
155159
private readonly codLensProvider: CodeLensProviderImpl;
156160
private readonly documentHeightProvider: DocumentHighlightProviderImpl;
161+
private readonly workspaceSymbolsProvider: WorkspaceSymbolsProvider;
157162

158163
constructor(
159164
configManager: LSConfigManager,
@@ -214,6 +219,10 @@ export class TypeScriptPlugin
214219
this.configManager
215220
);
216221
this.documentHeightProvider = new DocumentHighlightProviderImpl(this.lsAndTsDocResolver);
222+
this.workspaceSymbolsProvider = new WorkspaceSymbolsProviderImpl(
223+
this.lsAndTsDocResolver,
224+
configManager
225+
);
217226
}
218227

219228
async getDiagnostics(
@@ -701,6 +710,16 @@ export class TypeScriptPlugin
701710
return this.documentHeightProvider.findDocumentHighlight(document, position);
702711
}
703712

713+
async getWorkspaceSymbols(
714+
query: string,
715+
cancellationToken?: CancellationToken
716+
): Promise<WorkspaceSymbol[] | null> {
717+
if (!this.featureEnabled('workspaceSymbols')) {
718+
return null;
719+
}
720+
return this.workspaceSymbolsProvider.getWorkspaceSymbols(query, cancellationToken);
721+
}
722+
704723
private featureEnabled(feature: keyof LSTypescriptConfig) {
705724
return (
706725
this.configManager.enabled('typescript.enable') &&

0 commit comments

Comments
 (0)