@@ -382,6 +382,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
382382 }
383383
384384 observeTasks ( ctx : WorkspaceContext ) {
385+ this . disposables . push ( new TaskPoller ( ( ) => this . didChangeTreeDataEmitter . fire ( ) ) ) ;
386+
385387 this . disposables . push (
386388 vscode . tasks . onDidStartTask ( e => {
387389 const taskId = e . execution . task . detail ?? e . execution . task . name ;
@@ -578,7 +580,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
578580 // Plugin tasks are shown under the Commands header
579581 . filter (
580582 task =>
581- task . definition . cwd === folderContext . folder . fsPath &&
583+ ( ! task . definition . cwd ||
584+ task . definition . cwd === folderContext . folder . fsPath ) &&
582585 task . source !== "swift-plugin"
583586 )
584587 . map (
@@ -622,3 +625,52 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
622625 . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
623626 }
624627}
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