@@ -78,7 +78,7 @@ import { ITextEditorSelection, TextEditorSelectionRevealType } from 'vs/platform
78
78
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences' ;
79
79
import { CancellationToken , CancellationTokenSource } from 'vs/base/common/cancellation' ;
80
80
import { IViewsService , IViewDescriptorService } from 'vs/workbench/common/views' ;
81
- import { isWorkspaceFolder , ITaskQuickPickEntry , QUICKOPEN_DETAIL_CONFIG , TaskQuickPick , QUICKOPEN_SKIP_CONFIG , configureTaskIcon } from 'vs/workbench/contrib/tasks/browser/taskQuickPick' ;
81
+ import { isWorkspaceFolder , ITaskQuickPickEntry , QUICKOPEN_DETAIL_CONFIG , TaskQuickPick , QUICKOPEN_SKIP_CONFIG , configureTaskIcon , ITaskTwoLevelQuickPickEntry } from 'vs/workbench/contrib/tasks/browser/taskQuickPick' ;
82
82
import { ILogService } from 'vs/platform/log/common/log' ;
83
83
import { once } from 'vs/base/common/functional' ;
84
84
import { IThemeService , ThemeIcon } from 'vs/platform/theme/common/themeService' ;
@@ -347,7 +347,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
347
347
return this . inTerminal ( ) ;
348
348
}
349
349
350
- private _registerCommands ( ) : void {
350
+ private async _registerCommands ( ) : Promise < void > {
351
351
CommandsRegistry . registerCommand ( {
352
352
id : 'workbench.action.tasks.runTask' ,
353
353
handler : async ( accessor , arg ) => {
@@ -359,8 +359,30 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
359
359
description : 'Run Task' ,
360
360
args : [ {
361
361
name : 'args' ,
362
+ isOptional : true ,
363
+ description : nls . localize ( 'runTask.arg' , "Filters the tasks shown in the quickpick" ) ,
362
364
schema : {
363
- 'type' : 'string' ,
365
+ anyOf : [
366
+ {
367
+ type : 'string' ,
368
+ description : nls . localize ( 'runTask.label' , "The task's label or a term to filter by" )
369
+ } ,
370
+ {
371
+ type : 'object' ,
372
+ properties : {
373
+ type : {
374
+ type : 'string' ,
375
+ description : nls . localize ( 'runTask.type' , "The contributed task type" ) ,
376
+ enum : Array . from ( this . _providerTypes . values ( ) ) . map ( provider => provider )
377
+ } ,
378
+ taskName : {
379
+ type : 'string' ,
380
+ description : nls . localize ( 'runTask.taskName' , "The task's label or a term to filter by" ) ,
381
+ enum : await this . tasks ( ) . then ( ( tasks ) => tasks . map ( t => t . _label ) )
382
+ }
383
+ }
384
+ }
385
+ ]
364
386
}
365
387
} ]
366
388
}
@@ -2521,11 +2543,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2521
2543
return entries ;
2522
2544
}
2523
2545
2524
- private async _showTwoLevelQuickPick ( placeHolder : string , defaultEntry ?: ITaskQuickPickEntry ) {
2525
- return TaskQuickPick . show ( this , this . _configurationService , this . _quickInputService , this . _notificationService , this . _dialogService , this . _themeService , placeHolder , defaultEntry ) ;
2546
+ private async _showTwoLevelQuickPick ( placeHolder : string , defaultEntry ?: ITaskQuickPickEntry , filter ?: string ) {
2547
+ return TaskQuickPick . show ( this , this . _configurationService , this . _quickInputService , this . _notificationService , this . _dialogService , this . _themeService , placeHolder , defaultEntry , filter ) ;
2526
2548
}
2527
2549
2528
- private async _showQuickPick ( tasks : Promise < Task [ ] > | Task [ ] , placeHolder : string , defaultEntry ?: ITaskQuickPickEntry , group : boolean = false , sort : boolean = false , selectedEntry ?: ITaskQuickPickEntry , additionalEntries ?: ITaskQuickPickEntry [ ] ) : Promise < ITaskQuickPickEntry | undefined | null > {
2550
+ private async _showQuickPick ( tasks : Promise < Task [ ] > | Task [ ] , placeHolder : string , defaultEntry ?: ITaskQuickPickEntry , group : boolean = false , sort : boolean = false , selectedEntry ?: ITaskQuickPickEntry , additionalEntries ?: ITaskQuickPickEntry [ ] , filter ?: string ) : Promise < ITaskQuickPickEntry | undefined | null > {
2529
2551
const tokenSource = new CancellationTokenSource ( ) ;
2530
2552
const cancellationToken : CancellationToken = tokenSource . token ;
2531
2553
const createEntries = new Promise < QuickPickInput < ITaskQuickPickEntry > [ ] > ( ( resolve ) => {
@@ -2564,7 +2586,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2564
2586
const picker : IQuickPick < ITaskQuickPickEntry > = this . _quickInputService . createQuickPick ( ) ;
2565
2587
picker . placeholder = placeHolder ;
2566
2588
picker . matchOnDescription = true ;
2567
-
2568
2589
picker . onDidTriggerItemButton ( context => {
2569
2590
const task = context . item . task ;
2570
2591
this . _quickInputService . cancel ( ) ;
@@ -2580,7 +2601,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2580
2601
picker . items = entries ;
2581
2602
} ) ;
2582
2603
picker . show ( ) ;
2583
-
2604
+ if ( filter ) {
2605
+ picker . value = filter ;
2606
+ }
2584
2607
return new Promise < ITaskQuickPickEntry | undefined | null > ( resolve => {
2585
2608
this . _register ( picker . onDidAccept ( async ( ) => {
2586
2609
let selection = picker . selectedItems ? picker . selectedItems [ 0 ] : undefined ;
@@ -2654,12 +2677,20 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2654
2677
} ) ) === true ;
2655
2678
}
2656
2679
2657
- private _runTaskCommand ( arg ?: any ) : void {
2680
+ private async _runTaskCommand ( filter ?: { type ?: string ; taskName ?: string } | string ) : Promise < void > {
2658
2681
if ( ! this . _canRunCommand ( ) ) {
2659
2682
return ;
2660
2683
}
2661
- const identifier = this . _getTaskIdentifier ( arg ) ;
2662
- if ( identifier !== undefined ) {
2684
+
2685
+ let typeFilter : boolean = false ;
2686
+ if ( filter && typeof filter !== 'string' ) {
2687
+ // name takes precedence
2688
+ typeFilter = ! filter ?. taskName && ! ! filter ?. type ;
2689
+ filter = filter ?. taskName || filter ?. type ;
2690
+ }
2691
+
2692
+ const taskIdentifier : KeyedTaskIdentifier | undefined | string = this . _getTaskIdentifier ( filter ) ;
2693
+ if ( taskIdentifier ) {
2663
2694
this . _getGroupedTasks ( ) . then ( async ( grouped ) => {
2664
2695
const resolver = this . _createResolver ( grouped ) ;
2665
2696
const folderURIs : ( URI | string ) [ ] = this . _contextService . getWorkspace ( ) . folders . map ( folder => folder . uri ) ;
@@ -2668,15 +2699,15 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2668
2699
}
2669
2700
folderURIs . push ( USER_TASKS_GROUP_KEY ) ;
2670
2701
for ( const uri of folderURIs ) {
2671
- const task = await resolver . resolve ( uri , identifier ) ;
2702
+ const task = await resolver . resolve ( uri , taskIdentifier ) ;
2672
2703
if ( task ) {
2673
2704
this . run ( task ) . then ( undefined , reason => {
2674
2705
// eat the error, it has already been surfaced to the user and we don't care about it here
2675
2706
} ) ;
2676
2707
return ;
2677
2708
}
2678
2709
}
2679
- this . _doRunTaskCommand ( grouped . all ( ) ) ;
2710
+ this . _doRunTaskCommand ( grouped . all ( ) , typeof taskIdentifier === 'string' ? taskIdentifier : undefined , typeFilter ) ;
2680
2711
} , ( ) => {
2681
2712
this . _doRunTaskCommand ( ) ;
2682
2713
} ) ;
@@ -2716,7 +2747,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2716
2747
return { tasks, grouped } ;
2717
2748
}
2718
2749
2719
- private _doRunTaskCommand ( tasks ?: Task [ ] ) : void {
2750
+ private _doRunTaskCommand ( tasks ?: Task [ ] , filter ?: string , typeFilter ?: boolean ) : void {
2720
2751
const pickThen = ( task : Task | undefined | null ) => {
2721
2752
if ( task === undefined ) {
2722
2753
return ;
@@ -2732,28 +2763,58 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
2732
2763
2733
2764
const placeholder = nls . localize ( 'TaskService.pickRunTask' , 'Select the task to run' ) ;
2734
2765
2735
- this . _showIgnoredFoldersMessage ( ) . then ( ( ) => {
2766
+ this . _showIgnoredFoldersMessage ( ) . then ( async ( ) => {
2736
2767
if ( this . _configurationService . getValue ( USE_SLOW_PICKER ) ) {
2737
2768
let taskResult : { tasks : Promise < Task [ ] > ; grouped : Promise < TaskMap > } | undefined = undefined ;
2738
2769
if ( ! tasks ) {
2739
2770
taskResult = this . _tasksAndGroupedTasks ( ) ;
2740
2771
}
2772
+ if ( filter && typeFilter ) {
2773
+ const picker : IQuickPick < ITaskTwoLevelQuickPickEntry > = this . _quickInputService . createQuickPick ( ) ;
2774
+ picker . placeholder = nls . localize ( 'TaskService.pickRunTask' , 'Select the task to run' ) ;
2775
+ picker . matchOnDescription = true ;
2776
+ picker . ignoreFocusOut = false ;
2777
+ const taskQuickPick = new TaskQuickPick ( this , this . _configurationService , this . _quickInputService , this . _notificationService , this . _themeService , this . _dialogService ) ;
2778
+ const result = await taskQuickPick . doPickerSecondLevel ( picker , filter ) ;
2779
+ if ( result ?. task ) {
2780
+ pickThen ( result . task as Task ) ;
2781
+ taskQuickPick . dispose ( ) ;
2782
+ }
2783
+ return ;
2784
+ }
2741
2785
this . _showQuickPick ( tasks ? tasks : taskResult ! . tasks , placeholder ,
2742
2786
{
2743
2787
label : '$(plus) ' + nls . localize ( 'TaskService.noEntryToRun' , 'Configure a Task' ) ,
2744
2788
task : null
2745
2789
} ,
2746
- true ) .
2790
+ true , false , undefined , undefined , typeof filter === 'string' ? filter : undefined ) .
2747
2791
then ( ( entry ) => {
2748
2792
return pickThen ( entry ? entry . task : undefined ) ;
2749
2793
} ) ;
2750
2794
} else {
2751
- this . _showTwoLevelQuickPick ( placeholder ,
2752
- {
2753
- label : '$(plus) ' + nls . localize ( 'TaskService.noEntryToRun' , 'Configure a Task' ) ,
2754
- task : null
2755
- } ) .
2756
- then ( pickThen ) ;
2795
+ if ( filter && typeFilter ) {
2796
+ const picker : IQuickPick < ITaskTwoLevelQuickPickEntry > = this . _quickInputService . createQuickPick ( ) ;
2797
+ picker . placeholder = nls . localize ( 'TaskService.pickRunTask' , 'Select the task to run' ) ;
2798
+ picker . matchOnDescription = true ;
2799
+ picker . ignoreFocusOut = false ;
2800
+ const taskQuickPick = new TaskQuickPick ( this , this . _configurationService , this . _quickInputService , this . _notificationService , this . _themeService , this . _dialogService ) ;
2801
+ const result = await taskQuickPick . doPickerSecondLevel ( picker , filter ) ;
2802
+ if ( result ?. task ) {
2803
+ pickThen ( result . task as Task ) ;
2804
+ picker . dispose ( ) ;
2805
+ taskQuickPick . dispose ( ) ;
2806
+ return ;
2807
+ } else {
2808
+ return ;
2809
+ }
2810
+ } else {
2811
+ this . _showTwoLevelQuickPick ( placeholder ,
2812
+ {
2813
+ label : '$(plus) ' + nls . localize ( 'TaskService.noEntryToRun' , 'Configure a Task' ) ,
2814
+ task : null
2815
+ } , typeof filter === 'string' ? filter : undefined ) .
2816
+ then ( pickThen ) ;
2817
+ }
2757
2818
}
2758
2819
} ) ;
2759
2820
}
@@ -3055,7 +3116,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
3055
3116
}
3056
3117
}
3057
3118
3058
- private _getTaskIdentifier ( arg ?: any ) : string | KeyedTaskIdentifier | undefined {
3119
+ private _getTaskIdentifier ( arg ?: string | ITaskIdentifier ) : string | KeyedTaskIdentifier | undefined {
3059
3120
let result : string | KeyedTaskIdentifier | undefined = undefined ;
3060
3121
if ( Types . isString ( arg ) ) {
3061
3122
result = arg ;
0 commit comments