(start: InputStep) {
+ let step: InputStep | void = start;
+ while (step) {
+ this.steps.push(step);
+ if (this.current) {
+ this.current.enabled = false;
+ this.current.busy = true;
+ }
+ try {
+ step = await step(this);
+ } catch (err) {
+ if (err === InputFlowAction.back) {
+ this.steps.pop();
+ step = this.steps.pop();
+ } else if (err === InputFlowAction.resume) {
+ step = this.steps.pop();
+ } else if (err === InputFlowAction.cancel) {
+ step = undefined;
+ } else {
+ throw err;
+ }
+ }
+ }
+ if (this.current) {
+ this.current.dispose();
+ }
+ }
+
+ async showQuickPick({ title, step, totalSteps, items, placeholder, buttons, shouldResume }: P) {
+ const disposables: Disposable[] = [];
+ try {
+ return await new Promise((resolve, reject) => {
+ const input = window.createQuickPick();
+ input.title = title;
+ input.step = step;
+ input.totalSteps = totalSteps;
+ input.placeholder = placeholder;
+ input.items = items;
+ input.buttons = [
+ ...(this.steps.length > 1 ? [window.quickInputBackButton] : []),
+ ...(buttons || [])
+ ];
+ disposables.push(
+ input.onDidTriggerButton(item => {
+ if (item === window.quickInputBackButton) {
+ reject(InputFlowAction.back);
+ } else {
+ resolve(item);
+ }
+ }),
+ input.onDidChangeSelection(items => resolve(items[0])),
+ input.onDidHide(() => {
+ (async () => {
+ reject(shouldResume && await shouldResume() ? InputFlowAction.resume : InputFlowAction.cancel);
+ })()
+ .catch(reject);
+ })
+ );
+ if (this.current) {
+ this.current.dispose();
+ }
+ this.current = input;
+ this.current.show();
+ });
+ } finally {
+ disposables.forEach(d => d.dispose());
+ }
+ }
+
+ async showInputBox({ title, step, totalSteps, value, prompt, validate, buttons, shouldResume }: P) {
+ const disposables: Disposable[] = [];
+ try {
+ return await new Promise((resolve, reject) => {
+ const input = window.createInputBox();
+ input.title = title;
+ input.step = step;
+ input.totalSteps = totalSteps;
+ input.value = value || '';
+ input.prompt = prompt;
+ input.buttons = [
+ ...(this.steps.length > 1 ? [window.quickInputBackButton] : []),
+ ...(buttons || [])
+ ];
+ let validating = validate('');
+ disposables.push(
+ input.onDidTriggerButton(item => {
+ if (item === window.quickInputBackButton) {
+ reject(InputFlowAction.back);
+ } else {
+ resolve(item);
+ }
+ }),
+ input.onDidAccept(async () => {
+ const value = input.value;
+ input.enabled = false;
+ input.busy = true;
+ if (!(await validate(value))) {
+ resolve(value);
+ }
+ input.enabled = true;
+ input.busy = false;
+ }),
+ input.onDidChangeValue(async text => {
+ const current = validate(text);
+ validating = current;
+ const validationMessage = await current;
+ if (current === validating) {
+ input.validationMessage = validationMessage;
+ }
+ }),
+ input.onDidHide(() => {
+ (async () => {
+ reject(shouldResume && await shouldResume() ? InputFlowAction.resume : InputFlowAction.cancel);
+ })()
+ .catch(reject);
+ })
+ );
+ if (this.current) {
+ this.current.dispose();
+ }
+ this.current = input;
+ this.current.show();
+ });
+ } finally {
+ disposables.forEach(d => d.dispose());
+ }
+ }
+ }
+
+
+ // ---------------------------------------------------------------------------------------
+
+
+ async function validateNameIsUnique(name: string) {
+ // ...validate...
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ return name === 'vscode' ? 'Name not unique' : undefined;
+ }
+
+ async function getAvailableRuntimes(resourceGroup: QuickPickItem | string, token?: CancellationToken): Promise {
+ // ...retrieve...
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ return ['Node 8.9', 'Node 6.11', 'Node 4.5']
+ .map(label => ({ label }));
+ }
+
+ const state = await collectInputs();
+ window.showInformationMessage(`Got: ${typeof state.resourceGroup === 'string' ? state.resourceGroup : state.resourceGroup.label}, ${state.name}, ${state.runtime.label}`);
+}
diff --git a/quickinput-sample/src/ref.d.ts b/quickinput-sample/src/ref.d.ts
new file mode 100644
index 00000000..98187cf6
--- /dev/null
+++ b/quickinput-sample/src/ref.d.ts
@@ -0,0 +1,7 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+// TODO
+///
\ No newline at end of file
diff --git a/quickinput-sample/tsconfig.json b/quickinput-sample/tsconfig.json
new file mode 100644
index 00000000..034d41ec
--- /dev/null
+++ b/quickinput-sample/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es6",
+ "outDir": "out",
+ "lib": [
+ "es6"
+ ],
+ "sourceMap": true,
+ "rootDir": "src",
+ /* Strict Type-Checking Option */
+ "strict": true, /* enable all strict type-checking options */
+ /* Additional Checks */
+ "noUnusedLocals": true /* Report errors on unused locals. */
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/quickinput-sample/tslint.json b/quickinput-sample/tslint.json
new file mode 100644
index 00000000..2bd680db
--- /dev/null
+++ b/quickinput-sample/tslint.json
@@ -0,0 +1,15 @@
+{
+ "rules": {
+ "no-string-throw": true,
+ "no-unused-expression": true,
+ "no-duplicate-variable": true,
+ "curly": true,
+ "class-name": true,
+ "semicolon": [
+ true,
+ "always"
+ ],
+ "triple-equals": true
+ },
+ "defaultSeverity": "warning"
+}
\ No newline at end of file