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());
+ }
+ }
+}
diff --git a/quickinput-sample/src/quickOpen.ts b/quickinput-sample/src/quickOpen.ts
new file mode 100644
index 00000000..c6f8fa29
--- /dev/null
+++ b/quickinput-sample/src/quickOpen.ts
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as path from 'path';
+import * as cp from 'child_process';
+import { Uri, window, Disposable } from 'vscode';
+import { QuickPickItem } from 'vscode';
+import { workspace } from 'vscode';
+
+/**
+ * A file opener using window.createQuickPick().
+ *
+ * It shows how the list of items can be dynamically updated based on
+ * the user's input in the filter field.
+ */
+export async function quickOpen() {
+ const uri = await pickFile();
+ if (uri) {
+ const document = await workspace.openTextDocument(uri);
+ await window.showTextDocument(document);
+ }
+}
+
+class FileItem implements QuickPickItem {
+
+ label: string;
+ description: string;
+
+ constructor(public base: Uri, public uri: Uri) {
+ this.label = path.basename(uri.fsPath);
+ this.description = path.dirname(path.relative(base.fsPath, uri.fsPath));
+ }
+}
+
+async function pickFile() {
+ const disposables: Disposable[] = [];
+ try {
+ return await new Promise((resolve, reject) => {
+ const input = window.createQuickPick();
+ input.placeholder = 'Type to search for files';
+ let rgs: cp.ChildProcess[] = [];
+ disposables.push(
+ input.onDidChangeValue(value => {
+ rgs.forEach(rg => rg.kill());
+ if (!value) {
+ input.items = [];
+ return;
+ }
+ input.busy = true;
+ const cwds = workspace.workspaceFolders ? workspace.workspaceFolders.map(f => f.uri.fsPath) : [process.cwd()];
+ rgs = cwds.map(cwd => {
+ const rg = cp.exec(`rg --files -g '*${value}*'`, { cwd }, (err, stdout) => {
+ const i = rgs.indexOf(rg);
+ if (i !== -1) {
+ if (rgs.length === cwds.length) {
+ input.items = [];
+ }
+ if (!err) {
+ input.items = input.items.concat(
+ stdout
+ .split('\n').slice(0, 50)
+ .map(relative => new FileItem(Uri.file(cwd), Uri.file(path.join(cwd, relative))))
+ );
+ }
+ rgs.splice(i, 1);
+ if (!rgs.length) {
+ input.busy = false;
+ }
+ }
+ });
+ return rg;
+ });
+ }),
+ input.onDidChangeSelection(items => {
+ resolve(items[0].uri);
+ input.hide();
+ }),
+ input.onDidHide(() => {
+ rgs.forEach(rg => rg.kill());
+ resolve(undefined);
+ input.dispose();
+ })
+ );
+ input.show();
+ });
+ } finally {
+ disposables.forEach(d => d.dispose());
+ }
+}
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