From bd325409c2ba60ff303d47e75f529d93a9fc4433 Mon Sep 17 00:00:00 2001 From: Philip Langer Date: Wed, 15 May 2024 17:29:47 +0200 Subject: [PATCH] Enable extenders to overwrite default settings Extenders can use the `AdapterCapabilities` to specify their own default settings, including the visible columns (see `MemoryDisplaySettings` interface). If an extension specifies such settings for a specific debug session (or type), those settings take priority over the user's VS Code settings of the Memory Inspector. To indicate that default settings are overwritten by an extension, an additional message can be provided by the extension shown at the bottom of the options overlay. Users can prevent extenders from overwriting the default settings via a dedicated VS Code setting (`allowSettingsExtension`). As we now have two levels of defaults, this change also replaces the reset button with a `...` button opening a drop-down menu similar to the view menus in VS Code. This menu contains two reset entries, if the debugger extension provided defaults; one for resetting to debugger defaults, the other one for resetting to VS Code defaults. This also enables adding additional context menu entries via the usual VS Code menu contribution point, which can be used by extenders. In this change we already make use of it, to control the visibility of sections in the options overlay. We also hide columns and address format by default, because the columns can easily be enabled and disabled via context menu anyway, and address format is less-frequently changed by users. Fixes https://github.com/eclipse-cdt-cloud/vscode-memory-inspector/issues/77 --- media/options-widget.css | 15 +- package.json | 129 ++++++- src/common/manifest.ts | 8 +- src/common/messaging.ts | 1 - src/common/webview-configuration.ts | 42 ++- src/common/webview-context.ts | 9 +- .../adapter-registry/adapter-capabilities.ts | 4 + src/plugin/memory-provider.ts | 9 +- src/plugin/memory-webview-main.ts | 121 +++++-- src/webview/columns/ascii-column.ts | 3 +- src/webview/components/memory-table.tsx | 7 +- src/webview/components/memory-widget.tsx | 29 +- src/webview/components/multi-select.tsx | 7 +- src/webview/components/options-widget.tsx | 329 ++++++++++-------- src/webview/hovers/hover-service.tsx | 4 +- src/webview/hovers/variable-hover.tsx | 3 +- src/webview/memory-webview-view.tsx | 38 +- src/webview/utils/view-types.ts | 8 +- src/webview/utils/vscode-contexts.ts | 4 + src/webview/variables/variable-decorations.ts | 3 +- 20 files changed, 524 insertions(+), 249 deletions(-) diff --git a/media/options-widget.css b/media/options-widget.css index b2e8c1f..ddb6aba 100644 --- a/media/options-widget.css +++ b/media/options-widget.css @@ -100,11 +100,16 @@ .advanced-options-content { color: var(--vscode-settings-headerForeground); + margin-bottom: 1.2rem; +} + +.advanced-options-content:last-child { + margin-bottom: 0; } .advanced-options-content h2 { font-size: 110%; - margin: 1.2rem 0 0 0; + margin: 0 0 0 0; } .advanced-options-toggle { @@ -130,7 +135,7 @@ margin: 0.5rem 0 0.2rem 0; } -.reset-advanced-options-icon { +.more-actions-overlay-icon { position: absolute; top: 12px; right: 0; @@ -161,3 +166,9 @@ color: var(--vscode-button-background); margin-left: 0.2em; } + +.settings-contribution-message { + margin-top: 0; + margin-bottom: 0; + color: var(--vscode-descriptionForeground); +} \ No newline at end of file diff --git a/package.json b/package.json index 1969593..3583d77 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,66 @@ "title": "Apply Memory from File...", "enablement": "memory-inspector.canWrite", "category": "Memory" + }, + { + "command": "memory-inspector.show-columns-options", + "title": "Show Columns Visibility Options", + "enablement": "optionsMenu && !showColumnsOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.hide-columns-options", + "title": "Hide Columns Visibility Options", + "enablement": "optionsMenu && showColumnsOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.show-memory-options", + "title": "Show Memory Format Options", + "enablement": "optionsMenu && !showMemoryOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.hide-memory-options", + "title": "Hide Memory Format Options", + "enablement": "optionsMenu && showMemoryOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.show-address-options", + "title": "Show Address Format Options", + "enablement": "optionsMenu && !showAddressOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.hide-address-options", + "title": "Hide Address Format Options", + "enablement": "optionsMenu && showAddressOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.show-refresh-options", + "title": "Show Refresh Options", + "enablement": "optionsMenu && !showRefreshOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.hide-refresh-options", + "title": "Hide Refresh Options", + "enablement": "optionsMenu && showRefreshOptions", + "category": "Memory" + }, + { + "command": "memory-inspector.reset-display-options-to-debugger-defaults", + "title": "Reset to Debugger Defaults", + "enablement": "optionsMenu && hasDebuggerDefaults", + "category": "Memory" + }, + { + "command": "memory-inspector.reset-display-options", + "title": "Reset to Defaults", + "enablement": "optionsMenu", + "category": "Memory" } ], "menus": { @@ -183,37 +243,87 @@ { "command": "memory-inspector.toggle-variables-column", "group": "a_display@1", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.toggle-ascii-column", "group": "a_display@2", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.toggle-radix-prefix", "group": "a_display@3", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.store-file", "group": "c_store-and-restore@1", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.apply-file", "group": "c_store-and-restore@2", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.show-advanced-display-options", "group": "z_more", - "when": "webviewId === memory-inspector.memory" + "when": "webviewId === memory-inspector.memory && !optionsMenu" }, { "command": "memory-inspector.go-to-value", "group": "display@7", - "when": "webviewId === memory-inspector.memory && memory-inspector.variable.isPointer" + "when": "webviewId === memory-inspector.memory && memory-inspector.variable.isPointer && !optionsMenu" + }, + { + "command": "memory-inspector.reset-display-options-to-debugger-defaults", + "group": "a_reset@1", + "when": "webviewId === memory-inspector.memory && optionsMenu && hasDebuggerDefaults" + }, + { + "command": "memory-inspector.reset-display-options", + "group": "a_reset@2", + "when": "webviewId === memory-inspector.memory && optionsMenu" + }, + { + "command": "memory-inspector.show-columns-options", + "group": "b_advancedOptions@1", + "when": "webviewId === memory-inspector.memory && optionsMenu && !showColumnsOptions" + }, + { + "command": "memory-inspector.hide-columns-options", + "group": "b_advancedOptions@1", + "when": "webviewId === memory-inspector.memory && optionsMenu && showColumnsOptions" + }, + { + "command": "memory-inspector.show-memory-options", + "group": "b_advancedOptions@2", + "when": "webviewId === memory-inspector.memory && optionsMenu && !showMemoryOptions" + }, + { + "command": "memory-inspector.hide-memory-options", + "group": "b_advancedOptions@2", + "when": "webviewId === memory-inspector.memory && optionsMenu && showMemoryOptions" + }, + { + "command": "memory-inspector.show-address-options", + "group": "b_advancedOptions@3", + "when": "webviewId === memory-inspector.memory && optionsMenu && !showAddressOptions" + }, + { + "command": "memory-inspector.hide-address-options", + "group": "b_advancedOptions@3", + "when": "webviewId === memory-inspector.memory && optionsMenu && showAddressOptions" + }, + { + "command": "memory-inspector.show-refresh-options", + "group": "b_advancedOptions@4", + "when": "webviewId === memory-inspector.memory && optionsMenu && !showRefreshOptions" + }, + { + "command": "memory-inspector.hide-refresh-options", + "group": "b_advancedOptions@4", + "when": "webviewId === memory-inspector.memory && optionsMenu && showRefreshOptions" } ] }, @@ -407,6 +517,11 @@ "type": "boolean", "default": true, "description": "Display the radix prefix (e.g., '0x' for hexadecimal, '0b' for binary) before memory addresses." + }, + "memory-inspector.allowSettingsExtension": { + "type": "boolean", + "default": true, + "description": "Allow other extensions to overwrite the default memory display settings." } } } diff --git a/src/common/manifest.ts b/src/common/manifest.ts index be9a6d5..c0e0d3f 100644 --- a/src/common/manifest.ts +++ b/src/common/manifest.ts @@ -74,5 +74,9 @@ export const CONFIG_SHOW_RADIX_PREFIX = 'showRadixPrefix'; export const DEFAULT_SHOW_RADIX_PREFIX = true; // Columns -export const CONFIG_SHOW_VARIABLES_COLUMN = 'columns.variables'; -export const CONFIG_SHOW_ASCII_COLUMN = 'columns.ascii'; +export const CONFIG_SHOW_VARIABLES_COLUMN = 'variables'; +export const CONFIG_SHOW_ASCII_COLUMN = 'ascii'; +export const DEFAULT_VISIBLE_COLUMNS = [CONFIG_SHOW_VARIABLES_COLUMN, CONFIG_SHOW_ASCII_COLUMN]; + +// Extension Settings +export const CONFIG_ALLOW_SETTINGS_EXTENSION = 'allowSettingsExtension'; diff --git a/src/common/messaging.ts b/src/common/messaging.ts index 9b23854..480557c 100644 --- a/src/common/messaging.ts +++ b/src/common/messaging.ts @@ -48,7 +48,6 @@ export interface SessionContext { // Notifications export const readyType: NotificationType = { method: 'ready' }; export const setMemoryViewSettingsType: NotificationType> = { method: 'setMemoryViewSettings' }; -export const resetMemoryViewSettingsType: NotificationType = { method: 'resetMemoryViewSettings' }; export const setTitleType: NotificationType = { method: 'setTitle' }; export const memoryWrittenType: NotificationType = { method: 'memoryWritten' }; export const sessionContextChangedType: NotificationType = { method: 'sessionContextChanged' }; diff --git a/src/common/webview-configuration.ts b/src/common/webview-configuration.ts index 5532e65..209a752 100644 --- a/src/common/webview-configuration.ts +++ b/src/common/webview-configuration.ts @@ -14,19 +14,25 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { WebviewIdMessageParticipant } from 'vscode-messenger-common'; -import { Endianness, GroupsPerRowOption, PeriodicRefresh, RefreshOnStop } from './manifest'; +import { Endianness, PeriodicRefresh, RefreshOnStop } from './manifest'; import { Radix } from './memory-range'; -/** The memory display configuration that can be specified for the memory widget. */ -export interface MemoryDisplayConfiguration { +/** Specifies the settings for displaying memory addresses in the memory data table. */ +export interface MemoryAddressDisplaySettings { + addressPadding: AddressPadding; + addressRadix: Radix; + showRadixPrefix: boolean; +} + +export type AddressPadding = 'Min' | 0 | 32 | 64; + +/** Specifies the settings for displaying memory data in the memory data table, including the memory addresses. */ +export interface MemoryDataDisplaySettings extends MemoryAddressDisplaySettings { bytesPerMau: number; mausPerGroup: number; - groupsPerRow: GroupsPerRowOption; + groupsPerRow: 'Autofit' | number; endianness: Endianness; scrollingBehavior: ScrollingBehavior; - addressPadding: AddressPadding; - addressRadix: Radix; - showRadixPrefix: boolean; refreshOnStop: RefreshOnStop; periodicRefresh: PeriodicRefresh; periodicRefreshInterval: number; @@ -34,14 +40,28 @@ export interface MemoryDisplayConfiguration { export type ScrollingBehavior = 'Paginate' | 'Grow' | 'Auto-Append'; -export type AddressPadding = 'Minimal' | number; - -export interface ColumnVisibilityStatus { +/** Specifies the display settings of the memory data table, including the memory data and addresses. */ +export interface MemoryDisplaySettings extends MemoryDataDisplaySettings { visibleColumns: string[]; } +/** An extender's contribution to the `MemoryDisplaySettings` via the `AdapterCapabilities`. */ +export interface MemoryDisplaySettingsContribution { + message?: string; + settings?: Partial; +} + /** All settings related to memory view that can be specified for the webview from the extension "main". */ -export interface MemoryViewSettings extends ColumnVisibilityStatus, MemoryDisplayConfiguration { +export interface MemoryViewSettings extends MemoryDisplaySettings, AdvancedOptionsVisibilitySettings { title: string messageParticipant: WebviewIdMessageParticipant; + hasDebuggerDefaults?: boolean; + contributionMessage?: string; +} + +export interface AdvancedOptionsVisibilitySettings { + showColumnsOptions: boolean; + showMemoryOptions: boolean; + showAddressOptions: boolean; + showRefreshOptions: boolean; } diff --git a/src/common/webview-context.ts b/src/common/webview-context.ts index 6ae0afc..2bdc846 100644 --- a/src/common/webview-context.ts +++ b/src/common/webview-context.ts @@ -15,15 +15,18 @@ ********************************************************************************/ import { WebviewIdMessageParticipant } from 'vscode-messenger-common'; +import { CONFIG_SHOW_ASCII_COLUMN, CONFIG_SHOW_VARIABLES_COLUMN } from './manifest'; import { VariableMetadata } from './memory-range'; import { ReadMemoryArguments } from './messaging'; +import { AdvancedOptionsVisibilitySettings } from './webview-configuration'; -export interface WebviewContext { +export interface WebviewContext extends AdvancedOptionsVisibilitySettings { messageParticipant: WebviewIdMessageParticipant, webviewSection: string, showAsciiColumn: boolean showVariablesColumn: boolean, showRadixPrefix: boolean, + hasDebuggerDefaults?: boolean, activeReadArguments: Required } @@ -43,10 +46,10 @@ export interface WebviewVariableContext extends WebviewCellContext { export function getVisibleColumns(context: WebviewContext): string[] { const columns = []; if (context.showAsciiColumn) { - columns.push('ascii'); + columns.push(CONFIG_SHOW_ASCII_COLUMN); } if (context.showVariablesColumn) { - columns.push('variables'); + columns.push(CONFIG_SHOW_VARIABLES_COLUMN); } return columns; } diff --git a/src/plugin/adapter-registry/adapter-capabilities.ts b/src/plugin/adapter-registry/adapter-capabilities.ts index d3509e5..60fc17b 100644 --- a/src/plugin/adapter-registry/adapter-capabilities.ts +++ b/src/plugin/adapter-registry/adapter-capabilities.ts @@ -18,6 +18,7 @@ import { DebugProtocol } from '@vscode/debugprotocol'; import * as vscode from 'vscode'; import { isDebugRequest, isDebugResponse } from '../../common/debug-requests'; import { VariableRange } from '../../common/memory-range'; +import { MemoryDisplaySettingsContribution } from '../../common/webview-configuration'; import { Logger } from '../logger'; /** Represents capabilities that may be achieved with particular debug adapters but are not part of the DAP */ @@ -30,6 +31,9 @@ export interface AdapterCapabilities { getAddressOfVariable?(session: vscode.DebugSession, variableName: string): Promise; /** Resolves the size of a given variable in bytes within the current context. */ getSizeOfVariable?(session: vscode.DebugSession, variableName: string): Promise; + /** Retrieve the enforced default display settings for the memory view. */ + getMemoryDisplaySettings?(session: vscode.DebugSession): Promise>; + /** Initialize the trackers of this adapter's for the debug session. */ initializeAdapterTracker?(session: vscode.DebugSession): vscode.DebugAdapterTracker | undefined; } diff --git a/src/plugin/memory-provider.ts b/src/plugin/memory-provider.ts index 10b3e75..71584a2 100644 --- a/src/plugin/memory-provider.ts +++ b/src/plugin/memory-provider.ts @@ -20,6 +20,7 @@ import { sendRequest } from '../common/debug-requests'; import { stringToBytesMemory } from '../common/memory'; import { VariableRange } from '../common/memory-range'; import { ReadMemoryResult, WriteMemoryResult } from '../common/messaging'; +import { MemoryDisplaySettingsContribution } from '../common/webview-configuration'; import { AdapterRegistry } from './adapter-registry/adapter-registry'; import { isSessionEvent, SessionTracker } from './session-tracker'; @@ -84,8 +85,14 @@ export class MemoryProvider { } public async getSizeOfVariable(variableName: string): Promise { - const session = this.sessionTracker.assertActiveSession('get address of variable'); + const session = this.sessionTracker.assertActiveSession('get size of variable'); const handler = this.adapterRegistry?.getHandlerForSession(session.type); return handler?.getSizeOfVariable?.(session, variableName); } + + public async getMemoryDisplaySettingsContribution(): Promise { + const session = this.sessionTracker.assertActiveSession('get memory display settings contribution'); + const handler = this.adapterRegistry?.getHandlerForSession(session.type); + return handler?.getMemoryDisplaySettings?.(session) ?? {}; + } } diff --git a/src/plugin/memory-webview-main.ts b/src/plugin/memory-webview-main.ts index 9439ca6..2e41693 100644 --- a/src/plugin/memory-webview-main.ts +++ b/src/plugin/memory-webview-main.ts @@ -30,7 +30,6 @@ import { ReadMemoryResult, readMemoryType, readyType, - resetMemoryViewSettingsType, SessionContext, sessionContextChangedType, setMemoryViewSettingsType, @@ -44,8 +43,9 @@ import { WriteMemoryResult, writeMemoryType, } from '../common/messaging'; -import { MemoryViewSettings, ScrollingBehavior } from '../common/webview-configuration'; +import { MemoryDisplaySettings, MemoryDisplaySettingsContribution, MemoryViewSettings, ScrollingBehavior } from '../common/webview-configuration'; import { getVisibleColumns, isWebviewVariableContext, WebviewContext } from '../common/webview-context'; +import { AddressPaddingOptions } from '../webview/utils/view-types'; import { isVariablesContext } from './external-views'; import { outputChannelLogger } from './logger'; import { MemoryProvider } from './memory-provider'; @@ -65,6 +65,16 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider { public static ToggleAsciiColumnCommandType = `${manifest.PACKAGE_NAME}.toggle-ascii-column`; public static ToggleVariablesColumnCommandType = `${manifest.PACKAGE_NAME}.toggle-variables-column`; public static ToggleRadixPrefixCommandType = `${manifest.PACKAGE_NAME}.toggle-radix-prefix`; + public static ShowColumnsOptionsType = `${manifest.PACKAGE_NAME}.show-columns-options`; + public static HideColumnsOptionsType = `${manifest.PACKAGE_NAME}.hide-columns-options`; + public static ShowMemoryOptionsType = `${manifest.PACKAGE_NAME}.show-memory-options`; + public static HideMemoryOptionsType = `${manifest.PACKAGE_NAME}.hide-memory-options`; + public static ShowAddressOptionsType = `${manifest.PACKAGE_NAME}.show-address-options`; + public static HideAddressOptionsType = `${manifest.PACKAGE_NAME}.hide-address-options`; + public static ShowRefreshOptionsType = `${manifest.PACKAGE_NAME}.show-refresh-options`; + public static HideRefreshOptionsType = `${manifest.PACKAGE_NAME}.hide-refresh-options`; + public static ResetDisplayOptionsToDefaultsType = `${manifest.PACKAGE_NAME}.reset-display-options`; + public static ResetDisplayOptionsToDebuggerDefaultsType = `${manifest.PACKAGE_NAME}.reset-display-options-to-debugger-defaults`; public static ShowAdvancedDisplayConfigurationCommandType = `${manifest.PACKAGE_NAME}.show-advanced-display-options`; public static GetWebviewSelectionCommandType = `${manifest.PACKAGE_NAME}.get-webview-selection`; @@ -92,17 +102,51 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider { } }), vscode.commands.registerCommand(MemoryWebview.ToggleVariablesColumnCommandType, (ctx: WebviewContext) => { - this.toggleWebviewColumn(ctx, 'variables'); + this.toggleWebviewColumn(ctx, manifest.CONFIG_SHOW_VARIABLES_COLUMN); }), vscode.commands.registerCommand(MemoryWebview.ToggleAsciiColumnCommandType, (ctx: WebviewContext) => { - this.toggleWebviewColumn(ctx, 'ascii'); + this.toggleWebviewColumn(ctx, manifest.CONFIG_SHOW_ASCII_COLUMN); }), vscode.commands.registerCommand(MemoryWebview.ToggleRadixPrefixCommandType, (ctx: WebviewContext) => { this.setMemoryViewSettings(ctx.messageParticipant, { showRadixPrefix: !ctx.showRadixPrefix }); }), + + vscode.commands.registerCommand(MemoryWebview.ShowColumnsOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showColumnsOptions: true }); + }), + vscode.commands.registerCommand(MemoryWebview.HideColumnsOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showColumnsOptions: false }); + }), + vscode.commands.registerCommand(MemoryWebview.ShowMemoryOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showMemoryOptions: true }); + }), + vscode.commands.registerCommand(MemoryWebview.HideMemoryOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showMemoryOptions: false }); + }), + vscode.commands.registerCommand(MemoryWebview.ShowAddressOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showAddressOptions: true }); + }), + vscode.commands.registerCommand(MemoryWebview.HideAddressOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showAddressOptions: false }); + }), + vscode.commands.registerCommand(MemoryWebview.ShowRefreshOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showRefreshOptions: true }); + }), + vscode.commands.registerCommand(MemoryWebview.HideRefreshOptionsType, (ctx: WebviewContext) => { + this.setMemoryViewSettings(ctx.messageParticipant, { showRefreshOptions: false }); + }), + vscode.commands.registerCommand(MemoryWebview.ShowAdvancedDisplayConfigurationCommandType, async (ctx: WebviewContext) => { this.messenger.sendNotification(showAdvancedOptionsType, ctx.messageParticipant, undefined); }), + + vscode.commands.registerCommand(MemoryWebview.ResetDisplayOptionsToDefaultsType, (ctx: WebviewContext) => { + this.setMemoryDisplaySettings(ctx.messageParticipant, undefined, false); + }), + vscode.commands.registerCommand(MemoryWebview.ResetDisplayOptionsToDebuggerDefaultsType, (ctx: WebviewContext) => { + this.setMemoryDisplaySettings(ctx.messageParticipant); + }), + vscode.commands.registerCommand(MemoryWebview.GetWebviewSelectionCommandType, (ctx: WebviewContext) => this.getWebviewSelection(ctx.messageParticipant)), ); }; @@ -192,13 +236,16 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider { protected setWebviewMessageListener(panel: vscode.WebviewPanel, options?: MemoryOptions): void { const participant = this.messenger.registerWebviewPanel(panel); const disposables = [ - this.messenger.onNotification(readyType, () => this.initialize(participant, panel, options), { sender: participant }), + this.messenger.onNotification(readyType, async () => { + this.setSessionContext(participant, this.createContext()); + await this.setMemoryDisplaySettings(participant, panel.title); + this.refresh(participant, options); + }, { sender: participant }), this.messenger.onRequest(setOptionsType, newOptions => { options = { ...options, ...newOptions }; }, { sender: participant }), this.messenger.onRequest(logMessageType, message => outputChannelLogger.info('[webview]:', message), { sender: participant }), this.messenger.onRequest(readMemoryType, request => this.readMemory(request), { sender: participant }), this.messenger.onRequest(writeMemoryType, request => this.writeMemory(request), { sender: participant }), this.messenger.onRequest(getVariablesType, request => this.getVariables(request), { sender: participant }), - this.messenger.onNotification(resetMemoryViewSettingsType, () => this.setInitialSettings(participant, panel.title), { sender: participant }), this.messenger.onNotification(setTitleType, title => { panel.title = title; }, { sender: participant }), this.messenger.onRequest(storeMemoryType, args => this.storeMemory(args), { sender: participant }), this.messenger.onRequest(applyMemoryType, () => this.applyMemory(), { sender: participant }), @@ -207,20 +254,23 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider { panel.onDidDispose(() => disposables.forEach(disposable => disposable.dispose())); } - protected async initialize(participant: WebviewIdMessageParticipant, panel: vscode.WebviewPanel, options?: MemoryOptions): Promise { - this.setSessionContext(participant, this.createContext()); - this.setInitialSettings(participant, panel.title); - this.refresh(participant, options); + protected async setMemoryDisplaySettings(messageParticipant: WebviewIdMessageParticipant, title?: string, includeContributions: boolean = true): Promise { + const defaultSettings = this.getDefaultMemoryDisplaySettings(); + const settingsContribution = includeContributions ? await this.getMemoryDisplaySettingsContribution() : {}; + const settings = settingsContribution.settings ? { ...settingsContribution.settings, hasDebuggerDefaults: true } : {}; + this.setMemoryViewSettings(messageParticipant, { + messageParticipant, + title, + ...defaultSettings, + ...settings, + contributionMessage: settingsContribution.message + }); } protected async refresh(participant: WebviewIdMessageParticipant, options: MemoryOptions = {}): Promise { this.messenger.sendRequest(setOptionsType, participant, options); } - protected setInitialSettings(webviewParticipant: WebviewIdMessageParticipant, title: string): void { - this.setMemoryViewSettings(webviewParticipant, this.getMemoryViewSettings(webviewParticipant, title)); - } - protected setMemoryViewSettings(webviewParticipant: WebviewIdMessageParticipant, settings: Partial): void { this.messenger.sendNotification(setMemoryViewSettingsType, webviewParticipant, settings); } @@ -229,29 +279,36 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider { this.messenger.sendNotification(sessionContextChangedType, webviewParticipant, context); } - protected getMemoryViewSettings(messageParticipant: WebviewIdMessageParticipant, title: string): MemoryViewSettings { - const memoryInspectorConfiguration = vscode.workspace.getConfiguration(manifest.PACKAGE_NAME); - const bytesPerMau = memoryInspectorConfiguration.get(manifest.CONFIG_BYTES_PER_MAU, manifest.DEFAULT_BYTES_PER_MAU); - const mausPerGroup = memoryInspectorConfiguration.get(manifest.CONFIG_MAUS_PER_GROUP, manifest.DEFAULT_MAUS_PER_GROUP); - const groupsPerRow = memoryInspectorConfiguration.get(manifest.CONFIG_GROUPS_PER_ROW, manifest.DEFAULT_GROUPS_PER_ROW); - const endianness = memoryInspectorConfiguration.get(manifest.CONFIG_ENDIANNESS, manifest.DEFAULT_ENDIANNESS); - const scrollingBehavior = memoryInspectorConfiguration.get(manifest.CONFIG_SCROLLING_BEHAVIOR, manifest.DEFAULT_SCROLLING_BEHAVIOR); - const visibleColumns = CONFIGURABLE_COLUMNS - .filter(column => vscode.workspace.getConfiguration(manifest.PACKAGE_NAME).get(column, false)) - .map(columnId => columnId.replace('columns.', '')); - const addressPadding = memoryInspectorConfiguration.get(manifest.CONFIG_ADDRESS_PADDING, manifest.DEFAULT_ADDRESS_PADDING); - const addressRadix = memoryInspectorConfiguration.get(manifest.CONFIG_ADDRESS_RADIX, manifest.DEFAULT_ADDRESS_RADIX); - const showRadixPrefix = memoryInspectorConfiguration.get(manifest.CONFIG_SHOW_RADIX_PREFIX, manifest.DEFAULT_SHOW_RADIX_PREFIX); - const refreshOnStop = memoryInspectorConfiguration.get(manifest.CONFIG_REFRESH_ON_STOP, manifest.DEFAULT_REFRESH_ON_STOP); - const periodicRefresh = memoryInspectorConfiguration.get(manifest.CONFIG_PERIODIC_REFRESH, manifest.DEFAULT_PERIODIC_REFRESH); - const periodicRefreshInterval = memoryInspectorConfiguration.get(manifest.CONFIG_PERIODIC_REFRESH_INTERVAL, manifest.DEFAULT_PERIODIC_REFRESH_INTERVAL); + protected getDefaultMemoryDisplaySettings(): MemoryDisplaySettings { + const memoryInspectorSettings = vscode.workspace.getConfiguration(manifest.PACKAGE_NAME); + const bytesPerMau = memoryInspectorSettings.get(manifest.CONFIG_BYTES_PER_MAU, manifest.DEFAULT_BYTES_PER_MAU); + const mausPerGroup = memoryInspectorSettings.get(manifest.CONFIG_MAUS_PER_GROUP, manifest.DEFAULT_MAUS_PER_GROUP); + const groupsPerRow = memoryInspectorSettings.get(manifest.CONFIG_GROUPS_PER_ROW, manifest.DEFAULT_GROUPS_PER_ROW); + const endianness = memoryInspectorSettings.get(manifest.CONFIG_ENDIANNESS, manifest.DEFAULT_ENDIANNESS); + const scrollingBehavior = memoryInspectorSettings.get(manifest.CONFIG_SCROLLING_BEHAVIOR, manifest.DEFAULT_SCROLLING_BEHAVIOR); + const visibleColumns = CONFIGURABLE_COLUMNS.filter(column => memoryInspectorSettings.get(`columns.${column}`, false)); + const addressPadding = AddressPaddingOptions[memoryInspectorSettings.get(manifest.CONFIG_ADDRESS_PADDING, manifest.DEFAULT_ADDRESS_PADDING)]; + const addressRadix = memoryInspectorSettings.get(manifest.CONFIG_ADDRESS_RADIX, manifest.DEFAULT_ADDRESS_RADIX); + const showRadixPrefix = memoryInspectorSettings.get(manifest.CONFIG_SHOW_RADIX_PREFIX, manifest.DEFAULT_SHOW_RADIX_PREFIX); + const refreshOnStop = memoryInspectorSettings.get(manifest.CONFIG_REFRESH_ON_STOP, manifest.DEFAULT_REFRESH_ON_STOP); + const periodicRefresh = memoryInspectorSettings.get(manifest.CONFIG_PERIODIC_REFRESH, manifest.DEFAULT_PERIODIC_REFRESH); + const periodicRefreshInterval = memoryInspectorSettings.get(manifest.CONFIG_PERIODIC_REFRESH_INTERVAL, manifest.DEFAULT_PERIODIC_REFRESH_INTERVAL); return { - messageParticipant, title, bytesPerMau, mausPerGroup, groupsPerRow, - endianness, scrollingBehavior, visibleColumns, addressPadding, addressRadix, showRadixPrefix, + bytesPerMau, mausPerGroup, groupsPerRow, endianness, scrollingBehavior, + visibleColumns, addressPadding, addressRadix, showRadixPrefix, refreshOnStop, periodicRefresh, periodicRefreshInterval }; } + protected async getMemoryDisplaySettingsContribution(): Promise { + const memoryInspectorSettings = vscode.workspace.getConfiguration(manifest.PACKAGE_NAME); + const allowSettingsExtension = memoryInspectorSettings.get(manifest.CONFIG_ALLOW_SETTINGS_EXTENSION, true); + if (allowSettingsExtension) { + return this.memoryProvider.getMemoryDisplaySettingsContribution(); + } + return { settings: {}, message: undefined }; + } + protected handleSessionEvent(participant: WebviewIdMessageParticipant, event: SessionEvent): void { if (isSessionEvent('active', event)) { this.setSessionContext(participant, this.createContext(event.session?.raw)); diff --git a/src/webview/columns/ascii-column.ts b/src/webview/columns/ascii-column.ts index b90deb7..7ab0ee1 100644 --- a/src/webview/columns/ascii-column.ts +++ b/src/webview/columns/ascii-column.ts @@ -15,6 +15,7 @@ ********************************************************************************/ import { ReactNode } from 'react'; +import { CONFIG_SHOW_ASCII_COLUMN } from '../../common/manifest'; import { Memory } from '../../common/memory'; import { BigIntMemoryRange, toOffset } from '../../common/memory-range'; import { ColumnContribution, TableRenderOptions } from './column-contribution-service'; @@ -29,7 +30,7 @@ function getASCIIForSingleByte(byte: number | undefined): string { } export class AsciiColumn implements ColumnContribution { - readonly id = 'ascii'; + readonly id = CONFIG_SHOW_ASCII_COLUMN; readonly label = 'ASCII'; readonly priority = 3; render(range: BigIntMemoryRange, memory: Memory, options: TableRenderOptions): ReactNode { diff --git a/src/webview/components/memory-table.tsx b/src/webview/components/memory-table.tsx index 6dbde5c..e3c63e9 100644 --- a/src/webview/components/memory-table.tsx +++ b/src/webview/components/memory-table.tsx @@ -25,10 +25,9 @@ import { TooltipEvent } from 'primereact/tooltip/tooltipoptions'; import { classNames } from 'primereact/utils'; import React from 'react'; import { Memory } from '../../common/memory'; -import { WebviewSelection } from '../../common/messaging'; -import { MemoryOptions, ReadMemoryArguments } from '../../common/messaging'; +import { MemoryOptions, ReadMemoryArguments, WebviewSelection } from '../../common/messaging'; import { tryToNumber } from '../../common/typescript'; -import { MemoryDisplayConfiguration, ScrollingBehavior } from '../../common/webview-configuration'; +import { MemoryDataDisplaySettings, ScrollingBehavior } from '../../common/webview-configuration'; import { TableRenderOptions } from '../columns/column-contribution-service'; import { DataColumn } from '../columns/data-column'; import type { HoverService } from '../hovers/hover-service'; @@ -129,7 +128,7 @@ export const MoreMemorySelect: React.FC; activeReadArguments: Required; memory?: Memory; diff --git a/src/webview/components/memory-widget.tsx b/src/webview/components/memory-widget.tsx index 8accd2c..2501f0f 100644 --- a/src/webview/components/memory-widget.tsx +++ b/src/webview/components/memory-widget.tsx @@ -16,10 +16,11 @@ import React from 'react'; import { WebviewIdMessageParticipant } from 'vscode-messenger-common'; +import { CONFIG_SHOW_ASCII_COLUMN, CONFIG_SHOW_VARIABLES_COLUMN } from '../../common/manifest'; import { Memory } from '../../common/memory'; import { WebviewSelection } from '../../common/messaging'; import { MemoryOptions, ReadMemoryArguments, SessionContext } from '../../common/messaging'; -import { MemoryDisplayConfiguration } from '../../common/webview-configuration'; +import { AdvancedOptionsVisibilitySettings, MemoryDataDisplaySettings } from '../../common/webview-configuration'; import { ColumnStatus } from '../columns/column-contribution-service'; import { HoverService } from '../hovers/hover-service'; import { Decoration, MemoryState } from '../utils/view-types'; @@ -27,7 +28,7 @@ import { createAppVscodeContext, VscodeContext } from '../utils/vscode-contexts' import { MemoryTable } from './memory-table'; import { OptionsWidget } from './options-widget'; -interface MemoryWidgetProps extends MemoryDisplayConfiguration { +interface MemoryWidgetProps extends MemoryDataDisplaySettings, AdvancedOptionsVisibilitySettings { messageParticipant: WebviewIdMessageParticipant; sessionContext: SessionContext; configuredReadArguments: Required; @@ -39,12 +40,13 @@ interface MemoryWidgetProps extends MemoryDisplayConfiguration { columns: ColumnStatus[]; effectiveAddressLength: number; isMemoryFetching: boolean; + hasDebuggerDefaults?: boolean; + settingsContributionMessage?: string; updateMemoryState: (state: Partial) => void; toggleColumn(id: string, active: boolean): void; isFrozen: boolean; toggleFrozen: () => void; - updateMemoryDisplayConfiguration: (memoryArguments: Partial) => void; - resetMemoryDisplayConfiguration: () => void; + updateMemoryDisplaySettings: (memoryArguments: Partial) => void; updateTitle: (title: string) => void; fetchMemory(partialOptions?: MemoryOptions): Promise; storeMemory(): void; @@ -70,9 +72,14 @@ export class MemoryWidget extends React.Component unknown; } @@ -55,9 +56,9 @@ const MultiSelectBar: React.FC = ({ items, onSelectionChanged, ); }; -export const MultiSelectWithLabel: React.FC = ({ id, label, items, onSelectionChanged }) => ( -
-

{label}

+export const MultiSelectWithLabel: React.FC = ({ id, label, items, onSelectionChanged, classNames }) => ( +
+

{label}

); diff --git a/src/webview/components/options-widget.tsx b/src/webview/components/options-widget.tsx index 13ccd66..7dfdbcf 100644 --- a/src/webview/components/options-widget.tsx +++ b/src/webview/components/options-widget.tsx @@ -22,25 +22,26 @@ import { InputNumber } from 'primereact/inputnumber'; import { InputText } from 'primereact/inputtext'; import { OverlayPanel } from 'primereact/overlaypanel'; import { classNames } from 'primereact/utils'; -import React, { FocusEventHandler, KeyboardEvent, KeyboardEventHandler, MouseEventHandler, ReactNode } from 'react'; +import React, { FocusEventHandler, KeyboardEvent, KeyboardEventHandler, ReactNode } from 'react'; import { CONFIG_BYTES_PER_MAU_CHOICES, CONFIG_GROUPS_PER_ROW_CHOICES, CONFIG_MAUS_PER_GROUP_CHOICES, ENDIANNESS_CHOICES, PERIODIC_REFRESH_CHOICES } from '../../common/manifest'; import { validateCount, validateMemoryReference, validateOffset } from '../../common/memory'; import { MemoryOptions, ReadMemoryArguments, SessionContext } from '../../common/messaging'; import { tryToNumber } from '../../common/typescript'; +import { AdvancedOptionsVisibilitySettings } from '../../common/webview-configuration'; import { TableRenderOptions } from '../columns/column-contribution-service'; import { DEFAULT_MEMORY_DISPLAY_CONFIGURATION } from '../memory-webview-view'; import { AddressPaddingOptions, DEFAULT_READ_ARGUMENTS, MemoryState, SerializedTableRenderOptions } from '../utils/view-types'; -import { createSectionVscodeContext } from '../utils/vscode-contexts'; +import { createOverlayMoreActionsVscodeContext, createSectionVscodeContext } from '../utils/vscode-contexts'; import { MultiSelectWithLabel } from './multi-select'; export interface OptionsWidgetProps - extends Omit { + extends Omit, AdvancedOptionsVisibilitySettings { sessionContext: SessionContext; configuredReadArguments: Required; activeReadArguments: Required; title: string; + settingsContributionMessage?: string; updateRenderOptions: (options: Partial) => void; - resetRenderOptions: () => void; updateTitle: (title: string) => void; updateMemoryState: (state: Partial) => void; fetchMemory(partialOptions?: MemoryOptions): Promise @@ -85,6 +86,7 @@ export class OptionsWidget extends React.Component(); protected optionsMenuContext = createSectionVscodeContext('optionsWidget'); protected advancedOptionsContext = createSectionVscodeContext('advancedOptionsOverlay'); + protected moreActionsOverlayMenuContext = createOverlayMoreActionsVscodeContext(); protected get optionsFormValues(): OptionsForm { return { @@ -286,21 +288,23 @@ export class OptionsWidget extends React.Component )} - +
@@ -475,6 +505,11 @@ export class OptionsWidget extends React.Component) => void = e => this.triggerContextMenu(e); + protected triggerContextMenu(event: React.MouseEvent): void { + event.target.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true, clientX: event.clientX, clientY: event.clientY })); + } + protected updateOptions(id: InputId, value: string): void { switch (id) { case InputId.Address: @@ -567,8 +602,6 @@ export class OptionsWidget extends React.Component | undefined = () => this.props.resetRenderOptions(); - protected enableTitleEditing = () => this.doEnableTitleEditing(); protected doEnableTitleEditing(): void { if (this.labelEditInput.current) { diff --git a/src/webview/hovers/hover-service.tsx b/src/webview/hovers/hover-service.tsx index aea3aab..6a3b63d 100644 --- a/src/webview/hovers/hover-service.tsx +++ b/src/webview/hovers/hover-service.tsx @@ -17,7 +17,7 @@ import * as React from 'react'; import { HOST_EXTENSION } from 'vscode-messenger-common'; import { logMessageType } from '../../common/messaging'; -import { MemoryDisplayConfiguration } from '../../common/webview-configuration'; +import { MemoryDataDisplaySettings } from '../../common/webview-configuration'; import { MemoryAppState } from '../memory-webview-view'; import { Disposable } from '../utils/view-types'; import { messenger } from '../view-messenger'; @@ -29,7 +29,7 @@ export interface HoverableDetails { extraData: any; } -export interface MemoryDetails extends HoverableDetails, MemoryDisplayConfiguration, MemoryAppState { }; +export interface MemoryDetails extends HoverableDetails, MemoryDataDisplaySettings, MemoryAppState { }; export type HoverProvider = (data: MemoryDetails) => Promise; diff --git a/src/webview/hovers/variable-hover.tsx b/src/webview/hovers/variable-hover.tsx index 60da4f5..92e6363 100644 --- a/src/webview/hovers/variable-hover.tsx +++ b/src/webview/hovers/variable-hover.tsx @@ -15,6 +15,7 @@ ********************************************************************************/ import * as React from 'react'; +import { CONFIG_SHOW_VARIABLES_COLUMN } from '../../common/manifest'; import { VariableRange } from '../../common/memory-range'; import { HoverContribution, MemoryDetails } from './hover-service'; @@ -25,7 +26,7 @@ export class VariableHover implements HoverContribution { async render( { columnId, bytesPerMau, extraData }: MemoryDetails, ): Promise { - if (columnId !== 'variables') { return; } + if (columnId !== CONFIG_SHOW_VARIABLES_COLUMN) { return; } const { type, startAddress, endAddress, name } = extraData as VariableRange; const start = '0x' + parseInt(startAddress).toString(16); diff --git a/src/webview/memory-webview-view.tsx b/src/webview/memory-webview-view.tsx index 34c04bb..b0920b6 100644 --- a/src/webview/memory-webview-view.tsx +++ b/src/webview/memory-webview-view.tsx @@ -20,7 +20,7 @@ import { debounce } from 'lodash'; import { PrimeReactProvider } from 'primereact/api'; import React from 'react'; import { createRoot } from 'react-dom/client'; -import { HOST_EXTENSION, WebviewIdMessageParticipant } from 'vscode-messenger-common'; +import { HOST_EXTENSION } from 'vscode-messenger-common'; import * as manifest from '../common/manifest'; import { createMemoryFromRead, Memory } from '../common/memory'; import { BigIntMemoryRange, doOverlap, getAddressLength, getAddressString, WrittenMemory } from '../common/memory-range'; @@ -32,7 +32,6 @@ import { memoryWrittenType, readMemoryType, readyType, - resetMemoryViewSettingsType, SessionContext, sessionContextChangedType, setMemoryViewSettingsType, @@ -43,7 +42,7 @@ import { WebviewSelection, } from '../common/messaging'; import { Change, hasChanged, hasChangedTo } from '../common/typescript'; -import { MemoryDisplayConfiguration } from '../common/webview-configuration'; +import { MemoryDisplaySettings, MemoryViewSettings } from '../common/webview-configuration'; import { AddressColumn } from './columns/address-column'; import { AsciiColumn } from './columns/ascii-column'; import { columnContributionService, ColumnStatus } from './columns/column-contribution-service'; @@ -54,13 +53,11 @@ import { AddressHover } from './hovers/address-hover'; import { DataHover } from './hovers/data-hover'; import { HoverService, hoverService } from './hovers/hover-service'; import { VariableHover } from './hovers/variable-hover'; -import { Decoration, DEFAULT_READ_ARGUMENTS, MemoryState } from './utils/view-types'; +import { AddressPaddingOptions, Decoration, DEFAULT_READ_ARGUMENTS, MemoryState } from './utils/view-types'; import { variableDecorator } from './variables/variable-decorations'; import { messenger } from './view-messenger'; -export interface MemoryAppState extends MemoryState, MemoryDisplayConfiguration { - messageParticipant: WebviewIdMessageParticipant; - title: string; +export interface MemoryAppState extends MemoryState, MemoryViewSettings { sessionContext: SessionContext; effectiveAddressLength: number; decorations: Decoration[]; @@ -74,18 +71,19 @@ export const DEFAULT_SESSION_CONTEXT: SessionContext = { canWrite: false }; -export const DEFAULT_MEMORY_DISPLAY_CONFIGURATION: MemoryDisplayConfiguration = { +export const DEFAULT_MEMORY_DISPLAY_CONFIGURATION: MemoryDisplaySettings = { bytesPerMau: manifest.DEFAULT_BYTES_PER_MAU, mausPerGroup: manifest.DEFAULT_MAUS_PER_GROUP, groupsPerRow: manifest.DEFAULT_GROUPS_PER_ROW, endianness: manifest.DEFAULT_ENDIANNESS, scrollingBehavior: manifest.DEFAULT_SCROLLING_BEHAVIOR, - addressPadding: manifest.DEFAULT_ADDRESS_PADDING, + addressPadding: AddressPaddingOptions[manifest.DEFAULT_ADDRESS_PADDING], addressRadix: manifest.DEFAULT_ADDRESS_RADIX, showRadixPrefix: manifest.DEFAULT_SHOW_RADIX_PREFIX, refreshOnStop: manifest.DEFAULT_REFRESH_ON_STOP, periodicRefresh: manifest.DEFAULT_PERIODIC_REFRESH, - periodicRefreshInterval: manifest.DEFAULT_PERIODIC_REFRESH_INTERVAL + periodicRefreshInterval: manifest.DEFAULT_PERIODIC_REFRESH_INTERVAL, + visibleColumns: manifest.DEFAULT_VISIBLE_COLUMNS }; class App extends React.Component<{}, MemoryAppState> { @@ -115,6 +113,10 @@ class App extends React.Component<{}, MemoryAppState> { columns: columnContributionService.getColumns(), isMemoryFetching: false, isFrozen: false, + showColumnsOptions: false, + showMemoryOptions: true, + showAddressOptions: false, + showRefreshOptions: true, ...DEFAULT_MEMORY_DISPLAY_CONFIGURATION }; } @@ -144,7 +146,7 @@ class App extends React.Component<{}, MemoryAppState> { const stateChange: Change = { from, to: current }; const sessionContextChange: Change = { from: from.sessionContext, to: current.sessionContext }; - if (hasChanged(stateChange, 'addressPadding') || (this.state.addressPadding === 'Minimal' && hasChanged(stateChange, 'memory'))) { + if (hasChanged(stateChange, 'addressPadding') || (this.state.addressPadding === 'Min' && hasChanged(stateChange, 'memory'))) { const effectiveAddressLength = this.getEffectiveAddressLength(this.state.memory); if (this.state.effectiveAddressLength !== effectiveAddressLength) { this.setState({ effectiveAddressLength }); @@ -231,8 +233,7 @@ class App extends React.Component<{}, MemoryAppState> { title={this.state.title} effectiveAddressLength={this.state.effectiveAddressLength} updateMemoryState={this.updateMemoryState} - updateMemoryDisplayConfiguration={this.updateMemoryDisplayConfiguration} - resetMemoryDisplayConfiguration={this.resetMemoryDisplayConfiguration} + updateMemoryDisplaySettings={this.updateMemoryDisplayConfiguration} updateTitle={this.updateTitle} toggleColumn={this.toggleColumn} toggleFrozen={this.toggleFrozen} @@ -247,6 +248,12 @@ class App extends React.Component<{}, MemoryAppState> { addressPadding={this.state.addressPadding} addressRadix={this.state.addressRadix} showRadixPrefix={this.state.showRadixPrefix} + showColumnsOptions={this.state.showColumnsOptions} + showMemoryOptions={this.state.showMemoryOptions} + showAddressOptions={this.state.showAddressOptions} + showRefreshOptions={this.state.showRefreshOptions} + settingsContributionMessage={this.state.contributionMessage} + hasDebuggerDefaults={this.state.hasDebuggerDefaults} storeMemory={this.storeMemory} applyMemory={this.applyMemory} refreshOnStop={this.state.refreshOnStop} @@ -257,8 +264,7 @@ class App extends React.Component<{}, MemoryAppState> { } protected updateMemoryState = (newState?: Partial) => this.setState(prevState => ({ ...prevState, ...newState })); - protected updateMemoryDisplayConfiguration = (newState: Partial) => this.setState(prevState => ({ ...prevState, ...newState })); - protected resetMemoryDisplayConfiguration = () => messenger.sendNotification(resetMemoryViewSettingsType, HOST_EXTENSION, undefined); + protected updateMemoryDisplayConfiguration = (newState: Partial) => this.setState(prevState => ({ ...prevState, ...newState })); protected updateTitle = (title: string) => { this.setState({ title }); @@ -314,7 +320,7 @@ class App extends React.Component<{}, MemoryAppState> { protected getEffectiveAddressLength(memory?: Memory): number { const { addressRadix, addressPadding } = this.state; - return addressPadding === 'Minimal' ? this.getLastAddressLength(memory) : getAddressLength(addressPadding, addressRadix); + return addressPadding === 'Min' ? this.getLastAddressLength(memory) : getAddressLength(addressPadding, addressRadix); } protected getLastAddressLength(memory?: Memory): number { diff --git a/src/webview/utils/view-types.ts b/src/webview/utils/view-types.ts index f6967f7..85e7add 100644 --- a/src/webview/utils/view-types.ts +++ b/src/webview/utils/view-types.ts @@ -16,15 +16,13 @@ import deepequal from 'fast-deep-equal'; import type * as React from 'react'; -import { Endianness } from '../../common/manifest'; import { Memory } from '../../common/memory'; import { areRangesEqual, BigIntMemoryRange } from '../../common/memory-range'; import { ReadMemoryArguments } from '../../common/messaging'; -import { MemoryDisplayConfiguration } from '../../common/webview-configuration'; +import { MemoryDataDisplaySettings } from '../../common/webview-configuration'; -export interface SerializedTableRenderOptions extends MemoryDisplayConfiguration { +export interface SerializedTableRenderOptions extends MemoryDataDisplaySettings { columnOptions: Array<{ label: string, doRender: boolean }>; - endianness: Endianness; effectiveAddressLength: number; } @@ -80,7 +78,7 @@ export interface FullNodeAttributes extends StylableNodeAttributes { } export const AddressPaddingOptions = { - 'Minimal': 'Minimal', + 'Minimal': 'Min', 'Unpadded': 0, '32bit': 32, '64bit': 64, diff --git a/src/webview/utils/vscode-contexts.ts b/src/webview/utils/vscode-contexts.ts index dbbd54d..6ddb510 100644 --- a/src/webview/utils/vscode-contexts.ts +++ b/src/webview/utils/vscode-contexts.ts @@ -52,6 +52,10 @@ export function createSectionVscodeContext(webviewSection: WebviewSection): Vsco return createVscodeContext({ webviewSection }); } +export function createOverlayMoreActionsVscodeContext(): VscodeContext { + return createVscodeContext({ webviewSection: 'advancedOptionsOverlay', advancedOptions: true, optionsMenu: true }); +} + export function createColumnVscodeContext(column: string): VscodeContext { return createVscodeContext({ column }); } diff --git a/src/webview/variables/variable-decorations.ts b/src/webview/variables/variable-decorations.ts index b0ca61e..5595ae3 100644 --- a/src/webview/variables/variable-decorations.ts +++ b/src/webview/variables/variable-decorations.ts @@ -17,6 +17,7 @@ import { ReactNode } from 'react'; import * as React from 'react'; import { HOST_EXTENSION } from 'vscode-messenger-common'; +import { CONFIG_SHOW_VARIABLES_COLUMN } from '../../common/manifest'; import { areVariablesEqual, BigIntMemoryRange, BigIntVariableRange, compareBigInt, doOverlap } from '../../common/memory-range'; import { getVariablesType, ReadMemoryArguments } from '../../common/messaging'; import { stringifyWithBigInts } from '../../common/typescript'; @@ -36,7 +37,7 @@ const NON_HC_COLORS = [ ] as const; export class VariableDecorator implements ColumnContribution, Decorator { - readonly id = 'variables'; + readonly id = CONFIG_SHOW_VARIABLES_COLUMN; readonly label = 'Variables'; readonly priority = 2; protected active = false;