mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
quick fix API polish (#168688)
* fix #167649
* Update src/vs/platform/terminal/common/xterm/terminalQuickFix.ts
* fix #167652
* add builtin everywhere for consistency
* fix #167621 and fix #167646
* get rid of type in api
* fix #167584
* fix #167587
* fix #167587
* fix #167590 and fix #167557
* Revert "fix #167652"
This reverts commit cf4cc72790
.
* Update src/vs/workbench/contrib/terminal/common/terminal.ts
Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
* Update src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts
Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
* use const enum + more
* use classes
* update npm package.json
* add example for outputMatcher
* improve description
Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
parent
f99a293cef
commit
3e9bfdddc0
|
@ -346,13 +346,12 @@
|
||||||
{
|
{
|
||||||
"id": "ms-vscode.npm-command",
|
"id": "ms-vscode.npm-command",
|
||||||
"commandLineMatcher": "npm",
|
"commandLineMatcher": "npm",
|
||||||
"exitStatus": false,
|
"commandExitResult": "error",
|
||||||
"outputMatcher": {
|
"outputMatcher": {
|
||||||
"anchor": "bottom",
|
"anchor": "bottom",
|
||||||
"length": 8,
|
"length": 8,
|
||||||
"lineMatcher": "Did you mean (?:this|one of these)\\?((?:\\n.+?npm .+ #.+)+)",
|
"lineMatcher": "Did you mean (?:this|one of these)\\?((?:\\n.+?npm .+ #.+)+)",
|
||||||
"offset": 2,
|
"offset": 2
|
||||||
"multipleMatches": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -78,7 +78,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = outputMatch.regexMatch[1];
|
const lines = outputMatch.regexMatch[1];
|
||||||
const fixes: vscode.TerminalQuickFixCommandAction[] = [];
|
const fixes: vscode.TerminalQuickFixCommand[] = [];
|
||||||
for (const line of lines.split('\n')) {
|
for (const line of lines.split('\n')) {
|
||||||
// search from the second char, since the lines might be prefixed with
|
// search from the second char, since the lines might be prefixed with
|
||||||
// "npm ERR!" which comes before the actual command suggestion.
|
// "npm ERR!" which comes before the actual command suggestion.
|
||||||
|
@ -88,10 +88,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
const end = line.lastIndexOf('#');
|
const end = line.lastIndexOf('#');
|
||||||
fixes.push({
|
fixes.push({ terminalCommand: line.slice(begin, end === -1 ? undefined : end - 1) });
|
||||||
type: vscode.TerminalQuickFixType.command,
|
|
||||||
terminalCommand: line.slice(begin, end === -1 ? undefined : end - 1)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fixes;
|
return fixes;
|
||||||
|
|
|
@ -674,9 +674,6 @@ function getOutputMatchForCommand(executedMarker: IMarker | undefined, endMarker
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
match = lines.join('\n').match(matcher);
|
match = lines.join('\n').match(matcher);
|
||||||
if (!outputMatcher.multipleMatches && match) {
|
|
||||||
return { regexMatch: match };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -693,9 +690,6 @@ function getOutputMatchForCommand(executedMarker: IMarker | undefined, endMarker
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
match = lines.join('\n').match(matcher);
|
match = lines.join('\n').match(matcher);
|
||||||
if (!outputMatcher.multipleMatches && match) {
|
|
||||||
return { regexMatch: match };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,12 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||||
|
|
||||||
|
export enum TerminalQuickFixType {
|
||||||
|
Command = 0,
|
||||||
|
Opener = 1,
|
||||||
|
Port = 2
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITerminalCommandSelector {
|
export interface ITerminalCommandSelector {
|
||||||
id: string;
|
id: string;
|
||||||
commandLineMatcher: string | RegExp;
|
commandLineMatcher: string | RegExp;
|
||||||
|
@ -26,19 +32,19 @@ export interface ITerminalQuickFixOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITerminalQuickFix {
|
export interface ITerminalQuickFix {
|
||||||
type: 'command' | 'opener';
|
type: TerminalQuickFixType;
|
||||||
id: string;
|
id: string;
|
||||||
source: string;
|
source: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITerminalQuickFixCommandAction extends ITerminalQuickFix {
|
export interface ITerminalQuickFixCommandAction extends ITerminalQuickFix {
|
||||||
type: 'command';
|
type: TerminalQuickFixType.Command;
|
||||||
terminalCommand: string;
|
terminalCommand: string;
|
||||||
// TODO: Should this depend on whether alt is held?
|
// TODO: Should this depend on whether alt is held?
|
||||||
addNewLine?: boolean;
|
addNewLine?: boolean;
|
||||||
}
|
}
|
||||||
export interface ITerminalQuickFixOpenerAction extends ITerminalQuickFix {
|
export interface ITerminalQuickFixOpenerAction extends ITerminalQuickFix {
|
||||||
type: 'opener';
|
type: TerminalQuickFixType.Opener;
|
||||||
uri: URI;
|
uri: URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +75,7 @@ export interface ITerminalCommandMatchResult {
|
||||||
|
|
||||||
export interface ITerminalOutputMatch {
|
export interface ITerminalOutputMatch {
|
||||||
regexMatch: RegExpMatchArray;
|
regexMatch: RegExpMatchArray;
|
||||||
outputLines?: string[];
|
outputLines: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInternalOptions extends ITerminalQuickFixOptions {
|
export interface IInternalOptions extends ITerminalQuickFixOptions {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { DisposableStore, Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
import { DisposableStore, Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, TerminalLaunchConfig, ITerminalDimensionsDto, ExtHostTerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol';
|
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, TerminalLaunchConfig, ITerminalDimensionsDto, ExtHostTerminalIdentifier, TerminalQuickFix } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||||
|
@ -20,13 +20,14 @@ import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminal
|
||||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
import { OperatingSystem, OS } from 'vs/base/common/platform';
|
import { OperatingSystem, OS } from 'vs/base/common/platform';
|
||||||
import { TerminalEditorLocationOptions, TerminalQuickFix, TerminalQuickFixOpenerAction } from 'vscode';
|
import { TerminalEditorLocationOptions } from 'vscode';
|
||||||
import { Promises } from 'vs/base/common/async';
|
import { Promises } from 'vs/base/common/async';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||||
import { ITerminalOutputMatch, ITerminalOutputMatcher, ITerminalQuickFix, ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { ITerminalOutputMatch, ITerminalOutputMatcher, ITerminalQuickFix, ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes';
|
import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes';
|
||||||
|
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
|
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
|
||||||
export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
|
export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
|
||||||
|
|
||||||
|
@ -456,12 +457,14 @@ class ExtensionTerminalLinkProvider implements ITerminalExternalLinkProvider {
|
||||||
|
|
||||||
export function getOutputMatchForLines(lines: string[], outputMatcher: ITerminalOutputMatcher): ITerminalOutputMatch | undefined {
|
export function getOutputMatchForLines(lines: string[], outputMatcher: ITerminalOutputMatcher): ITerminalOutputMatch | undefined {
|
||||||
const match: RegExpMatchArray | null | undefined = lines.join('\n').match(outputMatcher.lineMatcher);
|
const match: RegExpMatchArray | null | undefined = lines.join('\n').match(outputMatcher.lineMatcher);
|
||||||
return match ? { regexMatch: match, outputLines: outputMatcher.multipleMatches ? lines : undefined } : undefined;
|
return match ? { regexMatch: match, outputLines: lines } : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseQuickFix(id: string, source: string, fix: TerminalQuickFix): ITerminalQuickFix {
|
function parseQuickFix(id: string, source: string, fix: TerminalQuickFix): ITerminalQuickFix {
|
||||||
if (fix.type === TerminalQuickFixType.opener) {
|
let type = TerminalQuickFixType.Command;
|
||||||
(fix as TerminalQuickFixOpenerAction).uri = URI.revive((fix as TerminalQuickFixOpenerAction).uri);
|
if ('uri' in fix) {
|
||||||
|
fix.uri = URI.revive(fix.uri);
|
||||||
|
type = TerminalQuickFixType.Opener;
|
||||||
}
|
}
|
||||||
return { id, source, ...fix };
|
return { id, type, source, ...fix };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1315,6 +1315,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||||
TaskRevealKind: extHostTypes.TaskRevealKind,
|
TaskRevealKind: extHostTypes.TaskRevealKind,
|
||||||
TaskScope: extHostTypes.TaskScope,
|
TaskScope: extHostTypes.TaskScope,
|
||||||
TerminalLink: extHostTypes.TerminalLink,
|
TerminalLink: extHostTypes.TerminalLink,
|
||||||
|
TerminalQuickFixCommand: extHostTypes.TerminalQuickFixCommand,
|
||||||
|
TerminalQuickFixOpener: extHostTypes.TerminalQuickFixOpener,
|
||||||
TerminalLocation: extHostTypes.TerminalLocation,
|
TerminalLocation: extHostTypes.TerminalLocation,
|
||||||
TerminalProfile: extHostTypes.TerminalProfile,
|
TerminalProfile: extHostTypes.TerminalProfile,
|
||||||
TerminalExitReason: extHostTypes.TerminalExitReason,
|
TerminalExitReason: extHostTypes.TerminalExitReason,
|
||||||
|
|
|
@ -70,7 +70,10 @@ import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplore
|
||||||
import { ITextQueryBuilderOptions } from 'vs/workbench/services/search/common/queryBuilder';
|
import { ITextQueryBuilderOptions } from 'vs/workbench/services/search/common/queryBuilder';
|
||||||
import * as search from 'vs/workbench/services/search/common/search';
|
import * as search from 'vs/workbench/services/search/common/search';
|
||||||
import { EditSessionIdentityMatch } from 'vs/platform/workspace/common/editSessions';
|
import { EditSessionIdentityMatch } from 'vs/platform/workspace/common/editSessions';
|
||||||
import { TerminalCommandMatchResult, TerminalQuickFix } from 'vscode';
|
import { TerminalCommandMatchResult, TerminalQuickFixCommand, TerminalQuickFixOpener } from 'vscode';
|
||||||
|
|
||||||
|
export type TerminalQuickFix = TerminalQuickFixCommand | TerminalQuickFixOpener;
|
||||||
|
|
||||||
|
|
||||||
export interface IWorkspaceData extends IStaticWorkspaceData {
|
export interface IWorkspaceData extends IStaticWorkspaceData {
|
||||||
folders: { uri: UriComponents; name: string; index: number }[];
|
folders: { uri: UriComponents; name: string; index: number }[];
|
||||||
|
|
|
@ -679,7 +679,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $provideTerminalQuickFixes(id: string, matchResult: vscode.TerminalCommandMatchResult): Promise<vscode.TerminalQuickFix[] | vscode.TerminalQuickFix | undefined> {
|
public async $provideTerminalQuickFixes(id: string, matchResult: vscode.TerminalCommandMatchResult): Promise<(vscode.TerminalQuickFixOpener | vscode.TerminalQuickFixCommand)[] | vscode.TerminalQuickFixOpener | vscode.TerminalQuickFixCommand | undefined> {
|
||||||
const token = new CancellationTokenSource().token;
|
const token = new CancellationTokenSource().token;
|
||||||
if (token.isCancellationRequested) {
|
if (token.isCancellationRequested) {
|
||||||
return;
|
return;
|
||||||
|
@ -688,7 +688,12 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return provider.provideTerminalQuickFixes(matchResult, token);
|
const quickFixes = await provider.provideTerminalQuickFixes(matchResult, token);
|
||||||
|
if (quickFixes === null) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return quickFixes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise<void> {
|
public async $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise<void> {
|
||||||
|
|
|
@ -46,13 +46,13 @@ function es5ClassCompat(target: Function): any {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TerminalOutputAnchor {
|
export enum TerminalOutputAnchor {
|
||||||
top = 'top',
|
Top = 0,
|
||||||
bottom = 'bottom'
|
Bottom = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TerminalQuickFixType {
|
export enum TerminalQuickFixType {
|
||||||
command = 'command',
|
Command = 0,
|
||||||
opener = 'opener'
|
Opener = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@es5ClassCompat
|
@es5ClassCompat
|
||||||
|
@ -1926,6 +1926,20 @@ export class TerminalLink implements vscode.TerminalLink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TerminalQuickFixOpener {
|
||||||
|
uri: vscode.Uri;
|
||||||
|
constructor(uri: vscode.Uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TerminalQuickFixCommand {
|
||||||
|
terminalCommand: string;
|
||||||
|
constructor(terminalCommand: string) {
|
||||||
|
this.terminalCommand = terminalCommand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export enum TerminalLocation {
|
export enum TerminalLocation {
|
||||||
Panel = 1,
|
Panel = 1,
|
||||||
Editor = 2,
|
Editor = 2,
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IInternalOptions, ITerminalCommandMatchResult, TerminalQuickFixActionInternal } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { IInternalOptions, ITerminalCommandMatchResult, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { TerminalQuickFixType } from 'vs/workbench/contrib/terminal/browser/widgets/terminalQuickFixMenuItems';
|
|
||||||
|
|
||||||
export const GitCommandLineRegex = /git/;
|
export const GitCommandLineRegex = /git/;
|
||||||
export const GitPushCommandLineRegex = /git\s+push/;
|
export const GitPushCommandLineRegex = /git\s+push/;
|
||||||
|
@ -20,6 +19,10 @@ export const GitPushOutputRegex = /git push --set-upstream origin (?<branchName>
|
||||||
// it's safe to assume it's a github pull request if the URL includes `/pull/`
|
// it's safe to assume it's a github pull request if the URL includes `/pull/`
|
||||||
export const GitCreatePrOutputRegex = /remote:\s*(?<link>https:\/\/github\.com\/.+\/.+\/pull\/new\/.+)/;
|
export const GitCreatePrOutputRegex = /remote:\s*(?<link>https:\/\/github\.com\/.+\/.+\/pull\/new\/.+)/;
|
||||||
|
|
||||||
|
export const enum QuickFixSource {
|
||||||
|
Builtin = 'builtin'
|
||||||
|
}
|
||||||
|
|
||||||
export function gitSimilar(): IInternalOptions {
|
export function gitSimilar(): IInternalOptions {
|
||||||
return {
|
return {
|
||||||
id: 'Git Similar',
|
id: 'Git Similar',
|
||||||
|
@ -46,7 +49,7 @@ export function gitSimilar(): IInternalOptions {
|
||||||
type: TerminalQuickFixType.Command,
|
type: TerminalQuickFixType.Command,
|
||||||
terminalCommand: matchResult.commandLine.replace(/git\s+[^\s]+/, () => `git ${fixedCommand}`),
|
terminalCommand: matchResult.commandLine.replace(/git\s+[^\s]+/, () => `git ${fixedCommand}`),
|
||||||
addNewLine: true,
|
addNewLine: true,
|
||||||
source: 'builtin'
|
source: QuickFixSource.Builtin
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +80,7 @@ export function gitTwoDashes(): IInternalOptions {
|
||||||
id: 'Git Two Dashes',
|
id: 'Git Two Dashes',
|
||||||
terminalCommand: matchResult.commandLine.replace(` -${problemArg}`, () => ` --${problemArg}`),
|
terminalCommand: matchResult.commandLine.replace(` -${problemArg}`, () => ` --${problemArg}`),
|
||||||
addNewLine: true,
|
addNewLine: true,
|
||||||
source: 'builtin'
|
source: QuickFixSource.Builtin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -101,11 +104,13 @@ export function freePort(terminalInstance?: Partial<ITerminalInstance>): IIntern
|
||||||
}
|
}
|
||||||
const label = localize("terminal.freePort", "Free port {0}", port);
|
const label = localize("terminal.freePort", "Free port {0}", port);
|
||||||
return {
|
return {
|
||||||
class: TerminalQuickFixType.Port,
|
type: TerminalQuickFixType.Port,
|
||||||
|
class: undefined,
|
||||||
tooltip: label,
|
tooltip: label,
|
||||||
id: 'Free Port',
|
id: 'Free Port',
|
||||||
label,
|
label,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
source: QuickFixSource.Builtin,
|
||||||
run: async () => {
|
run: async () => {
|
||||||
await terminalInstance?.freePortKillProcess?.(port, matchResult.commandLine);
|
await terminalInstance?.freePortKillProcess?.(port, matchResult.commandLine);
|
||||||
}
|
}
|
||||||
|
@ -147,11 +152,11 @@ export function gitPushSetUpstream(): IInternalOptions {
|
||||||
}
|
}
|
||||||
if (fixedCommand) {
|
if (fixedCommand) {
|
||||||
actions.push({
|
actions.push({
|
||||||
type: 'command',
|
type: TerminalQuickFixType.Command,
|
||||||
id: 'Git Push Set Upstream',
|
id: 'Git Push Set Upstream',
|
||||||
terminalCommand: fixedCommand,
|
terminalCommand: fixedCommand,
|
||||||
addNewLine: true,
|
addNewLine: true,
|
||||||
source: 'builtin'
|
source: QuickFixSource.Builtin
|
||||||
});
|
});
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
@ -179,14 +184,12 @@ export function gitCreatePr(): IInternalOptions {
|
||||||
}
|
}
|
||||||
const label = localize("terminal.createPR", "Create PR {0}", link);
|
const label = localize("terminal.createPR", "Create PR {0}", link);
|
||||||
return {
|
return {
|
||||||
class: undefined,
|
|
||||||
tooltip: label,
|
|
||||||
id: 'Git Create Pr',
|
id: 'Git Create Pr',
|
||||||
label,
|
label,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'opener',
|
type: TerminalQuickFixType.Opener,
|
||||||
uri: URI.parse(link),
|
uri: URI.parse(link),
|
||||||
run: () => { }
|
source: QuickFixSource.Builtin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,21 +9,16 @@ import { CodeActionKind } from 'vs/editor/contrib/codeAction/common/types';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { ActionListItemKind, IListMenuItem } from 'vs/platform/actionWidget/browser/actionList';
|
import { ActionListItemKind, IListMenuItem } from 'vs/platform/actionWidget/browser/actionList';
|
||||||
import { IActionItem } from 'vs/platform/actionWidget/common/actionWidget';
|
import { IActionItem } from 'vs/platform/actionWidget/common/actionWidget';
|
||||||
|
import { TerminalQuickFixType } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { ITerminalAction } from 'vs/workbench/contrib/terminal/browser/xterm/quickFixAddon';
|
import { ITerminalAction } from 'vs/workbench/contrib/terminal/browser/xterm/quickFixAddon';
|
||||||
|
|
||||||
export const enum TerminalQuickFixType {
|
|
||||||
Command = 'command',
|
|
||||||
Opener = 'opener',
|
|
||||||
Port = 'port'
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TerminalQuickFix implements IActionItem {
|
export class TerminalQuickFix implements IActionItem {
|
||||||
action: ITerminalAction;
|
action: ITerminalAction;
|
||||||
type: string;
|
type: TerminalQuickFixType;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
source: string;
|
source: string;
|
||||||
constructor(action: ITerminalAction, type: string, source: string, title?: string, disabled?: boolean) {
|
constructor(action: ITerminalAction, type: TerminalQuickFixType, source: string, title?: string, disabled?: boolean) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.disabled = disabled;
|
this.disabled = disabled;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
@ -72,5 +67,4 @@ function getQuickFixIcon(quickFix: TerminalQuickFix): { codicon: Codicon } {
|
||||||
case TerminalQuickFixType.Port:
|
case TerminalQuickFixType.Port:
|
||||||
return { codicon: Codicon.debugDisconnect };
|
return { codicon: Codicon.debugDisconnect };
|
||||||
}
|
}
|
||||||
return { codicon: Codicon.lightBulb };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
|
||||||
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
|
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
|
||||||
import { IActionWidgetService } from 'vs/platform/actionWidget/browser/actionWidget';
|
import { IActionWidgetService } from 'vs/platform/actionWidget/browser/actionWidget';
|
||||||
import { ActionSet } from 'vs/platform/actionWidget/common/actionWidget';
|
import { ActionSet } from 'vs/platform/actionWidget/common/actionWidget';
|
||||||
import { TerminalQuickFix, TerminalQuickFixType, toMenuItems } from 'vs/workbench/contrib/terminal/browser/widgets/terminalQuickFixMenuItems';
|
import { TerminalQuickFix, toMenuItems } from 'vs/workbench/contrib/terminal/browser/widgets/terminalQuickFixMenuItems';
|
||||||
import { ITerminalQuickFixProviderSelector, ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { ITerminalQuickFixProviderSelector, ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { ITerminalQuickFixOptions, IResolvedExtensionOptions, IUnresolvedExtensionOptions, ITerminalCommandSelector, ITerminalQuickFix, IInternalOptions, ITerminalQuickFixCommandAction, ITerminalQuickFixOpenerAction } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { ITerminalQuickFixOptions, IResolvedExtensionOptions, IUnresolvedExtensionOptions, ITerminalCommandSelector, ITerminalQuickFix, IInternalOptions, ITerminalQuickFixCommandAction, ITerminalQuickFixOpenerAction, TerminalQuickFixType } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { getLinesForCommand } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability';
|
import { getLinesForCommand } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability';
|
||||||
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
|
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
|
@ -117,7 +117,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What's documentation do? Need a vscode command?
|
// TODO: What's documentation do? Need a vscode command?
|
||||||
const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFix(f, f.class || TerminalQuickFixType.Command, f.source, f.label));
|
const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFix(f, f.type, f.source, f.label));
|
||||||
const documentation = this._currentRenderContext.quickFixes.map(f => { return { id: f.source, title: f.label, tooltip: f.source }; });
|
const documentation = this._currentRenderContext.quickFixes.map(f => { return { id: f.source, title: f.label, tooltip: f.source }; });
|
||||||
const actionSet = {
|
const actionSet = {
|
||||||
// TODO: Documentation and actions are separate?
|
// TODO: Documentation and actions are separate?
|
||||||
|
@ -280,6 +280,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITerminalAction extends IAction {
|
export interface ITerminalAction extends IAction {
|
||||||
|
type: TerminalQuickFixType;
|
||||||
source: string;
|
source: string;
|
||||||
uri?: URI;
|
uri?: URI;
|
||||||
command?: string;
|
command?: string;
|
||||||
|
@ -336,10 +337,11 @@ export async function getQuickFixesForCommand(
|
||||||
const fix = quickFix as ITerminalQuickFixCommandAction;
|
const fix = quickFix as ITerminalQuickFixCommandAction;
|
||||||
const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand);
|
const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand);
|
||||||
action = {
|
action = {
|
||||||
|
type: TerminalQuickFixType.Command,
|
||||||
|
class: undefined,
|
||||||
source: quickFix.source,
|
source: quickFix.source,
|
||||||
id: quickFix.id,
|
id: quickFix.id,
|
||||||
label,
|
label,
|
||||||
class: quickFix.type,
|
|
||||||
enabled: true,
|
enabled: true,
|
||||||
run: () => {
|
run: () => {
|
||||||
onDidRequestRerunCommand?.fire({
|
onDidRequestRerunCommand?.fire({
|
||||||
|
@ -364,7 +366,8 @@ export async function getQuickFixesForCommand(
|
||||||
source: quickFix.source,
|
source: quickFix.source,
|
||||||
id: quickFix.id,
|
id: quickFix.id,
|
||||||
label,
|
label,
|
||||||
class: quickFix.type,
|
type: TerminalQuickFixType.Opener,
|
||||||
|
class: undefined,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
run: () => openerService.open(fix.uri),
|
run: () => openerService.open(fix.uri),
|
||||||
tooltip: label,
|
tooltip: label,
|
||||||
|
@ -372,23 +375,26 @@ export async function getQuickFixesForCommand(
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TerminalQuickFixType.Port: {
|
||||||
|
const fix = quickFix as ITerminalAction;
|
||||||
|
action = {
|
||||||
|
source: 'builtin',
|
||||||
|
type: fix.type,
|
||||||
|
id: fix.id,
|
||||||
|
label: fix.label,
|
||||||
|
class: fix.class,
|
||||||
|
enabled: fix.enabled,
|
||||||
|
run: () => {
|
||||||
|
fix.run();
|
||||||
|
},
|
||||||
|
tooltip: fix.tooltip
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action) {
|
||||||
|
fixes.push(action);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
const fix = quickFix as ITerminalAction;
|
|
||||||
action = {
|
|
||||||
source: 'builtin',
|
|
||||||
id: fix.id,
|
|
||||||
label: fix.label,
|
|
||||||
class: fix.class,
|
|
||||||
enabled: fix.enabled,
|
|
||||||
run: () => {
|
|
||||||
fix.run();
|
|
||||||
},
|
|
||||||
tooltip: fix.tooltip
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (action) {
|
|
||||||
fixes.push(action);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -741,7 +741,8 @@ export const terminalContributionsDescriptor: IExtensionPointDescriptor<ITermina
|
||||||
description: nls.localize('vscode.extension.contributes.terminal.quickFixes', "Defines quick fixes for terminals with shell integration enabled."),
|
description: nls.localize('vscode.extension.contributes.terminal.quickFixes', "Defines quick fixes for terminals with shell integration enabled."),
|
||||||
items: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['id', 'commandLineMatcher', 'outputMatcher', 'exitStatus'],
|
additionalProperties: false,
|
||||||
|
required: ['id', 'commandLineMatcher', 'outputMatcher', 'commandExitResult'],
|
||||||
defaultSnippets: [{
|
defaultSnippets: [{
|
||||||
body: {
|
body: {
|
||||||
id: '$1',
|
id: '$1',
|
||||||
|
@ -752,15 +753,15 @@ export const terminalContributionsDescriptor: IExtensionPointDescriptor<ITermina
|
||||||
}],
|
}],
|
||||||
properties: {
|
properties: {
|
||||||
id: {
|
id: {
|
||||||
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.id', "The ID of the quick fix."),
|
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.id', "The ID of the quick fix provider."),
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
commandLineMatcher: {
|
commandLineMatcher: {
|
||||||
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.commandLineMatcher', "The command line to match."),
|
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.commandLineMatcher', "The regular expression to test the command line against."),
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
outputMatcher: {
|
outputMatcher: {
|
||||||
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.outputMatcher', "The output to match, which provides groups of the form <group_name> to be referenced via ${group:group_name} in commandToRun and linkToOpen."),
|
markdownDescription: nls.localize('vscode.extension.contributes.terminal.quickFixes.outputMatcher', "The regular expression to test the output against, which provides groups to be referenced in terminalCommand and uri.\n\nFor example:\n\n `lineMatcher: /git push --set-upstream origin (?<branchName>[^\s]+)/;`\n\n`terminalCommand: 'git push --set-upstream origin ${group:branchName}';`\n"),
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['lineMatcher', 'anchor', 'offset', 'length'],
|
required: ['lineMatcher', 'anchor', 'offset', 'length'],
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -769,11 +770,11 @@ export const terminalContributionsDescriptor: IExtensionPointDescriptor<ITermina
|
||||||
type: 'string'
|
type: 'string'
|
||||||
},
|
},
|
||||||
anchor: {
|
anchor: {
|
||||||
description: 'Which side of the output to anchor the offset and length against',
|
description: 'Where the search should begin in the buffer',
|
||||||
enum: ['top', 'bottom']
|
enum: ['top', 'bottom']
|
||||||
},
|
},
|
||||||
offset: {
|
offset: {
|
||||||
description: 'How far from either the top or the bottom of the butter to start matching against.',
|
description: 'The number of lines vertically from the anchor in the buffer to start matching against',
|
||||||
type: 'number'
|
type: 'number'
|
||||||
},
|
},
|
||||||
length: {
|
length: {
|
||||||
|
@ -783,7 +784,7 @@ export const terminalContributionsDescriptor: IExtensionPointDescriptor<ITermina
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
commandExitResult: {
|
commandExitResult: {
|
||||||
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.commandExitResult', "The command result to match on"),
|
description: nls.localize('vscode.extension.contributes.terminal.quickFixes.commandExitResult', "The command exit result to match on"),
|
||||||
enum: ['success', 'error'],
|
enum: ['success', 'error'],
|
||||||
enumDescriptions: [
|
enumDescriptions: [
|
||||||
'The command exited with an exit code of zero.',
|
'The command exited with an exit code of zero.',
|
||||||
|
|
|
@ -12,19 +12,16 @@ declare module 'vscode' {
|
||||||
* @param token A cancellation token indicating the result is no longer needed
|
* @param token A cancellation token indicating the result is no longer needed
|
||||||
* @return Terminal quick fix(es) if any
|
* @return Terminal quick fix(es) if any
|
||||||
*/
|
*/
|
||||||
provideTerminalQuickFixes(commandMatchResult: TerminalCommandMatchResult, token: CancellationToken): TerminalQuickFix[] | TerminalQuickFix | undefined;
|
provideTerminalQuickFixes(commandMatchResult: TerminalCommandMatchResult, token: CancellationToken): ProviderResult<(TerminalQuickFixCommand | TerminalQuickFixOpener)[] | TerminalQuickFixCommand | TerminalQuickFixOpener>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TerminalQuickFix {
|
|
||||||
type: TerminalQuickFixType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TerminalCommandMatchResult {
|
export interface TerminalCommandMatchResult {
|
||||||
commandLine: string;
|
commandLine: string;
|
||||||
commandLineMatch: RegExpMatchArray;
|
commandLineMatch: RegExpMatchArray;
|
||||||
outputMatch?: {
|
outputMatch?: {
|
||||||
regexMatch: RegExpMatchArray;
|
regexMatch: RegExpMatchArray;
|
||||||
outputLines?: string[];
|
outputLines: string[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +33,19 @@ declare module 'vscode' {
|
||||||
export function registerTerminalQuickFixProvider(id: string, provider: TerminalQuickFixProvider): Disposable;
|
export function registerTerminalQuickFixProvider(id: string, provider: TerminalQuickFixProvider): Disposable;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TerminalQuickFixCommandAction extends TerminalQuickFix {
|
export class TerminalQuickFixCommand {
|
||||||
type: TerminalQuickFixType.command;
|
/**
|
||||||
|
* The terminal command to run
|
||||||
|
*/
|
||||||
terminalCommand: string;
|
terminalCommand: string;
|
||||||
|
constructor(terminalCommand: string);
|
||||||
}
|
}
|
||||||
export interface TerminalQuickFixOpenerAction extends TerminalQuickFix {
|
export class TerminalQuickFixOpener {
|
||||||
type: TerminalQuickFixType.opener;
|
/**
|
||||||
|
* The uri to open
|
||||||
|
*/
|
||||||
uri: Uri;
|
uri: Uri;
|
||||||
|
constructor(uri: Uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,21 +70,15 @@ declare module 'vscode' {
|
||||||
* reasons. This is capped at 40.
|
* reasons. This is capped at 40.
|
||||||
*/
|
*/
|
||||||
length: number;
|
length: number;
|
||||||
|
|
||||||
/**
|
|
||||||
* If multiple matches are expected - this will result in {@link outputLines} being returned
|
|
||||||
* when there's a {@link regexMatch} from {@link offset} to {@link length}
|
|
||||||
*/
|
|
||||||
multipleMatches?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TerminalOutputAnchor {
|
enum TerminalOutputAnchor {
|
||||||
top = 'top',
|
Top = 0,
|
||||||
bottom = 'bottom'
|
Bottom = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TerminalQuickFixType {
|
enum TerminalQuickFixType {
|
||||||
command = 'command',
|
Command = 0,
|
||||||
opener = 'opener'
|
Opener = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue