diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 8ee0e22f6..d1f0cb8c9 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -58,7 +58,7 @@ import { DataBinding } from './dataBinding'; import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig'; import { CppSourceStr, clients, configPrefix, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension'; import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization'; -import { PersistentFolderState, PersistentWorkspaceState } from './persistentState'; +import { PersistentFolderState, PersistentState, PersistentWorkspaceState } from './persistentState'; import { RequestCancelled, ServerCancelled, createProtocolFilter } from './protocolFilter'; import * as refs from './references'; import { CppSettings, OtherSettings, SettingsParams, WorkspaceFolderSettingsParams } from './settings'; @@ -564,6 +564,16 @@ export interface ProjectContextResult { fileContext: FileContextResult; } +interface FolderFilesEncodingChanged { + uri: string; + filesEncoding: string; +} + +interface FilesEncodingChanged { + workspaceFallbackEncoding?: string; + foldersFilesEncoding: FolderFilesEncodingChanged[]; +} + // Requests const PreInitializationRequest: RequestType = new RequestType('cpptools/preinitialize'); const InitializationRequest: RequestType = new RequestType('cpptools/initialize'); @@ -642,6 +652,7 @@ const ReportCodeAnalysisTotalNotification: NotificationType = new Notifi const DoxygenCommentGeneratedNotification: NotificationType = new NotificationType('cpptools/insertDoxygenComment'); const CanceledReferencesNotification: NotificationType = new NotificationType('cpptools/canceledReferences'); const IntelliSenseResultNotification: NotificationType = new NotificationType('cpptools/intelliSenseResult'); +const FilesEncodingChangedNotification: NotificationType = new NotificationType('cpptools/filesEncodingChanged'); let failureMessageShown: boolean = false; @@ -819,6 +830,7 @@ export interface Client { getIncludes(maxDepth: number): Promise; getChatContext(uri: vscode.Uri, token: vscode.CancellationToken): Promise; getProjectContext(uri: vscode.Uri): Promise; + filesEncodingChanged(filesEncodingChanged: FilesEncodingChanged): void; } export function createClient(workspaceFolder?: vscode.WorkspaceFolder): Client { @@ -1367,7 +1379,13 @@ export class DefaultClient implements Client { DefaultClient.isStarted.resolve(); } - private getWorkspaceFolderSettings(workspaceFolderUri: vscode.Uri | undefined, settings: CppSettings, otherSettings: OtherSettings): WorkspaceFolderSettingsParams { + private getWorkspaceFolderSettings(workspaceFolderUri: vscode.Uri | undefined, workspaceFolder: vscode.WorkspaceFolder | undefined, settings: CppSettings, otherSettings: OtherSettings): WorkspaceFolderSettingsParams { + const filesEncoding: string = otherSettings.filesEncoding; + let filesEncodingChanged: boolean = false; + if (workspaceFolder) { + const lastFilesEncoding: PersistentFolderState = new PersistentFolderState("CPP.lastFilesEncoding", "", workspaceFolder); + filesEncodingChanged = lastFilesEncoding.Value !== filesEncoding; + } const result: WorkspaceFolderSettingsParams = { uri: workspaceFolderUri?.toString(), intelliSenseEngine: settings.intelliSenseEngine, @@ -1464,7 +1482,8 @@ export class DefaultClient implements Client { doxygenSectionTags: settings.doxygenSectionTags, filesExclude: otherSettings.filesExclude, filesAutoSaveAfterDelay: otherSettings.filesAutoSaveAfterDelay, - filesEncoding: otherSettings.filesEncoding, + filesEncoding: filesEncoding, + filesEncodingChanged: filesEncodingChanged, searchExclude: otherSettings.searchExclude, editorAutoClosingBrackets: otherSettings.editorAutoClosingBrackets, editorInlayHintsEnabled: otherSettings.editorInlayHintsEnabled, @@ -1480,10 +1499,10 @@ export class DefaultClient implements Client { const workspaceFolderSettingsParams: WorkspaceFolderSettingsParams[] = []; if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { for (const workspaceFolder of vscode.workspace.workspaceFolders) { - workspaceFolderSettingsParams.push(this.getWorkspaceFolderSettings(workspaceFolder.uri, new CppSettings(workspaceFolder.uri), new OtherSettings(workspaceFolder.uri))); + workspaceFolderSettingsParams.push(this.getWorkspaceFolderSettings(workspaceFolder.uri, workspaceFolder, new CppSettings(workspaceFolder.uri), new OtherSettings(workspaceFolder.uri))); } } else { - workspaceFolderSettingsParams.push(this.getWorkspaceFolderSettings(this.RootUri, workspaceSettings, workspaceOtherSettings)); + workspaceFolderSettingsParams.push(this.getWorkspaceFolderSettings(this.RootUri, undefined, workspaceSettings, workspaceOtherSettings)); } return workspaceFolderSettingsParams; } @@ -1498,9 +1517,13 @@ export class DefaultClient implements Client { if (this.currentCopilotHoverEnabled && workspaceSettings.copilotHover !== this.currentCopilotHoverEnabled.Value) { void util.promptForReloadWindowDueToSettingsChange(); } + const workspaceFallbackEncoding: string = workspaceOtherSettings.filesEncoding; + const lastWorkspaceFallbackEncoding: PersistentState = new PersistentState("CPP.lastWorkspaceFallbackEncoding", ""); + const workspaceFallbackEncodingChanged = lastWorkspaceFallbackEncoding.Value !== workspaceFallbackEncoding; return { filesAssociations: workspaceOtherSettings.filesAssociations, - workspaceFallbackEncoding: workspaceOtherSettings.filesEncoding, + workspaceFallbackEncoding: workspaceFallbackEncoding, + workspaceFallbackEncodingChanged: workspaceFallbackEncodingChanged, maxConcurrentThreads: workspaceSettings.maxConcurrentThreads, maxCachedProcesses: workspaceSettings.maxCachedProcesses, maxMemory: workspaceSettings.maxMemory, @@ -2438,6 +2461,7 @@ export class DefaultClient implements Client { this.languageClient.onNotification(ReportCodeAnalysisTotalNotification, (e) => this.updateCodeAnalysisTotal(e)); this.languageClient.onNotification(DoxygenCommentGeneratedNotification, (e) => void this.insertDoxygenComment(e)); this.languageClient.onNotification(CanceledReferencesNotification, this.serverCanceledReferences); + this.languageClient.onNotification(FilesEncodingChangedNotification, (e) => this.filesEncodingChanged(e)); } private handleIntelliSenseResult(intelliSenseResult: IntelliSenseResult): void { @@ -4085,6 +4109,20 @@ export class DefaultClient implements Client { public getCopilotHoverProvider(): CopilotHoverProvider | undefined { return this.copilotHoverProvider; } + + public filesEncodingChanged(filesEncodingChanged: FilesEncodingChanged): void { + if (filesEncodingChanged.workspaceFallbackEncoding !== undefined) { + const lastWorkspaceFallbackEncoding: PersistentState = new PersistentState("CPP.lastWorkspaceFallbackEncoding", ""); + lastWorkspaceFallbackEncoding.Value = filesEncodingChanged.workspaceFallbackEncoding; + } + for (const folderFilesEncoding of filesEncodingChanged.foldersFilesEncoding) { + const workspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(vscode.Uri.parse(folderFilesEncoding.uri)); + if (workspaceFolder !== undefined) { + const lastFilesEncoding: PersistentFolderState = new PersistentFolderState("CPP.lastFilesEncoding", "", workspaceFolder); + lastFilesEncoding.Value = folderFilesEncoding.filesEncoding; + } + } + } } function getLanguageServerFileName(): string { @@ -4200,4 +4238,5 @@ class NullClient implements Client { getIncludes(maxDepth: number): Promise { return Promise.resolve({} as GetIncludesResult); } getChatContext(uri: vscode.Uri, token: vscode.CancellationToken): Promise { return Promise.resolve({} as ChatContextResult); } getProjectContext(uri: vscode.Uri): Promise { return Promise.resolve({} as ProjectContextResult); } + filesEncodingChanged(filesEncodingChanged: FilesEncodingChanged): void { } } diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index a33a4b803..fb96b2afa 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -131,6 +131,7 @@ export interface WorkspaceFolderSettingsParams { filesExclude: Excludes; filesAutoSaveAfterDelay: boolean; filesEncoding: string; + filesEncodingChanged: boolean; searchExclude: Excludes; editorAutoClosingBrackets: string; editorInlayHintsEnabled: boolean; @@ -141,6 +142,7 @@ export interface WorkspaceFolderSettingsParams { export interface SettingsParams { filesAssociations: Associations; workspaceFallbackEncoding: string; + workspaceFallbackEncodingChanged: boolean; maxConcurrentThreads: number | null; maxCachedProcesses: number | null; maxMemory: number | null;