Skip to content

Commit

Permalink
Merge pull request #190050 from microsoft/tyriar/162950_3
Browse files Browse the repository at this point in the history
Update terminal quick fix proposal
  • Loading branch information
Tyriar authored Aug 9, 2023
2 parents bf217d2 + ccf15d3 commit c5702cd
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 18 deletions.
2 changes: 1 addition & 1 deletion extensions/npm/src/npmMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
}

const lines = outputMatch.regexMatch[1];
const fixes: vscode.TerminalQuickFixCommand[] = [];
const fixes: vscode.TerminalQuickFixExecuteTerminalCommand[] = [];
for (const line of lines.split('\n')) {
// search from the second char, since the lines might be prefixed with
// "npm ERR!" which comes before the actual command suggestion.
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
TaskRevealKind: extHostTypes.TaskRevealKind,
TaskScope: extHostTypes.TaskScope,
TerminalLink: extHostTypes.TerminalLink,
TerminalQuickFixCommand: extHostTypes.TerminalQuickFixCommand,
TerminalQuickFixExecuteTerminalCommand: extHostTypes.TerminalQuickFixCommand,
TerminalQuickFixOpener: extHostTypes.TerminalQuickFixOpener,
TerminalLocation: extHostTypes.TerminalLocation,
TerminalProfile: extHostTypes.TerminalProfile,
Expand Down
27 changes: 22 additions & 5 deletions src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,9 @@ import { CandidatePort } from 'vs/workbench/services/remote/common/tunnelModel';
import { ITextQueryBuilderOptions } from 'vs/workbench/services/search/common/queryBuilder';
import * as search from 'vs/workbench/services/search/common/search';
import { ISaveProfileResult } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
import { TerminalCommandMatchResult, TerminalQuickFixCommand, TerminalQuickFixOpener } from 'vscode';
import { IChatMessage, IChatResponseFragment, IChatResponseProviderMetadata } from 'vs/workbench/contrib/chat/common/chatProvider';
import { IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands';

export type TerminalQuickFix = TerminalQuickFixCommand | TerminalQuickFixOpener;


export interface IWorkspaceData extends IStaticWorkspaceData {
folders: { uri: UriComponents; name: string; index: number }[];
}
Expand Down Expand Up @@ -2033,6 +2029,27 @@ export interface ITerminalDimensionsDto {
rows: number;
}

type SingleOrMany<T> = T[] | T;

export interface ITerminalQuickFixExecuteTerminalCommandDto {
terminalCommand: string;
}

export interface ITerminalQuickFixOpenerDto {
uri: UriComponents;
}

export type TerminalQuickFix = ITerminalQuickFixExecuteTerminalCommandDto | ITerminalQuickFixOpenerDto | ICommandDto;

export interface TerminalCommandMatchResultDto {
commandLine: string;
commandLineMatch: RegExpMatchArray;
outputMatch?: {
regexMatch: RegExpMatchArray;
outputLines: string[];
};
}

export interface ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason): void;
$acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfig: IShellLaunchConfigDto): void;
Expand All @@ -2057,7 +2074,7 @@ export interface ExtHostTerminalServiceShape {
$initEnvironmentVariableCollections(collections: [string, ISerializableEnvironmentVariableCollection][]): void;
$acceptDefaultProfile(profile: ITerminalProfile, automationProfile: ITerminalProfile): void;
$createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise<void>;
$provideTerminalQuickFixes(id: string, matchResult: TerminalCommandMatchResult, token: CancellationToken): Promise<TerminalQuickFix[] | TerminalQuickFix | undefined>;
$provideTerminalQuickFixes(id: string, matchResult: TerminalCommandMatchResultDto, token: CancellationToken): Promise<SingleOrMany<TerminalQuickFix> | undefined>;
}

export interface ExtHostSCMShape {
Expand Down
36 changes: 28 additions & 8 deletions src/vs/workbench/api/common/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

import type * as vscode from 'vscode';
import { Event, Emitter } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, ITerminalDimensionsDto, ITerminalLinkDto, ExtHostTerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, ITerminalDimensionsDto, ITerminalLinkDto, ExtHostTerminalIdentifier, ICommandDto, ITerminalQuickFixOpenerDto, ITerminalQuickFixExecuteTerminalCommandDto, TerminalCommandMatchResultDto } from 'vs/workbench/api/common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable, DisposableStore, Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType, TerminalExitReason } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { localize } from 'vs/nls';
Expand All @@ -23,8 +23,9 @@ import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBu
import { ThemeColor } from 'vs/base/common/themables';
import { Promises } from 'vs/base/common/async';
import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { ViewColumn } from 'vs/workbench/api/common/extHostTypeConverters';
import { TerminalQuickFix, ViewColumn } from 'vs/workbench/api/common/extHostTypeConverters';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';

export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, IDisposable {

Expand Down Expand Up @@ -365,6 +366,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
protected _environmentVariableCollections: Map<string, UnifiedEnvironmentVariableCollection> = new Map();
private _defaultProfile: ITerminalProfile | undefined;
private _defaultAutomationProfile: ITerminalProfile | undefined;
private _lastQuickFixCommands: MutableDisposable<IDisposable> = this._register(new MutableDisposable());

private readonly _bufferer: TerminalDataBufferer;
private readonly _linkProviders: Set<vscode.TerminalLinkProvider> = new Set();
Expand Down Expand Up @@ -393,6 +395,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I

constructor(
supportsProcesses: boolean,
@IExtHostCommands private readonly _extHostCommands: IExtHostCommands,
@IExtHostRpcService extHostRpc: IExtHostRpcService
) {
super();
Expand Down Expand Up @@ -690,7 +693,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
});
}

public async $provideTerminalQuickFixes(id: string, matchResult: vscode.TerminalCommandMatchResult): Promise<(vscode.TerminalQuickFixOpener | vscode.TerminalQuickFixCommand)[] | vscode.TerminalQuickFixOpener | vscode.TerminalQuickFixCommand | undefined> {
public async $provideTerminalQuickFixes(id: string, matchResult: TerminalCommandMatchResultDto): Promise<(ITerminalQuickFixExecuteTerminalCommandDto | ITerminalQuickFixOpenerDto | ICommandDto)[] | ITerminalQuickFixExecuteTerminalCommandDto | ITerminalQuickFixOpenerDto | ICommandDto | undefined> {
const token = new CancellationTokenSource().token;
if (token.isCancellationRequested) {
return;
Expand All @@ -700,11 +703,27 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
return;
}
const quickFixes = await provider.provideTerminalQuickFixes(matchResult, token);
if (quickFixes === null) {
if (quickFixes === null || (Array.isArray(quickFixes) && quickFixes.length === 0)) {
return undefined;
} else {
return quickFixes;
}

const store = new DisposableStore();
this._lastQuickFixCommands.value = store;

// Single
if (!Array.isArray(quickFixes)) {
return quickFixes ? TerminalQuickFix.from(quickFixes, this._extHostCommands.converter, store) : undefined;
}

// Many
const result = [];
for (const fix of quickFixes) {
const converted = TerminalQuickFix.from(fix, this._extHostCommands.converter, store);
if (converted) {
result.push(converted);
}
}
return result;
}

public async $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise<void> {
Expand Down Expand Up @@ -1110,9 +1129,10 @@ class ScopedEnvironmentVariableCollection implements vscode.EnvironmentVariableC

export class WorkerExtHostTerminalService extends BaseExtHostTerminalService {
constructor(
@IExtHostCommands extHostCommands: IExtHostCommands,
@IExtHostRpcService extHostRpc: IExtHostRpcService
) {
super(false, extHostRpc);
super(false, extHostCommands, extHostRpc);
}

public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
Expand Down
12 changes: 12 additions & 0 deletions src/vs/workbench/api/common/extHostTypeConverters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2197,3 +2197,15 @@ export namespace ChatMessageRole {
}
}
}

export namespace TerminalQuickFix {
export function from(quickFix: vscode.TerminalQuickFixExecuteTerminalCommand | vscode.TerminalQuickFixOpener | vscode.Command, converter: Command.ICommandsConverter, disposables: DisposableStore): extHostProtocol.ITerminalQuickFixExecuteTerminalCommandDto | extHostProtocol.ITerminalQuickFixOpenerDto | extHostProtocol.ICommandDto | undefined {
if ('terminalCommand' in quickFix) {
return { terminalCommand: quickFix.terminalCommand };
}
if ('uri' in quickFix) {
return { uri: quickFix.uri };
}
return converter.toInternal(quickFix, disposables);
}
}
4 changes: 3 additions & 1 deletion src/vs/workbench/api/node/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { generateUuid } from 'vs/base/common/uuid';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { BaseExtHostTerminalService, ExtHostTerminal, ITerminalInternalOptions } from 'vs/workbench/api/common/extHostTerminalService';
import type * as vscode from 'vscode';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';

export class ExtHostTerminalService extends BaseExtHostTerminalService {

constructor(
@IExtHostCommands extHostCommands: IExtHostCommands,
@IExtHostRpcService extHostRpc: IExtHostRpcService
) {
super(true, extHostRpc);
super(true, extHostCommands, extHostRpc);
}

public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
Expand Down
6 changes: 4 additions & 2 deletions src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ declare module 'vscode' {

// https://github.com/microsoft/vscode/issues/162950

export type SingleOrMany<T> = T[] | T;

export interface TerminalQuickFixProvider {
/**
* Provides terminal quick fixes
* @param commandMatchResult The command match result for which to provide quick fixes
* @param token A cancellation token indicating the result is no longer needed
* @return Terminal quick fix(es) if any
*/
provideTerminalQuickFixes(commandMatchResult: TerminalCommandMatchResult, token: CancellationToken): ProviderResult<(TerminalQuickFixCommand | TerminalQuickFixOpener)[] | TerminalQuickFixCommand | TerminalQuickFixOpener>;
provideTerminalQuickFixes(commandMatchResult: TerminalCommandMatchResult, token: CancellationToken): ProviderResult<SingleOrMany<TerminalQuickFixExecuteTerminalCommand | TerminalQuickFixOpener | Command>>;
}


Expand All @@ -35,7 +37,7 @@ declare module 'vscode' {
export function registerTerminalQuickFixProvider(id: string, provider: TerminalQuickFixProvider): Disposable;
}

export class TerminalQuickFixCommand {
export class TerminalQuickFixExecuteTerminalCommand {
/**
* The terminal command to run
*/
Expand Down

0 comments on commit c5702cd

Please sign in to comment.