提交 8eccd643 编写于 作者: D Dirk Baeumer

Fixes #29913: Action to show and navigate to running tasks

上级 ce177da9
......@@ -913,9 +913,10 @@ export class CodeMenu {
private setTaskMenu(taskMenu: Electron.Menu): void {
const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask');
const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build');
const showTasks = this.createMenuItem(nls.localize({ key: 'miRunningTask', comment: ['&& denotes a mnemonic'] }, "Show Runnin&&g Tasks..."), 'workbench.action.tasks.showTasks');
const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Running Task..."), 'workbench.action.tasks.restartTask');
const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task..."), 'workbench.action.tasks.terminate');
const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "Run &&Build Task..."), 'workbench.action.tasks.build');
// const testTask = this.createMenuItem(nls.localize({ key: 'miTestTask', comment: ['&& denotes a mnemonic'] }, "Run Test T&&ask..."), 'workbench.action.tasks.test');
// const showTaskLog = this.createMenuItem(nls.localize({ key: 'miShowTaskLog', comment: ['&& denotes a mnemonic'] }, "&&Show Task Log"), 'workbench.action.tasks.showLog');
const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Tasks"), 'workbench.action.tasks.configureTaskRunner');
......@@ -930,6 +931,7 @@ export class CodeMenu {
__separator__(),
terminateTask,
restartTask,
showTasks,
__separator__(),
//showTaskLog,
configureTask,
......
......@@ -21,6 +21,7 @@ export namespace TaskServiceEvents {
export let Inactive: string = 'inactive';
export let ConfigChanged: string = 'configChanged';
export let Terminated: string = 'terminated';
export let Changed: string = 'changed';
}
export interface ITaskProvider {
......
......@@ -82,6 +82,7 @@ export namespace TaskSystemEvents {
export let Active: string = 'active';
export let Inactive: string = 'inactive';
export let Terminated: string = 'terminated';
export let Changed: string = 'changed';
}
export enum TaskType {
......@@ -113,4 +114,5 @@ export interface ITaskSystem extends IEventEmitter {
canAutoTerminate(): boolean;
terminate(id: string): TPromise<TaskTerminateResponse>;
terminateAll(): TPromise<TaskTerminateResponse[]>;
revealTask(task: Task): boolean;
}
\ No newline at end of file
......@@ -3,6 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.task-statusbar-runningItem {
display: inline-block;
}
.task-statusbar-runningItem-label {
display: inline-block;
cursor: pointer;
padding: 0 5px 0 5px;
}
.task-statusbar-item {
display: inline-block;
}
......
......@@ -263,7 +263,7 @@ class ViewTerminalAction extends Action {
}
}
class StatusBarItem extends Themable implements IStatusbarItem {
class BuildStatusBarItem extends Themable implements IStatusbarItem {
private intervalToken: any;
private activeCount: number;
private static progressChars: string = '|/-\\';
......@@ -309,7 +309,7 @@ class StatusBarItem extends Themable implements IStatusbarItem {
Dom.addClass(progress, 'task-statusbar-item-progress');
element.appendChild(progress);
progress.innerHTML = StatusBarItem.progressChars[0];
progress.innerHTML = BuildStatusBarItem.progressChars[0];
$(progress).hide();
Dom.addClass(label, 'task-statusbar-item-label');
......@@ -384,7 +384,7 @@ class StatusBarItem extends Themable implements IStatusbarItem {
this.activeCount++;
if (this.activeCount === 1) {
let index = 1;
let chars = StatusBarItem.progressChars;
let chars = BuildStatusBarItem.progressChars;
progress.innerHTML = chars[0];
this.intervalToken = setInterval(() => {
progress.innerHTML = chars[index];
......@@ -454,6 +454,69 @@ class StatusBarItem extends Themable implements IStatusbarItem {
}
}
class TaskStatusBarItem extends Themable implements IStatusbarItem {
constructor(
@IPanelService private panelService: IPanelService,
@IMarkerService private markerService: IMarkerService,
@IOutputService private outputService: IOutputService,
@ITaskService private taskService: ITaskService,
@IPartService private partService: IPartService,
@IThemeService themeService: IThemeService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
) {
super(themeService);
}
protected updateStyles(): void {
super.updateStyles();
}
public render(container: HTMLElement): IDisposable {
let callOnDispose: IDisposable[] = [];
const element = document.createElement('div');
const label = document.createElement('a');
Dom.addClass(element, 'task-statusbar-runningItem');
Dom.addClass(label, 'task-statusbar-runningItem-label');
element.appendChild(label);
element.title = nls.localize('runningTasks', "Show Running Tasks");
callOnDispose.push(Dom.addDisposableListener(label, 'click', (e: MouseEvent) => {
(this.taskService as TaskService).runShowTasks();
}));
let updateStatus = (): void => {
this.taskService.getActiveTasks().then(tasks => {
if (tasks.length === 0) {
label.innerHTML = nls.localize('nothingRunner', 'Running Tasks: 0');
} else if (tasks.length === 1) {
label.innerHTML = nls.localize('oneTasksRunnering', 'Running Tasks: 1');
} else {
label.innerHTML = nls.localize('nTasksRunnering', 'Running Tasks: {0}', tasks.length);
}
});
};
callOnDispose.push(this.taskService.addListener(TaskServiceEvents.Changed, (event: TaskEvent) => {
updateStatus();
}));
container.appendChild(element);
this.updateStyles();
updateStatus();
return {
dispose: () => {
callOnDispose = dispose(callOnDispose);
}
};
}
}
interface TaskServiceEventData {
error?: any;
}
......@@ -465,6 +528,9 @@ class NullTaskSystem extends EventEmitter implements ITaskSystem {
promise: TPromise.as<ITaskSummary>({})
};
}
public revealTask(task: Task): boolean {
return false;
}
public isActive(): TPromise<boolean> {
return TPromise.as(false);
}
......@@ -686,6 +752,10 @@ class TaskService extends EventEmitter implements ITaskService {
CommandsRegistry.registerCommand('workbench.action.tasks.configureDefaultTestTask', () => {
this.runConfigureDefaultTestTask();
});
CommandsRegistry.registerCommand('workbench.action.tasks.showTasks', () => {
this.runShowTasks();
});
}
private showOutput(): void {
......@@ -1189,6 +1259,7 @@ class TaskService extends EventEmitter implements ITaskService {
this._taskSystemListeners.push(this._taskSystem.addListener(TaskSystemEvents.Active, (event) => this.emit(TaskServiceEvents.Active, event)));
this._taskSystemListeners.push(this._taskSystem.addListener(TaskSystemEvents.Inactive, (event) => this.emit(TaskServiceEvents.Inactive, event)));
this._taskSystemListeners.push(this._taskSystem.addListener(TaskSystemEvents.Terminated, (event) => this.emit(TaskServiceEvents.Terminated, event)));
this._taskSystemListeners.push(this._taskSystem.addListener(TaskSystemEvents.Changed, () => this.emit(TaskServiceEvents.Changed)));
return this._taskSystem;
}
......@@ -1874,6 +1945,24 @@ class TaskService extends EventEmitter implements ITaskService {
this.configureAction().run();
}
}
public runShowTasks(): void {
if (!this.canRunCommand()) {
return;
}
if (!this._taskSystem) {
this.messageService.show(Severity.Info, nls.localize('TaskService.noTaskIsRunning', 'No task is running.'));
return;
}
this.getActiveTasks().then((tasks) => {
this.showQuickPick(tasks, nls.localize('TaskService.pickShowTask', 'Select the task to show its output'), false, true).then((task) => {
if (!task || !this._taskSystem) {
return;
}
this._taskSystem.revealTask(task);
});
});
}
}
......@@ -1883,6 +1972,7 @@ workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(Config
MenuRegistry.addCommand({ id: 'workbench.action.tasks.showLog', title: { value: nls.localize('ShowLogAction.label', "Show Task Log"), original: 'Show Task Log' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.runTask', title: { value: nls.localize('RunTaskAction.label', "Run Task"), original: 'Run Task' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.restartTask', title: { value: nls.localize('RestartTaskAction.label', "Restart Running Task"), original: 'Restart Running Task' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.showTasks', title: { value: nls.localize('ShowTasksAction.label', "Show Running Tasks"), original: 'Show Running Tasks' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.terminate', title: { value: nls.localize('TerminateAction.label', "Terminate Task"), original: 'Terminate Task' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.build', title: { value: nls.localize('BuildAction.label', "Run Build Task"), original: 'Run Build Task' }, category: { value: tasksCategory, original: 'Tasks' } });
MenuRegistry.addCommand({ id: 'workbench.action.tasks.test', title: { value: nls.localize('TestAction.label', "Run Test Task"), original: 'Run Test Task' }, category: { value: tasksCategory, original: 'Tasks' } });
......@@ -1913,7 +2003,8 @@ actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionCont
// Status bar
let statusbarRegistry = <IStatusbarRegistry>Registry.as(StatusbarExtensions.Statusbar);
statusbarRegistry.registerStatusbarItem(new StatusbarItemDescriptor(StatusBarItem, StatusbarAlignment.LEFT, 50 /* Medium Priority */));
statusbarRegistry.registerStatusbarItem(new StatusbarItemDescriptor(BuildStatusBarItem, StatusbarAlignment.LEFT, 50 /* Medium Priority */));
statusbarRegistry.registerStatusbarItem(new StatusbarItemDescriptor(TaskStatusBarItem, StatusbarAlignment.LEFT, 50 /* Medium Priority */));
// Output channel
let outputChannelRegistry = <IOutputChannelRegistry>Registry.as(OutputExt.OutputChannels);
......
......@@ -162,6 +162,17 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
}
}
public revealTask(task: Task): boolean {
let terminalData = this.activeTasks[task._id];
if (!terminalData) {
return false;
}
this.terminalService.setActiveInstance(terminalData.terminal);
this.terminalService.showPanel(task.command.presentation.focus);
return true;
}
public isActive(): TPromise<boolean> {
return TPromise.as(this.isActiveSync());
}
......@@ -301,6 +312,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
onData.dispose();
onExit.dispose();
delete this.activeTasks[task._id];
this.emit(TaskSystemEvents.Changed);
switch (task.command.presentation.panel) {
case PanelKind.Dedicated:
this.sameTaskTerminals[task._id] = terminal.id.toString();
......@@ -347,6 +359,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
onData.dispose();
onExit.dispose();
delete this.activeTasks[task._id];
this.emit(TaskSystemEvents.Changed);
switch (task.command.presentation.panel) {
case PanelKind.Dedicated:
this.sameTaskTerminals[task._id] = terminal.id.toString();
......@@ -372,6 +385,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
this.terminalService.showPanel(task.command.presentation.focus);
}
this.activeTasks[task._id] = { terminal, task, promise };
this.emit(TaskSystemEvents.Changed);
return promise.then((summary) => {
try {
let telemetryEvent: TelemetryEvent = {
......
......@@ -90,6 +90,11 @@ export class ProcessTaskSystem extends EventEmitter implements ITaskSystem {
return this.executeTask(task);
}
public revealTask(task: Task): boolean {
this.showOutput();
return true;
}
public hasErrors(value: boolean): void {
this.errorsShown = !value;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册