提交 fadfa543 编写于 作者: A Alex Ross

Use new task quick pick in quick access

Part of #90087
上级 bc6cf275
......@@ -33,7 +33,8 @@ const SHOW_ALL: string = nls.localize('taskQuickPick.showAll', "Show All Tasks..
export class TaskQuickPick extends Disposable {
private sorter: TaskSorter;
private constructor(
private topLevelEntries: QuickPickInput<TaskTwoLevelQuickPickEntry>[] | undefined;
constructor(
private taskService: ITaskService,
private configurationService: IConfigurationService,
private quickInputService: IQuickInputService) {
......@@ -118,33 +119,36 @@ export class TaskQuickPick extends Disposable {
return dedupedConfiguredTasks;
}
private async createTopLevelEntries(defaultEntry?: TaskQuickPickEntry): Promise<{ entries: QuickPickInput<TaskTwoLevelQuickPickEntry>[], isSingleConfigured?: Task | ConfiguringTask }> {
public async getTopLevelEntries(defaultEntry?: TaskQuickPickEntry): Promise<{ entries: QuickPickInput<TaskTwoLevelQuickPickEntry>[], isSingleConfigured?: Task | ConfiguringTask }> {
if (this.topLevelEntries !== undefined) {
return { entries: this.topLevelEntries };
}
const recentTasks: (Task | ConfiguringTask)[] = (await this.taskService.readRecentTasks()).reverse();
const configuredTasks: (Task | ConfiguringTask)[] = this.handleFolderTaskResult(await this.taskService.getWorkspaceTasks());
const extensionTaskTypes = this.taskService.taskTypes();
const taskQuickPickEntries: QuickPickInput<TaskTwoLevelQuickPickEntry>[] = [];
this.topLevelEntries = [];
if (recentTasks.length > 0) {
this.createEntriesForGroup(taskQuickPickEntries, recentTasks, nls.localize('recentlyUsed', 'recently used'));
this.createEntriesForGroup(this.topLevelEntries, recentTasks, nls.localize('recentlyUsed', 'recently used'));
}
if (configuredTasks.length > 0) {
let dedupedConfiguredTasks: (Task | ConfiguringTask)[] = this.dedupeConfiguredAndRecent(recentTasks, configuredTasks);
if (dedupedConfiguredTasks.length > 0) {
this.createEntriesForGroup(taskQuickPickEntries, dedupedConfiguredTasks, nls.localize('configured', 'configured'));
this.createEntriesForGroup(this.topLevelEntries, dedupedConfiguredTasks, nls.localize('configured', 'configured'));
}
}
if (defaultEntry && (configuredTasks.length === 0)) {
taskQuickPickEntries.push({ type: 'separator', label: nls.localize('configured', 'configured') });
taskQuickPickEntries.push(defaultEntry);
this.topLevelEntries.push({ type: 'separator', label: nls.localize('configured', 'configured') });
this.topLevelEntries.push(defaultEntry);
}
if (extensionTaskTypes.length > 0) {
this.createTypeEntries(taskQuickPickEntries, extensionTaskTypes);
this.createTypeEntries(this.topLevelEntries, extensionTaskTypes);
}
return { entries: taskQuickPickEntries, isSingleConfigured: configuredTasks.length === 1 ? configuredTasks[0] : undefined };
return { entries: this.topLevelEntries, isSingleConfigured: configuredTasks.length === 1 ? configuredTasks[0] : undefined };
}
private async show(placeHolder: string, defaultEntry?: TaskQuickPickEntry): Promise<Task | undefined | null> {
public async show(placeHolder: string, defaultEntry?: TaskQuickPickEntry, startAtType?: string): Promise<Task | undefined | null> {
const picker: IQuickPick<TaskTwoLevelQuickPickEntry> = this.quickInputService.createQuickPick();
picker.placeholder = placeHolder;
picker.matchOnDescription = true;
......@@ -161,22 +165,24 @@ export class TaskQuickPick extends Disposable {
}
});
// First show recent tasks configured tasks. Other tasks will be available at a second level
const topLevelEntriesResult = await this.createTopLevelEntries(defaultEntry);
if (topLevelEntriesResult.isSingleConfigured && this.configurationService.getValue<boolean>(QUICKOPEN_SKIP_CONFIG)) {
picker.dispose();
return this.toTask(topLevelEntriesResult.isSingleConfigured);
let firstLevelTask: Task | ConfiguringTask | string | undefined | null = startAtType;
if (!firstLevelTask) {
// First show recent tasks configured tasks. Other tasks will be available at a second level
const topLevelEntriesResult = await this.getTopLevelEntries(defaultEntry);
if (topLevelEntriesResult.isSingleConfigured && this.configurationService.getValue<boolean>(QUICKOPEN_SKIP_CONFIG)) {
picker.dispose();
return this.toTask(topLevelEntriesResult.isSingleConfigured);
}
const taskQuickPickEntries: QuickPickInput<TaskTwoLevelQuickPickEntry>[] = topLevelEntriesResult.entries;
firstLevelTask = await this.doPickerFirstLevel(picker, taskQuickPickEntries);
}
const taskQuickPickEntries: QuickPickInput<TaskTwoLevelQuickPickEntry>[] = topLevelEntriesResult.entries;
do {
const firstLevelTask = await this.doPickerFirstLevel(picker, taskQuickPickEntries);
if (Types.isString(firstLevelTask)) {
// Proceed to second level of quick pick
const selectedEntry = await this.doPickerSecondLevel(picker, firstLevelTask);
if (selectedEntry && selectedEntry.task === null) {
// The user has chosen to go back to the first level
continue;
firstLevelTask = await this.doPickerFirstLevel(picker, (await this.getTopLevelEntries(defaultEntry)).entries);
} else {
picker.dispose();
return (selectedEntry?.task && !Types.isString(selectedEntry?.task)) ? this.toTask(selectedEntry?.task) : undefined;
......
......@@ -4,15 +4,17 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
import { IQuickPickSeparator, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { matchesFuzzy } from 'vs/base/common/filters';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService';
import { CustomTask, ContributedTask } from 'vs/workbench/contrib/tasks/common/tasks';
import { ITaskService, Task } from 'vs/workbench/contrib/tasks/common/taskService';
import { CustomTask, ContributedTask, ConfiguringTask } from 'vs/workbench/contrib/tasks/common/tasks';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IStringDictionary } from 'vs/base/common/collections';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { TaskQuickPick, TaskTwoLevelQuickPickEntry } from 'vs/workbench/contrib/tasks/browser/taskQuickPick';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { isString } from 'vs/base/common/types';
export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQuickAccessItem> {
......@@ -22,7 +24,9 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQ
constructor(
@IExtensionService extensionService: IExtensionService,
@ITaskService private taskService: ITaskService
@ITaskService private taskService: ITaskService,
@IConfigurationService private configurationService: IConfigurationService,
@IQuickInputService private quickInputService: IQuickInputService
) {
super(TasksQuickAccessProvider.PREFIX);
......@@ -30,7 +34,6 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQ
}
protected async getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IPickerQuickAccessItem | IQuickPickSeparator>> {
// always await extensions
await this.activationPromise;
......@@ -38,102 +41,49 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQ
return [];
}
// Resolve custom and contributed tasks
const tasks = (await this.taskService.tasks())
.filter<CustomTask | ContributedTask>((task): task is CustomTask | ContributedTask => ContributedTask.is(task) || CustomTask.is(task));
if (token.isCancellationRequested) {
return [];
}
this.taskService.migrateRecentTasks(tasks);
const taskQuickPick = new TaskQuickPick(this.taskService, this.configurationService, this.quickInputService);
const topLevelPicks = await taskQuickPick.getTopLevelEntries();
const taskPicks: Array<IPickerQuickAccessItem | IQuickPickSeparator> = [];
// Split up tasks across recently used, configured and detected
const recentlyUsedTasks = this.taskService.getRecentlyUsedTasks();
const recent: Array<CustomTask | ContributedTask> = [];
const configured: CustomTask[] = [];
const detected: ContributedTask[] = [];
const taskMap: IStringDictionary<CustomTask | ContributedTask> = Object.create(null);
for (const task of tasks) {
const key = task.getRecentlyUsedKey();
if (key) {
taskMap[key] = task;
for (const entry of topLevelPicks.entries) {
if (entry.type === 'separator') {
taskPicks.push(entry);
}
}
for (const key of recentlyUsedTasks.keys()) {
const task = taskMap[key];
if (task) {
recent.push(task);
const highlights = matchesFuzzy(filter, entry.label!, true);
if (!highlights) {
continue;
}
}
for (const task of tasks) {
const key = task.getRecentlyUsedKey();
if (!key || !recentlyUsedTasks.has(key)) {
if (CustomTask.is(task)) {
configured.push(task);
const task: Task | ConfiguringTask | string = (<TaskTwoLevelQuickPickEntry>entry).task!;
const quickAccessEntry: IPickerQuickAccessItem = <TaskTwoLevelQuickPickEntry>entry;
quickAccessEntry.ariaLabel = localize('entryAriaLabel', "{0}, tasks picker", entry.label!);
quickAccessEntry.highlights = { label: highlights };
quickAccessEntry.trigger = () => {
if (ContributedTask.is(task)) {
this.taskService.customize(task, undefined, true);
} else if (CustomTask.is(task)) {
this.taskService.openConfig(task);
}
return TriggerAction.CLOSE_PICKER;
};
quickAccessEntry.accept = async () => {
if (isString(task)) {
// switch to quick pick and show second level
taskQuickPick.show(localize('TaskService.pickRunTask', 'Select the task to run'), undefined, task);
} else {
detected.push(task);
this.taskService.run(await this.toTask(task), { attachProblemMatcher: true });
}
}
}
const taskPicks: Array<IPickerQuickAccessItem | IQuickPickSeparator> = [];
const sorter = this.taskService.createSorter();
// Fill picks in sorted order
this.fillPicks(taskPicks, filter, recent, localize('recentlyUsed', "recently used tasks"));
configured.sort((a, b) => sorter.compare(a, b));
this.fillPicks(taskPicks, filter, configured, localize('configured', "configured tasks"));
detected.sort((a, b) => sorter.compare(a, b));
this.fillPicks(taskPicks, filter, detected, localize('detected', "detected tasks"));
};
taskPicks.push(quickAccessEntry);
}
return taskPicks;
}
private fillPicks(taskPicks: Array<IPickerQuickAccessItem | IQuickPickSeparator>, input: string, tasks: Array<CustomTask | ContributedTask>, groupLabel: string): void {
let first = true;
for (const task of tasks) {
const highlights = matchesFuzzy(input, task._label, true);
if (!highlights) {
continue;
}
if (first) {
first = false;
taskPicks.push({ type: 'separator', label: groupLabel });
}
taskPicks.push({
label: task._label,
ariaLabel: localize('entryAriaLabel', "{0}, tasks picker", task._label),
description: this.taskService.getTaskDescription(task),
highlights: { label: highlights },
buttons: (() => {
const buttons = [];
if (ContributedTask.is(task) || CustomTask.is(task)) {
buttons.push({
iconClass: 'codicon-gear',
tooltip: localize('customizeTask', "Configure Task")
});
}
return buttons;
})(),
trigger: () => {
if (ContributedTask.is(task)) {
this.taskService.customize(task, undefined, true);
} else {
this.taskService.openConfig(task);
}
return TriggerAction.CLOSE_PICKER;
},
accept: () => {
this.taskService.run(task, { attachProblemMatcher: true });
}
});
private async toTask(task: Task | ConfiguringTask): Promise<Task | undefined> {
if (!ConfiguringTask.is(task)) {
return task;
}
return this.taskService.tryResolveTask(task);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册