@@ -9,16 +9,18 @@ import { Task, ContributedTask, CustomTask, ConfiguringTask, TaskSorter, KeyedTa
9
9
import { IWorkspace , IWorkspaceFolder } from 'vs/platform/workspace/common/workspace' ;
10
10
import * as Types from 'vs/base/common/types' ;
11
11
import { ITaskService , IWorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService' ;
12
- import { IQuickPickItem , QuickPickInput , IQuickPick , IQuickInputButton } from 'vs/base/parts/quickinput/common/quickInput' ;
12
+ import { IQuickPickItem , QuickPickInput , IQuickPick , IQuickInputButton , IQuickPickSeparator } from 'vs/base/parts/quickinput/common/quickInput' ;
13
13
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
14
14
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput' ;
15
- import { Disposable } from 'vs/base/common/lifecycle' ;
15
+ import { Disposable , dispose , IDisposable } from 'vs/base/common/lifecycle' ;
16
16
import { Event } from 'vs/base/common/event' ;
17
17
import { INotificationService , Severity } from 'vs/platform/notification/common/notification' ;
18
18
import { Codicon } from 'vs/base/common/codicons' ;
19
- import { ThemeIcon } from 'vs/platform/theme/common/themeService' ;
19
+ import { IThemeService , ThemeIcon } from 'vs/platform/theme/common/themeService' ;
20
20
import { registerIcon } from 'vs/platform/theme/common/iconRegistry' ;
21
21
import { IDialogService } from 'vs/platform/dialogs/common/dialogs' ;
22
+ import { getColorClass , getColorStyleElement , getStandardColors } from 'vs/workbench/contrib/terminal/browser/terminalIcon' ;
23
+ import { TaskQuickPickEntryType } from 'vs/workbench/contrib/tasks/browser/abstractTaskService' ;
22
24
23
25
export const QUICKOPEN_DETAIL_CONFIG = 'task.quickOpen.detail' ;
24
26
export const QUICKOPEN_SKIP_CONFIG = 'task.quickOpen.skip' ;
@@ -49,6 +51,7 @@ export class TaskQuickPick extends Disposable {
49
51
private _configurationService : IConfigurationService ,
50
52
private _quickInputService : IQuickInputService ,
51
53
private _notificationService : INotificationService ,
54
+ private _themeService : IThemeService ,
52
55
private _dialogService : IDialogService ) {
53
56
super ( ) ;
54
57
this . _sorter = this . _taskService . createSorter ( ) ;
@@ -61,7 +64,7 @@ export class TaskQuickPick extends Disposable {
61
64
62
65
private _guessTaskLabel ( task : Task | ConfiguringTask ) : string {
63
66
if ( task . _label ) {
64
- return task . _label ;
67
+ return TaskQuickPick . getTaskLabelWithIcon ( task ) ;
65
68
}
66
69
if ( ConfiguringTask . is ( task ) ) {
67
70
let label : string = task . configures . type ;
@@ -74,9 +77,29 @@ export class TaskQuickPick extends Disposable {
74
77
return '' ;
75
78
}
76
79
80
+ public static getTaskLabelWithIcon ( task : Task | ConfiguringTask ) : string {
81
+ return task . configurationProperties . icon ? `$(${ task . configurationProperties . icon } ) ${ task . _label } ` : task . configurationProperties . color ? `$(${ Codicon . tools . id } ) ${ task . _label } ` : `${ task . _label } ` ;
82
+ }
83
+
84
+ public static applyColorStyles ( task : Task | ConfiguringTask , entry : TaskQuickPickEntryType | ITaskTwoLevelQuickPickEntry , themeService : IThemeService ) : void {
85
+ if ( task . configurationProperties . color ) {
86
+ const colorTheme = themeService . getColorTheme ( ) ;
87
+ const styleElement = getColorStyleElement ( colorTheme ) ;
88
+ entry . iconClasses = [ getColorClass ( task . configurationProperties . color ) ] ;
89
+ document . body . appendChild ( styleElement ) ;
90
+ }
91
+ }
92
+
77
93
private _createTaskEntry ( task : Task | ConfiguringTask , extraButtons : IQuickInputButton [ ] = [ ] ) : ITaskTwoLevelQuickPickEntry {
94
+ const customizeIconButton = { iconClass : ThemeIcon . asClassName ( Codicon . pencil ) , tooltip : nls . localize ( 'setIconAndColor' , "Choose color and icon" ) } ;
78
95
const entry : ITaskTwoLevelQuickPickEntry = { label : this . _guessTaskLabel ( task ) , description : this . _taskService . getTaskDescription ( task ) , task, detail : this . _showDetail ( ) ? task . configurationProperties . detail : undefined } ;
79
- entry . buttons = [ { iconClass : ThemeIcon . asClassName ( configureTaskIcon ) , tooltip : nls . localize ( 'configureTask' , "Configure Task" ) } , ...extraButtons ] ;
96
+ entry . buttons = [ ] ;
97
+ if ( CustomTask . is ( task ) ) {
98
+ entry . buttons . push ( customizeIconButton ) ;
99
+ }
100
+ entry . buttons . push ( { iconClass : ThemeIcon . asClassName ( configureTaskIcon ) , tooltip : nls . localize ( 'configureTask' , "Configure Task" ) } ) ;
101
+ entry . buttons . push ( ...extraButtons ) ;
102
+ TaskQuickPick . applyColorStyles ( task , entry , this . _themeService ) ;
80
103
return entry ;
81
104
}
82
105
@@ -211,6 +234,9 @@ export class TaskQuickPick extends Disposable {
211
234
if ( indexToRemove >= 0 ) {
212
235
picker . items = [ ...picker . items . slice ( 0 , indexToRemove ) , ...picker . items . slice ( indexToRemove + 1 ) ] ;
213
236
}
237
+ } else if ( context . button . iconClass = ThemeIcon . asClassName ( Codicon . pencil ) ) {
238
+ await this . _setColor ( task ) ;
239
+ await this . _setIcon ( task ) ;
214
240
} else {
215
241
this . _quickInputService . cancel ( ) ;
216
242
if ( ContributedTask . is ( task ) ) {
@@ -265,6 +291,74 @@ export class TaskQuickPick extends Disposable {
265
291
return ;
266
292
}
267
293
294
+ private async _setColor ( task : Task | ConfiguringTask | null | string | undefined ) : Promise < void > {
295
+ if ( task === undefined || task === null || typeof task === 'string' ) {
296
+ return ;
297
+ }
298
+ const colorTheme = this . _themeService . getColorTheme ( ) ;
299
+ const standardColors : string [ ] = getStandardColors ( colorTheme ) ;
300
+ const styleElement = getColorStyleElement ( colorTheme ) ;
301
+ const items : ( IQuickPickItem | IQuickPickSeparator ) [ ] = [ ] ;
302
+ for ( const colorKey of standardColors ) {
303
+ const colorClass = getColorClass ( colorKey ) ;
304
+ items . push ( {
305
+ label : `$(${ Codicon . circleFilled . id } ) ${ colorKey . replace ( 'terminal.ansi' , '' ) } ` , id : colorKey , description : colorKey , iconClasses : [ colorClass ]
306
+ } ) ;
307
+ }
308
+ items . push ( { type : 'separator' } ) ;
309
+ const showAllColorsItem = { label : 'Reset to default' } ;
310
+ items . push ( showAllColorsItem ) ;
311
+ document . body . appendChild ( styleElement ) ;
312
+
313
+ const quickPick = this . _quickInputService . createQuickPick ( ) ;
314
+ quickPick . items = items ;
315
+ quickPick . matchOnDescription = true ;
316
+ quickPick . show ( ) ;
317
+ const disposables : IDisposable [ ] = [ ] ;
318
+ const result = await new Promise < IQuickPickItem | undefined > ( r => {
319
+ disposables . push ( quickPick . onDidHide ( ( ) => r ( undefined ) ) ) ;
320
+ disposables . push ( quickPick . onDidAccept ( ( ) => r ( quickPick . selectedItems [ 0 ] ) ) ) ;
321
+ } ) ;
322
+ dispose ( disposables ) ;
323
+
324
+ if ( result && task && typeof task !== 'string' ) {
325
+ task . configurationProperties . color = result . id ;
326
+ }
327
+ document . body . removeChild ( styleElement ) ;
328
+ quickPick . hide ( ) ;
329
+ }
330
+
331
+ private async _setIcon ( task : Task | ConfiguringTask | null | string | undefined ) : Promise < void > {
332
+ if ( task === undefined || task === null || typeof task === 'string' ) {
333
+ return ;
334
+ }
335
+ type Item = IQuickPickItem & { icon : ThemeIcon } ;
336
+ const items : Item [ ] = [ ] ;
337
+ for ( const icon of Codicon . getAll ( ) ) {
338
+ items . push ( { label : `$(${ icon . id } )` , description : `${ icon . id } ` , id : icon . id , icon, iconClasses : task . configurationProperties . color ? [ getColorClass ( task . configurationProperties . color ) ] : undefined } ) ;
339
+ }
340
+
341
+ const quickPick = this . _quickInputService . createQuickPick ( ) ;
342
+ quickPick . items = items ;
343
+ quickPick . matchOnDescription = true ;
344
+ quickPick . show ( ) ;
345
+ const disposables : IDisposable [ ] = [ ] ;
346
+ const result = await new Promise < IQuickPickItem | undefined > ( r => {
347
+ disposables . push ( quickPick . onDidHide ( ( ) => r ( undefined ) ) ) ;
348
+ disposables . push ( quickPick . onDidAccept ( ( ) => r ( quickPick . selectedItems [ 0 ] ) ) ) ;
349
+ } ) ;
350
+ dispose ( disposables ) ;
351
+
352
+ if ( result && task && typeof task !== 'string' ) {
353
+ task . configurationProperties . icon = result . id ;
354
+ }
355
+ if ( CustomTask . is ( task ) && result ) {
356
+ await this . _taskService . customize ( task , { icon : result . id , color : task . configurationProperties . color } , false ) ;
357
+ }
358
+ quickPick . hide ( ) ;
359
+ }
360
+
361
+
268
362
private async _doPickerFirstLevel ( picker : IQuickPick < ITaskTwoLevelQuickPickEntry > , taskQuickPickEntries : QuickPickInput < ITaskTwoLevelQuickPickEntry > [ ] ) : Promise < Task | ConfiguringTask | string | null | undefined > {
269
363
picker . items = taskQuickPickEntries ;
270
364
const firstLevelPickerResult = await new Promise < ITaskTwoLevelQuickPickEntry | undefined | null > ( resolve => {
@@ -367,8 +461,8 @@ export class TaskQuickPick extends Disposable {
367
461
368
462
static async show ( taskService : ITaskService , configurationService : IConfigurationService ,
369
463
quickInputService : IQuickInputService , notificationService : INotificationService ,
370
- dialogService : IDialogService , placeHolder : string , defaultEntry ?: ITaskQuickPickEntry ) {
371
- const taskQuickPick = new TaskQuickPick ( taskService , configurationService , quickInputService , notificationService , dialogService ) ;
464
+ dialogService : IDialogService , themeService : IThemeService , placeHolder : string , defaultEntry ?: ITaskQuickPickEntry ) {
465
+ const taskQuickPick = new TaskQuickPick ( taskService , configurationService , quickInputService , notificationService , themeService , dialogService ) ;
372
466
return taskQuickPick . show ( placeHolder , defaultEntry ) ;
373
467
}
374
468
}
0 commit comments