Repository: vscode
Issue: Allow to bring up a dialog with multiple inputs
Labels: feature-request,api,linux,dialogs

## Feature request

It would be nice if an extension could present a single dialog with multiple input fields. For example, the [New Project command in Ionide](https://github.com/ionide/ionide-vscode-fsharp/blob/a58b470dfd2a891eb46a545df0eb326fb0d93038/src/Components/Forge.fs#L142) asks for project directory and project name, and it would be nice to be able to input both at once in a single dialog. Another use case: I would like to implement the [Project Scaffold init script](https://github.com/fsprojects/ProjectScaffold/blob/master/init.fsx#L86) as another option in Ionide's New Project setup. It asks at least seven questions (more if you choose to let it run `git init` for you), and asking each question one at a time in separate dialogs makes for a less-than-ideal user experience. I'd like to be able to present all seven questions in a single dialog.
## Suggested API

`showInputDialog(options: Map<string, InputBoxOptions|QuickPickOptions>, quickPickItems?: Map<string, string[] | Thenable<string[]>>): Thenable<Map<string,string>>`

`options` is an ES6 Map whose keys are the names of the fields we're asking the user to fill in. The user won't see these names, but they will be used as the keys of the resulting Map object. Their ordering matters, since the order of the keys in the Map will be used as the order in which to present the fields in the interaction dialog. (If using an ES6 Map is not yet possible in VS Code, then `options` would be a plain old Javascript object. In that case, an additional `fieldOrder` parameter, an array of strings, would be required -- see below for suggested API if ES6 Map is not yet possible).

The values of the `options` Map will be the InputBoxOptions or QuickPickOptions for that particular field in the interaction dialog. These will be treated exactly as they are in the `showInputBox` and `showQuickPick` functions. If any values of the `options` Map are `QuickPickOptions`, then the `quickPickItems` parameter is required. Its keys must match the keys of `options` that have a `QuickPickOptions` value, and its value is the list of items to pick from (exactly equivalent to the `items` parameter of the `showQuickPick` function). And, just like `showQuickPick`, there would need to be another overload that would match the `showQuickPick<T extends QuickPickItem>(items: T[] | Thenable<T[]>, ...)` overload. I.e.,

`showInputDialog<T extends QuickPickItem>(options: Map<string, InputBoxOptions|QuickPickOptions>, quickPickItems?: Map<string, T[] | Thenable<T[]>>): Thenable<Map<string,string|T>>`

The difference between this and the non-generic `showInputDialog` would be exactly the same as the difference between `showQuickPick<T>` and non-generic `showQuickPick`, so I won't go into further detail on this overload.

The return value of `showInputDialog` would be a promise that resolves to an ES6 Map whose keys are the same as the keys of the `options` parameter, and whose values are the result of what the user typed. If the user canceled the dialog by pressing Escape, the values of the Map will be `undefined`; otherwise, they will be strings in the case of `InputBoxOptions` fields, and either strings or `T` instances in the case of `QuickPickOptions` fields (where `T`, of course, extends `QuickPickItem`, and is only returned in the generic version of `showInputDialog`).

As mentioned above, if it is not yet possible in VS Code's codebase to use an ES6 Map, then my suggested API would look like:

`showInputDialog(fieldOrder: string[], options: object, quickPickItems?: object): Thenable<object>`

or:

`showInputDialog<T extends QuickPickItem>(fieldOrder: string[], options: object, quickPickItems?: object): Thenable<object>`

for the generic version (returning `T` instances, rather than strings, for any QuickPick fields). The keys and values of the input and output objects would be identical to the `Map` version; only the `fieldOrder` parameter is added to specify the order in which the fields should be listed in the dialog.
## Usage example

Since that specification is a bit hard to read, here is an example.

``` javascript
var opts = new Map<string,InputBoxOptions|QuickPickOptions>();
var items = new Map<string,string[]>;
opts.add("ProjectName", {prompt: "Project name?"});
opts.add("InitializeGit", {prompt: "Initialize Git? Y/N"});
opts.add("Template", {placeholder: "Project template"});
items.add("Template", ["F#", "C#", "VB"]);
showInputDialog(opts, items).then(function(result) {
    if (result["Template"] == "VB") {
        showWarningMessage("Visual Basic support is deprecated.");
    }
    showInformationMessage("Initializing project...");
    initializeProject(result["ProjectName"]);
    // etc.
});
```