Skip to content

Commit d27ed19

Browse files
committed
Debug: Support launch config grouping and sorting
fixes microsoft#82332
1 parent e94ab83 commit d27ed19

6 files changed

Lines changed: 98 additions & 24 deletions

File tree

src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,14 @@ export class StartDebugActionViewItem implements IActionViewItem {
157157
this.selected = 0;
158158
this.options = [];
159159
const manager = this.debugService.getConfigurationManager();
160-
const launches = manager.getLaunches();
161160
const inWorkspace = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE;
162-
launches.forEach(launch =>
163-
launch.getConfigurationNames().forEach(name => {
164-
if (name === manager.selectedConfiguration.name && launch === manager.selectedConfiguration.launch) {
165-
this.selected = this.options.length;
166-
}
167-
const label = inWorkspace ? `${name} (${launch.name})` : name;
168-
this.options.push({ label, handler: () => { manager.selectConfiguration(launch, name); return true; } });
169-
}));
161+
manager.getAllConfigurations().forEach(({ launch, name }) => {
162+
if (name === manager.selectedConfiguration.name && launch === manager.selectedConfiguration.launch) {
163+
this.selected = this.options.length;
164+
}
165+
const label = inWorkspace ? `${name} (${launch.name})` : name;
166+
this.options.push({ label, handler: () => { manager.selectConfiguration(launch, name); return true; } });
167+
});
170168

171169
if (this.options.length === 0) {
172170
this.options.push({ label: nls.localize('noConfigurations', "No Configurations"), handler: () => false });
@@ -175,7 +173,7 @@ export class StartDebugActionViewItem implements IActionViewItem {
175173
}
176174

177175
const disabledIdx = this.options.length - 1;
178-
launches.filter(l => !l.hidden).forEach(l => {
176+
manager.getLaunches().filter(l => !l.hidden).forEach(l => {
179177
const label = inWorkspace ? nls.localize("addConfigTo", "Add Config ({0})...", l.name) : nls.localize('addConfiguration', "Add Configuration...");
180178
this.options.push({
181179
label, handler: () => {

src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { IFileService } from 'vs/platform/files/common/files';
2121
import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace';
2222
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2323
import { ICommandService } from 'vs/platform/commands/common/commands';
24-
import { IDebugConfigurationProvider, ICompound, IDebugConfiguration, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, IDebugAdapterDescriptorFactory, IDebugAdapter, IDebugSession, IAdapterDescriptor, CONTEXT_DEBUG_CONFIGURATION_TYPE, IDebugAdapterFactory } from 'vs/workbench/contrib/debug/common/debug';
24+
import { IDebugConfigurationProvider, ICompound, IDebugConfiguration, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, IDebugAdapterDescriptorFactory, IDebugAdapter, IDebugSession, IAdapterDescriptor, CONTEXT_DEBUG_CONFIGURATION_TYPE, IDebugAdapterFactory, IConfigPresentation } from 'vs/workbench/contrib/debug/common/debug';
2525
import { Debugger } from 'vs/workbench/contrib/debug/common/debugger';
2626
import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
2727
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -214,6 +214,43 @@ export class ConfigurationManager implements IConfigurationManager {
214214
return results.reduce((first, second) => first.concat(second), []);
215215
}
216216

217+
getAllConfigurations(): { launch: ILaunch; name: string; }[] {
218+
const all: { launch: ILaunch, name: string, presentation?: IConfigPresentation }[] = [];
219+
for (let l of this.launches) {
220+
for (let name of l.getConfigurationNames()) {
221+
const config = l.getConfiguration(name) || l.getCompound(name);
222+
if (config && !config.presentation?.hidden) {
223+
all.push({ launch: l, name, presentation: config.presentation });
224+
}
225+
}
226+
}
227+
228+
return all.sort((first, second) => {
229+
if (!first.presentation) {
230+
return 1;
231+
}
232+
if (!second.presentation) {
233+
return -1;
234+
}
235+
if (!first.presentation.group) {
236+
return 1;
237+
}
238+
if (!second.presentation.group) {
239+
return -1;
240+
}
241+
if (first.presentation.group !== second.presentation.group) {
242+
return first.presentation.group.localeCompare(second.presentation.group);
243+
}
244+
if (typeof first.presentation.order !== 'number') {
245+
return 1;
246+
}
247+
if (typeof second.presentation.order !== 'number') {
248+
return -1;
249+
}
250+
return first.presentation.order - second.presentation.order;
251+
});
252+
}
253+
217254
private registerListeners(): void {
218255
debuggersExtPoint.setHandler((extensions, delta) => {
219256
delta.added.forEach(added => {

src/vs/workbench/contrib/debug/browser/debugQuickOpen.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,18 @@ export class DebugQuickOpenHandler extends QuickOpenHandler {
9696
const configurations: QuickOpenEntry[] = [];
9797

9898
const configManager = this.debugService.getConfigurationManager();
99-
const launches = configManager.getLaunches();
100-
for (let launch of launches) {
101-
launch.getConfigurationNames().map(config => ({ config: config, highlights: matchesFuzzy(input, config, true) || undefined }))
102-
.filter(({ highlights }) => !!highlights)
103-
.forEach(({ config, highlights }) => {
104-
if (launch === configManager.selectedConfiguration.launch && config === configManager.selectedConfiguration.name) {
105-
this.autoFocusIndex = configurations.length;
106-
}
107-
configurations.push(new StartDebugEntry(this.debugService, this.contextService, this.notificationService, launch, config, highlights));
108-
});
99+
const allConfigurations = configManager.getAllConfigurations();
100+
for (let config of allConfigurations) {
101+
const highlights = matchesFuzzy(input, config.name, true);
102+
if (highlights) {
103+
if (config.launch === configManager.selectedConfiguration.launch && config.name === configManager.selectedConfiguration.name) {
104+
this.autoFocusIndex = configurations.length;
105+
}
106+
configurations.push(new StartDebugEntry(this.debugService, this.contextService, this.notificationService, config.launch, config.name, highlights));
107+
}
109108
}
110-
launches.filter(l => !l.hidden).forEach((l, index) => {
109+
110+
configManager.getLaunches().filter(l => !l.hidden).forEach((l, index) => {
111111

112112
const label = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? nls.localize("addConfigTo", "Add Config ({0})...", l.name) : nls.localize('addConfiguration', "Add Configuration...");
113113
const entry = new AddConfigEntry(label, l, this.commandService, this.contextService, matchesFuzzy(input, label, true) || undefined);

src/vs/workbench/contrib/debug/common/debug.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,13 +487,19 @@ export interface IEnvConfig {
487487
noDebug?: boolean;
488488
}
489489

490+
export interface IConfigPresentation {
491+
hidden?: boolean;
492+
group?: string;
493+
order?: number;
494+
}
495+
490496
export interface IConfig extends IEnvConfig {
491497

492498
// fundamental attributes
493499
type: string;
494500
request: string;
495501
name: string;
496-
502+
presentation?: IConfigPresentation;
497503
// platform specifics
498504
windows?: IEnvConfig;
499505
osx?: IEnvConfig;
@@ -510,6 +516,7 @@ export interface ICompound {
510516
name: string;
511517
preLaunchTask?: string | TaskIdentifier;
512518
configurations: (string | { name: string, folder: string })[];
519+
presentation?: IConfigPresentation;
513520
}
514521

515522
export interface IDebugAdapter extends IDisposable {
@@ -631,6 +638,8 @@ export interface IConfigurationManager {
631638

632639
getLaunch(workspaceUri: uri | undefined): ILaunch | undefined;
633640

641+
getAllConfigurations(): { launch: ILaunch, name: string }[];
642+
634643
/**
635644
* Allows to register on change of selected debug configuration.
636645
*/

src/vs/workbench/contrib/debug/common/debugSchemas.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,33 @@ export const breakpointsExtPoint = extensionsRegistry.ExtensionsRegistry.registe
132132
});
133133

134134
// debug general schema
135+
136+
export const presentationSchema: IJSONSchema = {
137+
type: 'object',
138+
description: nls.localize('presentation', "Presentation options on how to show this configuration in the debug configuration dropdown and the command palette."),
139+
properties: {
140+
hidden: {
141+
type: 'boolean',
142+
default: false,
143+
description: nls.localize('presentation.hidden', "Controls if this configuration should be shown in the configuration dropdown and the command palette.")
144+
},
145+
group: {
146+
type: 'string',
147+
default: '',
148+
description: nls.localize('presentation.group', "Group that this configuration belongs to. Used for grouping and sorting in the configuration dropdown and the command palette.")
149+
},
150+
order: {
151+
type: 'number',
152+
default: 1,
153+
description: nls.localize('presentation.order', "Order of this configuration within a group. Used for grouping and sorting in the configuration dropdown and the command palette.")
154+
}
155+
},
156+
default: {
157+
hidden: false,
158+
group: '',
159+
order: 1
160+
}
161+
};
135162
const defaultCompound: ICompound = { name: 'Compound', configurations: [] };
136163
export const launchSchema: IJSONSchema = {
137164
id: launchSchemaId,
@@ -167,6 +194,7 @@ export const launchSchema: IJSONSchema = {
167194
type: 'string',
168195
description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.")
169196
},
197+
presentation: presentationSchema,
170198
configurations: {
171199
type: 'array',
172200
default: [],

src/vs/workbench/contrib/debug/common/debugger.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { URI } from 'vs/base/common/uri';
2222
import { Schemas } from 'vs/base/common/network';
2323
import { isDebuggerMainContribution } from 'vs/workbench/contrib/debug/common/debugUtils';
2424
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
25+
import { presentationSchema } from 'vs/workbench/contrib/debug/common/debugSchemas';
2526

2627
export class Debugger implements IDebugger {
2728

@@ -222,7 +223,7 @@ export class Debugger implements IDebugger {
222223
};
223224
properties['name'] = {
224225
type: 'string',
225-
description: nls.localize('debugName', "Name of configuration; appears in the launch configuration drop down menu."),
226+
description: nls.localize('debugName', "Name of configuration; appears in the launch configuration dropdown menu."),
226227
default: 'Launch'
227228
};
228229
properties['request'] = {
@@ -250,6 +251,7 @@ export class Debugger implements IDebugger {
250251
defaultSnippets: [{ body: { task: '', type: '' } }],
251252
description: nls.localize('debugPostDebugTask', "Task to run after debug session ends.")
252253
};
254+
properties['presentation'] = presentationSchema;
253255
properties['internalConsoleOptions'] = INTERNAL_CONSOLE_OPTIONS_SCHEMA;
254256
// Clear out windows, linux and osx fields to not have cycles inside the properties object
255257
delete properties['windows'];

0 commit comments

Comments
 (0)