Skip to content

Commit 58cfb5e

Browse files
authored
add support for custom variables (#1921)
* add support for custom variables * support for string[] variables * rename "variables" to "env"
1 parent 8deee74 commit 58cfb5e

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

Extension/c_cpp_properties.schema.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,26 @@
107107
}
108108
}
109109
},
110+
"env": {
111+
"type": "object",
112+
"description": "Custom variables that can be resused anywhere in this file using the ${variable} or ${env:variable} syntax.",
113+
"patternProperties": {
114+
"(?!^workspaceFolder$)(?!^workspaceRoot$)(?!^default$)(^.+$)": {
115+
"oneOf": [
116+
{
117+
"type": "string"
118+
},
119+
{
120+
"type": "array",
121+
"items": {
122+
"type": "string"
123+
}
124+
}
125+
]
126+
}
127+
},
128+
"additionalProperties": false
129+
},
110130
"version": {
111131
"type": "integer",
112132
"description": "Version of the configuration file. This property is managed by the extension. Please do not change it."
@@ -116,6 +136,9 @@
116136
"configurations": {
117137
"$ref": "#/definitions/configurations"
118138
},
139+
"env": {
140+
"$ref": "#/definitions/env"
141+
},
119142
"version": {
120143
"$ref": "#/definitions/version"
121144
}

Extension/src/LanguageServer/configurations.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ function getDefaultCppProperties(): ConfigurationJson {
3434

3535
interface ConfigurationJson {
3636
configurations: Configuration[];
37+
env?: {[key: string]: string | string[]};
3738
version: number;
3839
}
3940

@@ -336,7 +337,11 @@ export class CppProperties {
336337
let result: string[] = [];
337338
entries.forEach(entry => {
338339
if (entry === "${default}") {
339-
result = result.concat(defaultValue);
340+
// package.json default values for string[] properties is null.
341+
// If no default is set, return an empty array instead of an array with `null` in it.
342+
if (defaultValue !== null) {
343+
result = result.concat(defaultValue);
344+
}
340345
} else {
341346
result.push(entry);
342347
}
@@ -348,7 +353,7 @@ export class CppProperties {
348353
let result: string[] = [];
349354
if (paths) {
350355
paths.forEach(entry => {
351-
let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e);
356+
let entries: string[] = util.resolveVariables(entry, this.configurationJson.env).split(";").filter(e => e);
352357
entries = this.resolveDefaults(entries, defaultValue);
353358
result = result.concat(entries);
354359
});
@@ -363,7 +368,7 @@ export class CppProperties {
363368
if (typeof input === "boolean") {
364369
return input;
365370
}
366-
return util.resolveVariables(input);
371+
return util.resolveVariables(input, this.configurationJson.env);
367372
}
368373

369374
private updateConfiguration(property: string[], defaultValue: string[]): string[];
@@ -524,6 +529,13 @@ export class CppProperties {
524529
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(newJson);
525530
}
526531

532+
// Remove disallowed variable overrides
533+
if (this.configurationJson.env) {
534+
delete this.configurationJson.env['workspaceRoot'];
535+
delete this.configurationJson.env['workspaceFolder'];
536+
delete this.configurationJson.env['default'];
537+
}
538+
527539
// Warning: There is a chance that this is incorrect in the event that the c_cpp_properties.json file was created before
528540
// the system includes were available.
529541
this.configurationIncomplete = false;

Extension/src/common.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,13 @@ export function showReleaseNotes(): void {
143143
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.file(getExtensionFilePath("ReleaseNotes.html")), vscode.ViewColumn.One, "C/C++ Extension Release Notes");
144144
}
145145

146-
export function resolveVariables(input: string): string {
146+
export function resolveVariables(input: string, additionalEnvironment: {[key: string]: string | string[]}): string {
147147
if (!input) {
148148
return "";
149149
}
150+
if (!additionalEnvironment) {
151+
additionalEnvironment = {};
152+
}
150153

151154
// Replace environment and configuration variables.
152155
let regexp: RegExp = /\$\{((env|config)(.|:))?(.*?)\}/g;
@@ -158,7 +161,18 @@ export function resolveVariables(input: string): string {
158161
}
159162
let newValue: string = undefined;
160163
switch (varType) {
161-
case "env": { newValue = process.env[name]; break; }
164+
case "env": {
165+
let v: string | string[] = additionalEnvironment[name];
166+
if (typeof v === "string") {
167+
newValue = v;
168+
} else if (input === match && v instanceof Array) {
169+
newValue = v.join(";");
170+
}
171+
if (!newValue) {
172+
newValue = process.env[name];
173+
}
174+
break;
175+
}
162176
case "config": {
163177
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
164178
let keys: string[] = name.split('.');

0 commit comments

Comments
 (0)