diff --git a/extensions/terminal-suggest/package.json b/extensions/terminal-suggest/package.json index 4b6aef3f936..66e99b20e11 100644 --- a/extensions/terminal-suggest/package.json +++ b/extensions/terminal-suggest/package.json @@ -14,6 +14,7 @@ "Other" ], "enabledApiProposals": [ + "terminalCompletionProvider", "terminalShellEnv" ], "contributes": { diff --git a/src/vs/platform/extensions/common/extensionsApiProposals.ts b/src/vs/platform/extensions/common/extensionsApiProposals.ts index a8778a5980d..959b3477de4 100644 --- a/src/vs/platform/extensions/common/extensionsApiProposals.ts +++ b/src/vs/platform/extensions/common/extensionsApiProposals.ts @@ -403,6 +403,9 @@ const _allApiProposals = { telemetry: { proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.telemetry.d.ts', }, + terminalCompletionProvider: { + proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts', + }, terminalDataWriteEvent: { proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts', }, diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index f6757129db3..da16fe2d2e4 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -880,6 +880,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostTerminalService.registerProfileProvider(extension, id, provider); }, registerTerminalCompletionProvider(provider: vscode.TerminalCompletionProvider, ...triggerCharacters: string[]): vscode.Disposable { + checkProposedApiEnabled(extension, 'terminalCompletionProvider'); return extHostTerminalService.registerTerminalCompletionProvider(extension, provider, ...triggerCharacters); }, registerTerminalQuickFixProvider(id: string, provider: vscode.TerminalQuickFixProvider): vscode.Disposable { diff --git a/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts b/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts index 78f2d8ecb61..664e1942f62 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts @@ -9,6 +9,7 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta import { IExtensionTerminalProfile, ITerminalCompletionProviderContribution, ITerminalContributions, ITerminalProfileContribution } from '../../../../platform/terminal/common/terminal.js'; import { URI } from '../../../../base/common/uri.js'; import { Emitter, Event } from '../../../../base/common/event.js'; +import { isProposedApiEnabled } from '../../../services/extensions/common/extensions.js'; // terminal extension point const terminalsExtPoint = extensionsRegistry.ExtensionsRegistry.registerExtensionPoint(terminalContributionsDescriptor); @@ -48,6 +49,9 @@ export class TerminalContributionService implements ITerminalContributionService }).flat(); this._terminalCompletionProviders = contributions.map(c => { + if (!isProposedApiEnabled(c.description, 'terminalCompletionProvider')) { + return []; + } return c.value?.completionProviders?.map(p => { return { ...p, extensionIdentifier: c.description.identifier.value }; }) || []; diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 947b3e2568d..4728952d5ed 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -8209,255 +8209,6 @@ declare module 'vscode' { constructor(options: TerminalOptions | ExtensionTerminalOptions); } - /** - * A provider that supplies terminal completion items. - * - * Implementations of this interface should return an array of {@link TerminalCompletionItem} or a - * {@link TerminalCompletionList} describing completions for the current command line. - * - * @example Simple provider returning a single completion - * window.registerTerminalCompletionProvider({ - * provideTerminalCompletions(terminal, context) { - * return [{ label: '--help', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] }]; - * } - * }); - */ - export interface TerminalCompletionProvider { - /** - * Provide completions for the given terminal and context. - * @param terminal The terminal for which completions are being provided. - * @param context Information about the terminal's current state. - * @param token A cancellation token. - * @return A list of completions. - */ - provideTerminalCompletions(terminal: Terminal, context: TerminalCompletionContext, token: CancellationToken): ProviderResult>; - } - - - /** - * Represents a completion suggestion for a terminal command line. - * - * @example Completion item for `ls -|` - * const item = { - * label: '-A', - * replacementRange: [3, 4], // replace the single character at index 3 - * detail: 'List all entries except for . and .. (always set for the super-user)', - * kind: TerminalCompletionItemKind.Flag - * }; - * - * The fields on a completion item describe what text should be shown to the user - * and which portion of the command line should be replaced when the item is accepted. - */ - export class TerminalCompletionItem { - /** - * The label of the completion. - */ - label: string | CompletionItemLabel; - - /** - * The range in the command line to replace when the completion is accepted. Defined - * as a tuple where the first entry is the inclusive start index and the second entry is the - * exclusive end index. - * - */ - replacementRange: readonly [number, number]; - - /** - * The completion's detail which appears on the right of the list. - */ - detail?: string; - - /** - * A human-readable string that represents a doc-comment. - */ - documentation?: string | MarkdownString; - - /** - * The completion's kind. Note that this will map to an icon. If no kind is provided, a generic icon representing plaintext will be provided. - */ - kind?: TerminalCompletionItemKind; - - /** - * Creates a new terminal completion item. - * - * @param label The label of the completion. - * @param replacementRange The inclusive start and exclusive end index of the text to replace. - * @param kind The completion's kind. - */ - constructor( - label: string | CompletionItemLabel, - replacementRange: readonly [number, number], - kind?: TerminalCompletionItemKind - ); - } - - /** - * The kind of an individual terminal completion item. - * - * The kind is used to render an appropriate icon in the suggest list and to convey the semantic - * meaning of the suggestion (file, folder, flag, commit, branch, etc.). - */ - export enum TerminalCompletionItemKind { - /** - * A file completion item. - * Example: `README.md` - */ - File = 0, - /** - * A folder completion item. - * Example: `src/` - */ - Folder = 1, - /** - * A method completion item. - * Example: `git commit` - */ - Method = 2, - /** - * An alias completion item. - * Example: `ll` as an alias for `ls -l` - */ - Alias = 3, - /** - * An argument completion item. - * Example: `origin` in `git push origin master` - */ - Argument = 4, - /** - * An option completion item. An option value is expected to follow. - * Example: `--locale` in `code --locale en` - */ - Option = 5, - /** - * The value of an option completion item. - * Example: `en-US` in `code --locale en-US` - */ - OptionValue = 6, - /** - * A flag completion item. - * Example: `--amend` in `git commit --amend` - */ - Flag = 7, - /** - * A symbolic link file completion item. - * Example: `link.txt` (symlink to a file) - */ - SymbolicLinkFile = 8, - /** - * A symbolic link folder completion item. - * Example: `node_modules/` (symlink to a folder) - */ - SymbolicLinkFolder = 9, - /** - * A source control commit completion item. - * Example: `abc1234` (commit hash) - */ - ScmCommit = 10, - /** - * A source control branch completion item. - * Example: `main` - */ - ScmBranch = 11, - /** - * A source control tag completion item. - * Example: `v1.0.0` - */ - ScmTag = 12, - /** - * A source control stash completion item. - * Example: `stash@{0}` - */ - ScmStash = 13, - /** - * A source control remote completion item. - * Example: `origin` - */ - ScmRemote = 14, - /** - * A pull request completion item. - * Example: `#42 Add new feature` - */ - PullRequest = 15, - /** - * A closed pull request completion item. - * Example: `#41 Fix bug (closed)` - */ - PullRequestDone = 16, - } - - /** - * Context information passed to {@link TerminalCompletionProvider.provideTerminalCompletions}. - * - * It contains the full command line and the current cursor position - */ - export interface TerminalCompletionContext { - /** - * The complete terminal command line. - */ - readonly commandLine: string; - /** - * The index of the cursor in the command line. - */ - readonly cursorIndex: number; - } - - /** - * Represents a collection of {@link TerminalCompletionItem completion items} to be presented - * in the terminal plus {@link TerminalCompletionList.resourceOptions} which indicate - * which file and folder resources should be requested for the terminal's cwd. - * - * @example Create a completion list that requests files for the terminal cwd - * const list = new TerminalCompletionList([ - * { label: 'ls', replacementRange: [0, 0], kind: TerminalCompletionItemKind.Method } - * ], { showFiles: true, cwd: Uri.file('/home/user') }); - */ - export class TerminalCompletionList { - - /** - * Resources that should be shown in the completions list for the cwd of the terminal. - */ - resourceOptions?: TerminalCompletionResourceOptions; - - /** - * The completion items. - */ - items: T[]; - - /** - * Creates a new completion list. - * - * @param items The completion items. - * @param resourceOptions Indicates which resources should be shown as completions for the cwd of the terminal. - */ - constructor(items: T[], resourceOptions?: TerminalCompletionResourceOptions); - } - - - /** - * Configuration for requesting file and folder resources to be shown as completions. - * - * When a provider indicates that it wants file/folder resources, the terminal will surface completions for files and - * folders that match {@link globPattern} from the provided {@link cwd}. - */ - export interface TerminalCompletionResourceOptions { - /** - * Show files as completion items. - */ - showFiles: boolean; - /** - * Show folders as completion items. - */ - showDirectories: boolean; - /** - * A glob pattern string that controls which files suggest should surface. Note that this will only apply if {@param showFiles} or {@param showDirectories} is set to true. - */ - globPattern?: string; - /** - * The cwd from which to request resources. - */ - cwd: Uri; - } - /** * A file decoration represents metadata that can be rendered with a file. */ @@ -12033,33 +11784,6 @@ declare module 'vscode' { * @returns A {@link Disposable disposable} that unregisters the provider. */ export function registerTerminalProfileProvider(id: string, provider: TerminalProfileProvider): Disposable; - /** - * Register a completion provider for terminals. - * @param provider The completion provider. - * @param triggerCharacters Optional characters that trigger completion. When any of these characters is typed, - * the completion provider will be invoked. For example, passing `'-'` would cause the provider to be invoked - * whenever the user types a dash character. - * @returns A {@link Disposable} that unregisters this provider when being disposed. - * - * @example Register a provider for an extension - * window.registerTerminalCompletionProvider({ - * provideTerminalCompletions(terminal, context) { - * return new TerminalCompletionList([ - * { label: '--version', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] } - * ]); - * } - * }); - * - * @example Register a provider with trigger characters - * window.registerTerminalCompletionProvider({ - * provideTerminalCompletions(terminal, context) { - * return new TerminalCompletionList([ - * { label: '--help', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] } - * ]); - * } - * }, '-'); - */ - export function registerTerminalCompletionProvider(provider: TerminalCompletionProvider, ...triggerCharacters: string[]): Disposable; /** * Register a file decoration provider. * diff --git a/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts new file mode 100644 index 00000000000..5aa612e3d8b --- /dev/null +++ b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts @@ -0,0 +1,286 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/226562 + + /** + * A provider that supplies terminal completion items. + * + * Implementations of this interface should return an array of {@link TerminalCompletionItem} or a + * {@link TerminalCompletionList} describing completions for the current command line. + * + * @example Simple provider returning a single completion + * window.registerTerminalCompletionProvider({ + * provideTerminalCompletions(terminal, context) { + * return [{ label: '--help', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] }]; + * } + * }); + */ + export interface TerminalCompletionProvider { + /** + * Provide completions for the given terminal and context. + * @param terminal The terminal for which completions are being provided. + * @param context Information about the terminal's current state. + * @param token A cancellation token. + * @return A list of completions. + */ + provideTerminalCompletions(terminal: Terminal, context: TerminalCompletionContext, token: CancellationToken): ProviderResult>; + } + + /** + * Represents a completion suggestion for a terminal command line. + * + * @example Completion item for `ls -|` + * const item = { + * label: '-A', + * replacementRange: [3, 4], // replace the single character at index 3 + * detail: 'List all entries except for . and .. (always set for the super-user)', + * kind: TerminalCompletionItemKind.Flag + * }; + * + * The fields on a completion item describe what text should be shown to the user + * and which portion of the command line should be replaced when the item is accepted. + */ + export class TerminalCompletionItem { + /** + * The label of the completion. + */ + label: string | CompletionItemLabel; + + /** + * The range in the command line to replace when the completion is accepted. Defined + * as a tuple where the first entry is the inclusive start index and the second entry is the + * exclusive end index. + */ + replacementRange: readonly [number, number]; + + /** + * The completion's detail which appears on the right of the list. + */ + detail?: string; + + /** + * A human-readable string that represents a doc-comment. + */ + documentation?: string | MarkdownString; + + /** + * The completion's kind. Note that this will map to an icon. If no kind is provided, a generic icon representing plaintext will be provided. + */ + kind?: TerminalCompletionItemKind; + + /** + * Creates a new terminal completion item. + * + * @param label The label of the completion. + * @param replacementRange The inclusive start and exclusive end index of the text to replace. + * @param kind The completion's kind. + */ + constructor( + label: string | CompletionItemLabel, + replacementRange: readonly [number, number], + kind?: TerminalCompletionItemKind + ); + } + + /** + * The kind of an individual terminal completion item. + * + * The kind is used to render an appropriate icon in the suggest list and to convey the semantic + * meaning of the suggestion (file, folder, flag, commit, branch, etc.). + */ + export enum TerminalCompletionItemKind { + /** + * A file completion item. + * Example: `README.md` + */ + File = 0, + /** + * A folder completion item. + * Example: `src/` + */ + Folder = 1, + /** + * A method completion item. + * Example: `git commit` + */ + Method = 2, + /** + * An alias completion item. + * Example: `ll` as an alias for `ls -l` + */ + Alias = 3, + /** + * An argument completion item. + * Example: `origin` in `git push origin main` + */ + Argument = 4, + /** + * An option completion item. An option value is expected to follow. + * Example: `--locale` in `code --locale en` + */ + Option = 5, + /** + * The value of an option completion item. + * Example: `en-US` in `code --locale en-US` + */ + OptionValue = 6, + /** + * A flag completion item. + * Example: `--amend` in `git commit --amend` + */ + Flag = 7, + /** + * A symbolic link file completion item. + * Example: `link.txt` (symlink to a file) + */ + SymbolicLinkFile = 8, + /** + * A symbolic link folder completion item. + * Example: `node_modules/` (symlink to a folder) + */ + SymbolicLinkFolder = 9, + /** + * A source control commit completion item. + * Example: `abc1234` (commit hash) + */ + ScmCommit = 10, + /** + * A source control branch completion item. + * Example: `main` + */ + ScmBranch = 11, + /** + * A source control tag completion item. + * Example: `v1.0.0` + */ + ScmTag = 12, + /** + * A source control stash completion item. + * Example: `stash@{0}` + */ + ScmStash = 13, + /** + * A source control remote completion item. + * Example: `origin` + */ + ScmRemote = 14, + /** + * A pull request completion item. + * Example: `#42 Add new feature` + */ + PullRequest = 15, + /** + * A closed pull request completion item. + * Example: `#41 Fix bug (closed)` + */ + PullRequestDone = 16, + } + + /** + * Context information passed to {@link TerminalCompletionProvider.provideTerminalCompletions}. + * + * It contains the full command line and the current cursor position. + */ + export interface TerminalCompletionContext { + /** + * The complete terminal command line. + */ + readonly commandLine: string; + /** + * The index of the cursor in the command line. + */ + readonly cursorIndex: number; + } + + /** + * Represents a collection of {@link TerminalCompletionItem completion items} to be presented + * in the terminal plus {@link TerminalCompletionList.resourceOptions} which indicate + * which file and folder resources should be requested for the terminal's cwd. + * + * @example Create a completion list that requests files for the terminal cwd + * const list = new TerminalCompletionList([ + * { label: 'ls', replacementRange: [0, 0], kind: TerminalCompletionItemKind.Method } + * ], { showFiles: true, cwd: Uri.file('/home/user') }); + */ + export class TerminalCompletionList { + + /** + * Resources that should be shown in the completions list for the cwd of the terminal. + */ + resourceOptions?: TerminalCompletionResourceOptions; + + /** + * The completion items. + */ + items: T[]; + + /** + * Creates a new completion list. + * + * @param items The completion items. + * @param resourceOptions Indicates which resources should be shown as completions for the cwd of the terminal. + */ + constructor(items: T[], resourceOptions?: TerminalCompletionResourceOptions); + } + + /** + * Configuration for requesting file and folder resources to be shown as completions. + * + * When a provider indicates that it wants file/folder resources, the terminal will surface completions for files and + * folders that match {@link globPattern} from the provided {@link cwd}. + */ + export interface TerminalCompletionResourceOptions { + /** + * Show files as completion items. + */ + showFiles: boolean; + /** + * Show folders as completion items. + */ + showDirectories: boolean; + /** + * A glob pattern string that controls which files suggest should surface. Note that this will only apply if {@param showFiles} or {@param showDirectories} is set to true. + */ + globPattern?: string; + /** + * The cwd from which to request resources. + */ + cwd: Uri; + } + + export namespace window { + /** + * Register a completion provider for terminals. + * @param provider The completion provider. + * @param triggerCharacters Optional characters that trigger completion. When any of these characters is typed, + * the completion provider will be invoked. For example, passing `'-'` would cause the provider to be invoked + * whenever the user types a dash character. + * @returns A {@link Disposable} that unregisters this provider when being disposed. + * + * @example Register a provider for an extension + * window.registerTerminalCompletionProvider({ + * provideTerminalCompletions(terminal, context) { + * return new TerminalCompletionList([ + * { label: '--version', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] } + * ]); + * } + * }); + * + * @example Register a provider with trigger characters + * window.registerTerminalCompletionProvider({ + * provideTerminalCompletions(terminal, context) { + * return new TerminalCompletionList([ + * { label: '--help', replacementRange: [Math.max(0, context.cursorPosition - 2), context.cursorPosition] } + * ]); + * } + * }, '-'); + */ + export function registerTerminalCompletionProvider(provider: TerminalCompletionProvider, ...triggerCharacters: string[]): Disposable; + } +} +