Skip to content

Commit 8c46e0d

Browse files
committed
Poll for updated tasks in project panel
When a task is updated, added or deleted it is not reflected in the project panel. There are no VS Code APIs that notify on task modification/update/deletion, so poll every 2 seconds and check if the tasks are updated. If they are, refresh the tasks list in the project panel.
1 parent 5f94ace commit 8c46e0d

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

src/ui/ProjectPanelProvider.ts

+54-1
Original file line numberDiff line numberDiff line change
@@ -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,53 @@ 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 5 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+
private static POLL_INTERVAL = 5000;
637+
638+
constructor(private onTasksChanged: () => void) {
639+
this.pollTasks();
640+
}
641+
642+
private async pollTasks() {
643+
try {
644+
const tasks = await vscode.tasks.fetchTasks();
645+
const tasksChanged =
646+
tasks.length !== this.previousTasks.length ||
647+
tasks.some((task, i) => {
648+
const prev = this.previousTasks[i];
649+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
650+
const c1 = (task.execution as any).command;
651+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
652+
const c2 = (prev.execution as any).command;
653+
return (
654+
!prev ||
655+
task.name !== prev.name ||
656+
task.source !== prev.source ||
657+
task.definition.cwd !== prev.definition.cwd ||
658+
task.detail !== prev.detail ||
659+
c1 !== c2
660+
);
661+
});
662+
if (tasksChanged) {
663+
this.previousTasks = tasks;
664+
this.onTasksChanged();
665+
}
666+
} catch {
667+
// ignore errors
668+
}
669+
this.timeout = setTimeout(() => this.pollTasks(), TaskPoller.POLL_INTERVAL);
670+
}
671+
672+
dispose() {
673+
if (this.timeout) {
674+
clearTimeout(this.timeout);
675+
}
676+
}
677+
}

0 commit comments

Comments
 (0)