Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/common/extHostApiCommands.ts
5240 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { isFalsyOrEmpty } from '../../../base/common/arrays.js';
7
import { VSBuffer } from '../../../base/common/buffer.js';
8
import { Schemas, matchesSomeScheme } from '../../../base/common/network.js';
9
import { URI } from '../../../base/common/uri.js';
10
import { IPosition } from '../../../editor/common/core/position.js';
11
import { IRange } from '../../../editor/common/core/range.js';
12
import { ISelection } from '../../../editor/common/core/selection.js';
13
import * as languages from '../../../editor/common/languages.js';
14
import { decodeSemanticTokensDto } from '../../../editor/common/services/semanticTokensDto.js';
15
import { validateWhenClauses } from '../../../platform/contextkey/common/contextkey.js';
16
import { ITextEditorOptions } from '../../../platform/editor/common/editor.js';
17
import { ICallHierarchyItemDto, IIncomingCallDto, IInlineValueContextDto, IOutgoingCallDto, IRawColorInfo, ITypeHierarchyItemDto, IWorkspaceEditDto } from './extHost.protocol.js';
18
import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from './extHostCommands.js';
19
import { CustomCodeAction } from './extHostLanguageFeatures.js';
20
import * as typeConverters from './extHostTypeConverters.js';
21
import * as types from './extHostTypes.js';
22
import { TransientCellMetadata, TransientDocumentMetadata } from '../../contrib/notebook/common/notebookCommon.js';
23
import * as search from '../../contrib/search/common/search.js';
24
import type * as vscode from 'vscode';
25
import { PromptsType } from '../../contrib/chat/common/promptSyntax/promptTypes.js';
26
import type { IExtensionPromptFileResult } from '../../contrib/chat/common/promptSyntax/chatPromptFilesContribution.js';
27
28
//#region --- NEW world
29
30
const newCommands: ApiCommand[] = [
31
// -- document highlights
32
new ApiCommand(
33
'vscode.executeDocumentHighlights', '_executeDocumentHighlights', 'Execute document highlight provider.',
34
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
35
new ApiCommandResult<languages.DocumentHighlight[], types.DocumentHighlight[] | undefined>('A promise that resolves to an array of DocumentHighlight-instances.', tryMapWith(typeConverters.DocumentHighlight.to))
36
),
37
// -- document symbols
38
new ApiCommand(
39
'vscode.executeDocumentSymbolProvider', '_executeDocumentSymbolProvider', 'Execute document symbol provider.',
40
[ApiCommandArgument.Uri],
41
new ApiCommandResult<languages.DocumentSymbol[], vscode.SymbolInformation[] | undefined>('A promise that resolves to an array of SymbolInformation and DocumentSymbol instances.', (value, apiArgs) => {
42
43
if (isFalsyOrEmpty(value)) {
44
return undefined;
45
}
46
class MergedInfo extends types.SymbolInformation implements vscode.DocumentSymbol {
47
static to(symbol: languages.DocumentSymbol): MergedInfo {
48
const res = new MergedInfo(
49
symbol.name,
50
typeConverters.SymbolKind.to(symbol.kind),
51
symbol.containerName || '',
52
new types.Location(apiArgs[0], typeConverters.Range.to(symbol.range))
53
);
54
res.detail = symbol.detail;
55
res.range = res.location.range;
56
res.selectionRange = typeConverters.Range.to(symbol.selectionRange);
57
res.children = symbol.children ? symbol.children.map(MergedInfo.to) : [];
58
return res;
59
}
60
61
detail!: string;
62
range!: vscode.Range;
63
selectionRange!: vscode.Range;
64
children!: vscode.DocumentSymbol[];
65
override containerName: string = '';
66
}
67
return value.map(MergedInfo.to);
68
69
})
70
),
71
// -- formatting
72
new ApiCommand(
73
'vscode.executeFormatDocumentProvider', '_executeFormatDocumentProvider', 'Execute document format provider.',
74
[ApiCommandArgument.Uri, new ApiCommandArgument('options', 'Formatting options', _ => true, v => v)],
75
new ApiCommandResult<languages.TextEdit[], types.TextEdit[] | undefined>('A promise that resolves to an array of TextEdits.', tryMapWith(typeConverters.TextEdit.to))
76
),
77
new ApiCommand(
78
'vscode.executeFormatRangeProvider', '_executeFormatRangeProvider', 'Execute range format provider.',
79
[ApiCommandArgument.Uri, ApiCommandArgument.Range, new ApiCommandArgument('options', 'Formatting options', _ => true, v => v)],
80
new ApiCommandResult<languages.TextEdit[], types.TextEdit[] | undefined>('A promise that resolves to an array of TextEdits.', tryMapWith(typeConverters.TextEdit.to))
81
),
82
new ApiCommand(
83
'vscode.executeFormatOnTypeProvider', '_executeFormatOnTypeProvider', 'Execute format on type provider.',
84
[ApiCommandArgument.Uri, ApiCommandArgument.Position, new ApiCommandArgument('ch', 'Trigger character', v => typeof v === 'string', v => v), new ApiCommandArgument('options', 'Formatting options', _ => true, v => v)],
85
new ApiCommandResult<languages.TextEdit[], types.TextEdit[] | undefined>('A promise that resolves to an array of TextEdits.', tryMapWith(typeConverters.TextEdit.to))
86
),
87
// -- go to symbol (definition, type definition, declaration, impl, references)
88
new ApiCommand(
89
'vscode.executeDefinitionProvider', '_executeDefinitionProvider', 'Execute all definition providers.',
90
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
91
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
92
),
93
new ApiCommand(
94
'vscode.experimental.executeDefinitionProvider_recursive', '_executeDefinitionProvider_recursive', 'Execute all definition providers.',
95
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
96
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
97
),
98
new ApiCommand(
99
'vscode.executeTypeDefinitionProvider', '_executeTypeDefinitionProvider', 'Execute all type definition providers.',
100
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
101
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
102
),
103
new ApiCommand(
104
'vscode.experimental.executeTypeDefinitionProvider_recursive', '_executeTypeDefinitionProvider_recursive', 'Execute all type definition providers.',
105
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
106
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
107
),
108
new ApiCommand(
109
'vscode.executeDeclarationProvider', '_executeDeclarationProvider', 'Execute all declaration providers.',
110
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
111
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
112
),
113
new ApiCommand(
114
'vscode.experimental.executeDeclarationProvider_recursive', '_executeDeclarationProvider_recursive', 'Execute all declaration providers.',
115
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
116
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
117
),
118
new ApiCommand(
119
'vscode.executeImplementationProvider', '_executeImplementationProvider', 'Execute all implementation providers.',
120
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
121
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
122
),
123
new ApiCommand(
124
'vscode.experimental.executeImplementationProvider_recursive', '_executeImplementationProvider_recursive', 'Execute all implementation providers.',
125
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
126
new ApiCommandResult<(languages.Location | languages.LocationLink)[], (types.Location | vscode.LocationLink)[] | undefined>('A promise that resolves to an array of Location or LocationLink instances.', mapLocationOrLocationLink)
127
),
128
new ApiCommand(
129
'vscode.executeReferenceProvider', '_executeReferenceProvider', 'Execute all reference providers.',
130
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
131
new ApiCommandResult<languages.Location[], types.Location[] | undefined>('A promise that resolves to an array of Location-instances.', tryMapWith(typeConverters.location.to))
132
),
133
new ApiCommand(
134
'vscode.experimental.executeReferenceProvider', '_executeReferenceProvider_recursive', 'Execute all reference providers.',
135
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
136
new ApiCommandResult<languages.Location[], types.Location[] | undefined>('A promise that resolves to an array of Location-instances.', tryMapWith(typeConverters.location.to))
137
),
138
// -- hover
139
new ApiCommand(
140
'vscode.executeHoverProvider', '_executeHoverProvider', 'Execute all hover providers.',
141
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
142
new ApiCommandResult<languages.Hover[], types.Hover[] | undefined>('A promise that resolves to an array of Hover-instances.', tryMapWith(typeConverters.Hover.to))
143
),
144
new ApiCommand(
145
'vscode.experimental.executeHoverProvider_recursive', '_executeHoverProvider_recursive', 'Execute all hover providers.',
146
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
147
new ApiCommandResult<languages.Hover[], types.Hover[] | undefined>('A promise that resolves to an array of Hover-instances.', tryMapWith(typeConverters.Hover.to))
148
),
149
// -- selection range
150
new ApiCommand(
151
'vscode.executeSelectionRangeProvider', '_executeSelectionRangeProvider', 'Execute selection range provider.',
152
[ApiCommandArgument.Uri, new ApiCommandArgument<types.Position[], IPosition[]>('position', 'A position in a text document', v => Array.isArray(v) && v.every(v => types.Position.isPosition(v)), v => v.map(typeConverters.Position.from))],
153
new ApiCommandResult<IRange[][], types.SelectionRange[]>('A promise that resolves to an array of ranges.', result => {
154
return result.map(ranges => {
155
let node: types.SelectionRange | undefined;
156
for (const range of ranges.reverse()) {
157
node = new types.SelectionRange(typeConverters.Range.to(range), node);
158
}
159
return node!;
160
});
161
})
162
),
163
// -- symbol search
164
new ApiCommand(
165
'vscode.executeWorkspaceSymbolProvider', '_executeWorkspaceSymbolProvider', 'Execute all workspace symbol providers.',
166
[ApiCommandArgument.String.with('query', 'Search string')],
167
new ApiCommandResult<search.IWorkspaceSymbol[], types.SymbolInformation[]>('A promise that resolves to an array of SymbolInformation-instances.', value => {
168
return value.map(typeConverters.WorkspaceSymbol.to);
169
})
170
),
171
// --- call hierarchy
172
new ApiCommand(
173
'vscode.prepareCallHierarchy', '_executePrepareCallHierarchy', 'Prepare call hierarchy at a position inside a document',
174
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
175
new ApiCommandResult<ICallHierarchyItemDto[], types.CallHierarchyItem[]>('A promise that resolves to an array of CallHierarchyItem-instances', v => v.map(typeConverters.CallHierarchyItem.to))
176
),
177
new ApiCommand(
178
'vscode.provideIncomingCalls', '_executeProvideIncomingCalls', 'Compute incoming calls for an item',
179
[ApiCommandArgument.CallHierarchyItem],
180
new ApiCommandResult<IIncomingCallDto[], types.CallHierarchyIncomingCall[]>('A promise that resolves to an array of CallHierarchyIncomingCall-instances', v => v.map(typeConverters.CallHierarchyIncomingCall.to))
181
),
182
new ApiCommand(
183
'vscode.provideOutgoingCalls', '_executeProvideOutgoingCalls', 'Compute outgoing calls for an item',
184
[ApiCommandArgument.CallHierarchyItem],
185
new ApiCommandResult<IOutgoingCallDto[], types.CallHierarchyOutgoingCall[]>('A promise that resolves to an array of CallHierarchyOutgoingCall-instances', v => v.map(typeConverters.CallHierarchyOutgoingCall.to))
186
),
187
// --- rename
188
new ApiCommand(
189
'vscode.prepareRename', '_executePrepareRename', 'Execute the prepareRename of rename provider.',
190
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
191
new ApiCommandResult<languages.RenameLocation, { range: types.Range; placeholder: string } | undefined>('A promise that resolves to a range and placeholder text.', value => {
192
if (!value) {
193
return undefined;
194
}
195
return {
196
range: typeConverters.Range.to(value.range),
197
placeholder: value.text
198
};
199
})
200
),
201
new ApiCommand(
202
'vscode.executeDocumentRenameProvider', '_executeDocumentRenameProvider', 'Execute rename provider.',
203
[ApiCommandArgument.Uri, ApiCommandArgument.Position, ApiCommandArgument.String.with('newName', 'The new symbol name')],
204
new ApiCommandResult<IWorkspaceEditDto & { rejectReason?: string }, types.WorkspaceEdit | undefined>('A promise that resolves to a WorkspaceEdit.', value => {
205
if (!value) {
206
return undefined;
207
}
208
if (value.rejectReason) {
209
throw new Error(value.rejectReason);
210
}
211
return typeConverters.WorkspaceEdit.to(value);
212
})
213
),
214
// --- links
215
new ApiCommand(
216
'vscode.executeLinkProvider', '_executeLinkProvider', 'Execute document link provider.',
217
[ApiCommandArgument.Uri, ApiCommandArgument.Number.with('linkResolveCount', 'Number of links that should be resolved, only when links are unresolved.').optional()],
218
new ApiCommandResult<languages.ILink[], vscode.DocumentLink[]>('A promise that resolves to an array of DocumentLink-instances.', value => value.map(typeConverters.DocumentLink.to))
219
),
220
// --- semantic tokens
221
new ApiCommand(
222
'vscode.provideDocumentSemanticTokensLegend', '_provideDocumentSemanticTokensLegend', 'Provide semantic tokens legend for a document',
223
[ApiCommandArgument.Uri],
224
new ApiCommandResult<languages.SemanticTokensLegend, types.SemanticTokensLegend | undefined>('A promise that resolves to SemanticTokensLegend.', value => {
225
if (!value) {
226
return undefined;
227
}
228
return new types.SemanticTokensLegend(value.tokenTypes, value.tokenModifiers);
229
})
230
),
231
new ApiCommand(
232
'vscode.provideDocumentSemanticTokens', '_provideDocumentSemanticTokens', 'Provide semantic tokens for a document',
233
[ApiCommandArgument.Uri],
234
new ApiCommandResult<VSBuffer, types.SemanticTokens | undefined>('A promise that resolves to SemanticTokens.', value => {
235
if (!value) {
236
return undefined;
237
}
238
const semanticTokensDto = decodeSemanticTokensDto(value);
239
if (semanticTokensDto.type !== 'full') {
240
// only accepting full semantic tokens from provideDocumentSemanticTokens
241
return undefined;
242
}
243
return new types.SemanticTokens(semanticTokensDto.data, undefined);
244
})
245
),
246
new ApiCommand(
247
'vscode.provideDocumentRangeSemanticTokensLegend', '_provideDocumentRangeSemanticTokensLegend', 'Provide semantic tokens legend for a document range',
248
[ApiCommandArgument.Uri, ApiCommandArgument.Range.optional()],
249
new ApiCommandResult<languages.SemanticTokensLegend, types.SemanticTokensLegend | undefined>('A promise that resolves to SemanticTokensLegend.', value => {
250
if (!value) {
251
return undefined;
252
}
253
return new types.SemanticTokensLegend(value.tokenTypes, value.tokenModifiers);
254
})
255
),
256
new ApiCommand(
257
'vscode.provideDocumentRangeSemanticTokens', '_provideDocumentRangeSemanticTokens', 'Provide semantic tokens for a document range',
258
[ApiCommandArgument.Uri, ApiCommandArgument.Range],
259
new ApiCommandResult<VSBuffer, types.SemanticTokens | undefined>('A promise that resolves to SemanticTokens.', value => {
260
if (!value) {
261
return undefined;
262
}
263
const semanticTokensDto = decodeSemanticTokensDto(value);
264
if (semanticTokensDto.type !== 'full') {
265
// only accepting full semantic tokens from provideDocumentRangeSemanticTokens
266
return undefined;
267
}
268
return new types.SemanticTokens(semanticTokensDto.data, undefined);
269
})
270
),
271
// --- completions
272
new ApiCommand(
273
'vscode.executeCompletionItemProvider', '_executeCompletionItemProvider', 'Execute completion item provider.',
274
[
275
ApiCommandArgument.Uri,
276
ApiCommandArgument.Position,
277
ApiCommandArgument.String.with('triggerCharacter', 'Trigger completion when the user types the character, like `,` or `(`').optional(),
278
ApiCommandArgument.Number.with('itemResolveCount', 'Number of completions to resolve (too large numbers slow down completions)').optional()
279
],
280
new ApiCommandResult<languages.CompletionList, vscode.CompletionList>('A promise that resolves to a CompletionList-instance.', (value, _args, converter) => {
281
if (!value) {
282
return new types.CompletionList([]);
283
}
284
const items = value.suggestions.map(suggestion => typeConverters.CompletionItem.to(suggestion, converter));
285
return new types.CompletionList(items, value.incomplete);
286
})
287
),
288
// --- signature help
289
new ApiCommand(
290
'vscode.executeSignatureHelpProvider', '_executeSignatureHelpProvider', 'Execute signature help provider.',
291
[ApiCommandArgument.Uri, ApiCommandArgument.Position, ApiCommandArgument.String.with('triggerCharacter', 'Trigger signature help when the user types the character, like `,` or `(`').optional()],
292
new ApiCommandResult<languages.SignatureHelp, vscode.SignatureHelp | undefined>('A promise that resolves to SignatureHelp.', value => {
293
if (value) {
294
return typeConverters.SignatureHelp.to(value);
295
}
296
return undefined;
297
})
298
),
299
// --- code lens
300
new ApiCommand(
301
'vscode.executeCodeLensProvider', '_executeCodeLensProvider', 'Execute code lens provider.',
302
[ApiCommandArgument.Uri, ApiCommandArgument.Number.with('itemResolveCount', 'Number of lenses that should be resolved and returned. Will only return resolved lenses, will impact performance)').optional()],
303
new ApiCommandResult<languages.CodeLens[], vscode.CodeLens[] | undefined>('A promise that resolves to an array of CodeLens-instances.', (value, _args, converter) => {
304
return tryMapWith<languages.CodeLens, vscode.CodeLens>(item => {
305
return new types.CodeLens(typeConverters.Range.to(item.range), item.command && converter.fromInternal(item.command));
306
})(value);
307
})
308
),
309
// --- code actions
310
new ApiCommand(
311
'vscode.executeCodeActionProvider', '_executeCodeActionProvider', 'Execute code action provider.',
312
[
313
ApiCommandArgument.Uri,
314
new ApiCommandArgument('rangeOrSelection', 'Range in a text document. Some refactoring provider requires Selection object.', v => types.Range.isRange(v), v => types.Selection.isSelection(v) ? typeConverters.Selection.from(v) : typeConverters.Range.from(v)),
315
ApiCommandArgument.String.with('kind', 'Code action kind to return code actions for').optional(),
316
ApiCommandArgument.Number.with('itemResolveCount', 'Number of code actions to resolve (too large numbers slow down code actions)').optional()
317
],
318
new ApiCommandResult<CustomCodeAction[], (vscode.CodeAction | vscode.Command | undefined)[] | undefined>('A promise that resolves to an array of Command-instances.', (value, _args, converter) => {
319
return tryMapWith<CustomCodeAction, vscode.CodeAction | vscode.Command | undefined>((codeAction) => {
320
if (codeAction._isSynthetic) {
321
if (!codeAction.command) {
322
throw new Error('Synthetic code actions must have a command');
323
}
324
return converter.fromInternal(codeAction.command);
325
} else {
326
const ret = new types.CodeAction(
327
codeAction.title,
328
codeAction.kind ? new types.CodeActionKind(codeAction.kind) : undefined
329
);
330
if (codeAction.edit) {
331
ret.edit = typeConverters.WorkspaceEdit.to(codeAction.edit);
332
}
333
if (codeAction.command) {
334
ret.command = converter.fromInternal(codeAction.command);
335
}
336
ret.isPreferred = codeAction.isPreferred;
337
return ret;
338
}
339
})(value);
340
})
341
),
342
// --- colors
343
new ApiCommand(
344
'vscode.executeDocumentColorProvider', '_executeDocumentColorProvider', 'Execute document color provider.',
345
[ApiCommandArgument.Uri],
346
new ApiCommandResult<IRawColorInfo[], vscode.ColorInformation[]>('A promise that resolves to an array of ColorInformation objects.', result => {
347
if (result) {
348
return result.map(ci => new types.ColorInformation(typeConverters.Range.to(ci.range), typeConverters.Color.to(ci.color)));
349
}
350
return [];
351
})
352
),
353
new ApiCommand(
354
'vscode.executeColorPresentationProvider', '_executeColorPresentationProvider', 'Execute color presentation provider.',
355
[
356
new ApiCommandArgument<types.Color, [number, number, number, number]>('color', 'The color to show and insert', v => v instanceof types.Color, typeConverters.Color.from),
357
new ApiCommandArgument<{ uri: URI; range: types.Range }, { uri: URI; range: IRange }>('context', 'Context object with uri and range', _v => true, v => ({ uri: v.uri, range: typeConverters.Range.from(v.range) })),
358
],
359
new ApiCommandResult<languages.IColorPresentation[], types.ColorPresentation[]>('A promise that resolves to an array of ColorPresentation objects.', result => {
360
if (result) {
361
return result.map(typeConverters.ColorPresentation.to);
362
}
363
return [];
364
})
365
),
366
// --- inline hints
367
new ApiCommand(
368
'vscode.executeInlayHintProvider', '_executeInlayHintProvider', 'Execute inlay hints provider',
369
[ApiCommandArgument.Uri, ApiCommandArgument.Range],
370
new ApiCommandResult<languages.InlayHint[], vscode.InlayHint[]>('A promise that resolves to an array of Inlay objects', (result, args, converter) => {
371
return result.map(typeConverters.InlayHint.to.bind(undefined, converter));
372
})
373
),
374
// --- folding
375
new ApiCommand(
376
'vscode.executeFoldingRangeProvider', '_executeFoldingRangeProvider', 'Execute folding range provider',
377
[ApiCommandArgument.Uri],
378
new ApiCommandResult<languages.FoldingRange[] | undefined, vscode.FoldingRange[] | undefined>('A promise that resolves to an array of FoldingRange objects', (result, args) => {
379
if (result) {
380
return result.map(typeConverters.FoldingRange.to);
381
}
382
return undefined;
383
})
384
),
385
386
// --- notebooks
387
new ApiCommand(
388
'vscode.resolveNotebookContentProviders', '_resolveNotebookContentProvider', 'Resolve Notebook Content Providers',
389
[
390
// new ApiCommandArgument<string, string>('viewType', '', v => typeof v === 'string', v => v),
391
// new ApiCommandArgument<string, string>('displayName', '', v => typeof v === 'string', v => v),
392
// new ApiCommandArgument<object, object>('options', '', v => typeof v === 'object', v => v),
393
],
394
new ApiCommandResult<{
395
viewType: string;
396
displayName: string;
397
options: { transientOutputs: boolean; transientCellMetadata: TransientCellMetadata; transientDocumentMetadata: TransientDocumentMetadata };
398
filenamePattern: (vscode.GlobPattern | { include: vscode.GlobPattern; exclude: vscode.GlobPattern })[];
399
}[], {
400
viewType: string;
401
displayName: string;
402
filenamePattern: (vscode.GlobPattern | { include: vscode.GlobPattern; exclude: vscode.GlobPattern })[];
403
options: vscode.NotebookDocumentContentOptions;
404
}[] | undefined>('A promise that resolves to an array of NotebookContentProvider static info objects.', tryMapWith(item => {
405
return {
406
viewType: item.viewType,
407
displayName: item.displayName,
408
options: {
409
transientOutputs: item.options.transientOutputs,
410
transientCellMetadata: item.options.transientCellMetadata,
411
transientDocumentMetadata: item.options.transientDocumentMetadata
412
},
413
filenamePattern: item.filenamePattern.map(pattern => typeConverters.NotebookExclusiveDocumentPattern.to(pattern))
414
};
415
}))
416
),
417
// --- debug support
418
new ApiCommand(
419
'vscode.executeInlineValueProvider', '_executeInlineValueProvider', 'Execute inline value provider',
420
[
421
ApiCommandArgument.Uri,
422
ApiCommandArgument.Range,
423
new ApiCommandArgument<types.InlineValueContext, IInlineValueContextDto>('context', 'An InlineValueContext', v => v && typeof v.frameId === 'number' && v.stoppedLocation instanceof types.Range, v => typeConverters.InlineValueContext.from(v))
424
],
425
new ApiCommandResult<languages.InlineValue[], vscode.InlineValue[]>('A promise that resolves to an array of InlineValue objects', result => {
426
return result.map(typeConverters.InlineValue.to);
427
})
428
),
429
// --- open'ish commands
430
new ApiCommand(
431
'vscode.open', '_workbench.open', 'Opens the provided resource in the editor. Can be a text or binary file, or an http(s) URL. If you need more control over the options for opening a text file, use vscode.window.showTextDocument instead.',
432
[
433
new ApiCommandArgument<URI | string>('uriOrString', 'Uri-instance or string (only http/https)', v => URI.isUri(v) || (typeof v === 'string' && matchesSomeScheme(v, Schemas.http, Schemas.https)), v => v),
434
new ApiCommandArgument<vscode.ViewColumn | typeConverters.TextEditorOpenOptions | undefined, [vscode.ViewColumn?, ITextEditorOptions?] | undefined>('columnOrOptions', 'Either the column in which to open or editor options, see vscode.TextDocumentShowOptions',
435
v => v === undefined || typeof v === 'number' || typeof v === 'object',
436
v => !v ? v : typeof v === 'number' ? [typeConverters.ViewColumn.from(v), undefined] : [typeConverters.ViewColumn.from(v.viewColumn), typeConverters.TextEditorOpenOptions.from(v)]
437
).optional(),
438
ApiCommandArgument.String.with('label', '').optional()
439
],
440
ApiCommandResult.Void
441
),
442
new ApiCommand(
443
'vscode.openWith', '_workbench.openWith', 'Opens the provided resource with a specific editor.',
444
[
445
ApiCommandArgument.Uri.with('resource', 'Resource to open'),
446
ApiCommandArgument.String.with('viewId', 'Custom editor view id. This should be the viewType string for custom editors or the notebookType string for notebooks. Use \'default\' to use VS Code\'s default text editor'),
447
new ApiCommandArgument<vscode.ViewColumn | typeConverters.TextEditorOpenOptions | undefined, [vscode.ViewColumn?, ITextEditorOptions?] | undefined>('columnOrOptions', 'Either the column in which to open or editor options, see vscode.TextDocumentShowOptions',
448
v => v === undefined || typeof v === 'number' || typeof v === 'object',
449
v => !v ? v : typeof v === 'number' ? [typeConverters.ViewColumn.from(v), undefined] : [typeConverters.ViewColumn.from(v.viewColumn), typeConverters.TextEditorOpenOptions.from(v)],
450
).optional()
451
],
452
ApiCommandResult.Void
453
),
454
new ApiCommand(
455
'vscode.diff', '_workbench.diff', 'Opens the provided resources in the diff editor to compare their contents.',
456
[
457
ApiCommandArgument.Uri.with('left', 'Left-hand side resource of the diff editor'),
458
ApiCommandArgument.Uri.with('right', 'Right-hand side resource of the diff editor'),
459
ApiCommandArgument.String.with('title', 'Human readable title for the diff editor').optional(),
460
new ApiCommandArgument<typeConverters.TextEditorOpenOptions | undefined, [number?, ITextEditorOptions?] | undefined>('columnOrOptions', 'Either the column in which to open or editor options, see vscode.TextDocumentShowOptions',
461
v => v === undefined || typeof v === 'object',
462
v => v && [typeConverters.ViewColumn.from(v.viewColumn), typeConverters.TextEditorOpenOptions.from(v)]
463
).optional(),
464
],
465
ApiCommandResult.Void
466
),
467
new ApiCommand(
468
'vscode.changes', '_workbench.changes', 'Opens a list of resources in the changes editor to compare their contents.',
469
[
470
ApiCommandArgument.String.with('title', 'Human readable title for the changes editor'),
471
new ApiCommandArgument<[URI, URI?, URI?][]>('resourceList', 'List of resources to compare',
472
resources => {
473
for (const resource of resources) {
474
if (resource.length !== 3) {
475
return false;
476
}
477
478
const [label, left, right] = resource;
479
if (!URI.isUri(label) ||
480
(!URI.isUri(left) && left !== undefined && left !== null) ||
481
(!URI.isUri(right) && right !== undefined && right !== null)) {
482
return false;
483
}
484
}
485
486
return true;
487
},
488
v => v)
489
],
490
ApiCommandResult.Void
491
),
492
// --- type hierarchy
493
new ApiCommand(
494
'vscode.prepareTypeHierarchy', '_executePrepareTypeHierarchy', 'Prepare type hierarchy at a position inside a document',
495
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
496
new ApiCommandResult<ITypeHierarchyItemDto[], types.TypeHierarchyItem[]>('A promise that resolves to an array of TypeHierarchyItem-instances', v => v.map(typeConverters.TypeHierarchyItem.to))
497
),
498
new ApiCommand(
499
'vscode.provideSupertypes', '_executeProvideSupertypes', 'Compute supertypes for an item',
500
[ApiCommandArgument.TypeHierarchyItem],
501
new ApiCommandResult<ITypeHierarchyItemDto[], types.TypeHierarchyItem[]>('A promise that resolves to an array of TypeHierarchyItem-instances', v => v.map(typeConverters.TypeHierarchyItem.to))
502
),
503
new ApiCommand(
504
'vscode.provideSubtypes', '_executeProvideSubtypes', 'Compute subtypes for an item',
505
[ApiCommandArgument.TypeHierarchyItem],
506
new ApiCommandResult<ITypeHierarchyItemDto[], types.TypeHierarchyItem[]>('A promise that resolves to an array of TypeHierarchyItem-instances', v => v.map(typeConverters.TypeHierarchyItem.to))
507
),
508
// --- testing
509
new ApiCommand(
510
'vscode.revealTestInExplorer', '_revealTestInExplorer', 'Reveals a test instance in the explorer',
511
[ApiCommandArgument.TestItem],
512
ApiCommandResult.Void
513
),
514
new ApiCommand(
515
'vscode.startContinuousTestRun', 'testing.startContinuousRunFromExtension', 'Starts running the given tests with continuous run mode.',
516
[ApiCommandArgument.TestProfile, ApiCommandArgument.Arr(ApiCommandArgument.TestItem)],
517
ApiCommandResult.Void
518
),
519
new ApiCommand(
520
'vscode.stopContinuousTestRun', 'testing.stopContinuousRunFromExtension', 'Stops running the given tests with continuous run mode.',
521
[ApiCommandArgument.Arr(ApiCommandArgument.TestItem)],
522
ApiCommandResult.Void
523
),
524
// --- continue edit session
525
new ApiCommand(
526
'vscode.experimental.editSession.continue', '_workbench.editSessions.actions.continueEditSession', 'Continue the current edit session in a different workspace',
527
[ApiCommandArgument.Uri.with('workspaceUri', 'The target workspace to continue the current edit session in')],
528
ApiCommandResult.Void
529
),
530
// --- context keys
531
new ApiCommand(
532
'setContext', '_setContext', 'Set a custom context key value that can be used in when clauses.',
533
[
534
ApiCommandArgument.String.with('name', 'The context key name'),
535
new ApiCommandArgument('value', 'The context key value', () => true, v => v),
536
],
537
ApiCommandResult.Void
538
),
539
// --- inline chat
540
new ApiCommand(
541
'vscode.editorChat.start', 'inlineChat.start', 'Invoke a new editor chat session',
542
[new ApiCommandArgument<InlineChatEditorApiArg | undefined, InlineChatRunOptions | undefined>('Run arguments', '', _v => true, v => {
543
544
if (!v) {
545
return undefined;
546
}
547
548
return {
549
initialRange: v.initialRange ? typeConverters.Range.from(v.initialRange) : undefined,
550
initialSelection: types.Selection.isSelection(v.initialSelection) ? typeConverters.Selection.from(v.initialSelection) : undefined,
551
message: v.message,
552
attachments: v.attachments,
553
autoSend: v.autoSend,
554
position: v.position ? typeConverters.Position.from(v.position) : undefined,
555
resolveOnResponse: v.resolveOnResponse
556
};
557
})],
558
ApiCommandResult.Void
559
),
560
// --- extension prompt files
561
new ApiCommand(
562
'vscode.extensionPromptFileProvider', '_listExtensionPromptFiles', 'Get all extension-contributed prompt files (custom agents, instructions, and prompt files).',
563
[],
564
new ApiCommandResult<IExtensionPromptFileResult[], { uri: vscode.Uri; type: PromptsType }[]>(
565
'A promise that resolves to an array of objects containing uri and type.',
566
(value) => {
567
if (!value) {
568
return [];
569
}
570
return value.map(item => ({
571
uri: URI.revive(item.uri),
572
type: item.type
573
}));
574
}
575
)
576
)
577
];
578
579
type InlineChatEditorApiArg = {
580
initialRange?: vscode.Range;
581
initialSelection?: vscode.Selection;
582
message?: string;
583
attachments?: vscode.Uri[];
584
autoSend?: boolean;
585
position?: vscode.Position;
586
resolveOnResponse?: boolean;
587
};
588
589
type InlineChatRunOptions = {
590
initialRange?: IRange;
591
initialSelection?: ISelection;
592
message?: string;
593
attachments?: URI[];
594
autoSend?: boolean;
595
position?: IPosition;
596
resolveOnResponse?: boolean;
597
};
598
599
//#endregion
600
601
602
//#region OLD world
603
604
export class ExtHostApiCommands {
605
606
static register(commands: ExtHostCommands) {
607
608
newCommands.forEach(commands.registerApiCommand, commands);
609
610
this._registerValidateWhenClausesCommand(commands);
611
}
612
613
private static _registerValidateWhenClausesCommand(commands: ExtHostCommands) {
614
commands.registerCommand(false, '_validateWhenClauses', validateWhenClauses);
615
}
616
}
617
618
function tryMapWith<T, R>(f: (x: T) => R) {
619
return (value: T[]) => {
620
if (Array.isArray(value)) {
621
return value.map(f);
622
}
623
return undefined;
624
};
625
}
626
627
function mapLocationOrLocationLink(values: (languages.Location | languages.LocationLink)[]): (types.Location | vscode.LocationLink)[] | undefined {
628
if (!Array.isArray(values)) {
629
return undefined;
630
}
631
const result: (types.Location | vscode.LocationLink)[] = [];
632
for (const item of values) {
633
if (languages.isLocationLink(item)) {
634
result.push(typeConverters.DefinitionLink.to(item));
635
} else {
636
result.push(typeConverters.location.to(item));
637
}
638
}
639
return result;
640
}
641
642