Skip to content

Commit e6291f0

Browse files
FOLDER grouping in default build target dropdown (#3953)
* added FOLDER grouping in default build target dropdown * added option to enable/disable folder grouping * reworked folder grouping to use new option * Added folder grouping to changelog.md * Fix url and CMake capitalisation * changed variables to lowerCamelCase * bugfix showing folder popup when selecting a target with the same name as a folder * Moved FolderTarget to cmakeDriver * Changed the default of 'useFolderPropertyInBuildTargetDropdown' to false
1 parent a1aa2c3 commit e6291f0

File tree

9 files changed

+92
-5
lines changed

9 files changed

+92
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Features:
66

77
- Add an option to specify the launch target for debugging CTest tests. [#4273](https://github.com/microsoft/vscode-cmake-tools/pull/4273)
88
- Add a setting to enable/disable our built-in language services. [#4290](https://github.com/microsoft/vscode-cmake-tools/issues/4290)
9+
- Add an option to group the default build target dropdown using CMake groups [#3953](https://github.com/microsoft/vscode-cmake-tools/pull/3953) [@itzandroidtab](https://github.com/itzandroidtab)
910

1011
Improvements:
1112

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,6 +3650,12 @@
36503650
"default": [],
36513651
"description": "%cmake-tools.configuration.cmake.coverageInfoFiles.description%",
36523652
"scope": "resource"
3653+
},
3654+
"cmake.useFolderPropertyInBuildTargetDropdown": {
3655+
"type": "boolean",
3656+
"default": false,
3657+
"description": "%cmake-tools.configuration.cmake.useFolderPropertyInBuildTargetDropdown.description%",
3658+
"scope": "resource"
36533659
}
36543660
}
36553661
},

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@
298298
"cmake-tools.configuration.cmake.preRunCoverageTarget.description": "Target to build before running tests with coverage using the test explorer",
299299
"cmake-tools.configuration.cmake.postRunCoverageTarget.description": "Target to build after running tests with coverage using the test explorer",
300300
"cmake-tools.configuration.cmake.coverageInfoFiles.description": "LCOV coverage info files to be processed after running tests with coverage using the test explorer.",
301+
"cmake-tools.configuration.cmake.useFolderPropertyInBuildTargetDropdown.description": "Controls if the default build target dropdown is grouped by the CMake folder groups.",
301302
"cmake-tools.debugger.pipeName.description": "Name of the pipe (on Windows) or domain socket (on Unix) to use for debugger communication.",
302303
"cmake-tools.debugger.clean.description": "Clean prior to configuring.",
303304
"cmake-tools.debugger.configureAll.description": "Configure for all projects.",

src/cmakeProject.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { ProjectController } from '@cmt/projectController';
5252
import { MessageItem } from 'vscode';
5353
import { DebugTrackerFactory, DebuggerInformation, getDebuggerPipeName } from '@cmt/debug/cmakeDebugger/debuggerConfigureDriver';
5454
import { ConfigurationType } from 'vscode-cmake-tools';
55+
import { NamedTarget, RichTarget, FolderTarget } from '@cmt/drivers/cmakeDriver';
5556

5657
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
5758
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
@@ -2272,7 +2273,65 @@ export class CMakeProject {
22722273
if (!drv.targets.length) {
22732274
return await vscode.window.showInputBox({ prompt: localize('enter.target.name', 'Enter a target name') }) || null;
22742275
} else {
2275-
const choices = drv.uniqueTargets.map((t): vscode.QuickPickItem => {
2276+
const folders: string[] = [];
2277+
const itemsGroup: (RichTarget | NamedTarget | FolderTarget)[] = [];
2278+
2279+
// group the data
2280+
drv.uniqueTargets.forEach((t) => {
2281+
switch (t.type) {
2282+
case 'named': {
2283+
itemsGroup.push(t);
2284+
break;
2285+
}
2286+
case 'rich': {
2287+
// check if we need to group by folder
2288+
if (this.workspaceContext.config.useFolderPropertyInBuildTargetDropdown && t.folder) {
2289+
if (!folders.includes(t.folder.name)) {
2290+
folders.push(t.folder.name);
2291+
itemsGroup.push({ type: 'folder', name: t.folder.name });
2292+
}
2293+
} else {
2294+
itemsGroup.push(t);
2295+
}
2296+
break;
2297+
}
2298+
}
2299+
});
2300+
2301+
const choicesGroup = itemsGroup.map((t): vscode.QuickPickItem => {
2302+
switch (t.type) {
2303+
case 'named': {
2304+
return {
2305+
label: t.name,
2306+
description: localize('target.to.build.description', 'Target to build')
2307+
};
2308+
}
2309+
case 'rich': {
2310+
return { label: t.name, description: t.targetType, detail: t.filepath };
2311+
}
2312+
case 'folder': {
2313+
return { label: t.name, description: 'FOLDER' };
2314+
}
2315+
}
2316+
});
2317+
2318+
const selGroup = await vscode.window.showQuickPick(choicesGroup, { placeHolder: localize('select.active.target.tooltip', 'Select the default build target') });
2319+
2320+
// exit if we do not group the folders or if we got something other than a folder
2321+
if (!selGroup || !this.workspaceContext.config.useFolderPropertyInBuildTargetDropdown || selGroup.description !== "FOLDER") {
2322+
return selGroup ? selGroup.label : null;
2323+
}
2324+
2325+
const items: (RichTarget | NamedTarget)[] = [];
2326+
2327+
// the user has selected a folder group
2328+
drv.uniqueTargets.forEach((t) => {
2329+
if (t.type === 'rich' && t.folder && t.folder.name === selGroup.label) {
2330+
items.push(t);
2331+
}
2332+
});
2333+
2334+
const choices = items.map((t): vscode.QuickPickItem => {
22762335
switch (t.type) {
22772336
case 'named': {
22782337
return {
@@ -2285,6 +2344,7 @@ export class CMakeProject {
22852344
}
22862345
}
22872346
});
2347+
22882348
const sel = await vscode.window.showQuickPick(choices, { placeHolder: localize('select.active.target.tooltip', 'Select the default build target') });
22892349
return sel ? sel.label : null;
22902350
}

src/config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ export interface ExtensionConfigurationSettings {
221221
preRunCoverageTarget: string | null;
222222
postRunCoverageTarget: string | null;
223223
coverageInfoFiles: string[];
224+
useFolderPropertyInBuildTargetDropdown: boolean;
224225
}
225226

226227
type EmittersOf<T> = {
@@ -588,6 +589,10 @@ export class ConfigurationReader implements vscode.Disposable {
588589
return this.configData.coverageInfoFiles;
589590
}
590591

592+
get useFolderPropertyInBuildTargetDropdown(): boolean {
593+
return this.configData.useFolderPropertyInBuildTargetDropdown;
594+
}
595+
591596
private readonly emitters: EmittersOf<ExtensionConfigurationSettings> = {
592597
autoSelectActiveFolder: new vscode.EventEmitter<boolean>(),
593598
defaultActiveFolder: new vscode.EventEmitter<string | null>(),
@@ -656,7 +661,8 @@ export class ConfigurationReader implements vscode.Disposable {
656661
enableLanguageServices: new vscode.EventEmitter<boolean>(),
657662
preRunCoverageTarget: new vscode.EventEmitter<string | null>(),
658663
postRunCoverageTarget: new vscode.EventEmitter<string | null>(),
659-
coverageInfoFiles: new vscode.EventEmitter<string[]>()
664+
coverageInfoFiles: new vscode.EventEmitter<string[]>(),
665+
useFolderPropertyInBuildTargetDropdown: new vscode.EventEmitter<boolean>()
660666
};
661667

662668
/**

src/drivers/cmakeDriver.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { CacheEntry } from '@cmt/cache';
3636
import { CMakeBuildRunner } from '@cmt/cmakeBuildRunner';
3737
import { DebuggerInformation } from '@cmt/debug/cmakeDebugger/debuggerConfigureDriver';
3838
import { onBuildSettingsChange, onTestSettingsChange, onPackageSettingsChange } from '@cmt/ui/util';
39+
import { CodeModelKind } from '@cmt/drivers/cmakeFileApi';
3940
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
4041
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
4142

@@ -96,6 +97,15 @@ export interface ExecutableTarget {
9697
isInstallTarget?: boolean;
9798
}
9899

100+
/**
101+
* A target with a name, but no output. Only used for targets that have a
102+
* folder property.
103+
*/
104+
export interface FolderTarget {
105+
type: 'folder';
106+
name: string;
107+
}
108+
99109
/**
100110
* A target with a name, but no output. This may be created via `add_custom_command()`.
101111
*/
@@ -105,13 +115,14 @@ export interface NamedTarget {
105115
}
106116

107117
/**
108-
* A target with a name, path, and type.
118+
* A target with a name, path, type and folder.
109119
*/
110120
export interface RichTarget {
111121
type: 'rich';
112122
name: string;
113123
filepath: string;
114124
targetType: string;
125+
folder?: CodeModelKind.TargetObject;
115126
installPaths?: InstallPath[];
116127
}
117128

src/drivers/cmakeFileApi.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ async function convertTargetObjectFileToExtensionTarget(buildDirectory: string,
419419
name: targetObject.name,
420420
filepath: executablePath,
421421
targetType: targetObject.type,
422+
folder: targetObject.folder,
422423
type: 'rich' as 'rich',
423424
installPaths: installPaths
424425
} as RichTarget;

src/drivers/cmakeServerDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ export class CMakeServerDriver extends CMakeDriver {
470470
* @t the RichTarget currently being examined.
471471
*/
472472
function targetReducer(set: RichTarget[], t: RichTarget): RichTarget[] {
473-
if (!set.find(t2 => t.name === t2.name && t.filepath === t2.filepath && t.targetType === t2.targetType)) {
473+
if (!set.find(t2 => t.name === t2.name && t.filepath === t2.filepath && t.targetType === t2.targetType && t.folder === t2.folder)) {
474474
set.push(t);
475475
}
476476
return set;

test/unit-tests/config.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ function createConfig(conf: Partial<ExtensionConfigurationSettings>): Configurat
8181
enableLanguageServices: true,
8282
preRunCoverageTarget: null,
8383
postRunCoverageTarget: null,
84-
coverageInfoFiles: []
84+
coverageInfoFiles: [],
85+
useFolderPropertyInBuildTargetDropdown: true
8586
});
8687
ret.updatePartial(conf);
8788
return ret;

0 commit comments

Comments
 (0)