Skip to content

Commit

Permalink
QuickInput Proposed API (microsoft#49340)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrmarti committed Jun 12, 2018
1 parent e0ac369 commit 965c186
Show file tree
Hide file tree
Showing 13 changed files with 1,426 additions and 502 deletions.
7 changes: 5 additions & 2 deletions extensions/vscode-api-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
"version": "0.0.1",
"publisher": "vscode",
"enableProposedApi": true,
"private": true,
"private": true,
"main": "horse",
"activationEvents": [
],
"engines": {
"vscode": "*"
"vscode": "1.25.0"
},
"contributes": {
"configuration": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

'use strict';

import * as assert from 'assert';
import { window, commands } from 'vscode';
import { closeAllEditors } from '../utils';

suite('window namespace tests', function () {

suite('QuickInput tests', function () {
teardown(closeAllEditors);

test('createQuickPick, select second', function (_done) {
let done = (err?: any) => {
done = () => {};
_done(err);
};
const quickPick = window.createQuickPick();
const expectedFocusChanges = [['eins'], ['zwei']];
quickPick.onDidChangeActive(items => {
try {
assert.deepEqual(items.map(item => item.label), expectedFocusChanges.shift());
} catch (err) {
done(err);
}
});
quickPick.onDidAccept(() => {
try {
const items = quickPick.activeItems;
quickPick.dispose();
assert.equal(items.length, 1);
assert.equal(items[0].label, 'zwei');
assert.equal(expectedFocusChanges.length, 0);
done();
} catch (err) {
done(err);
}
});
quickPick.items = ['eins', 'zwei', 'drei'].map(label => ({ label }));
quickPick.show();

(async () => {
await commands.executeCommand('workbench.action.quickOpenSelectNext');
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
})()
.catch(err => done(err));
});
});
});
18 changes: 4 additions & 14 deletions extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ suite('window namespace tests', () => {
});
});

test('Default value for showInput Box accepted even if fails validateInput, #33691', function () {
test('Default value for showInput Box not accepted when it fails validateInput, reversing #33691', async function () {
const result = window.showInputBox({
validateInput: (value: string) => {
if (!value || value.trim().length === 0) {
Expand All @@ -427,19 +427,9 @@ suite('window namespace tests', () => {
}
});

const accept = commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
return Promise.race([
result.then(() => assert.ok(false)),
accept.then(() => assert.ok(false), err => assert.ok(err))
.then(() => new Promise(resolve => setTimeout(resolve, 10)))
])
.then(() => {
const close = commands.executeCommand('workbench.action.closeQuickOpen');
return Promise.all([result, close])
.then(([value]) => {
assert.equal(value, undefined);
});
});
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
await commands.executeCommand('workbench.action.closeQuickOpen');
assert.equal(await result, undefined);
});


Expand Down
98 changes: 88 additions & 10 deletions src/vs/platform/quickinput/common/quickInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { TPromise } from 'vs/base/common/winjs.base';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import URI from 'vs/base/common/uri';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { Event } from 'vs/base/common/event';

export interface IPickOpenEntry {
export interface IQuickPickItem {
id?: string;
label: string;
description?: string;
Expand Down Expand Up @@ -86,24 +89,99 @@ export interface IInputOptions {

export interface IQuickInput {


enabled: boolean;

busy: boolean;

ignoreFocusOut: boolean;

show(): void;

hide(): void;

onDidHide: Event<void>;

dispose(): void;
}

export interface IQuickPick extends IQuickInput {

value: string;

placeholder: string;

readonly onDidValueChange: Event<string>;

readonly onDidAccept: Event<string>;

buttons: ReadonlyArray<IQuickInputButton>;

readonly onDidTriggerCommand: Event<IQuickInputButton>;

items: ReadonlyArray<IQuickPickItem>;

canSelectMany: boolean;

matchOnDescription: boolean;

matchOnDetail: boolean;

readonly activeItems: ReadonlyArray<IQuickPickItem>;

readonly onDidChangeActive: Event<IQuickPickItem[]>;

readonly selectedItems: ReadonlyArray<IQuickPickItem>;

readonly onDidChangeSelection: Event<IQuickPickItem[]>;
}

export interface IInputBox extends IQuickInput {

value: string;

valueSelection: Readonly<[number, number]>;

placeholder: string;

password: boolean;

readonly onDidChangeValue: Event<string>;

readonly onDidAccept: Event<string>;

buttons: ReadonlyArray<IQuickInputButton>;

readonly onDidTriggerButton: Event<IQuickInputButton>;

prompt: string;

validationMessage: string;
}

export interface IQuickInputButton {
iconPath: string | URI | { light: string | URI; dark: string | URI } | ThemeIcon;
tooltip?: string | undefined;
}

export const IQuickInputService = createDecorator<IQuickInputService>('quickInputService');

export interface IQuickInputService {

_serviceBrand: any;

/**
* Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any.
*/
pick<T extends IPickOpenEntry, O extends IPickOptions>(picks: TPromise<T[]>, options?: O, token?: CancellationToken): TPromise<O extends { canPickMany: true } ? T[] : T>;
pick<T extends IQuickPickItem, O extends IPickOptions>(picks: TPromise<T[]>, options?: O, token?: CancellationToken): TPromise<O extends { canPickMany: true } ? T[] : T>;

/**
* Opens the quick input box for text input and returns a promise with the user typed value if any.
*/
input(options?: IInputOptions, token?: CancellationToken): TPromise<string>;
}

export const IQuickInputService = createDecorator<IQuickInputService>('quickInputService');

export interface IQuickInputService extends IQuickInput {

_serviceBrand: any;

multiStepInput<T>(handler: (input: IQuickInput, token: CancellationToken) => Thenable<T>, token?: CancellationToken): Thenable<T>;
createQuickPick(): IQuickPick;
createInputBox(): IInputBox;

focus(): void;

Expand Down
93 changes: 93 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

// This is the place for API experiments and proposal.

import { QuickPickItem } from 'vscode';

declare module 'vscode' {

export namespace window {
Expand Down Expand Up @@ -430,6 +432,97 @@ declare module 'vscode' {

//#endregion

//#region QuickInput API

export namespace window {

/**
* Implementation incomplete. See #49340.
*/
export function createQuickPick(): QuickPick;

/**
* Implementation incomplete. See #49340.
*/
export function createInputBox(): InputBox;
}

export interface QuickInput {

enabled: boolean;

busy: boolean;

ignoreFocusOut: boolean;

show(): void;

hide(): void;

onDidHide: Event<void>;

dispose(): void;
}

export interface QuickPick extends QuickInput {

value: string;

placeholder: string;

readonly onDidChangeValue: Event<string>;

readonly onDidAccept: Event<void>;

buttons: ReadonlyArray<QuickInputButton>;

readonly onDidTriggerButton: Event<QuickInputButton>;

items: ReadonlyArray<QuickPickItem>;

canSelectMany: boolean;

matchOnDescription: boolean;

matchOnDetail: boolean;

readonly activeItems: ReadonlyArray<QuickPickItem>;

readonly onDidChangeActive: Event<QuickPickItem[]>;

readonly selectedItems: ReadonlyArray<QuickPickItem>;

readonly onDidChangeSelection: Event<QuickPickItem[]>;
}

export interface InputBox extends QuickInput {

value: string;

placeholder: string;

password: boolean;

readonly onDidChangeValue: Event<string>;

readonly onDidAccept: Event<string>;

buttons: ReadonlyArray<QuickInputButton>;

readonly onDidTriggerButton: Event<QuickInputButton>;

prompt: string;

validationMessage: string;
}

export interface QuickInputButton {
iconPath: string | Uri | { light: string | Uri; dark: string | Uri } | ThemeIcon;
tooltip?: string | undefined;
}

//#endregion

//#region mjbvz: Unused diagnostics
/**
* Additional metadata about the type of diagnostic.
Expand Down
Loading

0 comments on commit 965c186

Please sign in to comment.