diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index d9491186439..a9813b52755 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -47,6 +47,8 @@ import { IBrowserWorkbenchEnvironmentService } from '../../environment/browser/e import { workbenchConfigurationNodeBase } from '../../../common/configuration.js'; import { mainWindow } from '../../../../base/browser/window.js'; import { runWhenWindowIdle } from '../../../../base/browser/dom.js'; +import { renderAsPlaintext } from '../../../../base/browser/markdownRenderer.js'; +import { fixSettingLinks } from '../../preferences/common/preferencesModels.js'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { const isDefaultProfile = userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings; @@ -1176,6 +1178,15 @@ class RegisterConfigurationSchemasContribution extends Disposable implements IWo } private registerConfigurationSchemas(): void { + // Ensure deprecationMessage is plain text for properties where it was derived from + // markdownDeprecationMessage, since the JSON editor diagnostics don't support markdown. + for (const key of Object.keys(allSettings.properties)) { + const prop = allSettings.properties[key]; + if (prop.markdownDeprecationMessage && prop.deprecationMessage === prop.markdownDeprecationMessage) { + prop.deprecationMessage = renderAsPlaintext({ value: fixSettingLinks(prop.markdownDeprecationMessage) }); + } + } + const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 84fa12bc44d..1d399cefc95 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -28,6 +28,14 @@ import { isString } from '../../../../base/common/types.js'; export const nullRange: IRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 }; function isNullRange(range: IRange): boolean { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; } +/** + * Strips VS Code's custom `#settingId#` link syntax from a markdown string so the setting key + * remains as inline code (e.g. `` `settingId` ``). Useful for contexts that don't render markdown links. + */ +export function fixSettingLinks(text: string): string { + return text.replace(/`#([^#`]*)#`/g, (_, settingName) => `\`${settingName}\``); +} + abstract class AbstractSettingsModel extends EditorModel { protected _currentResultGroups = new Map(); @@ -1072,13 +1080,11 @@ class SettingsContentBuilder { } private pushSettingDescription(setting: ISetting, indent: string): void { - const fixSettingLink = (line: string) => line.replace(/`#(.*)#`/g, (match, settingName) => `\`${settingName}\``); - setting.descriptionRanges = []; const descriptionPreValue = indent + '// '; const deprecationMessageLines = setting.deprecationMessage?.split(/\n/g) ?? []; for (let line of [...deprecationMessageLines, ...setting.description]) { - line = fixSettingLink(line); + line = fixSettingLinks(line); this._contentByLines.push(descriptionPreValue + line); setting.descriptionRanges.push({ startLineNumber: this.lineCountWithOffset, startColumn: this.lastLine.indexOf(line) + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length }); @@ -1088,7 +1094,7 @@ class SettingsContentBuilder { setting.enumDescriptions.forEach((desc, i) => { const displayEnum = escapeInvisibleChars(String(setting.enum![i])); const line = desc ? - `${displayEnum}: ${fixSettingLink(desc)}` : + `${displayEnum}: ${fixSettingLinks(desc)}` : displayEnum; const lines = line.split(/\n/g);