@@ -382,6 +382,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
382
382
}
383
383
384
384
observeTasks ( ctx : WorkspaceContext ) {
385
+ this . disposables . push ( new TaskPoller ( ( ) => this . didChangeTreeDataEmitter . fire ( ) ) ) ;
386
+
385
387
this . disposables . push (
386
388
vscode . tasks . onDidStartTask ( e => {
387
389
const taskId = e . execution . task . detail ?? e . execution . task . name ;
@@ -578,7 +580,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
578
580
// Plugin tasks are shown under the Commands header
579
581
. filter (
580
582
task =>
581
- task . definition . cwd === folderContext . folder . fsPath &&
583
+ ( ! task . definition . cwd ||
584
+ task . definition . cwd === folderContext . folder . fsPath ) &&
582
585
task . source !== "swift-plugin"
583
586
)
584
587
. map (
@@ -622,3 +625,52 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
622
625
. sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
623
626
}
624
627
}
628
+
629
+ /*
630
+ * A simple task poller that checks for changes in the tasks every 2 seconds.
631
+ * This is a workaround for the lack of an event when tasks are added or removed.
632
+ */
633
+ class TaskPoller implements vscode . Disposable {
634
+ private previousTasks : vscode . Task [ ] = [ ] ;
635
+ private timeout ?: NodeJS . Timeout ;
636
+
637
+ constructor ( private onTasksChanged : ( ) => void ) {
638
+ this . pollTasks ( ) ;
639
+ }
640
+
641
+ private async pollTasks ( ) {
642
+ try {
643
+ const tasks = await vscode . tasks . fetchTasks ( ) ;
644
+ const tasksChanged =
645
+ tasks . length !== this . previousTasks . length ||
646
+ tasks . some ( ( task , i ) => {
647
+ const prev = this . previousTasks [ i ] ;
648
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
649
+ const c1 = ( task . execution as any ) . command ;
650
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
651
+ const c2 = ( prev . execution as any ) . command ;
652
+ return (
653
+ ! prev ||
654
+ task . name !== prev . name ||
655
+ task . source !== prev . source ||
656
+ task . definition . cwd !== prev . definition . cwd ||
657
+ task . detail !== prev . detail ||
658
+ c1 !== c2
659
+ ) ;
660
+ } ) ;
661
+ if ( tasksChanged ) {
662
+ this . previousTasks = tasks ;
663
+ this . onTasksChanged ( ) ;
664
+ }
665
+ } catch {
666
+ // ignore errors
667
+ }
668
+ this . timeout = setTimeout ( ( ) => this . pollTasks ( ) , 2000 ) ;
669
+ }
670
+
671
+ dispose ( ) {
672
+ if ( this . timeout ) {
673
+ clearTimeout ( this . timeout ) ;
674
+ }
675
+ }
676
+ }
0 commit comments