Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explain quick fix kind #190969

Merged
merged 3 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,7 @@ export interface ITerminalCommandSelector {
outputMatcher?: ITerminalOutputMatcher;
exitStatus: boolean;
commandExitResult: 'success' | 'error';
kind?: 'fix' | 'explain';
}

export interface ITerminalBackend {
Expand Down
7 changes: 6 additions & 1 deletion src/vs/workbench/contrib/terminal/browser/media/terminal.css
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,12 @@
}
.monaco-workbench .terminal .terminal-command-decoration.quick-fix {
color: var(--vscode-editorLightBulb-foreground) !important;
background-color: var(--vscode-terminal-background, --vscode-panel-background);
background-color: var(--vscode-terminal-background, var(--vscode-panel-background));
}
.monaco-workbench .terminal .terminal-command-decoration.quick-fix.explainOnly {
/* Use success background to blend in with the terminal better as it's lower priority. We will
* probably want to add an explicit color for this eventually. */
color: var(--vscode-terminalCommandDecoration-successBackground) !important;
}

.terminal-scroll-highlight {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export const enum DecorationSelector {
Codicon = 'codicon',
XtermDecoration = 'xterm-decoration',
OverviewRuler = '.xterm-decoration-overview-ruler',
QuickFix = 'quick-fix',
LightBulb = 'codicon-light-bulb'
QuickFix = 'quick-fix'
}

export class TerminalDecorationHoverManager extends Disposable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface ITerminalQuickFixOptions {
commandLineMatcher: string | RegExp;
outputMatcher?: ITerminalOutputMatcher;
commandExitResult: 'success' | 'error';
kind?: 'fix' | 'explain';
}

export interface ITerminalQuickFix {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ import { Codicon } from 'vs/base/common/codicons';
import { ThemeIcon } from 'vs/base/common/themables';
import { ICommandService } from 'vs/platform/commands/common/commands';

const quickFixSelectors = [
const quickFixClasses = [
DecorationSelector.QuickFix,
DecorationSelector.LightBulb,
DecorationSelector.Codicon,
DecorationSelector.CommandDecoration,
DecorationSelector.XtermDecoration
Expand Down Expand Up @@ -116,7 +115,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
}

// TODO: What's documentation do? Need a vscode command?
const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFixItem(f, f.type, f.source, f.label));
const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFixItem(f, f.type, f.source, f.label, f.kind));
const documentation = this._currentRenderContext.quickFixes.map(f => { return { id: f.source, title: f.label, tooltip: f.source }; });
const actionSet = {
// TODO: Documentation and actions are separate?
Expand Down Expand Up @@ -150,7 +149,8 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
type: 'unresolved',
commandLineMatcher: selector.commandLineMatcher,
outputMatcher: selector.outputMatcher,
commandExitResult: selector.commandExitResult
commandExitResult: selector.commandExitResult,
kind: selector.kind
});
this._registeredSelectors.add(selector.id);
this._commandListeners.set(matcherKey, currentOptions);
Expand Down Expand Up @@ -192,7 +192,14 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
}
const id = selector.id;
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);
return this._quickFixService.providers.get(id)?.provideTerminalQuickFixes(command, lines, {
type: 'resolved',
commandLineMatcher: selector.commandLineMatcher,
outputMatcher: selector.outputMatcher,
commandExitResult: selector.commandExitResult,
kind: selector.kind,
id: selector.id
}, new CancellationTokenSource().token);
};
const result = await getQuickFixesForCommand(aliases, terminal, command, this._commandListeners, this._commandService, this._openerService, this._labelService, this._onDidRequestRerunCommand, resolver);
if (!result) {
Expand Down Expand Up @@ -266,7 +273,13 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,
return;
}

e.classList.add(...quickFixSelectors);
e.classList.add(...quickFixClasses);
const isExplainOnly = fixes.every(e => e.kind === 'explain');
if (isExplainOnly) {
e.classList.add('explainOnly');
}
e.classList.add(...ThemeIcon.asClassNameArray(isExplainOnly ? Codicon.sparkle : Codicon.lightBulb));

updateLayout(this._configurationService, e);
this._audioCueService.playAudioCue(AudioCue.terminalQuickFix);

Expand All @@ -285,6 +298,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon,

export interface ITerminalAction extends IAction {
type: TerminalQuickFixType;
kind?: 'fix' | 'explain';
source: string;
uri?: URI;
command?: string;
Expand Down Expand Up @@ -351,6 +365,7 @@ export async function getQuickFixesForCommand(
const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand);
action = {
type: TerminalQuickFixType.TerminalCommand,
kind: option.kind,
class: undefined,
source: quickFix.source,
id: quickFix.id,
Expand Down Expand Up @@ -384,6 +399,7 @@ export async function getQuickFixesForCommand(
id: quickFix.id,
label,
type: TerminalQuickFixType.Opener,
kind: option.kind,
class: undefined,
enabled: true,
run: () => openerService.open(fix.uri),
Expand All @@ -397,6 +413,7 @@ export async function getQuickFixesForCommand(
action = {
source: 'builtin',
type: fix.type,
kind: option.kind,
id: fix.id,
label: fix.label,
class: fix.class,
Expand All @@ -413,6 +430,7 @@ export async function getQuickFixesForCommand(
action = {
source: quickFix.source,
type: fix.type,
kind: option.kind,
id: fix.id,
label: fix.title,
class: undefined,
Expand Down Expand Up @@ -441,22 +459,20 @@ function convertToQuickFixOptions(selectorProvider: ITerminalQuickFixProviderSel
commandLineMatcher: selectorProvider.selector.commandLineMatcher,
outputMatcher: selectorProvider.selector.outputMatcher,
commandExitResult: selectorProvider.selector.commandExitResult,
kind: selectorProvider.selector.kind,
getQuickFixes: selectorProvider.provider.provideTerminalQuickFixes
};
}

class TerminalQuickFixItem {
action: ITerminalAction;
type: TerminalQuickFixType;
disabled?: boolean;
title?: string;
source: string;
constructor(action: ITerminalAction, type: TerminalQuickFixType, source: string, title?: string, disabled?: boolean) {
this.action = action;
this.disabled = disabled;
this.title = title;
this.source = source;
this.type = type;
readonly disabled = false;
constructor(
readonly action: ITerminalAction,
readonly type: TerminalQuickFixType,
readonly source: string,
readonly title: string | undefined,
readonly kind: 'fix' | 'explain' = 'fix'
) {
}
}

Expand Down Expand Up @@ -488,6 +504,9 @@ function toActionWidgetItems(inputQuickFixes: readonly TerminalQuickFixItem[], s
}

function getQuickFixIcon(quickFix: TerminalQuickFixItem): ThemeIcon {
if (quickFix.kind === 'explain') {
return Codicon.sparkle;
}
switch (quickFix.type) {
case TerminalQuickFixType.Opener:
if ('uri' in quickFix.action && quickFix.action.uri) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ const quickFixExtensionPoint = ExtensionsRegistry.registerExtensionPoint<ITermin
'The command exited with an exit code of zero.',
'The command exited with a non-zero exit code.'
]
},
kind: {
description: localize('vscode.extension.contributes.terminalQuickFixes.kind', "The kind of the resulting quick fix. This changes how the quick fix is presented. Defaults to {0}.", '`"fix"`'),
enum: ['default', 'explain'],
enumDescriptions: [
'A high confidence quick fix.',
'An explanation of the problem.'
]
}
},
}
Expand Down