diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index daab5df909d53..295cafe4de098 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -20,10 +20,9 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { OperatingSystem, OS } from 'vs/base/common/platform'; import { TerminalEditorLocationOptions } from 'vscode'; import { Promises } from 'vs/base/common/async'; -import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes'; import { ISerializableEnvironmentDescriptionMap, ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { ITerminalLinkProviderService } from 'vs/workbench/contrib/terminalContrib/links/browser/links'; -import { ITerminalQuickFixService, ITerminalQuickFix } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; +import { ITerminalQuickFixService, ITerminalQuickFix, TerminalQuickFixType } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) @@ -448,10 +447,12 @@ export function getOutputMatchForLines(lines: string[], outputMatcher: ITerminal } function parseQuickFix(id: string, source: string, fix: TerminalQuickFix): ITerminalQuickFix { - let type = TerminalQuickFixType.Command; + let type = TerminalQuickFixType.TerminalCommand; if ('uri' in fix) { fix.uri = URI.revive(fix.uri); type = TerminalQuickFixType.Opener; + } else if ('id' in fix) { + type = TerminalQuickFixType.VscodeCommand; } return { id, type, source, ...fix }; } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 1673b845c0c57..291edaf4e3333 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1478,7 +1478,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TerminalLocation: extHostTypes.TerminalLocation, TerminalProfile: extHostTypes.TerminalProfile, TerminalExitReason: extHostTypes.TerminalExitReason, - TerminalQuickFixType: extHostTypes.TerminalQuickFixType, TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason, TextEdit: extHostTypes.TextEdit, SnippetTextEdit: extHostTypes.SnippetTextEdit, diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index be6ebc586b23f..2f2bba714330e 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -52,8 +52,9 @@ export enum TerminalOutputAnchor { } export enum TerminalQuickFixType { - Command = 0, - Opener = 1 + TerminalCommand = 0, + Opener = 1, + Command = 3 } @es5ClassCompat diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts index 382d5144b2374..8a13380b9713a 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts @@ -29,7 +29,7 @@ export interface ITerminalQuickFixProviderSelector { provider: ITerminalQuickFixProvider; } -export type TerminalQuickFixActionInternal = IAction | ITerminalQuickFixCommandAction | ITerminalQuickFixOpenerAction; +export type TerminalQuickFixActionInternal = IAction | ITerminalQuickFixExecuteTerminalCommandAction | ITerminalQuickFixOpenerAction; export type TerminalQuickFixCallback = (matchResult: ITerminalCommandMatchResult) => TerminalQuickFixActionInternal[] | TerminalQuickFixActionInternal | undefined; export type TerminalQuickFixCallbackExtension = (terminalCommand: ITerminalCommand, lines: string[] | undefined, option: ITerminalQuickFixOptions, token: CancellationToken) => Promise; @@ -44,9 +44,10 @@ export interface ITerminalQuickFixProvider { } export enum TerminalQuickFixType { - Command = 0, + TerminalCommand = 0, Opener = 1, - Port = 2 + Port = 2, + VscodeCommand = 3 } export interface ITerminalQuickFixOptions { @@ -63,8 +64,8 @@ export interface ITerminalQuickFix { source: string; } -export interface ITerminalQuickFixCommandAction extends ITerminalQuickFix { - type: TerminalQuickFixType.Command; +export interface ITerminalQuickFixExecuteTerminalCommandAction extends ITerminalQuickFix { + type: TerminalQuickFixType.TerminalCommand; terminalCommand: string; // TODO: Should this depend on whether alt is held? addNewLine?: boolean; @@ -73,6 +74,9 @@ export interface ITerminalQuickFixOpenerAction extends ITerminalQuickFix { type: TerminalQuickFixType.Opener; uri: URI; } +export interface ITerminalQuickFixCommandAction extends ITerminalQuickFix { + title: string; +} export interface ITerminalCommandMatchResult { commandLine: string; diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts index 765d03c2141e5..0631a1e4e044d 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts @@ -28,12 +28,13 @@ import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { ILabelService } from 'vs/platform/label/common/label'; import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; -import { ITerminalQuickFixInternalOptions, ITerminalQuickFixResolvedExtensionOptions, ITerminalQuickFix, ITerminalQuickFixCommandAction, ITerminalQuickFixOpenerAction, ITerminalQuickFixOptions, ITerminalQuickFixProviderSelector, ITerminalQuickFixService, ITerminalQuickFixUnresolvedExtensionOptions, TerminalQuickFixType } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; +import { ITerminalQuickFixInternalOptions, ITerminalQuickFixResolvedExtensionOptions, ITerminalQuickFix, ITerminalQuickFixExecuteTerminalCommandAction, ITerminalQuickFixOpenerAction, ITerminalQuickFixOptions, ITerminalQuickFixProviderSelector, ITerminalQuickFixService, ITerminalQuickFixUnresolvedExtensionOptions, TerminalQuickFixType, ITerminalQuickFixCommandAction } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; import { ITerminalCommandSelector } from 'vs/platform/terminal/common/terminal'; import { ActionListItemKind, IActionListItem } from 'vs/platform/actionWidget/browser/actionList'; import { CodeActionKind } from 'vs/editor/contrib/codeAction/common/types'; import { Codicon } from 'vs/base/common/codicons'; import { ThemeIcon } from 'vs/base/common/themables'; +import { ICommandService } from 'vs/platform/commands/common/commands'; const quickFixSelectors = [ DecorationSelector.QuickFix, @@ -75,6 +76,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, private readonly _aliases: string[][] | undefined, private readonly _capabilities: ITerminalCapabilityStore, @ITerminalQuickFixService private readonly _quickFixService: ITerminalQuickFixService, + @ICommandService private readonly _commandService: ICommandService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IAudioCueService private readonly _audioCueService: IAudioCueService, @IOpenerService private readonly _openerService: IOpenerService, @@ -192,7 +194,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, await this._extensionService.activateByEvent(`onTerminalQuickFixRequest:${id}`); return this._quickFixService.providers.get(id)?.provideTerminalQuickFixes(command, lines, { type: 'resolved', commandLineMatcher: selector.commandLineMatcher, outputMatcher: selector.outputMatcher, commandExitResult: selector.commandExitResult, id: selector.id }, new CancellationTokenSource().token); }; - const result = await getQuickFixesForCommand(aliases, terminal, command, this._commandListeners, this._openerService, this._labelService, this._onDidRequestRerunCommand, resolver); + const result = await getQuickFixesForCommand(aliases, terminal, command, this._commandListeners, this._commandService, this._openerService, this._labelService, this._onDidRequestRerunCommand, resolver); if (!result) { return; } @@ -293,6 +295,7 @@ export async function getQuickFixesForCommand( terminal: Terminal, terminalCommand: ITerminalCommand, quickFixOptions: Map, + commandService: ICommandService, openerService: IOpenerService, labelService: ILabelService, onDidRequestRerunCommand?: Emitter<{ command: string; addNewLine?: boolean }>, @@ -339,15 +342,15 @@ export async function getQuickFixesForCommand( let action: ITerminalAction | undefined; if ('type' in quickFix) { switch (quickFix.type) { - case TerminalQuickFixType.Command: { - const fix = quickFix as ITerminalQuickFixCommandAction; + case TerminalQuickFixType.TerminalCommand: { + const fix = quickFix as ITerminalQuickFixExecuteTerminalCommandAction; if (commandQuickFixSet.has(fix.terminalCommand)) { continue; } commandQuickFixSet.add(fix.terminalCommand); const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand); action = { - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, class: undefined, source: quickFix.source, id: quickFix.id, @@ -405,6 +408,20 @@ export async function getQuickFixesForCommand( }; break; } + case TerminalQuickFixType.VscodeCommand: { + const fix = quickFix as ITerminalQuickFixCommandAction; + action = { + source: quickFix.source, + type: fix.type, + id: fix.id, + label: fix.title, + class: undefined, + enabled: true, + run: () => commandService.executeCommand(fix.id), + tooltip: fix.title + }; + break; + } } if (action) { fixes.push(action); @@ -477,9 +494,11 @@ function getQuickFixIcon(quickFix: TerminalQuickFixItem): ThemeIcon { const isUrl = (quickFix.action.uri.scheme === Schemas.http || quickFix.action.uri.scheme === Schemas.https); return isUrl ? Codicon.linkExternal : Codicon.goToFile; } - case TerminalQuickFixType.Command: + case TerminalQuickFixType.TerminalCommand: return Codicon.run; case TerminalQuickFixType.Port: return Codicon.debugDisconnect; + case TerminalQuickFixType.VscodeCommand: + return Codicon.lightbulb; } } diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts index 0bc357b08b4a9..386eb5153fb52 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { ITerminalQuickFixInternalOptions, ITerminalCommandMatchResult, ITerminalQuickFixCommandAction, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; +import { ITerminalQuickFixInternalOptions, ITerminalCommandMatchResult, ITerminalQuickFixExecuteTerminalCommandAction, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; export const GitCommandLineRegex = /git/; export const GitPushCommandLineRegex = /git\s+push/; @@ -49,7 +49,7 @@ export function gitSimilar(): ITerminalQuickFixInternalOptions { if (fixedCommand) { actions.push({ id: 'Git Similar', - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, terminalCommand: matchResult.commandLine.replace(/git\s+[^\s]+/, () => `git ${fixedCommand}`), addNewLine: true, source: QuickFixSource.Builtin @@ -79,7 +79,7 @@ export function gitTwoDashes(): ITerminalQuickFixInternalOptions { return; } return { - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, id: 'Git Two Dashes', terminalCommand: matchResult.commandLine.replace(` -${problemArg}`, () => ` --${problemArg}`), addNewLine: true, @@ -175,7 +175,7 @@ export function gitPushSetUpstream(): ITerminalQuickFixInternalOptions { } if (fixedCommand) { actions.push({ - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, id: 'Git Push Set Upstream', terminalCommand: fixedCommand, addNewLine: true, @@ -268,11 +268,11 @@ export function pwshGeneralError(): ITerminalQuickFixInternalOptions { if (!suggestions) { return; } - const result: ITerminalQuickFixCommandAction[] = []; + const result: ITerminalQuickFixExecuteTerminalCommandAction[] = []; for (const suggestion of suggestions) { result.push({ id: 'Pwsh General Error', - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, terminalCommand: suggestion, source: QuickFixSource.Builtin }); @@ -314,7 +314,7 @@ export function pwshUnixCommandNotFoundError(): ITerminalQuickFixInternalOptions } // Always remove the first element as it's the "Suggestion [cmd-not-found]"" line - const result: ITerminalQuickFixCommandAction[] = []; + const result: ITerminalQuickFixExecuteTerminalCommandAction[] = []; let inSuggestions = false; for (; i < lines.length; i++) { const line = lines[i].trim(); @@ -325,7 +325,7 @@ export function pwshUnixCommandNotFoundError(): ITerminalQuickFixInternalOptions if (installCommand) { result.push({ id: 'Pwsh Unix Command Not Found Error', - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, terminalCommand: installCommand, source: QuickFixSource.Builtin }); @@ -339,7 +339,7 @@ export function pwshUnixCommandNotFoundError(): ITerminalQuickFixInternalOptions if (inSuggestions) { result.push({ id: 'Pwsh Unix Command Not Found Error', - type: TerminalQuickFixType.Command, + type: TerminalQuickFixType.TerminalCommand, terminalCommand: line.trim(), source: QuickFixSource.Builtin }); diff --git a/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts b/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts index 094d1b969c4b8..4daa96722d835 100644 --- a/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts @@ -80,9 +80,4 @@ declare module 'vscode' { Top = 0, Bottom = 1 } - - enum TerminalQuickFixType { - Command = 0, - Opener = 1 - } }