Initial cut of QuickPick separators (#137244)

* initial cut of QuickPick separators

* add proposed gate
This commit is contained in:
Tyler James Leonhardt 2021-11-15 12:43:10 -08:00 committed by GitHub
parent e1e648fe6e
commit b256d9bc74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 54 deletions

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IPickOptions, IInputOptions, IQuickInputService, IQuickInput, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, TransferQuickPickItem, MainContext, IExtHostContext, TransferQuickInput, TransferQuickInputButton, IInputBoxOptions } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, TransferQuickPickItem, MainContext, IExtHostContext, TransferQuickInput, TransferQuickInputButton, IInputBoxOptions, TransferQuickPickItemOrSeparator } from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { URI } from 'vs/base/common/uri';
import { CancellationToken } from 'vs/base/common/cancellation';
@ -27,7 +27,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
private readonly _proxy: ExtHostQuickOpenShape;
private readonly _quickInputService: IQuickInputService;
private readonly _items: Record<number, {
resolve(items: TransferQuickPickItem[]): void;
resolve(items: TransferQuickPickItemOrSeparator[]): void;
reject(error: Error): void;
}> = {};
@ -43,7 +43,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
}
$show(instance: number, options: IPickOptions<TransferQuickPickItem>, token: CancellationToken): Promise<number | number[] | undefined> {
const contents = new Promise<TransferQuickPickItem[]>((resolve, reject) => {
const contents = new Promise<TransferQuickPickItemOrSeparator[]>((resolve, reject) => {
this._items[instance] = { resolve, reject };
});
@ -73,7 +73,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
}
}
$setItems(instance: number, items: TransferQuickPickItem[]): Promise<void> {
$setItems(instance: number, items: TransferQuickPickItemOrSeparator[]): Promise<void> {
if (this._items[instance]) {
this._items[instance].resolve(items);
delete this._items[instance];
@ -169,7 +169,11 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
}
} else if (param === 'items') {
handlesToItems.clear();
params[param].forEach((item: TransferQuickPickItem) => {
params[param].forEach((item: TransferQuickPickItemOrSeparator) => {
if (item.type === 'separator') {
return;
}
if (item.buttons) {
item.buttons = item.buttons.map((button: TransferQuickInputButton) => {
if (button.iconPath) {

View file

@ -600,6 +600,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return <Thenable<any>>extHostMessageService.showMessage(extension, Severity.Error, message, rest[0], <Array<string | vscode.MessageItem>>rest.slice(1));
},
showQuickPick(items: any, options?: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
// TODO: remove this once quickPickSeparators has been finalized.
if (Array.isArray(items) && items.some((item) => item.kind !== undefined)) {
checkProposedApiEnabled(extension, 'quickPickSeparators');
}
return extHostQuickOpen.showQuickPick(items, options, token);
},
showWorkspaceFolderPick(options?: vscode.WorkspaceFolderPickOptions) {
@ -689,7 +693,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostUrls.registerUriHandler(extension.identifier, handler);
},
createQuickPick<T extends vscode.QuickPickItem>(): vscode.QuickPick<T> {
return extHostQuickOpen.createQuickPick(extension.identifier);
return extHostQuickOpen.createQuickPick(extension);
},
createInputBox(): vscode.InputBox {
return extHostQuickOpen.createInputBox(extension.identifier);
@ -1307,6 +1311,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
FunctionCoverage: extHostTypes.FunctionCoverage,
WorkspaceTrustState: extHostTypes.WorkspaceTrustState,
LanguageStatusSeverity: extHostTypes.LanguageStatusSeverity,
QuickPickItemKind: extHostTypes.QuickPickItemKind,
};
};
}

View file

@ -510,6 +510,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$sendProcessExit(terminalId: number, exitCode: number | undefined): void;
}
export type TransferQuickPickItemOrSeparator = TransferQuickPickItem | quickInput.IQuickPickSeparator;
export interface TransferQuickPickItem extends quickInput.IQuickPickItem {
handle: number;
buttons?: TransferQuickInputButton[];
@ -548,7 +549,7 @@ export interface TransferQuickPick extends BaseTransferQuickInput {
buttons?: TransferQuickInputButton[];
items?: TransferQuickPickItem[];
items?: TransferQuickPickItemOrSeparator[];
activeItems?: number[];
@ -594,7 +595,7 @@ export interface IInputBoxOptions {
export interface MainThreadQuickOpenShape extends IDisposable {
$show(instance: number, options: quickInput.IPickOptions<TransferQuickPickItem>, token: CancellationToken): Promise<number | number[] | undefined>;
$setItems(instance: number, items: TransferQuickPickItem[]): Promise<void>;
$setItems(instance: number, items: TransferQuickPickItemOrSeparator[]): Promise<void>;
$setError(instance: number, error: Error): Promise<void>;
$input(options: IInputBoxOptions | undefined, validateInput: boolean, token: CancellationToken): Promise<string | undefined>;
$createOrUpdate(params: TransferQuickInput): Promise<void>;

View file

@ -9,15 +9,16 @@ import { Emitter } from 'vs/base/common/event';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorkspace';
import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickPickItem, TransferQuickInput, TransferQuickInputButton } from './extHost.protocol';
import type { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickInput, TransferQuickInputButton, TransferQuickPickItemOrSeparator } from './extHost.protocol';
import { URI } from 'vs/base/common/uri';
import { ThemeIcon, QuickInputButtons } from 'vs/workbench/api/common/extHostTypes';
import { ThemeIcon, QuickInputButtons, QuickPickItemKind } from 'vs/workbench/api/common/extHostTypes';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { coalesce } from 'vs/base/common/arrays';
import Severity from 'vs/base/common/severity';
import { ThemeIcon as ThemeIconUtils } from 'vs/platform/theme/common/themeService';
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
export type Item = string | QuickPickItem;
@ -31,7 +32,7 @@ export interface ExtHostQuickOpen {
showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions, token?: CancellationToken): Promise<WorkspaceFolder | undefined>
createQuickPick<T extends QuickPickItem>(extensionId: ExtensionIdentifier): QuickPick<T>;
createQuickPick<T extends QuickPickItem>(extensionId: IExtensionDescription): QuickPick<T>;
createInputBox(extensionId: ExtensionIdentifier): InputBox;
}
@ -87,33 +88,23 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
return itemsPromise.then(items => {
const pickItems: TransferQuickPickItem[] = [];
const pickItems: TransferQuickPickItemOrSeparator[] = [];
for (let handle = 0; handle < items.length; handle++) {
const item = items[handle];
let label: string;
let description: string | undefined;
let detail: string | undefined;
let picked: boolean | undefined;
let alwaysShow: boolean | undefined;
if (typeof item === 'string') {
label = item;
pickItems.push({ label: item, handle });
} else if (item.kind === QuickPickItemKind.Separator) {
pickItems.push({ type: 'separator', label: item.label });
} else {
label = item.label;
description = item.description;
detail = item.detail;
picked = item.picked;
alwaysShow = item.alwaysShow;
pickItems.push({
label: item.label,
description: item.description,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
handle
});
}
pickItems.push({
label,
description,
handle,
detail,
picked,
alwaysShow
});
}
// handle selection changes
@ -192,8 +183,8 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
// ---- QuickInput
createQuickPick<T extends QuickPickItem>(extensionId: ExtensionIdentifier): QuickPick<T> {
const session: ExtHostQuickPick<T> = new ExtHostQuickPick(extensionId, () => this._sessions.delete(session._id));
createQuickPick<T extends QuickPickItem>(extension: IExtensionDescription): QuickPick<T> {
const session: ExtHostQuickPick<T> = new ExtHostQuickPick(extension, () => this._sessions.delete(session._id));
this._sessions.set(session._id, session);
return session;
}
@ -531,8 +522,9 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
private readonly _onDidChangeSelectionEmitter = new Emitter<T[]>();
private readonly _onDidTriggerItemButtonEmitter = new Emitter<QuickPickItemButtonEvent<T>>();
constructor(extensionId: ExtensionIdentifier, onDispose: () => void) {
super(extensionId, onDispose);
// TODO: revert this change once quickPickSeparators has been finalized.
constructor(private readonly extension: IExtensionDescription, onDispose: () => void) {
super(extension.identifier, onDispose);
this._disposables.push(
this._onDidChangeActiveEmitter,
this._onDidChangeSelectionEmitter,
@ -546,6 +538,10 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
}
set items(items: T[]) {
if (items.some((item) => item.kind !== undefined)) {
checkProposedApiEnabled(this.extension, 'quickPickSeparators');
}
this._items = items.slice();
this._handlesToItems.clear();
this._itemsToHandles.clear();
@ -553,22 +549,33 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
this._handlesToItems.set(i, item);
this._itemsToHandles.set(item, i);
});
const pickItems: TransferQuickPickItemOrSeparator[] = [];
for (let handle = 0; handle < items.length; handle++) {
const item = items[handle];
if (item.kind === QuickPickItemKind.Separator) {
pickItems.push({ type: 'separator', label: item.label });
} else {
pickItems.push({
handle,
label: item.label,
description: item.description,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
buttons: item.buttons?.map<TransferQuickInputButton>((button, i) => {
return {
...getIconPathOrClass(button),
tooltip: button.tooltip,
handle: i
};
}),
});
}
}
this.update({
items: items.map((item, i) => ({
label: item.label,
description: item.description,
handle: i,
detail: item.detail,
picked: item.picked,
alwaysShow: item.alwaysShow,
buttons: item.buttons?.map<TransferQuickInputButton>((button, i) => {
return {
...getIconPathOrClass(button),
tooltip: button.tooltip,
handle: i
};
}),
}))
items: pickItems,
});
}

View file

@ -2904,6 +2904,11 @@ export class QuickInputButtons {
private constructor() { }
}
export enum QuickPickItemKind {
Default = 1,
Separator = 2,
}
export enum ExtensionKind {
UI = 1,
Workspace = 2

View file

@ -39,6 +39,7 @@ export const allApiProposals = Object.freeze({
notebookMessaging: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts',
notebookMime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMime.d.ts',
portsAttributes: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.portsAttributes.d.ts',
quickPickSeparators: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSeparators.d.ts',
quickPickSortByLabel: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts',
resolvers: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.resolvers.d.ts',
scmActionButton: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.scmActionButton.d.ts',

View file

@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/74967
export enum QuickPickItemKind {
Default = 1,
Separator = 2,
}
export interface QuickPickItem {
kind?: QuickPickItemKind
}
}