Skip to content

Commit

Permalink
Implement allowCustomValues
Browse files Browse the repository at this point in the history
Fix #33
  • Loading branch information
MarcelRobitaille committed Sep 23, 2024
1 parent d73a8d5 commit bfee3bd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## [Unreleased]

- Add support for custom values

## [1.11.0] 2024-09-21

- Add support for getting results from stderr (fix issue #86)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Arguments for the extension:
* `useFirstResult`: skip 'Quick Pick' dialog and use first result returned from the command
* `useSingleResult`: skip 'Quick Pick' dialog and use the single result if only one returned from the command
* `rememberPrevious`: remember the value you previously selected and default to it the next time (default false) (:warning: **need taskId to be set**)
* `allowCustomValues`: If true, it's possible to enter a new value that is not part of the command output.
* `taskId`: Unique id to use for storing the last-used value.
* `fieldSeparator`: the string that separates `value`, `label`, `description` and `detail` fields
* `description`: shown as a placeholder in 'Quick Pick', provides context for the input
Expand Down
61 changes: 44 additions & 17 deletions src/lib/CommandHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class CommandHandler {
useFirstResult: CommandHandler.parseBoolean(args.useFirstResult, false),
useSingleResult: CommandHandler.parseBoolean(args.useSingleResult, false),
rememberPrevious: CommandHandler.parseBoolean(args.rememberPrevious, false),
allowCustomValues: CommandHandler.parseBoolean(args.allowCustomValues, false),
stdio: ["stdout", "stderr", "both"].includes(args.stdio as string) ? args.stdio : "stdout",
...args,
} as ShellCommandOptions;
Expand Down Expand Up @@ -214,12 +215,10 @@ export class CommandHandler {

protected async quickPick(input: QuickPickItem[]) {
if (input.length === 0) {
input = this.args.defaultOptions?.map(o => {
return {
value: o,
label: o
};
}) ?? [];
input = this.args.defaultOptions?.map((option) => ({
value: option,
label: option,
})) ?? [];
}

const defaultValue = this.getDefault();
Expand All @@ -234,8 +233,22 @@ export class CommandHandler {
picker.placeholder = this.args.description;
}

const disposable = vscode.Disposable.from(
// Compute all constant (non custom) picker items.
const constantItems = input.map(
(item) =>
({
label: item.label,
description: item.value === defaultValue
? `${item.description} (Default)`
: item.description,
detail: item.detail,
value: item.value,
} as vscode.QuickPickItem),
);

const disposableLikes = [
picker,

picker.onDidAccept(() => {
resolve((picker.selectedItems[0] as QuickPickItem).value);
disposable.dispose();
Expand All @@ -256,17 +269,31 @@ export class CommandHandler {
}
disposable.dispose();
}),
);
];

if (this.args.allowCustomValues) {
// Cache item labels to save some work on keypress.
const itemLabels = input.map((item) => item.label);

disposableLikes.push(picker.onDidChangeValue(() => {
// Vscode API has no mechanism to detect visible items.
// The best we can do is check if it's not exactly equal to an existing item.
if (picker.value !== "" && !itemLabels.includes(picker.value)) {
// There's no more efficient way to do this.
// Vscode doesn't update unless we give it a new object.
picker.items = [...constantItems, {
label: picker.value,
description: "(Custom)",
}];
} else {
picker.items = constantItems;
}
}));
}

picker.items = input.map(
(item) =>
({
label: item.label,
description: item.value === defaultValue ? `${item.description} (Default)` : item.description,
detail: item.detail,
value: item.value,
} as vscode.QuickPickItem),
);
const disposable = vscode.Disposable.from(...disposableLikes);

picker.items = constantItems;

for (const item of picker.items) {
if ((item as QuickPickItem).value === defaultValue) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/ShellCommandOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface ShellCommandOptions
useFirstResult?: boolean;
useSingleResult?: boolean;
rememberPrevious?: boolean;
allowCustomValues?: boolean;
fieldSeparator?: string;
description?: string;
maxBuffer?: number;
Expand Down

0 comments on commit bfee3bd

Please sign in to comment.