Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuickInput : Add an example of prompt with history #89

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions quickinput-sample/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import { window, commands, ExtensionContext } from 'vscode';
import { showQuickPick, showInputBox } from './basicInput';
import { multiStepInput } from './multiStepInput';
import { quickOpen } from './quickOpen';
import { getPromptCommand } from './promptCommandWithHistory';

export function activate(context: ExtensionContext) {
context.subscriptions.push(commands.registerCommand('samples.quickInput', async () => {
const promptCommand = getPromptCommand(context.globalState);
const options: { [key: string]: (context: ExtensionContext) => Promise<void> } = {
showQuickPick,
showInputBox,
multiStepInput,
quickOpen,
promptCommand
};
const quickPick = window.createQuickPick();
quickPick.items = Object.keys(options).map(label => ({ label }));
Expand Down
101 changes: 101 additions & 0 deletions quickinput-sample/src/promptCommandWithHistory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { window, Disposable, Memento } from 'vscode';
import { QuickPickItem } from 'vscode';

const HISTORY_KEY = 'HISTORY_KEY';


/**
* A command prompt with history
*
*/
export const getPromptCommand = (memo: Memento) => {
const pickCommand = getPickCommand(memo);
// §TODO: cache promptCommand!
return async function promptCommand() {
const command = await pickCommand();
if (command) {
window.showInformationMessage(`You picked the following command: '${command}'`)
AdrieanKhisbe marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

class CommandItem implements QuickPickItem {
public static HISTORY: string = 'history';
public static INPUT: string = 'input';

public label: string;
public description?: string;
public type: string;

constructor(type: string, label: string, description?: string) {
this.type = type;
this.label = label;
this.description = description;
}

static input(content: string): CommandItem {
return new CommandItem(CommandItem.INPUT, content, '(current input)');
}
static history(content: string, description?: string): CommandItem {
return new CommandItem(CommandItem.HISTORY, content, description);
}
}

const getPickCommand = (memo: Memento) => async function pickCommand() {
const disposables: Disposable[] = [];
try {
return await new Promise<string | undefined>((resolve, reject) => {
const input = window.createQuickPick<CommandItem>();
input.placeholder = 'Type a command';
input.items = [];

const updateQuickPick = (value?: string): void => {
if (value === input.value) return;
if (!value) {
AdrieanKhisbe marked this conversation as resolved.
Show resolved Hide resolved
if (input.items[0] && input.items[0].type === 'input')
input.items = input.items.slice(1);
return;
}
input.items = [CommandItem.input(value)].concat(
AdrieanKhisbe marked this conversation as resolved.
Show resolved Hide resolved
input.items[0] && input.items[0].type === 'input'
? input.items.slice(1)
:input.items
);
// §todo: add autocomplete suggestions
};

disposables.push(
input.onDidChangeValue(updateQuickPick),
input.onDidChangeSelection((items: CommandItem[]) => {
const item = items[0];
if (item.type === CommandItem.HISTORY) {
resolve(item.label);
input.hide();
// do not record new input in history
// §todo : maybe reorder
} else if (item.type === CommandItem.INPUT) {
resolve(item.label);
input.hide();
// record new input in history
if (!item.label.startsWith(' ')) {
chrmarti marked this conversation as resolved.
Show resolved Hide resolved
const currentHistory: string[] = memo.get(HISTORY_KEY, []);
currentHistory.unshift(item.label);
memo.update(HISTORY_KEY, currentHistory);
}
}
}),
input.onDidHide(() => {
resolve(undefined);
input.dispose();
})
);
input.show();
const historyItems: CommandItem[] = memo.get(HISTORY_KEY, []).map(
(cmd: string, index: number) => CommandItem.history(cmd, `(history item ${index})`)
);
input.items = input.items.concat(historyItems);
});
} finally {
disposables.forEach(d => d.dispose());
}
};