Skip to content

Commit

Permalink
refactor the task terminal widget option
Browse files Browse the repository at this point in the history
- opener options are passed from task extension to terminal extension as
part of the terminal widget option. It works but it should not be
implemented this way because opener options are not need to recreate
widgets. This change separates the widget options and opener options for
task terminal.
- resolves #7438

Signed-off-by: Liang Huang <lhuang4@ualberta.ca>
  • Loading branch information
elaihau committed Apr 5, 2020
1 parent 2c16d4e commit 2ccfa67
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 31 deletions.
29 changes: 14 additions & 15 deletions packages/task/src/browser/task-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import { TaskConfigurationManager } from './task-configuration-manager';
import { PROBLEMS_WIDGET_ID, ProblemWidget } from '@theia/markers/lib/browser/problem/problem-widget';
import { TaskNode } from './task-node';
import { MonacoWorkspace } from '@theia/monaco/lib/browser/monaco-workspace';
import { TaskTerminalWidgetManager, TaskTerminalWidgetOpenerOptions } from './task-terminal-widget-manager';
import { TaskTerminalWidgetManager } from './task-terminal-widget-manager';

export interface QuickPickProblemMatcherItem {
problemMatchers: NamedProblemMatcher[] | undefined;
Expand Down Expand Up @@ -1001,20 +1001,19 @@ export class TaskService implements TaskConfigurationClient {
}

// Create / find a terminal widget to display an execution output of a task that was launched as a command inside a shell.
const widget = await this.taskTerminalWidgetManager.open(
<TaskTerminalWidgetOpenerOptions>{
created: new Date().toString(),
taskId,
id: this.getTerminalWidgetId(terminalId),
title: taskInfo
? `Task: ${taskInfo.config.label}`
: `Task: #${taskId}`,
destroyTermOnClose: true,
widgetOptions: { area: 'bottom' },
mode: widgetOpenMode,
taskConfig: taskInfo ? taskInfo.config : undefined
}
);
const widget = await this.taskTerminalWidgetManager.open({
created: new Date().toString(),
id: this.getTerminalWidgetId(terminalId),
title: taskInfo
? `Task: ${taskInfo.config.label}`
: `Task: #${taskId}`,
destroyTermOnClose: true
}, {
taskId,
widgetOptions: { area: 'bottom' },
mode: widgetOpenMode,
taskConfig: taskInfo ? taskInfo.config : undefined
});
widget.start(terminalId);
}

Expand Down
34 changes: 18 additions & 16 deletions packages/task/src/browser/task-terminal-widget-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export namespace TaskTerminalWidget {
}
}

export interface TaskTerminalWidgetOpenerOptions extends WidgetOpenerOptions, TerminalWidgetFactoryOptions {
export interface TaskTerminalWidgetOpenerOptions extends WidgetOpenerOptions {
taskId: number;
taskConfig?: TaskConfiguration;
}
Expand Down Expand Up @@ -118,45 +118,47 @@ export class TaskTerminalWidgetManager {
});
}

async open(options: TaskTerminalWidgetOpenerOptions): Promise<TerminalWidget> {
const dedicated = TaskTerminalWidgetOpenerOptions.isDedicatedTerminal(options);
if (dedicated && !options.taskConfig) {
async open(factoryOptions: TerminalWidgetFactoryOptions, openerOptions: TaskTerminalWidgetOpenerOptions): Promise<TerminalWidget> {
const dedicated = TaskTerminalWidgetOpenerOptions.isDedicatedTerminal(openerOptions);
if (dedicated && !openerOptions.taskConfig) {
throw new Error('"taskConfig" must be included as part of the "option" if "isDedicated" is true');
}

const { isNew, widget } = await this.getWidgetToRunTask(options);
const { isNew, widget } = await this.getWidgetToRunTask(factoryOptions, openerOptions);
if (isNew) {
this.shell.addWidget(widget, { area: options.widgetOptions ? options.widgetOptions.area : 'bottom' });
this.shell.addWidget(widget, { area: openerOptions.widgetOptions ? openerOptions.widgetOptions.area : 'bottom' });
widget.resetTerminal();
} else {
if (options.title) {
widget.setTitle(options.title);
if (factoryOptions.title) {
widget.setTitle(factoryOptions.title);
}
if (options.taskConfig && TaskOutputPresentation.shouldClearTerminalBeforeRun(options.taskConfig)) {
if (openerOptions.taskConfig && TaskOutputPresentation.shouldClearTerminalBeforeRun(openerOptions.taskConfig)) {
widget.clearOutput();
}
}
this.terminalService.open(widget, options);
this.terminalService.open(widget, openerOptions);

return widget;
}

protected async getWidgetToRunTask(options: TaskTerminalWidgetOpenerOptions): Promise<{ isNew: boolean, widget: TerminalWidget }> {
protected async getWidgetToRunTask(
factoryOptions: TerminalWidgetFactoryOptions, openerOptions: TaskTerminalWidgetOpenerOptions
): Promise<{ isNew: boolean, widget: TerminalWidget }> {
let reusableTerminalWidget: TerminalWidget | undefined;
if (TaskTerminalWidgetOpenerOptions.isDedicatedTerminal(options)) {
if (TaskTerminalWidgetOpenerOptions.isDedicatedTerminal(openerOptions)) {
for (const widget of this.getTaskTerminalWidgets()) {
// to run a task whose `taskPresentation === 'dedicated'`, the terminal to be reused must be
// 1) dedicated, 2) idle, 3) the one that ran the same task
if (widget.dedicated &&
!widget.busy &&
widget.taskConfig && options.taskConfig &&
this.taskDefinitionRegistry.compareTasks(options.taskConfig, widget.taskConfig)) {
widget.taskConfig && openerOptions.taskConfig &&
this.taskDefinitionRegistry.compareTasks(openerOptions.taskConfig, widget.taskConfig)) {

reusableTerminalWidget = widget;
break;
}
}
} else if (TaskTerminalWidgetOpenerOptions.isSharedTerminal(options)) {
} else if (TaskTerminalWidgetOpenerOptions.isSharedTerminal(openerOptions)) {
const availableWidgets: TerminalWidget[] = [];
for (const widget of this.getTaskTerminalWidgets()) {
// to run a task whose `taskPresentation === 'shared'`, the terminal to be used must be
Expand All @@ -174,7 +176,7 @@ export class TaskTerminalWidgetManager {

// we are unable to find a terminal widget to run the task, or `taskPresentation === 'new'`
if (!reusableTerminalWidget) {
const widget = await this.terminalService.newTerminal({ ...options, kind: 'task' });
const widget = await this.terminalService.newTerminal({ ...factoryOptions, kind: 'task' });
return { isNew: true, widget };
}
return { isNew: false, widget: reusableTerminalWidget };
Expand Down

0 comments on commit 2ccfa67

Please sign in to comment.