Apply mergeConfigurations for browse.path, auto-update the config, and avoid accumulating old configs (#13678)
* Apply mergeConfigurations for browse.path. * Fix a bug with old merge properties being added.
This commit is contained in:
@@ -180,12 +180,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
"mergeConfigurations": {
|
||||
"markdownDescription": "Set to `true` to merge include paths, defines, and forced includes with those from a configuration provider.",
|
||||
"descriptionHint": "Markdown text between `` should not be translated or localized (they represent literal text) and the capitalization, spacing, and punctuation (including the ``) should not be altered.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"string"
|
||||
]
|
||||
"markdownDescription": "Set to `true` to merge `includePath`, `defines`, `forcedInclude`, and `browse.path` with those received from the configuration provider.",
|
||||
"descriptionHint": "{Locked=\"`true`\"} {Locked=\"`includePath`\"} {Locked=\"`defines`\"} {Locked=\"`forcedInclude`\"} {Locked=\"`browse.path`\"}",
|
||||
"type": "boolean"
|
||||
},
|
||||
"browse": {
|
||||
"type": "object",
|
||||
|
||||
@@ -841,6 +841,7 @@
|
||||
},
|
||||
"C_Cpp.default.mergeConfigurations": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "%c_cpp.configuration.default.mergeConfigurations.markdownDescription%",
|
||||
"scope": "resource"
|
||||
},
|
||||
|
||||
@@ -32,7 +32,6 @@ import { CloseAction, DidOpenTextDocumentParams, ErrorAction, LanguageClientOpti
|
||||
import { LanguageClient, ServerOptions } from 'vscode-languageclient/node';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { DebugConfigurationProvider } from '../Debugger/configurationProvider';
|
||||
import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderExtensionId } from '../LanguageServer/customProviders';
|
||||
import { ManualPromise } from '../Utility/Async/manualPromise';
|
||||
import { ManualSignal } from '../Utility/Async/manualSignal';
|
||||
import { logAndReturn } from '../Utility/Async/returns';
|
||||
@@ -57,6 +56,7 @@ import {
|
||||
import { Location, TextEdit, WorkspaceEdit } from './commonTypes';
|
||||
import * as configs from './configurations';
|
||||
import { CopilotCompletionContextFeatures, CopilotCompletionContextProvider } from './copilotCompletionContextProvider';
|
||||
import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderExtensionId } from './customProviders';
|
||||
import { DataBinding } from './dataBinding';
|
||||
import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig';
|
||||
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
|
||||
@@ -889,6 +889,11 @@ export class DefaultClient implements Client {
|
||||
private settingsTracker: SettingsTracker;
|
||||
private loggingLevel: number = 1;
|
||||
private configurationProvider?: string;
|
||||
private mergeConfigurations: boolean = false;
|
||||
private includePath?: string[];
|
||||
private defines?: string[];
|
||||
private forcedInclude?: string[];
|
||||
private browsePath?: string[];
|
||||
private hoverProvider: HoverProvider | undefined;
|
||||
private copilotHoverProvider: CopilotHoverProvider | undefined;
|
||||
private copilotCompletionProvider?: CopilotCompletionContextProvider;
|
||||
@@ -2181,6 +2186,7 @@ export class DefaultClient implements Client {
|
||||
if (configs && configs.length > 0 && configs[0]) {
|
||||
const fileConfiguration: configs.Configuration | undefined = this.configuration.CurrentConfiguration;
|
||||
if (fileConfiguration?.mergeConfigurations) {
|
||||
configs = deepCopy(configs);
|
||||
configs.forEach(config => {
|
||||
if (fileConfiguration.includePath) {
|
||||
fileConfiguration.includePath.forEach(p => {
|
||||
@@ -3139,11 +3145,45 @@ export class DefaultClient implements Client {
|
||||
const configName: string | undefined = configurations[params.currentConfiguration].name ?? "";
|
||||
this.model.activeConfigName.setValueIfActive(configName);
|
||||
const newProvider: string | undefined = this.configuration.CurrentConfigurationProvider;
|
||||
if (!isSameProviderExtensionId(newProvider, this.configurationProvider)) {
|
||||
if (this.configurationProvider) {
|
||||
const previousProvider: string | undefined = this.configurationProvider;
|
||||
let updateCustomConfigs: boolean = false;
|
||||
if (!isSameProviderExtensionId(previousProvider, newProvider)) {
|
||||
this.configurationProvider = newProvider;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
if (newProvider !== undefined) {
|
||||
const newMergeConfigurations: boolean = this.configuration.CurrentMergeConfigurations;
|
||||
if (this.mergeConfigurations !== newMergeConfigurations) {
|
||||
this.mergeConfigurations = newMergeConfigurations;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
if (newMergeConfigurations) {
|
||||
const newIncludePath: string[] | undefined = this.configuration.CurrentIncludePath;
|
||||
if (!util.equals(this.includePath, newIncludePath)) {
|
||||
this.includePath = newIncludePath;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
const newDefines: string[] | undefined = this.configuration.CurrentDefines;
|
||||
if (!util.equals(this.defines, newDefines)) {
|
||||
this.defines = newDefines;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
const newForcedInclude: string[] | undefined = this.configuration.CurrentForcedInclude;
|
||||
if (!util.equals(this.forcedInclude, newForcedInclude)) {
|
||||
this.forcedInclude = newForcedInclude;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
const newBrowsePath: string[] | undefined = this.configuration.CurrentBrowsePath;
|
||||
if (!util.equals(this.browsePath, newBrowsePath)) {
|
||||
this.browsePath = newBrowsePath;
|
||||
updateCustomConfigs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updateCustomConfigs) {
|
||||
if (previousProvider) {
|
||||
void this.clearCustomBrowseConfiguration().catch(logAndReturn.undefined);
|
||||
}
|
||||
this.configurationProvider = newProvider;
|
||||
void this.updateCustomBrowseConfiguration().catch(logAndReturn.undefined);
|
||||
void this.updateCustomConfigurations().catch(logAndReturn.undefined);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ export interface Configuration {
|
||||
forcedInclude?: string[];
|
||||
configurationProviderInCppPropertiesJson?: string;
|
||||
configurationProvider?: string;
|
||||
mergeConfigurations?: boolean | string;
|
||||
mergeConfigurations?: boolean;
|
||||
browse?: Browse;
|
||||
recursiveIncludes?: RecursiveIncludes;
|
||||
customConfigurationVariables?: { [key: string]: string };
|
||||
@@ -204,6 +204,41 @@ export class CppProperties {
|
||||
return new CppSettings(this.rootUri).defaultConfigurationProvider;
|
||||
}
|
||||
|
||||
public get CurrentMergeConfigurations(): boolean {
|
||||
if (this.CurrentConfiguration?.mergeConfigurations) {
|
||||
return this.CurrentConfiguration.mergeConfigurations;
|
||||
}
|
||||
return new CppSettings(this.rootUri).defaultMergeConfigurations;
|
||||
}
|
||||
|
||||
public get CurrentIncludePath(): string[] | undefined {
|
||||
if (this.CurrentConfiguration?.includePath) {
|
||||
return this.CurrentConfiguration.includePath;
|
||||
}
|
||||
return new CppSettings(this.rootUri).defaultIncludePath;
|
||||
}
|
||||
|
||||
public get CurrentDefines(): string[] | undefined {
|
||||
if (this.CurrentConfiguration?.defines) {
|
||||
return this.CurrentConfiguration.defines;
|
||||
}
|
||||
return new CppSettings(this.rootUri).defaultDefines;
|
||||
}
|
||||
|
||||
public get CurrentForcedInclude(): string[] | undefined {
|
||||
if (this.CurrentConfiguration?.forcedInclude) {
|
||||
return this.CurrentConfiguration.forcedInclude;
|
||||
}
|
||||
return new CppSettings(this.rootUri).defaultForcedInclude;
|
||||
}
|
||||
|
||||
public get CurrentBrowsePath(): string[] | undefined {
|
||||
if (this.CurrentConfiguration?.browse?.path) {
|
||||
return this.CurrentConfiguration.browse.path;
|
||||
}
|
||||
return new CppSettings(this.rootUri).defaultBrowsePath;
|
||||
}
|
||||
|
||||
public get ConfigurationNames(): string[] | undefined {
|
||||
const result: string[] = [];
|
||||
if (this.configurationJson) {
|
||||
|
||||
@@ -440,7 +440,7 @@ export class CppSettings extends Settings {
|
||||
public get defaultCStandard(): string | undefined { return this.getAsStringOrUndefined("default.cStandard"); }
|
||||
public get defaultCppStandard(): string | undefined { return this.getAsStringOrUndefined("default.cppStandard"); }
|
||||
public get defaultConfigurationProvider(): string | undefined { return changeBlankStringToUndefined(this.getAsStringOrUndefined("default.configurationProvider")); }
|
||||
public get defaultMergeConfigurations(): boolean | undefined { return this.getAsBooleanOrUndefined("default.mergeConfigurations"); }
|
||||
public get defaultMergeConfigurations(): boolean { return this.getAsBoolean("default.mergeConfigurations"); }
|
||||
public get defaultBrowsePath(): string[] | undefined { return this.getArrayOfStringsWithUndefinedDefault("default.browse.path"); }
|
||||
public get defaultDatabaseFilename(): string | undefined { return changeBlankStringToUndefined(this.getAsStringOrUndefined("default.browse.databaseFilename")); }
|
||||
public get defaultLimitSymbolsToIncludedHeaders(): boolean { return this.getAsBoolean("default.browse.limitSymbolsToIncludedHeaders"); }
|
||||
@@ -569,21 +569,6 @@ export class CppSettings extends Settings {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Returns the value of a setting as a boolean with proper type validation and checks for valid enum values while returning an undefined value if necessary.
|
||||
private getAsBooleanOrUndefined(settingName: string): boolean | undefined {
|
||||
const value: any = super.Section.get<any>(settingName);
|
||||
const setting = getRawSetting("C_Cpp." + settingName, true);
|
||||
if (setting.default !== undefined) {
|
||||
console.error(`Default value for ${settingName} is expected to be undefined.`);
|
||||
}
|
||||
|
||||
if (isBoolean(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private isValidDefault(isValid: (x: any) => boolean, value: any, allowNull: boolean): boolean {
|
||||
return isValid(value) || (allowNull && value === null);
|
||||
}
|
||||
|
||||
@@ -1810,3 +1810,21 @@ export function findExePathInArgs(args: CommandString[]): string | undefined {
|
||||
export function getVsCodeVersion(): number[] {
|
||||
return vscode.version.split('.').map(num => parseInt(num, undefined));
|
||||
}
|
||||
|
||||
export function equals(array1: string[] | undefined, array2: string[] | undefined): boolean {
|
||||
if (array1 === undefined && array2 === undefined) {
|
||||
return true;
|
||||
}
|
||||
if (array1 === undefined || array2 === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i: number = 0; i < array1.length; ++i) {
|
||||
if (array1[i] !== array2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -687,7 +687,7 @@
|
||||
<div class="section-title" data-loc-id="merge.configurations">Merge configurations</div>
|
||||
<div>
|
||||
<input type="checkbox" id="mergeConfigurations" style="vertical-align: middle; transform: scale(1.5)">
|
||||
<span data-loc-id="merge.configurations.description">When <code>true</code> (or checked), merge include paths, defines, and forced includes with those from a configuration provider.</span>
|
||||
<span data-loc-id="merge.configurations.description">When <code>true</code> (or checked), merge <code>includePath</code>, <code>defines</code>, <code>forcedInclude</code>, and <code>browse.path</code> with those received from the configuration provider.</span>
|
||||
</input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user