From c6f97a0b7cd353ee95b4de1d4c4ad0336eb529b5 Mon Sep 17 00:00:00 2001 From: Thomas Willson Date: Sat, 18 Sep 2021 20:17:46 -0700 Subject: [PATCH] Allow merge of C_Cpp_Properties & configuration provider. Adds a configuration that enables the include paths, defines, and forced includes from `c_cpp_properties.json` to be merged with those provided by a configuration provider. This is especially helpful for projects that use unsupported compilers as defines/includePaths/forcedIncludes can be provided as shims for intellisense. --- Extension/c_cpp_properties.schema.json | 4 +++ Extension/src/LanguageServer/client.ts | 31 +++++++++++++++++-- .../src/LanguageServer/configurations.ts | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Extension/c_cpp_properties.schema.json b/Extension/c_cpp_properties.schema.json index 380b4adda5..5e4a4a6354 100644 --- a/Extension/c_cpp_properties.schema.json +++ b/Extension/c_cpp_properties.schema.json @@ -155,6 +155,10 @@ "description": "The id of a VS Code extension that can provide IntelliSense configuration information for source files.", "type": "string" }, + "mergeConfigurations": { + "description": "Set to `true` to merge include paths, defines, and forced includes with those from a configuration provider.", + "type": "boolean" + }, "browse": { "type": "object", "properties": { diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 703cbbff82..6e9b066246 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -1797,9 +1797,36 @@ export class DefaultClient implements Client { const candidate: string = response.candidates[i]; const tuUri: vscode.Uri = vscode.Uri.parse(candidate); if (await provider.canProvideConfiguration(tuUri, tokenSource.token)) { - const configs: SourceFileConfigurationItem[] = await provider.provideConfigurations([tuUri], tokenSource.token); + const configs: util.Mutable[] = await provider.provideConfigurations([tuUri], tokenSource.token); if (configs && configs.length > 0 && configs[0]) { - return configs; + const fileConfiguration: configs.Configuration | undefined = this.configuration.CurrentConfiguration; + if (fileConfiguration?.mergeConfigurations ?? false) { + configs.forEach(config => { + fileConfiguration?.includePath?.forEach(p => { + if (!config.configuration.includePath.includes(p)) { + config.configuration.includePath.push(p); + } + }); + + fileConfiguration?.defines?.forEach(d => { + if (!config.configuration.defines.includes(d)) { + config.configuration.defines.push(d); + } + }); + + if (!config.configuration.forcedInclude) { + config.configuration.forcedInclude = []; + } + + fileConfiguration?.forcedInclude?.forEach(i => { + if (!config.configuration.forcedInclude?.includes(i) ?? false) { + config.configuration.forcedInclude?.push(i); + } + }); + }); + } + + return configs as SourceFileConfigurationItem[]; } } if (tokenSource.token.isCancellationRequested) { diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 9faa5d67c3..14f38860e3 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -73,6 +73,7 @@ export interface Configuration { compileCommands?: string; forcedInclude?: string[]; configurationProvider?: string; + mergeConfigurations?: boolean; browse?: Browse; customConfigurationVariables?: {[key: string]: string}; }