Skip to content

Commit bd32540

Browse files
committed
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 #77
1 parent e44ca7f commit bd32540

20 files changed

Lines changed: 524 additions & 249 deletions

media/options-widget.css

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,16 @@
100100

101101
.advanced-options-content {
102102
color: var(--vscode-settings-headerForeground);
103+
margin-bottom: 1.2rem;
104+
}
105+
106+
.advanced-options-content:last-child {
107+
margin-bottom: 0;
103108
}
104109

105110
.advanced-options-content h2 {
106111
font-size: 110%;
107-
margin: 1.2rem 0 0 0;
112+
margin: 0 0 0 0;
108113
}
109114

110115
.advanced-options-toggle {
@@ -130,7 +135,7 @@
130135
margin: 0.5rem 0 0.2rem 0;
131136
}
132137

133-
.reset-advanced-options-icon {
138+
.more-actions-overlay-icon {
134139
position: absolute;
135140
top: 12px;
136141
right: 0;
@@ -161,3 +166,9 @@
161166
color: var(--vscode-button-background);
162167
margin-left: 0.2em;
163168
}
169+
170+
.settings-contribution-message {
171+
margin-top: 0;
172+
margin-bottom: 0;
173+
color: var(--vscode-descriptionForeground);
174+
}

package.json

Lines changed: 122 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,66 @@
126126
"title": "Apply Memory from File...",
127127
"enablement": "memory-inspector.canWrite",
128128
"category": "Memory"
129+
},
130+
{
131+
"command": "memory-inspector.show-columns-options",
132+
"title": "Show Columns Visibility Options",
133+
"enablement": "optionsMenu && !showColumnsOptions",
134+
"category": "Memory"
135+
},
136+
{
137+
"command": "memory-inspector.hide-columns-options",
138+
"title": "Hide Columns Visibility Options",
139+
"enablement": "optionsMenu && showColumnsOptions",
140+
"category": "Memory"
141+
},
142+
{
143+
"command": "memory-inspector.show-memory-options",
144+
"title": "Show Memory Format Options",
145+
"enablement": "optionsMenu && !showMemoryOptions",
146+
"category": "Memory"
147+
},
148+
{
149+
"command": "memory-inspector.hide-memory-options",
150+
"title": "Hide Memory Format Options",
151+
"enablement": "optionsMenu && showMemoryOptions",
152+
"category": "Memory"
153+
},
154+
{
155+
"command": "memory-inspector.show-address-options",
156+
"title": "Show Address Format Options",
157+
"enablement": "optionsMenu && !showAddressOptions",
158+
"category": "Memory"
159+
},
160+
{
161+
"command": "memory-inspector.hide-address-options",
162+
"title": "Hide Address Format Options",
163+
"enablement": "optionsMenu && showAddressOptions",
164+
"category": "Memory"
165+
},
166+
{
167+
"command": "memory-inspector.show-refresh-options",
168+
"title": "Show Refresh Options",
169+
"enablement": "optionsMenu && !showRefreshOptions",
170+
"category": "Memory"
171+
},
172+
{
173+
"command": "memory-inspector.hide-refresh-options",
174+
"title": "Hide Refresh Options",
175+
"enablement": "optionsMenu && showRefreshOptions",
176+
"category": "Memory"
177+
},
178+
{
179+
"command": "memory-inspector.reset-display-options-to-debugger-defaults",
180+
"title": "Reset to Debugger Defaults",
181+
"enablement": "optionsMenu && hasDebuggerDefaults",
182+
"category": "Memory"
183+
},
184+
{
185+
"command": "memory-inspector.reset-display-options",
186+
"title": "Reset to Defaults",
187+
"enablement": "optionsMenu",
188+
"category": "Memory"
129189
}
130190
],
131191
"menus": {
@@ -183,37 +243,87 @@
183243
{
184244
"command": "memory-inspector.toggle-variables-column",
185245
"group": "a_display@1",
186-
"when": "webviewId === memory-inspector.memory"
246+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
187247
},
188248
{
189249
"command": "memory-inspector.toggle-ascii-column",
190250
"group": "a_display@2",
191-
"when": "webviewId === memory-inspector.memory"
251+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
192252
},
193253
{
194254
"command": "memory-inspector.toggle-radix-prefix",
195255
"group": "a_display@3",
196-
"when": "webviewId === memory-inspector.memory"
256+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
197257
},
198258
{
199259
"command": "memory-inspector.store-file",
200260
"group": "c_store-and-restore@1",
201-
"when": "webviewId === memory-inspector.memory"
261+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
202262
},
203263
{
204264
"command": "memory-inspector.apply-file",
205265
"group": "c_store-and-restore@2",
206-
"when": "webviewId === memory-inspector.memory"
266+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
207267
},
208268
{
209269
"command": "memory-inspector.show-advanced-display-options",
210270
"group": "z_more",
211-
"when": "webviewId === memory-inspector.memory"
271+
"when": "webviewId === memory-inspector.memory && !optionsMenu"
212272
},
213273
{
214274
"command": "memory-inspector.go-to-value",
215275
"group": "display@7",
216-
"when": "webviewId === memory-inspector.memory && memory-inspector.variable.isPointer"
276+
"when": "webviewId === memory-inspector.memory && memory-inspector.variable.isPointer && !optionsMenu"
277+
},
278+
{
279+
"command": "memory-inspector.reset-display-options-to-debugger-defaults",
280+
"group": "a_reset@1",
281+
"when": "webviewId === memory-inspector.memory && optionsMenu && hasDebuggerDefaults"
282+
},
283+
{
284+
"command": "memory-inspector.reset-display-options",
285+
"group": "a_reset@2",
286+
"when": "webviewId === memory-inspector.memory && optionsMenu"
287+
},
288+
{
289+
"command": "memory-inspector.show-columns-options",
290+
"group": "b_advancedOptions@1",
291+
"when": "webviewId === memory-inspector.memory && optionsMenu && !showColumnsOptions"
292+
},
293+
{
294+
"command": "memory-inspector.hide-columns-options",
295+
"group": "b_advancedOptions@1",
296+
"when": "webviewId === memory-inspector.memory && optionsMenu && showColumnsOptions"
297+
},
298+
{
299+
"command": "memory-inspector.show-memory-options",
300+
"group": "b_advancedOptions@2",
301+
"when": "webviewId === memory-inspector.memory && optionsMenu && !showMemoryOptions"
302+
},
303+
{
304+
"command": "memory-inspector.hide-memory-options",
305+
"group": "b_advancedOptions@2",
306+
"when": "webviewId === memory-inspector.memory && optionsMenu && showMemoryOptions"
307+
},
308+
{
309+
"command": "memory-inspector.show-address-options",
310+
"group": "b_advancedOptions@3",
311+
"when": "webviewId === memory-inspector.memory && optionsMenu && !showAddressOptions"
312+
},
313+
{
314+
"command": "memory-inspector.hide-address-options",
315+
"group": "b_advancedOptions@3",
316+
"when": "webviewId === memory-inspector.memory && optionsMenu && showAddressOptions"
317+
},
318+
{
319+
"command": "memory-inspector.show-refresh-options",
320+
"group": "b_advancedOptions@4",
321+
"when": "webviewId === memory-inspector.memory && optionsMenu && !showRefreshOptions"
322+
},
323+
{
324+
"command": "memory-inspector.hide-refresh-options",
325+
"group": "b_advancedOptions@4",
326+
"when": "webviewId === memory-inspector.memory && optionsMenu && showRefreshOptions"
217327
}
218328
]
219329
},
@@ -407,6 +517,11 @@
407517
"type": "boolean",
408518
"default": true,
409519
"description": "Display the radix prefix (e.g., '0x' for hexadecimal, '0b' for binary) before memory addresses."
520+
},
521+
"memory-inspector.allowSettingsExtension": {
522+
"type": "boolean",
523+
"default": true,
524+
"description": "Allow other extensions to overwrite the default memory display settings."
410525
}
411526
}
412527
}

src/common/manifest.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,9 @@ export const CONFIG_SHOW_RADIX_PREFIX = 'showRadixPrefix';
7474
export const DEFAULT_SHOW_RADIX_PREFIX = true;
7575

7676
// Columns
77-
export const CONFIG_SHOW_VARIABLES_COLUMN = 'columns.variables';
78-
export const CONFIG_SHOW_ASCII_COLUMN = 'columns.ascii';
77+
export const CONFIG_SHOW_VARIABLES_COLUMN = 'variables';
78+
export const CONFIG_SHOW_ASCII_COLUMN = 'ascii';
79+
export const DEFAULT_VISIBLE_COLUMNS = [CONFIG_SHOW_VARIABLES_COLUMN, CONFIG_SHOW_ASCII_COLUMN];
80+
81+
// Extension Settings
82+
export const CONFIG_ALLOW_SETTINGS_EXTENSION = 'allowSettingsExtension';

src/common/messaging.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export interface SessionContext {
4848
// Notifications
4949
export const readyType: NotificationType<void> = { method: 'ready' };
5050
export const setMemoryViewSettingsType: NotificationType<Partial<MemoryViewSettings>> = { method: 'setMemoryViewSettings' };
51-
export const resetMemoryViewSettingsType: NotificationType<void> = { method: 'resetMemoryViewSettings' };
5251
export const setTitleType: NotificationType<string> = { method: 'setTitle' };
5352
export const memoryWrittenType: NotificationType<WrittenMemory> = { method: 'memoryWritten' };
5453
export const sessionContextChangedType: NotificationType<SessionContext> = { method: 'sessionContextChanged' };

src/common/webview-configuration.ts

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,54 @@
1414
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1515
********************************************************************************/
1616
import { WebviewIdMessageParticipant } from 'vscode-messenger-common';
17-
import { Endianness, GroupsPerRowOption, PeriodicRefresh, RefreshOnStop } from './manifest';
17+
import { Endianness, PeriodicRefresh, RefreshOnStop } from './manifest';
1818
import { Radix } from './memory-range';
1919

20-
/** The memory display configuration that can be specified for the memory widget. */
21-
export interface MemoryDisplayConfiguration {
20+
/** Specifies the settings for displaying memory addresses in the memory data table. */
21+
export interface MemoryAddressDisplaySettings {
22+
addressPadding: AddressPadding;
23+
addressRadix: Radix;
24+
showRadixPrefix: boolean;
25+
}
26+
27+
export type AddressPadding = 'Min' | 0 | 32 | 64;
28+
29+
/** Specifies the settings for displaying memory data in the memory data table, including the memory addresses. */
30+
export interface MemoryDataDisplaySettings extends MemoryAddressDisplaySettings {
2231
bytesPerMau: number;
2332
mausPerGroup: number;
24-
groupsPerRow: GroupsPerRowOption;
33+
groupsPerRow: 'Autofit' | number;
2534
endianness: Endianness;
2635
scrollingBehavior: ScrollingBehavior;
27-
addressPadding: AddressPadding;
28-
addressRadix: Radix;
29-
showRadixPrefix: boolean;
3036
refreshOnStop: RefreshOnStop;
3137
periodicRefresh: PeriodicRefresh;
3238
periodicRefreshInterval: number;
3339
}
3440

3541
export type ScrollingBehavior = 'Paginate' | 'Grow' | 'Auto-Append';
3642

37-
export type AddressPadding = 'Minimal' | number;
38-
39-
export interface ColumnVisibilityStatus {
43+
/** Specifies the display settings of the memory data table, including the memory data and addresses. */
44+
export interface MemoryDisplaySettings extends MemoryDataDisplaySettings {
4045
visibleColumns: string[];
4146
}
4247

48+
/** An extender's contribution to the `MemoryDisplaySettings` via the `AdapterCapabilities`. */
49+
export interface MemoryDisplaySettingsContribution {
50+
message?: string;
51+
settings?: Partial<MemoryDisplaySettings>;
52+
}
53+
4354
/** All settings related to memory view that can be specified for the webview from the extension "main". */
44-
export interface MemoryViewSettings extends ColumnVisibilityStatus, MemoryDisplayConfiguration {
55+
export interface MemoryViewSettings extends MemoryDisplaySettings, AdvancedOptionsVisibilitySettings {
4556
title: string
4657
messageParticipant: WebviewIdMessageParticipant;
58+
hasDebuggerDefaults?: boolean;
59+
contributionMessage?: string;
60+
}
61+
62+
export interface AdvancedOptionsVisibilitySettings {
63+
showColumnsOptions: boolean;
64+
showMemoryOptions: boolean;
65+
showAddressOptions: boolean;
66+
showRefreshOptions: boolean;
4767
}

src/common/webview-context.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515
********************************************************************************/
1616

1717
import { WebviewIdMessageParticipant } from 'vscode-messenger-common';
18+
import { CONFIG_SHOW_ASCII_COLUMN, CONFIG_SHOW_VARIABLES_COLUMN } from './manifest';
1819
import { VariableMetadata } from './memory-range';
1920
import { ReadMemoryArguments } from './messaging';
21+
import { AdvancedOptionsVisibilitySettings } from './webview-configuration';
2022

21-
export interface WebviewContext {
23+
export interface WebviewContext extends AdvancedOptionsVisibilitySettings {
2224
messageParticipant: WebviewIdMessageParticipant,
2325
webviewSection: string,
2426
showAsciiColumn: boolean
2527
showVariablesColumn: boolean,
2628
showRadixPrefix: boolean,
29+
hasDebuggerDefaults?: boolean,
2730
activeReadArguments: Required<ReadMemoryArguments>
2831
}
2932

@@ -43,10 +46,10 @@ export interface WebviewVariableContext extends WebviewCellContext {
4346
export function getVisibleColumns(context: WebviewContext): string[] {
4447
const columns = [];
4548
if (context.showAsciiColumn) {
46-
columns.push('ascii');
49+
columns.push(CONFIG_SHOW_ASCII_COLUMN);
4750
}
4851
if (context.showVariablesColumn) {
49-
columns.push('variables');
52+
columns.push(CONFIG_SHOW_VARIABLES_COLUMN);
5053
}
5154
return columns;
5255
}

src/plugin/adapter-registry/adapter-capabilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { DebugProtocol } from '@vscode/debugprotocol';
1818
import * as vscode from 'vscode';
1919
import { isDebugRequest, isDebugResponse } from '../../common/debug-requests';
2020
import { VariableRange } from '../../common/memory-range';
21+
import { MemoryDisplaySettingsContribution } from '../../common/webview-configuration';
2122
import { Logger } from '../logger';
2223

2324
/** Represents capabilities that may be achieved with particular debug adapters but are not part of the DAP */
@@ -30,6 +31,9 @@ export interface AdapterCapabilities {
3031
getAddressOfVariable?(session: vscode.DebugSession, variableName: string): Promise<string | undefined>;
3132
/** Resolves the size of a given variable in bytes within the current context. */
3233
getSizeOfVariable?(session: vscode.DebugSession, variableName: string): Promise<bigint | undefined>;
34+
/** Retrieve the enforced default display settings for the memory view. */
35+
getMemoryDisplaySettings?(session: vscode.DebugSession): Promise<Partial<MemoryDisplaySettingsContribution>>;
36+
/** Initialize the trackers of this adapter's for the debug session. */
3337
initializeAdapterTracker?(session: vscode.DebugSession): vscode.DebugAdapterTracker | undefined;
3438
}
3539

src/plugin/memory-provider.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { sendRequest } from '../common/debug-requests';
2020
import { stringToBytesMemory } from '../common/memory';
2121
import { VariableRange } from '../common/memory-range';
2222
import { ReadMemoryResult, WriteMemoryResult } from '../common/messaging';
23+
import { MemoryDisplaySettingsContribution } from '../common/webview-configuration';
2324
import { AdapterRegistry } from './adapter-registry/adapter-registry';
2425
import { isSessionEvent, SessionTracker } from './session-tracker';
2526

@@ -84,8 +85,14 @@ export class MemoryProvider {
8485
}
8586

8687
public async getSizeOfVariable(variableName: string): Promise<bigint | undefined> {
87-
const session = this.sessionTracker.assertActiveSession('get address of variable');
88+
const session = this.sessionTracker.assertActiveSession('get size of variable');
8889
const handler = this.adapterRegistry?.getHandlerForSession(session.type);
8990
return handler?.getSizeOfVariable?.(session, variableName);
9091
}
92+
93+
public async getMemoryDisplaySettingsContribution(): Promise<MemoryDisplaySettingsContribution> {
94+
const session = this.sessionTracker.assertActiveSession('get memory display settings contribution');
95+
const handler = this.adapterRegistry?.getHandlerForSession(session.type);
96+
return handler?.getMemoryDisplaySettings?.(session) ?? {};
97+
}
9198
}

0 commit comments

Comments
 (0)