mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 01:37:20 +00:00
introduce alternative column syntax for variable replacment
fixes #16064
This commit is contained in:
parent
db8a4cbd78
commit
00104cc62d
3 changed files with 46 additions and 38 deletions
|
@ -223,6 +223,10 @@ export class Adapter {
|
|||
description: nls.localize('debugLinuxConfiguration', "Linux specific launch configuration attributes."),
|
||||
properties: osProperties
|
||||
};
|
||||
Object.keys(attributes.properties).forEach(name => {
|
||||
attributes.properties[name].errorMessage = attributes.properties[name].errorMessage || nls.localize('deprecatedVariables', "'env.', 'config.' and 'command.' are deprecated, use 'env:', 'config:' and 'command:' instead.");
|
||||
attributes.properties[name].pattern = attributes.properties[name].pattern || '^(?!\\$\\{(env|config|command)\\.)';
|
||||
});
|
||||
|
||||
return attributes;
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@ import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
|
|||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { toResource } from 'vs/workbench/common/editor';
|
||||
|
||||
// TODO@Isidor remove support for env, config. and command. in march
|
||||
export class ConfigurationResolverService implements IConfigurationResolverService {
|
||||
_serviceBrand: any;
|
||||
private _workspaceRoot: string;
|
||||
|
@ -34,6 +35,7 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
this._execPath = environmentService.execPath;
|
||||
Object.keys(envVariables).forEach(key => {
|
||||
this[`env.${key}`] = envVariables[key];
|
||||
this[`env:${key}`] = envVariables[key];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -139,7 +141,7 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
if (types.isString(newValue)) {
|
||||
return newValue;
|
||||
} else {
|
||||
return match && match.indexOf('env.') > 0 ? '' : match;
|
||||
return match && (match.indexOf('env.') > 0 || match.indexOf('env:') > 0) ? '' : match;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -147,8 +149,7 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
}
|
||||
|
||||
private resolveConfigVariable(value: string, originalValue: string): string {
|
||||
let regexp = /\$\{config\.(.+?)\}/g;
|
||||
return value.replace(regexp, (match: string, name: string) => {
|
||||
const replacer = (match: string, name: string) => {
|
||||
let config = this.configurationService.getConfiguration();
|
||||
let newValue: any;
|
||||
try {
|
||||
|
@ -173,7 +174,9 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
} else {
|
||||
return this.resolve(newValue) + '';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return value.replace(/\$\{config\.(.+?)\}/g, replacer).replace(/\$\{config:(.+?)\}/g, replacer);
|
||||
}
|
||||
|
||||
private resolveLiteral(values: IStringDictionary<string | IStringDictionary<string> | string[]>): IStringDictionary<string | IStringDictionary<string> | string[]> {
|
||||
|
@ -220,7 +223,8 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
if (object[key] && typeof object[key] === 'object') {
|
||||
findInteractiveVariables(object[key]);
|
||||
} else if (typeof object[key] === 'string') {
|
||||
const matches = /\${command.(.+)}/.exec(object[key]);
|
||||
object[key] = object[key].replace(new RegExp('command.', 'g'), 'command:');
|
||||
const matches = /\${command:(.+)}/.exec(object[key]);
|
||||
if (matches && matches.length === 2) {
|
||||
const interactiveVariable = matches[1];
|
||||
if (!interactiveVariablesToSubstitutes[interactiveVariable]) {
|
||||
|
@ -246,7 +250,7 @@ export class ConfigurationResolverService implements IConfigurationResolverServi
|
|||
return this.commandService.executeCommand<string>(commandId, configuration).then(result => {
|
||||
if (result) {
|
||||
interactiveVariablesToSubstitutes[interactiveVariable].forEach(substitute =>
|
||||
substitute.object[substitute.key] = substitute.object[substitute.key].replace(`\${command.${interactiveVariable}}`, result)
|
||||
substitute.object[substitute.key] = substitute.object[substitute.key].replace(`\${command:${interactiveVariable}}`, result)
|
||||
);
|
||||
} else {
|
||||
substitionCanceled = true;
|
||||
|
|
|
@ -57,17 +57,17 @@ suite('Configuration Resolver Service', () => {
|
|||
|
||||
test('substitute one env variable', () => {
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env.key1} xyz'), 'abc \\VSCode\\workspaceLocation Value for Key1 xyz');
|
||||
assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env:key1} xyz'), 'abc \\VSCode\\workspaceLocation Value for Key1 xyz');
|
||||
} else {
|
||||
assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env.key1} xyz'), 'abc /VSCode/workspaceLocation Value for Key1 xyz');
|
||||
assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env:key1} xyz'), 'abc /VSCode/workspaceLocation Value for Key1 xyz');
|
||||
}
|
||||
});
|
||||
|
||||
test('substitute many env variable', () => {
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), '\\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2');
|
||||
assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env:key1} - ${env:key2}'), '\\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2');
|
||||
} else {
|
||||
assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), '/VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2');
|
||||
assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env:key1} - ${env:key2}'), '/VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -85,7 +85,7 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} xyz'), 'abc foo xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} xyz'), 'abc foo xyz');
|
||||
});
|
||||
|
||||
test('substitute many configuration variables', () => {
|
||||
|
@ -102,14 +102,14 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz');
|
||||
});
|
||||
|
||||
test('substitute nested configuration variables', () => {
|
||||
let configurationService: IConfigurationService;
|
||||
configurationService = new MockConfigurationService({
|
||||
editor: {
|
||||
fontFamily: 'foo ${workspaceRoot} ${config.terminal.integrated.fontFamily}'
|
||||
fontFamily: 'foo ${workspaceRoot} ${config:terminal.integrated.fontFamily}'
|
||||
},
|
||||
terminal: {
|
||||
integrated: {
|
||||
|
@ -120,9 +120,9 @@ suite('Configuration Resolver Service', () => {
|
|||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz');
|
||||
} else {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -130,7 +130,7 @@ suite('Configuration Resolver Service', () => {
|
|||
let configurationService: IConfigurationService;
|
||||
configurationService = new MockConfigurationService({
|
||||
editor: {
|
||||
fontFamily: 'foo ${workspaceRoot} ${config.terminal.integrated.fontFamily} ${config.editor.fontFamily}'
|
||||
fontFamily: 'foo ${workspaceRoot} ${config:terminal.integrated.fontFamily} ${config:editor.fontFamily}'
|
||||
},
|
||||
terminal: {
|
||||
integrated: {
|
||||
|
@ -141,9 +141,9 @@ suite('Configuration Resolver Service', () => {
|
|||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz');
|
||||
} else {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -162,9 +162,9 @@ suite('Configuration Resolver Service', () => {
|
|||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${workspaceRoot} ${env.key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for Key1 xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${workspaceRoot} ${env:key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for Key1 xyz');
|
||||
} else {
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${workspaceRoot} ${env.key1} xyz'), 'abc foo /VSCode/workspaceLocation Value for Key1 xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${workspaceRoot} ${env:key1} xyz'), 'abc foo /VSCode/workspaceLocation Value for Key1 xyz');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -183,9 +183,9 @@ suite('Configuration Resolver Service', () => {
|
|||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
if (platform.isWindows) {
|
||||
assert.strictEqual(service.resolve('${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2');
|
||||
assert.strictEqual(service.resolve('${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env:key1} - ${env:key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2');
|
||||
} else {
|
||||
assert.strictEqual(service.resolve('${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), 'foo bar /VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2');
|
||||
assert.strictEqual(service.resolve('${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env:key1} - ${env:key2}'), 'foo bar /VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -216,7 +216,7 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.editor.lineNumbers} ${config.editor.insertSpaces} xyz'), 'abc foo 123 false xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.fontFamily} ${config:editor.lineNumbers} ${config:editor.insertSpaces} xyz'), 'abc foo 123 false xyz');
|
||||
});
|
||||
|
||||
test('configuration should not evaluate Javascript', () => {
|
||||
|
@ -228,7 +228,7 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor[\'abc\'.substr(0)]} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor[\'abc\'.substr(0)]} xyz'), 'abc xyz');
|
||||
});
|
||||
|
||||
test('uses empty string as fallback', () => {
|
||||
|
@ -238,10 +238,10 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.abc} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.abc.def} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.panel} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.panel.abc} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.abc} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.abc.def} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:panel} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:panel.abc} xyz'), 'abc xyz');
|
||||
});
|
||||
|
||||
test('is restricted to own properties', () => {
|
||||
|
@ -251,8 +251,8 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.__proto__} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.toString} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.__proto__} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.toString} xyz'), 'abc xyz');
|
||||
});
|
||||
|
||||
test('configuration variables with invalid accessor', () => {
|
||||
|
@ -264,9 +264,9 @@ suite('Configuration Resolver Service', () => {
|
|||
});
|
||||
|
||||
let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService);
|
||||
assert.strictEqual(service.resolve('abc ${config.} xyz'), 'abc ${config.} xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.editor..fontFamily} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config.editor.none.none2} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:} xyz'), 'abc ${config:} xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor..fontFamily} xyz'), 'abc xyz');
|
||||
assert.strictEqual(service.resolve('abc ${config:editor.none.none2} xyz'), 'abc xyz');
|
||||
});
|
||||
|
||||
test('interactive variable simple', () => {
|
||||
|
@ -274,7 +274,7 @@ suite('Configuration Resolver Service', () => {
|
|||
'name': 'Attach to Process',
|
||||
'type': 'node',
|
||||
'request': 'attach',
|
||||
'processId': '${command.interactiveVariable1}',
|
||||
'processId': '${command:interactiveVariable1}',
|
||||
'port': 5858,
|
||||
'sourceMaps': false,
|
||||
'outDir': null
|
||||
|
@ -303,12 +303,12 @@ suite('Configuration Resolver Service', () => {
|
|||
'name': 'Attach to Process',
|
||||
'type': 'node',
|
||||
'request': 'attach',
|
||||
'processId': '${command.interactiveVariable1}',
|
||||
'port': '${command.interactiveVariable2}',
|
||||
'processId': '${command:interactiveVariable1}',
|
||||
'port': '${command:interactiveVariable2}',
|
||||
'sourceMaps': false,
|
||||
'outDir': 'src/${command.interactiveVariable2}',
|
||||
'outDir': 'src/${command:interactiveVariable2}',
|
||||
'env': {
|
||||
'processId': '__${command.interactiveVariable2}__',
|
||||
'processId': '__${command:interactiveVariable2}__',
|
||||
}
|
||||
};
|
||||
const interactiveVariables = Object.create(null);
|
||||
|
|
Loading…
Reference in a new issue