diff --git a/src/cmakeProject.ts b/src/cmakeProject.ts index 1779acb20..8ca658a9e 100644 --- a/src/cmakeProject.ts +++ b/src/cmakeProject.ts @@ -52,6 +52,7 @@ import { ProjectController } from './projectController'; import { MessageItem } from 'vscode'; import { DebugTrackerFactory, DebuggerInformation, getDebuggerPipeName } from './debug/debuggerConfigureDriver'; import { ConfigurationType } from 'vscode-cmake-tools'; +import { NamedTarget, RichTarget } from '@cmt/drivers/cmakeDriver'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -123,6 +124,15 @@ export interface ConfigureCancelInformation { canceled: boolean; } +/** + * A target with a name, but no output. Only used for targets that have a + * folder property. + */ +interface FolderTarget { + type: 'folder'; + name: string; +} + /** * Class implementing the extension. It's all here! * @@ -2258,21 +2268,60 @@ export class CMakeProject { if (!drv.targets.length) { return await vscode.window.showInputBox({ prompt: localize('enter.target.name', 'Enter a target name') }) || null; } else { - const choices = drv.uniqueTargets.map((t): vscode.QuickPickItem => { - switch (t.type) { - case 'named': { - return { - label: t.name, - description: localize('target.to.build.description', 'Target to build') - }; + type Target = RichTarget | NamedTarget | FolderTarget; + let currentFolder: string | undefined; + + for (let i = 0; i < 2; i++) { + const items: Target[] = []; + const folders: string[] = []; + + drv.uniqueTargets.forEach((t) => { + if (!currentFolder) { + if (t.type === 'named') { + items.push(t); + } else if (t.type === 'rich') { + if (!t.folder) { + items.push(t); + } else if (t.folder && !folders.includes(t.folder.name)) { + folders.push(t.folder.name); + items.push({ type: 'folder', name: t.folder.name }); + } + } + } else { + if (t.type === 'rich' && t.folder && t.folder.name === currentFolder) { + items.push(t); + } } - case 'rich': { - return { label: t.name, description: t.targetType, detail: t.filepath }; + }); + + const choices = items.map((t): vscode.QuickPickItem => { + switch (t.type) { + case 'named': { + return { + label: t.name, + description: localize('target.to.build.description', 'Target to build') + }; + } + case 'rich': { + return { label: t.name, description: t.targetType, detail: t.filepath }; + } + case 'folder': { + return { label: t.name, description: 'FOLDER' }; + } } + }); + + const sel = await vscode.window.showQuickPick(choices, { placeHolder: localize('select.active.target.tooltip', 'Select the default build target') }); + if (!sel) { + return null; + } else if (!folders.includes(sel.label) || currentFolder === sel.label) { + return sel.label; + } else { + currentFolder = sel.label; } - }); - const sel = await vscode.window.showQuickPick(choices, { placeHolder: localize('select.active.target.tooltip', 'Select the default build target') }); - return sel ? sel.label : null; + } + + return null; } } diff --git a/src/drivers/cmakeDriver.ts b/src/drivers/cmakeDriver.ts index f229b55bb..43627aa02 100644 --- a/src/drivers/cmakeDriver.ts +++ b/src/drivers/cmakeDriver.ts @@ -36,6 +36,7 @@ import { CacheEntry } from '@cmt/cache'; import { CMakeBuildRunner } from '@cmt/cmakeBuildRunner'; import { DebuggerInformation } from '@cmt/debug/debuggerConfigureDriver'; import { onBuildSettingsChange, onTestSettingsChange, onPackageSettingsChange } from '@cmt/ui/util'; +import { CodeModelKind } from '@cmt/drivers/cmakeFileApi'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -105,13 +106,14 @@ export interface NamedTarget { } /** - * A target with a name, path, and type. + * A target with a name, path, type and folder. */ export interface RichTarget { type: 'rich'; name: string; filepath: string; targetType: string; + folder?: CodeModelKind.TargetObject; installPaths?: InstallPath[]; } diff --git a/src/drivers/cmakeFileApi.ts b/src/drivers/cmakeFileApi.ts index 81f9eec5d..4fcebdb6d 100644 --- a/src/drivers/cmakeFileApi.ts +++ b/src/drivers/cmakeFileApi.ts @@ -419,6 +419,7 @@ async function convertTargetObjectFileToExtensionTarget(buildDirectory: string, name: targetObject.name, filepath: executablePath, targetType: targetObject.type, + folder: targetObject.folder, type: 'rich' as 'rich', installPaths: installPaths } as RichTarget; diff --git a/src/drivers/cmakeServerDriver.ts b/src/drivers/cmakeServerDriver.ts index 8e048565b..57f46c8db 100644 --- a/src/drivers/cmakeServerDriver.ts +++ b/src/drivers/cmakeServerDriver.ts @@ -470,7 +470,7 @@ export class CMakeServerDriver extends CMakeDriver { * @t the RichTarget currently being examined. */ function targetReducer(set: RichTarget[], t: RichTarget): RichTarget[] { - if (!set.find(t2 => t.name === t2.name && t.filepath === t2.filepath && t.targetType === t2.targetType)) { + if (!set.find(t2 => t.name === t2.name && t.filepath === t2.filepath && t.targetType === t2.targetType && t.folder === t2.folder)) { set.push(t); } return set;