Skip to content

Commit 56fd1a7

Browse files
committed
Add support for multi-select choice prompts
This change adds support for the variant of $host.UI.PromptForChoice which is enabled by the IHostUISupportsMultipleChoiceSelection.
1 parent 5a745dd commit 56fd1a7

File tree

2 files changed

+83
-29
lines changed

2 files changed

+83
-29
lines changed

examples/PromptExamples.ps1

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
# Multi-choice prompt
3+
$choices = @(
4+
New-Object "System.Management.Automation.Host.ChoiceDescription" "&Apple", "Apple"
5+
New-Object "System.Management.Automation.Host.ChoiceDescription" "&Banana", "Banana"
6+
New-Object "System.Management.Automation.Host.ChoiceDescription" "&Orange", "Orange"
7+
)
8+
9+
$defaults = [int[]]@(0, 2)
10+
$host.UI.PromptForChoice("Choose a fruit", "You may choose more than one", $choices, $defaults)

src/features/Console.ts

+73-29
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import vscode = require('vscode');
66
import { IFeature } from '../feature';
7+
import { showCheckboxQuickPick, CheckboxQuickPickItem } from '../checkboxQuickPick'
78
import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient';
89

910
export namespace EvaluateRequest {
@@ -46,14 +47,15 @@ interface ShowInputPromptRequestArgs {
4647
}
4748

4849
interface ShowChoicePromptRequestArgs {
50+
isMultiChoice: boolean;
4951
caption: string;
5052
message: string;
5153
choices: ChoiceDetails[];
52-
defaultChoice: number;
54+
defaultChoices: number[];
5355
}
5456

5557
interface ShowChoicePromptResponseBody {
56-
chosenItem: string;
58+
responseText: string;
5759
promptCancelled: boolean;
5860
}
5961

@@ -66,36 +68,62 @@ function showChoicePrompt(
6668
promptDetails: ShowChoicePromptRequestArgs,
6769
client: LanguageClient) : Thenable<ShowChoicePromptResponseBody> {
6870

69-
var quickPickItems =
70-
promptDetails.choices.map<vscode.QuickPickItem>(choice => {
71-
return {
72-
label: choice.label,
73-
description: choice.helpMessage
74-
}
75-
});
71+
var resultThenable: Thenable<ShowChoicePromptResponseBody> = undefined;
72+
73+
if (!promptDetails.isMultiChoice) {
74+
var quickPickItems =
75+
promptDetails.choices.map<vscode.QuickPickItem>(choice => {
76+
return {
77+
label: choice.label,
78+
description: choice.helpMessage
79+
}
80+
});
81+
82+
if (promptDetails.defaultChoices &&
83+
promptDetails.defaultChoices.length > 0) {
7684

77-
// Shift the default item to the front of the
78-
// array so that the user can select it easily
79-
if (promptDetails.defaultChoice > -1 &&
80-
promptDetails.defaultChoice < promptDetails.choices.length) {
85+
// Shift the default items to the front of the
86+
// array so that the user can select it easily
87+
var defaultChoice = promptDetails.defaultChoices[0];
88+
if (defaultChoice > -1 &&
89+
defaultChoice < promptDetails.choices.length) {
8190

82-
var defaultChoiceItem = quickPickItems[promptDetails.defaultChoice];
83-
quickPickItems.splice(promptDetails.defaultChoice, 1);
91+
var defaultChoiceItem = quickPickItems[defaultChoice];
92+
quickPickItems.splice(defaultChoice, 1);
8493

85-
// Add the default choice to the head of the array
86-
quickPickItems = [defaultChoiceItem].concat(quickPickItems);
94+
// Add the default choice to the head of the array
95+
quickPickItems = [defaultChoiceItem].concat(quickPickItems);
96+
}
97+
}
98+
99+
resultThenable =
100+
vscode.window
101+
.showQuickPick(
102+
quickPickItems,
103+
{ placeHolder: promptDetails.caption + " - " + promptDetails.message })
104+
.then(onItemSelected);
87105
}
106+
else {
107+
var checkboxQuickPickItems =
108+
promptDetails.choices.map<CheckboxQuickPickItem>(choice => {
109+
return {
110+
label: choice.label,
111+
description: choice.helpMessage,
112+
isSelected: false
113+
}
114+
});
88115

89-
// For some bizarre reason, the quick pick dialog does not
90-
// work if I return the Thenable immediately at this point.
91-
// It only works if I save the thenable to a variable and
92-
// return the variable instead...
93-
var resultThenable =
94-
vscode.window
95-
.showQuickPick(
96-
quickPickItems,
97-
{ placeHolder: promptDetails.caption + " - " + promptDetails.message })
98-
.then(onItemSelected);
116+
// Select the defaults
117+
promptDetails.defaultChoices.forEach(choiceIndex => {
118+
checkboxQuickPickItems[choiceIndex].isSelected = true
119+
});
120+
121+
resultThenable =
122+
showCheckboxQuickPick(
123+
checkboxQuickPickItems,
124+
{ confirmPlaceHolder: `${promptDetails.caption} - ${promptDetails.message}`})
125+
.then(onItemsSelected);
126+
}
99127

100128
return resultThenable;
101129
}
@@ -112,18 +140,34 @@ function showInputPrompt(
112140
return resultThenable;
113141
}
114142

143+
function onItemsSelected(chosenItems: CheckboxQuickPickItem[]): ShowChoicePromptResponseBody {
144+
if (chosenItems !== undefined) {
145+
return {
146+
promptCancelled: false,
147+
responseText: chosenItems.filter(item => item.isSelected).map(item => item.label).join(", ")
148+
};
149+
}
150+
else {
151+
// User cancelled the prompt, send the cancellation
152+
return {
153+
promptCancelled: true,
154+
responseText: undefined
155+
};
156+
}
157+
}
158+
115159
function onItemSelected(chosenItem: vscode.QuickPickItem): ShowChoicePromptResponseBody {
116160
if (chosenItem !== undefined) {
117161
return {
118162
promptCancelled: false,
119-
chosenItem: chosenItem.label
163+
responseText: chosenItem.label
120164
};
121165
}
122166
else {
123167
// User cancelled the prompt, send the cancellation
124168
return {
125169
promptCancelled: true,
126-
chosenItem: undefined
170+
responseText: undefined
127171
};
128172
}
129173
}

0 commit comments

Comments
 (0)