提交 b643600e 编写于 作者: B Benjamin Pasero

quick access - operate on picker from providers

上级 9a3c1d43
......@@ -402,7 +402,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
quickNavigate: IQuickNavigateConfiguration | undefined;
get value() {
return this._value;
}
......@@ -412,6 +411,8 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.update();
}
filterValue = (value: string) => value;
get placeholder() {
return this._placeholder;
}
......@@ -597,7 +598,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
return;
}
this._value = value;
this.ui.list.filter(this.ui.inputBox.value);
this.ui.list.filter(this.filterValue(this.ui.inputBox.value));
this.trySelectFirst();
this.onDidChangeValueEmitter.fire(value);
}));
......@@ -771,7 +772,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
if (this.itemsUpdated) {
this.itemsUpdated = false;
this.ui.list.setElements(this.items);
this.ui.list.filter(this.ui.inputBox.value);
this.ui.list.filter(this.filterValue(this.ui.inputBox.value));
this.ui.checkAll.checked = this.ui.list.getAllVisibleChecked();
this.ui.visibleCount.setCount(this.ui.list.getVisibleCount());
this.ui.count.setCount(this.ui.list.getCheckedCount());
......
......@@ -156,6 +156,12 @@ export interface IQuickPick<T extends IQuickPickItem> extends IQuickInput {
value: string;
/**
* A method that allows to massage the value used
* for filtering, e.g, to remove certain parts.
*/
filterValue: (value: string) => string;
placeholder: string | undefined;
readonly onDidChangeValue: Event<string>;
......
......@@ -5,15 +5,17 @@
import 'vs/platform/quickinput/browser/quickAccessHelp';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { IQuickAccessController, IQuickAccessProvider, IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess';
import { Registry } from 'vs/platform/registry/common/platform';
import { CancellationToken } from 'vs/base/common/cancellation';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { once } from 'vs/base/common/functional';
export class QuickAccessController extends Disposable implements IQuickAccessController {
private readonly registry = Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess);
private readonly mapProviderToDescriptor = new Map<IQuickAccessProviderDescriptor, IQuickAccessProvider>();
constructor(
@IQuickInputService private readonly quickInputService: IQuickInputService,
......@@ -22,16 +24,42 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
super();
}
async show(prefix = ''): Promise<void> {
const provider = this.getOrInstantiateProvider(prefix);
show(value = ''): void {
provider.provide(this.quickInputService, CancellationToken.None);
}
// Find provider for the value to show
const [provider, prefix] = this.getOrInstantiateProvider(value);
// Create a picker for the provider to use with the initial value
// and adjust the filtering to exclude the prefix from filtering
const picker = this.quickInputService.createQuickPick();
picker.value = value;
picker.valueSelection = [value.length, value.length];
picker.filterValue = (value: string) => value.substring(prefix.length);
// Cleanup when picker hides
const disposables = new DisposableStore();
once(picker.onDidHide)(() => disposables.dispose());
private mapProviderToDescriptor = new Map<IQuickAccessProviderDescriptor, IQuickAccessProvider>();
// Whenever the value changes, check if the provider has
// changed and if so - re-create the picker from the beginning
disposables.add(picker.onDidChangeValue(value => {
const [providerForValue] = this.getOrInstantiateProvider(value);
if (providerForValue !== provider) {
this.show(value);
}
}));
// Create a cancellation token source that is valid
// as long as the picker has not been closed
const cts = new CancellationTokenSource();
disposables.add(toDisposable(() => cts.dispose(true)));
// Finally ask provider to fill the picker as needed
provider.provide(picker, cts.token);
}
private getOrInstantiateProvider(prefix: string): IQuickAccessProvider {
const providerDescriptor = this.registry.getQuickAccessProvider(prefix) || this.registry.defaultProvider;
private getOrInstantiateProvider(value: string): [IQuickAccessProvider, string /* prefix */] {
const providerDescriptor = this.registry.getQuickAccessProvider(value) || this.registry.defaultProvider;
let provider = this.mapProviderToDescriptor.get(providerDescriptor);
if (!provider) {
......@@ -39,6 +67,6 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
this.mapProviderToDescriptor.set(providerDescriptor, provider);
}
return provider;
return [provider, providerDescriptor.prefix];
}
}
......@@ -3,17 +3,21 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
import { QuickPickInput, IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IQuickAccessProvider, IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess';
import { Registry } from 'vs/platform/registry/common/platform';
import { CancellationToken } from 'vs/base/common/cancellation';
import { localize } from 'vs/nls';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { once } from 'vs/base/common/functional';
class HelpQuickAccessProvider implements IQuickAccessProvider {
private readonly registry = Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess);
async provide(service: IQuickInputService, token: CancellationToken): Promise<void> {
constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { }
async provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): Promise<void> {
const picks: QuickPickInput[] = [];
for (const provider of this.registry.getQuickAccessProviders()) {
......@@ -25,7 +29,18 @@ class HelpQuickAccessProvider implements IQuickAccessProvider {
}
}
await service.pick(picks);
const disposables = new DisposableStore();
once(token.onCancellationRequested)(() => disposables.dispose());
disposables.add(picker.onDidAccept(() => {
const items = picker.selectedItems;
if (items.length === 1) {
this.quickInputService.quickAccess.show(items[0].label);
}
}));
picker.items = picks;
picker.show();
}
}
......
......@@ -3,9 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
import { Registry } from 'vs/platform/registry/common/platform';
import { first } from 'vs/base/common/arrays';
import { startsWith } from 'vs/base/common/strings';
......@@ -14,9 +13,9 @@ import { assertIsDefined } from 'vs/base/common/types';
export interface IQuickAccessController {
/**
* Open the quick access picker with the optional prefix.
* Open the quick access picker with the optional value prefilled.
*/
show(prefix?: string): Promise<void>;
show(value?: string): void;
}
export interface IQuickAccessProvider {
......@@ -24,10 +23,12 @@ export interface IQuickAccessProvider {
/**
* Called whenever a prefix was typed into quick pick that matches the provider.
*
* @param service the service to use to drive the quick input widget
* @param token cancellation support
* @param picker the picker to use for showing provider results.
* @param token providers have to check the cancellation token everytime after
* a long running operation because it could be that the picker has been closed
* or changed meanwhile.
*/
provide(service: IQuickInputService, token: CancellationToken): Promise<void>;
provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): Promise<void>;
}
export interface QuickAccessProviderHelp {
......@@ -50,9 +51,26 @@ export interface QuickAccessProviderHelp {
}
export interface IQuickAccessProviderDescriptor {
readonly ctor: IConstructorSignature0<IQuickAccessProvider>;
/**
* The actual provider that will be instantiated as needed.
*/
readonly ctor: { new(...services: any /* TS BrandedService but no clue how to type this properly */[]): IQuickAccessProvider };
/**
* The prefix for quick access picker to use the provider for.
*/
readonly prefix: string;
/**
* Documentation for the provider in the quick access help.
*/
readonly helpEntries: QuickAccessProviderHelp[];
/**
* A context key that will be set automatically when the
* picker for the provider is showing.
*/
readonly contextKey?: string;
}
......
......@@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
......@@ -209,12 +209,14 @@ export class LegacyQuickInputQuickOpenController extends Disposable {
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready);
class SampleQuickAccessProvider implements IQuickAccessProvider {
async provide(service: IQuickInputService, token: CancellationToken): Promise<void> {
service.pick([
async provide(picker: IQuickPick<IQuickPickItem>, token: CancellationToken): Promise<void> {
picker.items = [
{ label: '1' },
{ label: '2' },
{ label: '3' }
]);
];
picker.show();
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册