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

44146 automatically show problems panel #71387

15 changes: 13 additions & 2 deletions src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,27 @@ const presentation: IJSONSchema = {
default: false,
description: nls.localize('JsonSchema.tasks.presentation.focus', 'Controls whether the panel takes focus. Default is false. If set to true the panel is revealed as well.')
},
revealProblem: {
type: 'string',
enum: ['always', 'onProblem', 'never'],
enumDescriptions: [
nls.localize('JsonSchema.tasks.presentation.revealProblem.always', 'Always reveals the problems panel when this task is executed.'),
nls.localize('JsonSchema.tasks.presentation.revealProblem.onProblem', 'Only reveals the problems panel if a problem is found.'),
nls.localize('JsonSchema.tasks.presentation.revealProblem.never', 'Never reveals the problems panel when this task is executed.'),
],
default: 'never',
description: nls.localize('JsonSchema.tasks.presentation.revealProblem', 'Controls whether the problems panel is revealed when running this task or not. Takes precedence over option \"reveal\". Default is \"never\".')
},
reveal: {
type: 'string',
enum: ['always', 'silent', 'never'],
enumDescriptions: [
nls.localize('JsonSchema.tasks.presentation.reveal.always', 'Always reveals the terminal when this task is executed.'),
nls.localize('JsonSchema.tasks.presentation.reveal.silent', 'Only reveals the terminal if the task exits with an error.'),
nls.localize('JsonSchema.tasks.presentation.reveal.silent', 'Only reveals the terminal if the task exits with an error or the problem matcher finds an error.'),
nls.localize('JsonSchema.tasks.presentation.reveal.never', 'Never reveals the terminal when this task is executed.'),
],
default: 'always',
description: nls.localize('JsonSchema.tasks.presentation.reveals', 'Controls whether the panel running the task is revealed or not. Default is \"always\".')
description: nls.localize('JsonSchema.tasks.presentation.reveals', 'Controls whether the panel running the task is revealed or not. May be overridden by option \"revealProblem\". Default is \"always\".')
},
panel: {
type: 'string',
Expand Down
16 changes: 13 additions & 3 deletions src/vs/workbench/contrib/tasks/common/taskConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ export interface PresentationOptionsConfig {
*/
reveal?: string;

/**
* Controls whether the problems panel is revealed when running this task or not.
* Defaults to `RevealKind.Never`.
*/
revealProblem?: string;

/**
* Controls whether the executed command is printed to the output window or terminal as well.
*/
Expand Down Expand Up @@ -796,7 +802,7 @@ namespace CommandOptions {
namespace CommandConfiguration {

export namespace PresentationOptions {
const properties: MetaData<Tasks.PresentationOptions, void>[] = [{ property: 'echo' }, { property: 'reveal' }, { property: 'focus' }, { property: 'panel' }, { property: 'showReuseMessage' }, { property: 'clear' }, { property: 'group' }];
const properties: MetaData<Tasks.PresentationOptions, void>[] = [{ property: 'echo' }, { property: 'reveal' }, { property: 'revealProblem' }, { property: 'focus' }, { property: 'panel' }, { property: 'showReuseMessage' }, { property: 'clear' }, { property: 'group' }];

interface PresentationOptionsShape extends LegacyCommandProperties {
presentation?: PresentationOptionsConfig;
Expand All @@ -805,6 +811,7 @@ namespace CommandConfiguration {
export function from(this: void, config: PresentationOptionsShape, context: ParseContext): Tasks.PresentationOptions | undefined {
let echo: boolean;
let reveal: Tasks.RevealKind;
let revealProblem: Tasks.RevealProblemKind;
let focus: boolean;
let panel: Tasks.PanelKind;
let showReuseMessage: boolean;
Expand All @@ -827,6 +834,9 @@ namespace CommandConfiguration {
if (Types.isString(presentation.reveal)) {
reveal = Tasks.RevealKind.fromString(presentation.reveal);
}
if (Types.isString(presentation.revealProblem)) {
revealProblem = Tasks.RevealProblemKind.fromString(presentation.revealProblem);
}
if (Types.isBoolean(presentation.focus)) {
focus = presentation.focus;
}
Expand All @@ -847,7 +857,7 @@ namespace CommandConfiguration {
if (!hasProps) {
return undefined;
}
return { echo: echo!, reveal: reveal!, focus: focus!, panel: panel!, showReuseMessage: showReuseMessage!, clear: clear!, group };
return { echo: echo!, reveal: reveal!, revealProblem: revealProblem!, focus: focus!, panel: panel!, showReuseMessage: showReuseMessage!, clear: clear!, group };
}

export function assignProperties(target: Tasks.PresentationOptions, source: Tasks.PresentationOptions | undefined): Tasks.PresentationOptions | undefined {
Expand All @@ -860,7 +870,7 @@ namespace CommandConfiguration {

export function fillDefaults(value: Tasks.PresentationOptions, context: ParseContext): Tasks.PresentationOptions | undefined {
let defaultEcho = context.engine === Tasks.ExecutionEngine.Terminal ? true : false;
return _fillDefaults(value, { echo: defaultEcho, reveal: Tasks.RevealKind.Always, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false }, properties, context);
return _fillDefaults(value, { echo: defaultEcho, reveal: Tasks.RevealKind.Always, revealProblem: Tasks.RevealProblemKind.Never, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false }, properties, context);
}

export function freeze(value: Tasks.PresentationOptions): Readonly<Tasks.PresentationOptions> | undefined {
Expand Down
47 changes: 44 additions & 3 deletions src/vs/workbench/contrib/tasks/common/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { UriComponents } from 'vs/base/common/uri';
import { ProblemMatcher } from 'vs/workbench/contrib/tasks/common/problemMatcher';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';

export const TASK_RUNNING_STATE = new RawContextKey<boolean>('taskRunning', false);

Expand Down Expand Up @@ -123,7 +123,9 @@ export enum RevealKind {

/**
* Only brings the terminal to front if a problem is detected executing the task
* (e.g. the task couldn't be started because).
* e.g. the task couldn't be started,
* the task ended with an exit code other than zero,
* or the problem matcher found an error.
*/
Silent = 2,

Expand All @@ -148,6 +150,39 @@ export namespace RevealKind {
}
}

export enum RevealProblemKind {
/**
* Never reveals the problems panel when this task is executed.
*/
Never = 1,


/**
* Only reveals the problems panel if a problem is found.
*/
OnProblem = 2,

/**
* Never reveals the problems panel when this task is executed.
*/
Always = 3
}

export namespace RevealProblemKind {
export function fromString(this: void, value: string): RevealProblemKind {
switch (value.toLowerCase()) {
case 'always':
return RevealProblemKind.Always;
case 'never':
return RevealProblemKind.Never;
case 'onproblem':
return RevealProblemKind.OnProblem;
default:
return RevealProblemKind.OnProblem;
}
}
}

export enum PanelKind {

/**
Expand Down Expand Up @@ -189,6 +224,12 @@ export interface PresentationOptions {
*/
reveal: RevealKind;

/**
* Controls whether the problems pane is revealed when running this task or not.
* Defaults to `RevealProblemKind.Never`.
*/
revealProblem: RevealProblemKind;

/**
* Controls whether the command associated with the task is echoed
* in the user interface.
Expand Down Expand Up @@ -225,7 +266,7 @@ export interface PresentationOptions {

export namespace PresentationOptions {
export const defaults: PresentationOptions = {
echo: true, reveal: RevealKind.Always, focus: false, panel: PanelKind.Shared, showReuseMessage: true, clear: false
echo: true, reveal: RevealKind.Always, revealProblem: RevealProblemKind.Never, focus: false, panel: PanelKind.Shared, showReuseMessage: true, clear: false
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ class TaskService extends Disposable implements ITaskService {
@IConfigurationService private readonly configurationService: IConfigurationService,
@IMarkerService private readonly markerService: IMarkerService,
@IOutputService private readonly outputService: IOutputService,
@IPanelService private readonly panelService: IPanelService,
@IEditorService private readonly editorService: IEditorService,
@IFileService private readonly fileService: IFileService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
Expand Down Expand Up @@ -1352,7 +1353,7 @@ class TaskService extends Disposable implements ITaskService {
}
if (this.executionEngine === ExecutionEngine.Terminal) {
this._taskSystem = new TerminalTaskSystem(
this.terminalService, this.outputService, this.markerService,
this.terminalService, this.outputService, this.panelService, this.markerService,
this.modelService, this.configurationResolverService, this.telemetryService,
this.contextService, this._windowService,
TaskService.OutputChannelId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/marke
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ProblemMatcher, ProblemMatcherRegistry /*, ProblemPattern, getResource */ } from 'vs/workbench/contrib/tasks/common/problemMatcher';
import Constants from 'vs/workbench/contrib/markers/browser/constants';

import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';

Expand All @@ -31,7 +32,7 @@ import { IOutputService } from 'vs/workbench/contrib/output/common/output';
import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind } from 'vs/workbench/contrib/tasks/common/problemCollectors';
import {
Task, CustomTask, ContributedTask, RevealKind, CommandOptions, ShellConfiguration, RuntimeType, PanelKind,
TaskEvent, TaskEventKind, ShellQuotingOptions, ShellQuoting, CommandString, CommandConfiguration, ExtensionTaskSource, TaskScope
TaskEvent, TaskEventKind, ShellQuotingOptions, ShellQuoting, CommandString, CommandConfiguration, ExtensionTaskSource, TaskScope, RevealProblemKind
} from 'vs/workbench/contrib/tasks/common/tasks';
import {
ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver,
Expand All @@ -42,6 +43,7 @@ import { URI } from 'vs/base/common/uri';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { Schemas } from 'vs/base/common/network';
import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';

interface TerminalData {
terminal: ITerminalInstance;
Expand Down Expand Up @@ -160,6 +162,7 @@ export class TerminalTaskSystem implements ITaskSystem {
private readonly _onDidStateChange: Emitter<TaskEvent>;

constructor(private terminalService: ITerminalService, private outputService: IOutputService,
private panelService: IPanelService,
private markerService: IMarkerService, private modelService: IModelService,
private configurationResolverService: IConfigurationResolverService,
private telemetryService: ITelemetryService,
Expand Down Expand Up @@ -514,11 +517,16 @@ export class TerminalTaskSystem implements ITaskSystem {
eventCounter--;
this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Inactive, task));
if (eventCounter === 0) {
let reveal = task.command.presentation!.reveal;
if ((reveal === RevealKind.Silent) && (watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity &&
if ((watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity &&
(watchingProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error)) {
this.terminalService.setActiveInstance(terminal!);
this.terminalService.showPanel(false);
let reveal = task.command.presentation!.reveal;
let revealProblem = task.command.presentation!.revealProblem;
if (revealProblem === RevealProblemKind.OnProblem) {
this.panelService.openPanel(Constants.MARKERS_PANEL_ID, true);
} else if (reveal === RevealKind.Silent) {
this.terminalService.setActiveInstance(terminal!);
this.terminalService.showPanel(false);
}
}
}
}
Expand Down Expand Up @@ -642,7 +650,11 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
let reveal = task.command.presentation!.reveal;
if (terminal && (reveal === RevealKind.Silent) && ((exitCode !== 0) || (startStopProblemMatcher.numberOfMatches > 0) && startStopProblemMatcher.maxMarkerSeverity &&
let revealProblem = task.command.presentation!.revealProblem;
let revealProblemPanel = terminal && (revealProblem === RevealProblemKind.OnProblem) && (startStopProblemMatcher.numberOfMatches > 0);
if (revealProblemPanel) {
this.panelService.openPanel(Constants.MARKERS_PANEL_ID);
} else if (terminal && (reveal === RevealKind.Silent) && ((exitCode !== 0) || (startStopProblemMatcher.numberOfMatches > 0) && startStopProblemMatcher.maxMarkerSeverity &&
(startStopProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error))) {
this.terminalService.setActiveInstance(terminal);
this.terminalService.showPanel(false);
Expand Down Expand Up @@ -673,7 +685,10 @@ export class TerminalTaskSystem implements ITaskSystem {
if (!terminal) {
return Promise.reject(new Error(`Failed to create terminal for task ${task._label}`));
}
if (task.command.presentation && (task.command.presentation.reveal === RevealKind.Always)) {
let showProblemPanel = task.command.presentation && (task.command.presentation.revealProblem === RevealProblemKind.Always);
if (showProblemPanel) {
this.panelService.openPanel(Constants.MARKERS_PANEL_ID);
} else if (task.command.presentation && (task.command.presentation.reveal === RevealKind.Always)) {
this.terminalService.setActiveInstance(terminal);
this.terminalService.showPanel(task.command.presentation.focus);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class PresentationBuilder {
public result: Tasks.PresentationOptions;

constructor(public parent: CommandConfigurationBuilder) {
this.result = { echo: false, reveal: Tasks.RevealKind.Always, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false };
this.result = { echo: false, reveal: Tasks.RevealKind.Always, revealProblem: Tasks.RevealProblemKind.Never, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false };
}

public echo(value: boolean): PresentationBuilder {
Expand Down