async addConfigurePreset()

in src/presetsController.ts [238:424]


    async addConfigurePreset(): Promise<boolean> {
        interface AddPresetQuickPickItem extends vscode.QuickPickItem {
            name: string;
        }

        enum SpecialOptions {
            CreateFromCompilers = '__createFromCompilers__',
            InheritConfigurationPreset = '__inheritConfigurationPreset__',
            ToolchainFile = '__toolchainFile__',
            Custom = '__custom__'
        }

        const items: AddPresetQuickPickItem[] = [];
        if (preset.configurePresets(this.folderFsPath).length > 0) {
            items.push({
                name: SpecialOptions.InheritConfigurationPreset,
                label: localize('inherit.config.preset', 'Inherit from Configure Preset'),
                description: localize('description.inherit.config.preset', 'Inherit from an existing configure preset')
            });
        }
        items.push({
            name: SpecialOptions.ToolchainFile,
            label: localize('toolchain.file', 'Toolchain File'),
            description: localize('description.toolchain.file', 'Configure with a CMake toolchain file')
        }, {
            name: SpecialOptions.Custom,
            label: localize('custom.config.preset', 'Custom'),
            description: localize('description.custom.config.preset', 'Add an custom configure preset')
        }, {
            name: SpecialOptions.CreateFromCompilers,
            label: localize('create.from.compilers', 'Create from Compilers'),
            description: localize('description.create.from.compilers', 'Create from a pair of compilers on this computer')
        });

        const chosenItem = await vscode.window.showQuickPick(items,
            { placeHolder: localize('add.a.config.preset.placeholder', 'Add a configure preset for {0}', this.folder.name) });
        if (!chosenItem) {
            log.debug(localize('user.cancelled.add.config.preset', 'User cancelled adding configure preset'));
            return false;
        } else {
            let newPreset: preset.ConfigurePreset | undefined;
            switch (chosenItem.name) {
                case SpecialOptions.CreateFromCompilers: {
                    // Check that we have kits
                    if (!await this._kitsController.checkHaveKits()) {
                        return false;
                    }

                    const allKits = this._kitsController.availableKits;
                    // Filter VS based on generators, for example:
                    // VS 2019 Release x86, VS 2019 Preview x86, and VS 2017 Release x86
                    // will be filtered to
                    // VS 2019 x86, VS 2017 x86
                    // Remove toolchain kits
                    const filteredKits: Kit[] = [];
                    for (const kit of allKits) {
                        if (kit.toolchainFile || kit.name === SpecialKits.Unspecified) {
                            continue;
                        }
                        let found = false;
                        if (kit.visualStudio && !kit.compilers) {
                            for (const filteredKit of filteredKits) {
                                if (filteredKit.preferredGenerator?.name === kit.preferredGenerator?.name &&
                                    filteredKit.preferredGenerator?.platform === kit.preferredGenerator?.platform &&
                                    filteredKit.preferredGenerator?.toolset === kit.preferredGenerator?.toolset) {
                                    // Found same generator in the filtered list
                                    found = true;
                                    break;
                                }
                            }
                        }
                        if (!found) {
                            filteredKits.push(kit);
                        }
                    }

                    log.debug(localize('start.selection.of.compilers', 'Start selection of compilers. Found {0} compilers.', filteredKits.length));

                    interface KitItem extends vscode.QuickPickItem {
                        kit: Kit;
                    }
                    log.debug(localize('opening.compiler.selection', 'Opening compiler selection QuickPick'));
                    // Generate the quickpick items from our known kits
                    const getKitName = (kit: Kit) => {
                        if (kit.name === SpecialKits.ScanForKits) {
                            return `[${localize('scan.for.compilers.button', 'Scan for compilers')}]`;
                        } else if (kit.visualStudio && !kit.compilers) {
                            const hostTargetArch = kitHostTargetArch(kit.visualStudioArchitecture!, kit.preferredGenerator?.platform);
                            return `${(kit.preferredGenerator?.name || 'Visual Studio')} ${hostTargetArch}`;
                        } else {
                            return kit.name;
                        }
                    };
                    const item_promises = filteredKits.map(
                        async (kit): Promise<KitItem> => ({
                            label: getKitName(kit),
                            description: await descriptionForKit(kit, true),
                            kit
                        })
                    );
                    const quickPickItems = await Promise.all(item_promises);
                    const chosen_kit = await vscode.window.showQuickPick(quickPickItems,
                        { placeHolder: localize('select.a.compiler.placeholder', 'Select a Kit for {0}', this.folder.name) });
                    if (chosen_kit === undefined) {
                        log.debug(localize('user.cancelled.compiler.selection', 'User cancelled compiler selection'));
                        // No selection was made
                        return false;
                    } else {
                        if (chosen_kit.kit.name === SpecialKits.ScanForKits) {
                            await KitsController.scanForKits(this._cmakeTools);
                            preset.setCompilers(this._kitsController.availableKits);
                            return false;
                        } else {
                            log.debug(localize('user.selected.compiler', 'User selected compiler {0}', JSON.stringify(chosen_kit)));
                            newPreset = {
                                name: '__placeholder__',
                                displayName: chosen_kit.kit.name,
                                description: chosen_kit.description,
                                generator: chosen_kit.kit.preferredGenerator?.name,
                                toolset: chosen_kit.kit.preferredGenerator?.toolset,
                                architecture: chosen_kit.kit.preferredGenerator?.platform,
                                binaryDir: '${sourceDir}/out/build/${presetName}',
                                cacheVariables: {
                                    CMAKE_BUILD_TYPE: 'Debug',
                                    CMAKE_INSTALL_PREFIX: '${sourceDir}/out/install/${presetName}',
                                    CMAKE_C_COMPILER: chosen_kit.kit.compilers?.['C']!,
                                    CMAKE_CXX_COMPILER: chosen_kit.kit.compilers?.['CXX']!
                                }
                            };
                        }
                    }
                    break;
                }
                case SpecialOptions.InheritConfigurationPreset: {
                    const placeHolder = localize('select.one.or.more.config.preset.placeholder', 'Select one or more configure presets');
                    const presets = preset.configurePresets(this.folderFsPath);
                    const inherits = await this.selectAnyPreset(presets, presets, { placeHolder, canPickMany: true });
                    newPreset = { name: '__placeholder__', description: '', displayName: '', inherits };
                    break;
                }
                case SpecialOptions.ToolchainFile: {
                    newPreset = {
                        name: '__placeholder__',
                        displayName: `Configure preset using toolchain file`,
                        description: 'Sets Ninja generator, build and install directory',
                        generator: 'Ninja',
                        binaryDir: '${sourceDir}/out/build/${presetName}',
                        cacheVariables: {
                            CMAKE_BUILD_TYPE: 'Debug',
                            CMAKE_TOOLCHAIN_FILE: '',
                            CMAKE_INSTALL_PREFIX: '${sourceDir}/out/install/${presetName}'
                        }
                    };
                    break;
                }
                case SpecialOptions.Custom: {
                    newPreset = {
                        name: '__placeholder__',
                        displayName: `Custom configure preset`,
                        description: 'Sets Ninja generator, build and install directory',
                        generator: 'Ninja',
                        binaryDir: '${sourceDir}/out/build/${presetName}',
                        cacheVariables: {
                            CMAKE_BUILD_TYPE: 'Debug',
                            CMAKE_INSTALL_PREFIX: '${sourceDir}/out/install/${presetName}'
                        }
                    };
                    break;
                }
                default:
                    // Shouldn't reach here
                    break;
            }

            if (newPreset) {
                const name = await this.showNameInputBox();
                if (!name) {
                    return false;
                }

                newPreset.name = name;
                await this.addPresetAddUpdate(newPreset, 'configurePresets');
            }

            return true;
        }
    }