Skip to content

Commit

Permalink
Enable extenders to overwrite default settings
Browse files Browse the repository at this point in the history
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 #77
  • Loading branch information
planger committed May 16, 2024
1 parent e44ca7f commit d079e95
Show file tree
Hide file tree
Showing 20 changed files with 522 additions and 247 deletions.
15 changes: 13 additions & 2 deletions media/options-widget.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
129 changes: 122 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -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"
}
]
},
Expand Down Expand Up @@ -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."
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/common/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
1 change: 0 additions & 1 deletion src/common/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export interface SessionContext {
// Notifications
export const readyType: NotificationType<void> = { method: 'ready' };
export const setMemoryViewSettingsType: NotificationType<Partial<MemoryViewSettings>> = { method: 'setMemoryViewSettings' };
export const resetMemoryViewSettingsType: NotificationType<void> = { method: 'resetMemoryViewSettings' };
export const setTitleType: NotificationType<string> = { method: 'setTitle' };
export const memoryWrittenType: NotificationType<WrittenMemory> = { method: 'memoryWritten' };
export const sessionContextChangedType: NotificationType<SessionContext> = { method: 'sessionContextChanged' };
Expand Down
38 changes: 29 additions & 9 deletions src/common/webview-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,51 @@ import { WebviewIdMessageParticipant } from 'vscode-messenger-common';
import { Endianness, GroupsPerRowOption, 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;
endianness: Endianness;
scrollingBehavior: ScrollingBehavior;
addressPadding: AddressPadding;
addressRadix: Radix;
showRadixPrefix: boolean;
refreshOnStop: RefreshOnStop;
periodicRefresh: PeriodicRefresh;
periodicRefreshInterval: number;
}

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<MemoryDisplaySettings>;
}

/** 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;
}
9 changes: 6 additions & 3 deletions src/common/webview-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@
********************************************************************************/

import { WebviewIdMessageParticipant } from 'vscode-messenger-common';
import * as manifest from '../common/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<ReadMemoryArguments>
}

Expand All @@ -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(manifest.CONFIG_SHOW_ASCII_COLUMN);
}
if (context.showVariablesColumn) {
columns.push('variables');
columns.push(manifest.CONFIG_SHOW_VARIABLES_COLUMN);
}
return columns;
}
Expand Down
4 changes: 4 additions & 0 deletions src/plugin/adapter-registry/adapter-capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -30,6 +31,9 @@ export interface AdapterCapabilities {
getAddressOfVariable?(session: vscode.DebugSession, variableName: string): Promise<string | undefined>;
/** Resolves the size of a given variable in bytes within the current context. */
getSizeOfVariable?(session: vscode.DebugSession, variableName: string): Promise<bigint | undefined>;
/** Retrieve the enforced default display settings for the memory view. */
getMemoryDisplaySettings?(session: vscode.DebugSession): Promise<Partial<MemoryDisplaySettingsContribution>>;
/** Initialize the trackers of this adapter's for the debug session. */
initializeAdapterTracker?(session: vscode.DebugSession): vscode.DebugAdapterTracker | undefined;
}

Expand Down
9 changes: 8 additions & 1 deletion src/plugin/memory-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -84,8 +85,14 @@ export class MemoryProvider {
}

public async getSizeOfVariable(variableName: string): Promise<bigint | undefined> {
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<MemoryDisplaySettingsContribution> {
const session = this.sessionTracker.assertActiveSession('get memory display settings contribution');
const handler = this.adapterRegistry?.getHandlerForSession(session.type);
return handler?.getMemoryDisplaySettings?.(session) ?? {};
}
}
Loading

0 comments on commit d079e95

Please sign in to comment.