Skip to content

Add activation events for providing/resolving tasks (TaskProvider extension API) #102013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
@@ -6931,6 +6931,10 @@ declare module 'vscode' {
/**
* Register a task provider.
*
* When looking for tasks, VS Code fires an `onTaskProvide:taskType` activation event.
* When a task is being resolved, VS Code fires an `onTaskResolve:taskType` activation event.
* Your extension can listen to these events to make sure the task provider is available.
*
* @param type The task kind type this provider is registered for.
* @param provider A task provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
@@ -10928,6 +10932,10 @@ declare module 'vscode' {
*
* @deprecated Use the corresponding function on the `tasks` namespace instead
*
* When looking for tasks, VS Code fires an `onTaskProvide:taskType` activation event.
* When a task is being resolved, VS Code fires an `onTaskResolve:taskType` activation event.
* Your extension can listen to these events to make sure the task provider is available.
*
* @param type The task kind type this provider is registered for.
* @param provider A task provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
29 changes: 26 additions & 3 deletions src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts
Original file line number Diff line number Diff line change
@@ -607,6 +607,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return;
}
await Promise.all([this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask'), this.extensionService.whenInstalledExtensionsRegistered()]);
if (configuringTask.type) {
await Promise.all([this.extensionService.activateByEvent(`onTaskResolve:${configuringTask.type}`), this.extensionService.whenInstalledExtensionsRegistered()]);
}
let matchingProvider: ITaskProvider | undefined;
let matchingProviderUnavailable: boolean = false;
for (const [handle, provider] of this._providers) {
@@ -700,6 +703,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return types;
}

public async getPossibleTaskTypes(): Promise<string[]> {
const types: string[] = this.taskTypes();
if (this.isProvideTasksEnabled()) {
await TaskDefinitionRegistry.onReady();
for (const task of TaskDefinitionRegistry.all()) {
if (!types.includes(task.taskType)) {
types.push(task.taskType);
}
}
}
return types;
}

public createSorter(): TaskSorter {
return new TaskSorter(this.contextService.getWorkspace() ? this.contextService.getWorkspace().folders : []);
}
@@ -1664,12 +1680,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer

private getGroupedTasks(type?: string): Promise<TaskMap> {
const needsRecentTasksMigration = this.needsRecentTasksMigration();
const isProvideTasksEnabled = this.isProvideTasksEnabled();
return Promise.all([this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask'), this.extensionService.whenInstalledExtensionsRegistered()]).then(() => {
let validTypes: IStringDictionary<boolean> = Object.create(null);
TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true);
validTypes['shell'] = true;
validTypes['process'] = true;
return new Promise<TaskSet[]>(resolve => {
const activationPromises: Promise<void>[] = [];
TaskDefinitionRegistry.all().forEach(({ taskType }) => {
validTypes[taskType] = true;
if (isProvideTasksEnabled && (type === undefined || type === taskType)) {
activationPromises.push(this.extensionService.activateByEvent(`onTaskProvide:${taskType}`));
}
});
return Promise.all(activationPromises).then(() => new Promise<TaskSet[]>(resolve => {
let result: TaskSet[] = [];
let counter: number = 0;
let done = (value: TaskSet | undefined) => {
@@ -1723,7 +1746,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
} else {
resolve(result);
}
});
}));
}).then((contributedTaskSets) => {
let result: TaskMap = new TaskMap();
let contributedTasks: TaskMap = new TaskMap();
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts
Original file line number Diff line number Diff line change
@@ -147,7 +147,7 @@ export class TaskQuickPick extends Disposable {
}
let recentTasks: (Task | ConfiguringTask)[] = (await this.taskService.readRecentTasks()).reverse();
const configuredTasks: (Task | ConfiguringTask)[] = this.handleFolderTaskResult(await this.taskService.getWorkspaceTasks());
const extensionTaskTypes = this.taskService.taskTypes();
const extensionTaskTypes = await this.taskService.getPossibleTaskTypes();
this.topLevelEntries = [];
// Dedupe will update recent tasks if they've changed in tasks.json.
const dedupeAndPrune = this.dedupeConfiguredAndRecent(recentTasks, configuredTasks);
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/tasks/common/taskService.ts
Original file line number Diff line number Diff line change
@@ -70,6 +70,7 @@ export interface ITaskService {
terminate(task: Task): Promise<TaskTerminateResponse>;
tasks(filter?: TaskFilter): Promise<Task[]>;
taskTypes(): string[];
getPossibleTaskTypes(): Promise<string[]>;
getWorkspaceTasks(runSource?: TaskRunSource): Promise<Map<string, WorkspaceFolderTaskResult>>;
readRecentTasks(): Promise<(Task | ConfiguringTask)[]>;
removeRecentlyUsedTask(taskRecentlyUsedKey: string): void;
10 changes: 10 additions & 0 deletions src/vs/workbench/services/extensions/common/extensionsRegistry.ts
Original file line number Diff line number Diff line change
@@ -309,6 +309,16 @@ export const schema: IJSONSchema = {
body: 'onCustomEditor:${9:viewType}',
description: nls.localize('vscode.extension.activationEvents.onCustomEditor', 'An activation event emitted whenever the specified custom editor becomes visible.'),
},
{
label: 'onTaskProvide',
description: nls.localize('vscode.extension.activationEvents.onTaskProvide', 'An activation event emitted whenever VS Code is looking for tasks of a given (or any) type.'),
body: 'onTaskResolve:${1:taskType}'
},
{
label: 'onTaskResolve',
description: nls.localize('vscode.extension.activationEvents.onTaskResolve', 'An activation event emitted whenever a task with the given type gets resolved.'),
body: 'onTaskResolve:${1:taskType}'
},
{
label: 'onNotebook',
body: 'onNotebook:${1:type}',