diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index cf3c71bde9e6a..552ab5e1db69b 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -1319,10 +1319,19 @@ export interface TaskDto { problemMatcher?: any; group?: string; detail?: string; + presentation?: TaskPresentationOptionsDTO; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } +export interface TaskPresentationOptionsDTO { + reveal?: number; + focus?: boolean; + echo?: boolean; + panel?: number; + showReuseMessage?: boolean; +} + export interface TaskExecutionDto { id: number; task: TaskDto; diff --git a/packages/plugin-ext/src/main/browser/tasks-main.ts b/packages/plugin-ext/src/main/browser/tasks-main.ts index 28e1e83504225..7cb79fa8f839e 100644 --- a/packages/plugin-ext/src/main/browser/tasks-main.ts +++ b/packages/plugin-ext/src/main/browser/tasks-main.ts @@ -19,17 +19,40 @@ import { MAIN_RPC_CONTEXT, TaskExecutionDto, TasksExt, - TaskDto + TaskDto, + TaskPresentationOptionsDTO } from '../../common/plugin-api-rpc'; import { RPCProtocol } from '../../common/rpc-protocol'; import { Disposable, DisposableCollection } from '@theia/core/lib/common'; import { TaskProviderRegistry, TaskResolverRegistry, TaskProvider, TaskResolver } from '@theia/task/lib/browser/task-contribution'; import { interfaces } from '@theia/core/shared/inversify'; -import { TaskInfo, TaskExitedEvent, TaskConfiguration, TaskCustomization } from '@theia/task/lib/common/task-protocol'; +import { TaskInfo, TaskExitedEvent, TaskConfiguration, TaskCustomization, TaskOutputPresentation, RevealKind, PanelKind } from '@theia/task/lib/common/task-protocol'; import { TaskWatcher } from '@theia/task/lib/common/task-watcher'; import { TaskService } from '@theia/task/lib/browser/task-service'; import { TaskDefinitionRegistry } from '@theia/task/lib/browser'; +const revealKindMap = new Map( + [ + [1, RevealKind.Always], + [2, RevealKind.Silent], + [3, RevealKind.Never], + [RevealKind.Always, 1], + [RevealKind.Silent, 2], + [RevealKind.Never, 3] + ] +); + +const panelKindMap = new Map( + [ + [1, PanelKind.Shared], + [2, PanelKind.Dedicated], + [3, PanelKind.New], + [PanelKind.Shared, 1], + [PanelKind.Dedicated, 2], + [PanelKind.New, 3] + ] +); + export class TasksMainImpl implements TasksMain, Disposable { private readonly proxy: TasksExt; private readonly taskProviderRegistry: TaskProviderRegistry; @@ -175,31 +198,62 @@ export class TasksMainImpl implements TasksMain, Disposable { } protected toTaskConfiguration(taskDto: TaskDto): TaskConfiguration { - const { group, ...taskConfiguration } = taskDto; + const { group, presentation, scope, source, ...common } = taskDto; + const partialConfig: Partial = {}; + if (presentation) { + partialConfig.presentation = this.convertTaskPresentation(presentation); + } if (group === 'build' || group === 'test') { - taskConfiguration.group = group; + partialConfig.group = group; } - - return Object.assign(taskConfiguration, { - _source: taskConfiguration.source, - _scope: taskConfiguration.scope - }); + return { + ...common, + ...partialConfig, + _scope: scope, + _source: source, + }; } protected fromTaskConfiguration(task: TaskConfiguration): TaskDto { - const { group, ...taskDto } = task; + const { group, presentation, _scope, _source, ...common } = task; + const partialDto: Partial = {}; + if (presentation) { + partialDto.presentation = this.convertTaskPresentation(presentation); + } if (group) { if (TaskCustomization.isBuildTask(task)) { - taskDto.group = 'build'; + partialDto.group = 'build'; } else if (TaskCustomization.isTestTask(task)) { - taskDto.group = 'test'; + partialDto.group = 'test'; } } - - return Object.assign(taskDto, { - source: taskDto._source, - scope: taskDto._scope - }); + return { + ...common, + ...partialDto, + scope: _scope, + source: _source, + }; } + private convertTaskPresentation(presentationFrom: undefined): undefined; + private convertTaskPresentation(presentationFrom: TaskOutputPresentation): TaskPresentationOptionsDTO; + private convertTaskPresentation(presentationFrom: TaskPresentationOptionsDTO): TaskOutputPresentation; + private convertTaskPresentation( + presentationFrom: TaskOutputPresentation | TaskPresentationOptionsDTO | undefined + ): TaskOutputPresentation | TaskPresentationOptionsDTO | undefined { + if (presentationFrom) { + const { reveal, panel, ...common } = presentationFrom; + const presentationTo: Partial = {}; + if (reveal) { + presentationTo.reveal = revealKindMap.get(reveal); + } + if (panel) { + presentationTo.panel = panelKindMap.get(panel)!; + } + return { + ...common, + ...presentationTo, + }; + } + } } diff --git a/packages/plugin-ext/src/plugin/type-converters.spec.ts b/packages/plugin-ext/src/plugin/type-converters.spec.ts index e986b958c51c4..356437cab58cb 100644 --- a/packages/plugin-ext/src/plugin/type-converters.spec.ts +++ b/packages/plugin-ext/src/plugin/type-converters.spec.ts @@ -194,6 +194,10 @@ describe('Type converters:', () => { args, options: { cwd }, additionalProperty, + presentation: { + reveal: 3, + focus: true + }, group: groupDto }; @@ -215,6 +219,10 @@ describe('Type converters:', () => { type: shellType, additionalProperty }, + presentationOptions: { + reveal: types.TaskRevealKind.Never, + focus: true + }, group, execution: { command, diff --git a/packages/plugin-ext/src/plugin/type-converters.ts b/packages/plugin-ext/src/plugin/type-converters.ts index ba6af8e3cd246..da2fb3ceacbf6 100644 --- a/packages/plugin-ext/src/plugin/type-converters.ts +++ b/packages/plugin-ext/src/plugin/type-converters.ts @@ -708,6 +708,7 @@ export function fromTask(task: theia.Task): TaskDto | undefined { const taskDto = {} as TaskDto; taskDto.label = task.name; taskDto.source = task.source; + if ((task as types.Task).hasProblemMatchers) { taskDto.problemMatcher = task.problemMatchers; } @@ -720,6 +721,10 @@ export function fromTask(task: theia.Task): TaskDto | undefined { taskDto.scope = task.scope; } + if (task.presentationOptions) { + taskDto.presentation = task.presentationOptions; + } + const group = task.group; if (group === TaskGroup.Build) { taskDto.group = BUILD_GROUP; @@ -761,7 +766,7 @@ export function toTask(taskDto: TaskDto): theia.Task { throw new Error('Task should be provided for converting'); } - const { type, label, source, scope, problemMatcher, detail, command, args, options, windows, group, ...properties } = taskDto; + const { type, label, source, scope, problemMatcher, detail, command, args, options, windows, group, presentation, ...properties } = taskDto; const result = {} as theia.Task; result.name = label; result.source = source; @@ -803,6 +808,10 @@ export function toTask(taskDto: TaskDto): theia.Task { } } + if (presentation) { + result.presentationOptions = presentation; + } + if (!properties) { return result; } diff --git a/packages/plugin-ext/src/plugin/types-impl.ts b/packages/plugin-ext/src/plugin/types-impl.ts index 6f183da7a4732..88e224f1a0215 100644 --- a/packages/plugin-ext/src/plugin/types-impl.ts +++ b/packages/plugin-ext/src/plugin/types-impl.ts @@ -1710,7 +1710,7 @@ export class Task { private isTaskBackground: boolean; private taskSource: string; private taskGroup: TaskGroup | undefined; - private taskPresentationOptions: theia.TaskPresentationOptions | undefined; + private taskPresentationOptions: theia.TaskPresentationOptions; constructor( taskDefinition: theia.TaskDefinition, scope: theia.WorkspaceFolder | theia.TaskScope.Global | theia.TaskScope.Workspace, @@ -1774,6 +1774,7 @@ export class Task { this.hasTaskProblemMatchers = false; } this.isTaskBackground = false; + this.presentationOptions = Object.create(null); } get definition(): theia.TaskDefinition { @@ -1873,13 +1874,13 @@ export class Task { this.taskGroup = value; } - get presentationOptions(): theia.TaskPresentationOptions | undefined { + get presentationOptions(): theia.TaskPresentationOptions { return this.taskPresentationOptions; } - set presentationOptions(value: theia.TaskPresentationOptions | undefined) { - if (value === null) { - value = undefined; + set presentationOptions(value: theia.TaskPresentationOptions) { + if (value === null || value === undefined) { + value = Object.create(null); } this.taskPresentationOptions = value; }