diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 22ccc7d96..98b473775 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -55,6 +55,7 @@ import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderE import { DataBinding } from './dataBinding'; import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig'; import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, isWritingCrashCallStack, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension'; +import { IncludeCleanupPreferences, getIncludeCleanupPreferences } from './includeCleanupEditorConfig'; import { InactiveRegion, InactiveRegionStore, getInactiveRegionStartLines } from './inactiveRegions'; import { LanguageClient } from './languageClient'; import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization'; @@ -507,6 +508,7 @@ interface TagParseStatus { interface VisibleEditorInfo { visibleRanges: Range[]; originalEncoding: string; + includeCleanupPreferences: IncludeCleanupPreferences; } interface DidChangeVisibleTextEditorsParams { @@ -1952,9 +1954,11 @@ export class DefaultClient implements Client { // First, we just concat all ranges for the same file. const uri: string = editor.document.uri.toString(); if (!visibileEditorInfo[uri]) { + const editorConfigSettings: any = getEditorConfigSettings(editor.document.uri.fsPath); visibileEditorInfo[uri] = { visibleRanges: [], - originalEncoding: editor.document.encoding + originalEncoding: editor.document.encoding, + includeCleanupPreferences: getIncludeCleanupPreferences(editorConfigSettings) }; } visibileEditorInfo[uri].visibleRanges = visibileEditorInfo[uri].visibleRanges.concat(editor.visibleRanges.map(makeLspRange)); @@ -2713,6 +2717,15 @@ export class DefaultClient implements Client { private associations_for_did_change?: Set; + private refreshEditorConfigSettings(): void { + cachedEditorConfigSettings.clear(); + cachedEditorConfigLookups.clear(); + this.updateActiveDocumentTextOptions(); + + const cppEditors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(editor => util.isCpp(editor.document)); + void this.onDidChangeVisibleTextEditors(cppEditors).catch(logAndReturn.undefined); + } + /** * listen for file created/deleted events under the ${workspaceFolder} folder */ @@ -2733,9 +2746,7 @@ export class DefaultClient implements Client { } const fileName: string = path.basename(uri.fsPath).toLowerCase(); if (fileName === ".editorconfig") { - cachedEditorConfigSettings.clear(); - cachedEditorConfigLookups.clear(); - this.updateActiveDocumentTextOptions(); + this.refreshEditorConfigSettings(); } if (fileName === ".clang-format" || fileName === "_clang-format") { cachedEditorConfigLookups.clear(); @@ -2761,9 +2772,7 @@ export class DefaultClient implements Client { const dotIndex: number = uri.fsPath.lastIndexOf('.'); const fileName: string = path.basename(uri.fsPath).toLowerCase(); if (fileName === ".editorconfig") { - cachedEditorConfigSettings.clear(); - cachedEditorConfigLookups.clear(); - this.updateActiveDocumentTextOptions(); + this.refreshEditorConfigSettings(); } const ext: string | undefined = dotIndex !== -1 ? uri.fsPath.substring(dotIndex + 1) : undefined; const isTrackedFile: boolean = hasNativeFileTypeMappings() @@ -2788,8 +2797,7 @@ export class DefaultClient implements Client { } const fileName: string = path.basename(uri.fsPath).toLowerCase(); if (fileName === ".editorconfig") { - cachedEditorConfigSettings.clear(); - cachedEditorConfigLookups.clear(); + this.refreshEditorConfigSettings(); } if (fileName === ".clang-format" || fileName === "_clang-format") { cachedEditorConfigLookups.clear(); diff --git a/Extension/src/LanguageServer/includeCleanupEditorConfig.ts b/Extension/src/LanguageServer/includeCleanupEditorConfig.ts new file mode 100644 index 000000000..69cc3f31c --- /dev/null +++ b/Extension/src/LanguageServer/includeCleanupEditorConfig.ts @@ -0,0 +1,23 @@ +export interface IncludeCleanupPreferences { + alternateFiles: string; + excludedFiles: string; + replacementFiles: string; + requiredFiles: string; +} + +function getStringSetting(settings: any, key: string): string { + const value: unknown = settings?.[key]; + if (typeof value !== 'string' || value.toLowerCase() === 'unset') { + return ''; + } + return value; +} + +export function getIncludeCleanupPreferences(settings: any): IncludeCleanupPreferences { + return { + alternateFiles: getStringSetting(settings, 'cpp_include_cleanup_alternate_files'), + excludedFiles: getStringSetting(settings, 'cpp_include_cleanup_excluded_files'), + replacementFiles: getStringSetting(settings, 'cpp_include_cleanup_replacement_files'), + requiredFiles: getStringSetting(settings, 'cpp_include_cleanup_required_files') + }; +} diff --git a/Extension/test/unit/includeCleanupEditorConfig.test.ts b/Extension/test/unit/includeCleanupEditorConfig.test.ts new file mode 100644 index 000000000..427c35e62 --- /dev/null +++ b/Extension/test/unit/includeCleanupEditorConfig.test.ts @@ -0,0 +1,32 @@ +import { deepStrictEqual } from 'assert'; +import { describe, it } from 'mocha'; +import { getIncludeCleanupPreferences } from '../../src/LanguageServer/includeCleanupEditorConfig'; + +describe('Include Cleanup editorconfig settings', () => { + it('maps semantic preference strings', () => { + deepStrictEqual(getIncludeCleanupPreferences({ + cpp_include_cleanup_alternate_files: 'umbrella.h:internal.h', + cpp_include_cleanup_excluded_files: 'generated.h', + cpp_include_cleanup_replacement_files: 'stdio.h:cstdio', + cpp_include_cleanup_required_files: 'atlwin.h:atlbase.h' + }), { + alternateFiles: 'umbrella.h:internal.h', + excludedFiles: 'generated.h', + replacementFiles: 'stdio.h:cstdio', + requiredFiles: 'atlwin.h:atlbase.h' + }); + }); + + it('maps unset and non-string values to empty strings', () => { + deepStrictEqual(getIncludeCleanupPreferences({ + cpp_include_cleanup_alternate_files: 'unset', + cpp_include_cleanup_excluded_files: true, + cpp_include_cleanup_replacement_files: 42 + }), { + alternateFiles: '', + excludedFiles: '', + replacementFiles: '', + requiredFiles: '' + }); + }); +});