Skip to content

Commit c7a9cd2

Browse files
authored
allow setting icon/color for tasks (microsoft#151949)
1 parent 8b0b3ee commit c7a9cd2

File tree

6 files changed

+87
-10
lines changed

6 files changed

+87
-10
lines changed

src/vs/workbench/api/browser/mainThreadTask.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ namespace TaskDTO {
318318
isBackground: task.configurationProperties.isBackground,
319319
problemMatchers: [],
320320
hasDefinedMatchers: ContributedTask.is(task) ? task.hasDefinedMatchers : false,
321+
icon: task.configurationProperties.icon,
322+
color: task.configurationProperties.color,
321323
runOptions: RunOptionsDTO.from(task.runOptions),
322324
};
323325
result.group = TaskGroupDTO.from(task.configurationProperties.group);
@@ -382,7 +384,9 @@ namespace TaskDTO {
382384
group: task.group,
383385
isBackground: !!task.isBackground,
384386
problemMatchers: task.problemMatchers.slice(),
385-
detail: task.detail
387+
detail: task.detail,
388+
color: task.color,
389+
icon: task.icon
386390
}
387391
);
388392
return result;

src/vs/workbench/api/common/shared/tasks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ export interface ITaskSourceDTO {
7676
label: string;
7777
extensionId?: string;
7878
scope?: number | UriComponents;
79+
color?: string;
80+
icon?: string;
7981
}
8082

8183
export interface ITaskHandleDTO {
@@ -101,6 +103,8 @@ export interface ITaskDTO {
101103
problemMatchers: string[];
102104
hasDefinedMatchers: boolean;
103105
runOptions?: IRunOptionsDTO;
106+
color?: string;
107+
icon?: string;
104108
}
105109

106110
export interface ITaskSetDTO {

src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { TaskTerminalStatus } from 'vs/workbench/contrib/tasks/browser/taskTermi
5050
import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService';
5151
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
5252
import { INotificationService } from 'vs/platform/notification/common/notification';
53+
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
5354

5455
interface ITerminalData {
5556
terminal: ITerminalInstance;
@@ -1032,9 +1033,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
10321033
type,
10331034
executable: defaultProfile.path,
10341035
args: defaultProfile.args,
1035-
icon: defaultProfile.icon,
10361036
env: { ...defaultProfile.env },
1037-
color: defaultProfile.color,
1037+
icon: task.configurationProperties.icon ? ThemeIcon.fromId(task.configurationProperties.icon) : defaultProfile.icon,
1038+
color: task.configurationProperties.color || defaultProfile.color,
10381039
waitOnExit
10391040
};
10401041
let shellSpecified: boolean = false;
@@ -1125,6 +1126,8 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
11251126
shellLaunchConfig = {
11261127
name: terminalName,
11271128
type,
1129+
icon: task.configurationProperties.icon ? ThemeIcon.fromId(task.configurationProperties.icon) : undefined,
1130+
color: task.configurationProperties.color,
11281131
executable: executable,
11291132
args: args.map(a => Types.isString(a) ? a : a.value),
11301133
waitOnExit
@@ -1243,7 +1246,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
12431246
waitOnExit,
12441247
name: this._createTerminalName(task),
12451248
initialText: task.command.presentation && task.command.presentation.echo ? `\x1b[1m> Executing task: ${task._label} <\x1b[0m\n` : undefined,
1246-
isFeatureTerminal: true
1249+
isFeatureTerminal: true,
1250+
icon: task.configurationProperties.icon ? ThemeIcon.fromId(task.configurationProperties.icon) : undefined,
1251+
color: task.configurationProperties.color
12471252
};
12481253
} else {
12491254
const resolvedResult: { command: CommandString; args: CommandString[] } = await this._resolveCommandAndArgs(resolver, task.command);

src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ const detail: IJSONSchema = {
9494
description: nls.localize('JsonSchema.tasks.detail', 'An optional description of a task that shows in the Run Task quick pick as a detail.')
9595
};
9696

97+
const color: IJSONSchema = {
98+
type: 'string',
99+
description: nls.localize('JsonSchema.tasks.color', 'An optional color for the task icon')
100+
};
101+
102+
const icon: IJSONSchema = {
103+
type: 'string',
104+
description: nls.localize('JsonSchema.tasks.icon', 'An optional icon for the task')
105+
};
106+
97107
const presentation: IJSONSchema = {
98108
type: 'object',
99109
default: {
@@ -378,6 +388,8 @@ const taskConfiguration: IJSONSchema = {
378388
default: false
379389
},
380390
presentation: Objects.deepClone(presentation),
391+
color: Objects.deepClone(color),
392+
icon: Objects.deepClone(icon),
381393
options: options,
382394
problemMatcher: {
383395
$ref: '#/definitions/problemMatcherType',
@@ -455,6 +467,8 @@ taskDescriptionProperties.identifier = Objects.deepClone(identifier);
455467
taskDescriptionProperties.type = Objects.deepClone(taskType);
456468
taskDescriptionProperties.presentation = Objects.deepClone(presentation);
457469
taskDescriptionProperties.terminal = terminal;
470+
taskDescriptionProperties.color = color;
471+
taskDescriptionProperties.icon = icon;
458472
taskDescriptionProperties.group = Objects.deepClone(group);
459473
taskDescriptionProperties.runOptions = Objects.deepClone(runOptions);
460474
taskDescriptionProperties.detail = detail;

src/vs/workbench/contrib/tasks/common/taskConfiguration.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,16 @@ export interface IConfigurationProperties {
352352
* Task run options. Control run related properties.
353353
*/
354354
runOptions?: IRunOptionsConfig;
355+
356+
/**
357+
* The icon for this task in the terminal tabs list
358+
*/
359+
icon?: string;
360+
361+
/**
362+
* The icon's color in the terminal tabs list
363+
*/
364+
color?: string;
355365
}
356366

357367
export interface ICustomTask extends ICommandProperties, IConfigurationProperties {
@@ -1303,11 +1313,17 @@ namespace DependsOrder {
13031313
namespace ConfigurationProperties {
13041314

13051315
const properties: IMetaData<Tasks.IConfigurationProperties, any>[] = [
1306-
1307-
{ property: 'name' }, { property: 'identifier' }, { property: 'group' }, { property: 'isBackground' },
1308-
{ property: 'promptOnClose' }, { property: 'dependsOn' },
1309-
{ property: 'presentation', type: CommandConfiguration.PresentationOptions }, { property: 'problemMatchers' },
1310-
{ property: 'options' }
1316+
{ property: 'name' },
1317+
{ property: 'identifier' },
1318+
{ property: 'group' },
1319+
{ property: 'isBackground' },
1320+
{ property: 'promptOnClose' },
1321+
{ property: 'dependsOn' },
1322+
{ property: 'presentation', type: CommandConfiguration.PresentationOptions },
1323+
{ property: 'problemMatchers' },
1324+
{ property: 'options' },
1325+
{ property: 'color' },
1326+
{ property: 'icon' }
13111327
];
13121328

13131329
export function from(this: void, external: IConfigurationProperties & { [key: string]: any }, context: IParseContext,
@@ -1334,6 +1350,13 @@ namespace ConfigurationProperties {
13341350
if (Types.isString(external.identifier)) {
13351351
result.identifier = external.identifier;
13361352
}
1353+
if (Types.isString(external.color)) {
1354+
result.color = external.color;
1355+
}
1356+
if (Types.isString(external.icon)) {
1357+
result.icon = external.icon;
1358+
}
1359+
13371360
if (external.isBackground !== undefined) {
13381361
result.isBackground = !!external.isBackground;
13391362
}
@@ -1618,7 +1641,10 @@ namespace CustomTask {
16181641
{
16191642
name: configuredProps.configurationProperties.name || contributedTask.configurationProperties.name,
16201643
identifier: configuredProps.configurationProperties.identifier || contributedTask.configurationProperties.identifier,
1621-
}
1644+
icon: contributedTask.configurationProperties.icon,
1645+
color: contributedTask.configurationProperties.color
1646+
},
1647+
16221648
);
16231649
result.addTaskLoadMessages(configuredProps.taskLoadMessages);
16241650
const resultConfigProps: Tasks.IConfigurationProperties = result.configurationProperties;

src/vs/workbench/contrib/tasks/common/tasks.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,16 @@ export interface IConfigurationProperties {
544544
* The problem watchers to use for this task
545545
*/
546546
problemMatchers?: Array<string | ProblemMatcher>;
547+
548+
/**
549+
* The icon for this task in the terminal tabs list
550+
*/
551+
icon?: string;
552+
553+
/**
554+
* The icon's color in the terminal tabs list
555+
*/
556+
color?: string;
547557
}
548558

549559
export enum RunOnOptions {
@@ -681,6 +691,12 @@ export abstract class CommonTask {
681691
}
682692
}
683693

694+
/**
695+
* For tasks of type shell or process, this is created upon parse
696+
* of the tasks.json or workspace file.
697+
* For ContributedTasks of all other types, this is the result of
698+
* resolving a ConfiguringTask.
699+
*/
684700
export class CustomTask extends CommonTask {
685701

686702
override type!: '$customized'; // CUSTOMIZED_TASK_TYPE
@@ -812,6 +828,11 @@ export class CustomTask extends CommonTask {
812828
}
813829
}
814830

831+
/**
832+
* After a contributed task has been parsed, but before
833+
* the task has been resolved via the extension, its properties
834+
* are stored in this
835+
*/
815836
export class ConfiguringTask extends CommonTask {
816837

817838
/**
@@ -871,6 +892,9 @@ export class ConfiguringTask extends CommonTask {
871892
}
872893
}
873894

895+
/**
896+
* A task from an extension created via resolveTask or provideTask
897+
*/
874898
export class ContributedTask extends CommonTask {
875899

876900
/**

0 commit comments

Comments
 (0)