提交 6312e73f 编写于 作者: I Isidor Nikolic 提交者: GitHub

Merge pull request #16014 from Microsoft/isidorn/compound

Isidorn/compound
......@@ -61,9 +61,12 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined) {
const ranges: vscode.Range[] = [];
let addPropertyAndValue = false;
let depthInArray = 0;
visit(editor.document.getText(), {
onObjectProperty: (property, offset, length) => {
addPropertyAndValue = property === 'version' || property === 'type' || property === 'request' || property === 'configurations';
// Decorate attributes which are unlikely to be edited by the user.
// Only decorate "configurations" if it is not inside an array (compounds have a configurations property which should not be decorated).
addPropertyAndValue = property === 'version' || property === 'type' || property === 'request' || property === 'compounds' || (property === 'configurations' && depthInArray === 0);
if (addPropertyAndValue) {
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
}
......@@ -72,6 +75,12 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined) {
if (addPropertyAndValue) {
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
}
},
onArrayBegin: (offset: number, length: number) => {
depthInArray++;
},
onArrayEnd: (offset: number, length: number) => {
depthInArray--;
}
});
......
......@@ -36,9 +36,13 @@ export class SelectConfigurationActionItem extends SelectActionItem {
if (!config || !config.configurations || config.configurations.length === 0) {
this.setOptions([NO_CONFIGURATIONS_LABEL], 0);
} else {
const configurationNames = config.configurations.filter(cfg => !!cfg.name).map(cfg => cfg.name);
const selected = configurationNames.indexOf(this.debugService.getViewModel().selectedConfigurationName);
this.setOptions(configurationNames, selected);
const options = config.configurations.filter(cfg => !!cfg.name).map(cfg => cfg.name);
if (config.compounds) {
options.push(...config.compounds.filter(compound => !!compound.name).map(compound => compound.name));
}
const selected = options.indexOf(this.debugService.getViewModel().selectedConfigurationName);
this.setOptions(options, selected);
}
if (changeDebugConfiguration) {
......
......@@ -281,6 +281,7 @@ export interface IDebugConfiguration {
export interface IGlobalConfig {
version: string;
debugServer?: number;
compounds: ICompound[];
configurations: IConfig[];
}
......@@ -300,6 +301,11 @@ export interface IConfig extends IEnvConfig {
linux?: IEnvConfig;
}
export interface ICompound {
name: string;
configurations: string[];
}
export interface IRawEnvAdapter {
type?: string;
label?: string;
......@@ -335,6 +341,12 @@ export interface IConfigurationManager {
*/
getConfiguration(nameOrConfig: string | IConfig): TPromise<IConfig>;
/**
* Returns a compound with the specified name.
* Returns null if there is no compound with the specified name.
*/
getCompound(name: string): ICompound;
/**
* Opens the launch.json file
*/
......
......@@ -549,8 +549,17 @@ export class DebugService implements debug.IDebugService {
return this.textFileService.saveAll() // make sure all dirty files are saved
.then(() => this.configurationService.reloadConfiguration() // make sure configuration is up to date
.then(() => this.extensionService.onReady()
.then(() => this.configurationManager.getConfiguration(configurationOrName)
.then(configuration => {
.then(() => {
const compound = typeof configurationOrName === 'string' ? this.configurationManager.getCompound(configurationOrName) : null;
if (compound) {
if (!compound.configurations) {
return TPromise.wrapError(new Error(nls.localize('compoundMustHaveConfigurationNames', "Compound must have \"configurationNames\" attribute set in order to start multiple configurations.")));
}
return TPromise.join(compound.configurations.map(name => this.createProcess(name)));
}
return this.configurationManager.getConfiguration(configurationOrName).then(configuration => {
if (!configuration) {
return this.configurationManager.openConfigFile(false).then(openend => {
if (openend) {
......@@ -592,7 +601,8 @@ export class DebugService implements debug.IDebugService {
actions: [this.taskService.configureAction(), CloseAction]
});
});
}))));
});
})));
}
private doCreateProcess(sessionId: string, configuration: debug.IConfig): TPromise<any> {
......
......@@ -131,6 +131,7 @@ export const breakpointsExtPoint = extensionsRegistry.ExtensionsRegistry.registe
// debug general schema
export const schemaId = 'vscode://schemas/launch';
const defaultCompound: debug.ICompound = { name: 'Compound', configurations: [] };
const schema: IJSONSchema = {
id: schemaId,
type: 'object',
......@@ -156,6 +157,32 @@ const schema: IJSONSchema = {
type: 'number',
description: nls.localize('app.launch.json.debugServer', "DEPRECATED: please move debugServer inside a configuration.")
},
compounds: {
type: 'array',
description: nls.localize('app.launch.json.compounds', "List of compounds. Each compound references multiple configurations which will get launched together."),
items: {
type: 'object',
required: ['name', 'configurations'],
properties: {
name: {
type: 'string',
description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.")
},
configurations: {
type: 'array',
default: [],
items: {
type: 'string'
},
description: nls.localize('app.launch.json.compounds.configurations', "Names of configurations that will be started as part of this compound.")
}
},
default: defaultCompound
},
default: [
defaultCompound
]
}
}
};
......@@ -230,6 +257,15 @@ export class ConfigurationManager implements debug.IConfigurationManager {
return this.adapters.filter(adapter => strings.equalsIgnoreCase(adapter.type, type)).pop();
}
public getCompound(name: string): debug.ICompound {
const config = this.configurationService.getConfiguration<debug.IGlobalConfig>('launch');
if (!config || !config.compounds) {
return null;
}
return config.compounds.filter(compound => compound.name === name).pop();
}
public getConfiguration(nameOrConfig: string | debug.IConfig): TPromise<debug.IConfig> {
const config = this.configurationService.getConfiguration<debug.IGlobalConfig>('launch');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册