From ea8cfb10157229cf8ab6451cd59bf52162e6decc Mon Sep 17 00:00:00 2001 From: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Date: Mon, 30 Mar 2026 19:25:17 -0700 Subject: [PATCH] align whitespace menu option with setting (#306483) * align render whitespace menu option (https://github.com/microsoft/vscode/issues/305883) * Use descriptive titles and shortTitle for render whitespace mode commands Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/d7e269a5-e4e5-4d4c-967d-2b2c9f09b835 Co-authored-by: joshspicer <23246594+joshspicer@users.noreply.github.com> * Move submenu registration into Action2 menu property, remove duplicate MenuRegistry calls Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/68d6d9ff-b7a9-41b1-89f7-3c561b677802 Co-authored-by: joshspicer <23246594+joshspicer@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- src/vs/platform/actions/common/actions.ts | 1 + .../browser/toggleRenderWhitespace.ts | 121 ++++++++++++++++-- 2 files changed, 109 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index e87ffd1d630..910c40db359 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -100,6 +100,7 @@ export class MenuId { static readonly EditorTabsBarShowTabsSubmenu = new MenuId('EditorTabsBarShowTabsSubmenu'); static readonly EditorTabsBarShowTabsZenModeSubmenu = new MenuId('EditorTabsBarShowTabsZenModeSubmenu'); static readonly EditorActionsPositionSubmenu = new MenuId('EditorActionsPositionSubmenu'); + static readonly EditorRenderWhitespaceSubmenu = new MenuId('EditorRenderWhitespaceSubmenu'); static readonly EditorSplitMoveSubmenu = new MenuId('EditorSplitMoveSubmenu'); static readonly ExplorerContext = new MenuId('ExplorerContext'); static readonly ExplorerContextShare = new MenuId('ExplorerContextShare'); diff --git a/src/vs/workbench/contrib/codeEditor/browser/toggleRenderWhitespace.ts b/src/vs/workbench/contrib/codeEditor/browser/toggleRenderWhitespace.ts index 9f61e2363ba..630493a3fdd 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/toggleRenderWhitespace.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/toggleRenderWhitespace.ts @@ -4,12 +4,104 @@ *--------------------------------------------------------------------------------------------*/ import { localize, localize2 } from '../../../../nls.js'; -import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js'; +import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../platform/actions/common/actions.js'; import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js'; import { Categories } from '../../../../platform/action/common/actionCommonCategories.js'; import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js'; +const renderWhitespaceSetting = 'editor.renderWhitespace'; + +class RenderWhitespaceNoneAction extends Action2 { + static readonly ID = 'editor.action.renderWhitespace.none'; + constructor() { + super({ + id: RenderWhitespaceNoneAction.ID, + title: localize2('renderWhitespace.setNone', "Set Render Whitespace to None"), + shortTitle: localize2('renderWhitespace.none', "None"), + category: Categories.View, + f1: false, + toggled: ContextKeyExpr.equals(`config.${renderWhitespaceSetting}`, 'none'), + menu: { id: MenuId.EditorRenderWhitespaceSubmenu, group: '1_config', order: 1 }, + }); + } + override run(accessor: ServicesAccessor): Promise { + return accessor.get(IConfigurationService).updateValue(renderWhitespaceSetting, 'none'); + } +} + +class RenderWhitespaceBoundaryAction extends Action2 { + static readonly ID = 'editor.action.renderWhitespace.boundary'; + constructor() { + super({ + id: RenderWhitespaceBoundaryAction.ID, + title: localize2('renderWhitespace.setBoundary', "Set Render Whitespace to Boundary"), + shortTitle: localize2('renderWhitespace.boundary', "Boundary"), + category: Categories.View, + f1: false, + toggled: ContextKeyExpr.equals(`config.${renderWhitespaceSetting}`, 'boundary'), + menu: { id: MenuId.EditorRenderWhitespaceSubmenu, group: '1_config', order: 2 }, + }); + } + override run(accessor: ServicesAccessor): Promise { + return accessor.get(IConfigurationService).updateValue(renderWhitespaceSetting, 'boundary'); + } +} + +class RenderWhitespaceSelectionAction extends Action2 { + static readonly ID = 'editor.action.renderWhitespace.selection'; + constructor() { + super({ + id: RenderWhitespaceSelectionAction.ID, + title: localize2('renderWhitespace.setSelection', "Set Render Whitespace to Selection"), + shortTitle: localize2('renderWhitespace.selection', "Selection"), + category: Categories.View, + f1: false, + toggled: ContextKeyExpr.equals(`config.${renderWhitespaceSetting}`, 'selection'), + menu: { id: MenuId.EditorRenderWhitespaceSubmenu, group: '1_config', order: 3 }, + }); + } + override run(accessor: ServicesAccessor): Promise { + return accessor.get(IConfigurationService).updateValue(renderWhitespaceSetting, 'selection'); + } +} + +class RenderWhitespaceTrailingAction extends Action2 { + static readonly ID = 'editor.action.renderWhitespace.trailing'; + constructor() { + super({ + id: RenderWhitespaceTrailingAction.ID, + title: localize2('renderWhitespace.setTrailing', "Set Render Whitespace to Trailing"), + shortTitle: localize2('renderWhitespace.trailing', "Trailing"), + category: Categories.View, + f1: false, + toggled: ContextKeyExpr.equals(`config.${renderWhitespaceSetting}`, 'trailing'), + menu: { id: MenuId.EditorRenderWhitespaceSubmenu, group: '1_config', order: 4 }, + }); + } + override run(accessor: ServicesAccessor): Promise { + return accessor.get(IConfigurationService).updateValue(renderWhitespaceSetting, 'trailing'); + } +} + +class RenderWhitespaceAllAction extends Action2 { + static readonly ID = 'editor.action.renderWhitespace.all'; + constructor() { + super({ + id: RenderWhitespaceAllAction.ID, + title: localize2('renderWhitespace.setAll', "Set Render Whitespace to All"), + shortTitle: localize2('renderWhitespace.all', "All"), + category: Categories.View, + f1: false, + toggled: ContextKeyExpr.equals(`config.${renderWhitespaceSetting}`, 'all'), + menu: { id: MenuId.EditorRenderWhitespaceSubmenu, group: '1_config', order: 5 }, + }); + } + override run(accessor: ServicesAccessor): Promise { + return accessor.get(IConfigurationService).updateValue(renderWhitespaceSetting, 'all'); + } +} + class ToggleRenderWhitespaceAction extends Action2 { static readonly ID = 'editor.action.toggleRenderWhitespace'; @@ -17,25 +109,16 @@ class ToggleRenderWhitespaceAction extends Action2 { constructor() { super({ id: ToggleRenderWhitespaceAction.ID, - title: { - ...localize2('toggleRenderWhitespace', "Toggle Render Whitespace"), - mnemonicTitle: localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "&&Render Whitespace"), - }, + title: localize2('toggleRenderWhitespace', "Toggle Render Whitespace"), category: Categories.View, f1: true, - toggled: ContextKeyExpr.notEquals('config.editor.renderWhitespace', 'none'), - menu: { - id: MenuId.MenubarAppearanceMenu, - group: '4_editor', - order: 4 - } }); } override run(accessor: ServicesAccessor): Promise { const configurationService = accessor.get(IConfigurationService); - const renderWhitespace = configurationService.getValue('editor.renderWhitespace'); + const renderWhitespace = configurationService.getValue(renderWhitespaceSetting); let newRenderWhitespace: string; if (renderWhitespace === 'none') { @@ -44,8 +127,20 @@ class ToggleRenderWhitespaceAction extends Action2 { newRenderWhitespace = 'none'; } - return configurationService.updateValue('editor.renderWhitespace', newRenderWhitespace); + return configurationService.updateValue(renderWhitespaceSetting, newRenderWhitespace); } } +registerAction2(RenderWhitespaceNoneAction); +registerAction2(RenderWhitespaceBoundaryAction); +registerAction2(RenderWhitespaceSelectionAction); +registerAction2(RenderWhitespaceTrailingAction); +registerAction2(RenderWhitespaceAllAction); registerAction2(ToggleRenderWhitespaceAction); + +MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { + submenu: MenuId.EditorRenderWhitespaceSubmenu, + title: localize('renderWhitespace', "Render Whitespace"), + group: '4_editor', + order: 4 +});