From 8e9224b1cf76066ce88b32659adcd410f69ea9ec Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 22 Jun 2018 11:40:08 +0200 Subject: [PATCH] QuickOpen sample --- quickinput-sample/src/extension.ts | 2 + quickinput-sample/src/quickOpen.ts | 85 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 quickinput-sample/src/quickOpen.ts diff --git a/quickinput-sample/src/extension.ts b/quickinput-sample/src/extension.ts index f5224dfb..9ba76752 100644 --- a/quickinput-sample/src/extension.ts +++ b/quickinput-sample/src/extension.ts @@ -9,6 +9,7 @@ import { window, commands, ExtensionContext } from 'vscode'; import { showInputBox } from './basicInput'; import { createQuickPick } from './generalInput'; import { multiStepInput } from './multiStepInput'; +import { quickOpen } from './quickOpen'; export function activate(context: ExtensionContext) { context.subscriptions.push(commands.registerCommand('samples.quickInput', async () => { @@ -16,6 +17,7 @@ export function activate(context: ExtensionContext) { showInputBox, createQuickPick, multiStepInput, + quickOpen, }; const quickPick = window.createQuickPick(); quickPick.items = Object.keys(options).map(label => ({ label })); diff --git a/quickinput-sample/src/quickOpen.ts b/quickinput-sample/src/quickOpen.ts new file mode 100644 index 00000000..d40d639c --- /dev/null +++ b/quickinput-sample/src/quickOpen.ts @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------------------------- + * 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'; + +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()); + } +}