From 8bfcb33fd3c2ad5e0d49e9e3d0d7dd9e5d385a40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 01:21:16 +0000 Subject: [PATCH 1/4] Initial plan From dfe6844f744bde97c415563c205277323b6dc329 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 01:27:37 +0000 Subject: [PATCH 2/4] Fix markdown syntax showing in deprecated setting diagnostic messages Co-authored-by: mjbvz <12821956+mjbvz@users.noreply.github.com> --- .../configuration/common/configurationRegistry.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index a212c47ef1b..14a24d763bb 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -742,8 +742,12 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry } this.configurationProperties[key] = properties[key]; if (!properties[key].deprecationMessage && properties[key].markdownDeprecationMessage) { - // If not set, default deprecationMessage to the markdown source - properties[key].deprecationMessage = properties[key].markdownDeprecationMessage; + // If not set, default deprecationMessage to the markdown source with markdown stripped + // since diagnostics don't support markdown rendering + properties[key].deprecationMessage = properties[key].markdownDeprecationMessage! + .replace(/`#([^#`]*)#`/g, '$1') // strip setting links: `#settingId#` -> settingId + .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1') // strip links: [text](url) -> text + .replace(/`([^`]*)`/g, '$1'); // strip inline code: `code` -> code } } From d2345ae4806d679dd1f58e78adb6f105d3b74105 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 18:57:49 +0000 Subject: [PATCH 3/4] Use renderAsPlaintext and rewriteSettingLinks for deprecation message stripping Co-authored-by: mjbvz <12821956+mjbvz@users.noreply.github.com> --- .../common/configurationRegistry.ts | 8 ++----- .../browser/configurationService.ts | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index 14a24d763bb..a212c47ef1b 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -742,12 +742,8 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry } this.configurationProperties[key] = properties[key]; if (!properties[key].deprecationMessage && properties[key].markdownDeprecationMessage) { - // If not set, default deprecationMessage to the markdown source with markdown stripped - // since diagnostics don't support markdown rendering - properties[key].deprecationMessage = properties[key].markdownDeprecationMessage! - .replace(/`#([^#`]*)#`/g, '$1') // strip setting links: `#settingId#` -> settingId - .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1') // strip links: [text](url) -> text - .replace(/`([^`]*)`/g, '$1'); // strip inline code: `code` -> code + // If not set, default deprecationMessage to the markdown source + properties[key].deprecationMessage = properties[key].markdownDeprecationMessage; } } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index b6b3e48dcd3..29ffc197e14 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -47,6 +47,7 @@ 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'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { const isDefaultProfile = userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings; @@ -1151,6 +1152,17 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat } } +/** + * Rewrites VS Code's custom `#settingId#` syntax to standard markdown links + * so that {@link renderAsPlaintext} can properly extract the setting key as plain text. + */ +function rewriteSettingLinks(text: string): string { + return text.replace(/`#([^#\s`]+)#`|'#([^#\s']+)#'/g, (_, backtickGroup, quoteGroup) => { + const settingKey: string = backtickGroup ?? quoteGroup; + return `[${settingKey}](#${settingKey})`; + }); +} + class RegisterConfigurationSchemasContribution extends Disposable implements IWorkbenchContribution { constructor( @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @@ -1172,6 +1184,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: rewriteSettingLinks(prop.markdownDeprecationMessage) }); + } + } + const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, From 8ea255612fc6b28c8e734d8cb1427f1c8e05506e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:15:26 +0000 Subject: [PATCH 4/4] Reuse fixSettingLinks from preferencesModels.ts instead of custom rewriteSettingLinks Co-authored-by: mjbvz <12821956+mjbvz@users.noreply.github.com> --- .../configuration/browser/configurationService.ts | 14 ++------------ .../preferences/common/preferencesModels.ts | 14 ++++++++++---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 29ffc197e14..654e9c2585c 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -48,6 +48,7 @@ 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; @@ -1152,17 +1153,6 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat } } -/** - * Rewrites VS Code's custom `#settingId#` syntax to standard markdown links - * so that {@link renderAsPlaintext} can properly extract the setting key as plain text. - */ -function rewriteSettingLinks(text: string): string { - return text.replace(/`#([^#\s`]+)#`|'#([^#\s']+)#'/g, (_, backtickGroup, quoteGroup) => { - const settingKey: string = backtickGroup ?? quoteGroup; - return `[${settingKey}](#${settingKey})`; - }); -} - class RegisterConfigurationSchemasContribution extends Disposable implements IWorkbenchContribution { constructor( @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @@ -1189,7 +1179,7 @@ class RegisterConfigurationSchemasContribution extends Disposable implements IWo for (const key of Object.keys(allSettings.properties)) { const prop = allSettings.properties[key]; if (prop.markdownDeprecationMessage && prop.deprecationMessage === prop.markdownDeprecationMessage) { - prop.deprecationMessage = renderAsPlaintext({ value: rewriteSettingLinks(prop.markdownDeprecationMessage) }); + prop.deprecationMessage = renderAsPlaintext({ value: fixSettingLinks(prop.markdownDeprecationMessage) }); } } 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);