Skip to content

Commit 1d49136

Browse files
authored
Store/restore view states to/from settings.json (#997)
* cpuStates: (re-)store states in settings.json and add a global command to reset all settings * componentViewer: (re-)store states in settings.json and add buttons for periodicUpdate * Let attached session not take focus * Unify view state storage * Update command conditions for `periodicUpdate` in component viewer * Live watch: (re-)stroe the periodic update state
1 parent 8f4010a commit 1d49136

15 files changed

Lines changed: 1176 additions & 31 deletions

__mocks__/vscode.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ const StatusBarAlignment = {
3030
Right: 2
3131
};
3232

33+
const ConfigurationTarget = {
34+
Global: 1,
35+
Workspace: 2,
36+
};
37+
3338
const MockTreeItemCollapsibleState = {
3439
None: 0,
3540
Collapsed: 1,
@@ -118,6 +123,8 @@ module.exports = {
118123
workspace: {
119124
getConfiguration: jest.fn(() => ({
120125
get: jest.fn(),
126+
update: jest.fn().mockResolvedValue(undefined),
127+
inspect: jest.fn().mockReturnValue(undefined),
121128
})),
122129
fs: {
123130
readFile: jest.fn(uri => {
@@ -163,4 +170,5 @@ module.exports = {
163170
},
164171
EnvironmentVariableMutatorType,
165172
StatusBarAlignment,
173+
ConfigurationTarget,
166174
};

package.json

Lines changed: 112 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@
7474
]
7575
},
7676
"commands": [
77+
{
78+
"command": "vscode-cmsis-debugger.resetDynamicViewState",
79+
"title": "Reset All Dynamic View States",
80+
"category": "CMSIS Debugger"
81+
},
7782
{
7883
"command": "vscode-cmsis-debugger.openDisassemblyView",
7984
"title": "Open Disassembly View",
@@ -163,6 +168,18 @@
163168
"title": "Show in Memory Inspector",
164169
"category": "Live Watch"
165170
},
171+
{
172+
"command": "vscode-cmsis-debugger.liveWatch.enablePeriodicUpdate",
173+
"title": "Enable Periodic Update",
174+
"icon": "$(sync)",
175+
"category": "Live Watch"
176+
},
177+
{
178+
"command": "vscode-cmsis-debugger.liveWatch.disablePeriodicUpdate",
179+
"title": "Disable Periodic Update",
180+
"icon": "$(sync-ignored)",
181+
"category": "Live Watch"
182+
},
166183
{
167184
"command": "vscode-cmsis-debugger.liveWatch.setValue",
168185
"title": "Set Value",
@@ -183,11 +200,13 @@
183200
{
184201
"command": "vscode-cmsis-debugger.componentViewer.enablePeriodicUpdate",
185202
"title": "Enable Periodic Update",
203+
"icon": "$(sync)",
186204
"category": "Component Viewer"
187205
},
188206
{
189207
"command": "vscode-cmsis-debugger.componentViewer.disablePeriodicUpdate",
190208
"title": "Disable Periodic Update",
209+
"icon": "$(sync-ignored)",
191210
"category": "Component Viewer"
192211
},
193212
{
@@ -223,11 +242,13 @@
223242
{
224243
"command": "vscode-cmsis-debugger.corePeripherals.enablePeriodicUpdate",
225244
"title": "Enable Periodic Update",
245+
"icon": "$(sync)",
226246
"category": "Core Peripherals"
227247
},
228248
{
229249
"command": "vscode-cmsis-debugger.corePeripherals.disablePeriodicUpdate",
230250
"title": "Disable Periodic Update",
251+
"icon": "$(sync-ignored)",
231252
"category": "Core Peripherals"
232253
},
233254
{
@@ -279,6 +300,10 @@
279300
}
280301
],
281302
"commandPalette": [
303+
{
304+
"command": "vscode-cmsis-debugger.resetDynamicViewState",
305+
"when": "true"
306+
},
282307
{
283308
"command": "vscode-cmsis-debugger.openDisassemblyView",
284309
"when": "false"
@@ -331,6 +356,14 @@
331356
"command": "vscode-cmsis-debugger.liveWatch.showInMemoryInspector",
332357
"when": "false"
333358
},
359+
{
360+
"command": "vscode-cmsis-debugger.liveWatch.enablePeriodicUpdate",
361+
"when": "!liveWatch.periodicUpdateEnabled"
362+
},
363+
{
364+
"command": "vscode-cmsis-debugger.liveWatch.disablePeriodicUpdate",
365+
"when": "liveWatch.periodicUpdateEnabled"
366+
},
334367
{
335368
"command": "vscode-cmsis-debugger.liveWatch.setValue",
336369
"when": "false"
@@ -345,11 +378,11 @@
345378
},
346379
{
347380
"command": "vscode-cmsis-debugger.componentViewer.enablePeriodicUpdate",
348-
"when": "true"
381+
"when": "!componentViewer.periodicUpdateEnabled"
349382
},
350383
{
351384
"command": "vscode-cmsis-debugger.componentViewer.disablePeriodicUpdate",
352-
"when": "true"
385+
"when": "componentViewer.periodicUpdateEnabled"
353386
},
354387
{
355388
"command": "vscode-cmsis-debugger.componentViewer.expandAll",
@@ -373,11 +406,11 @@
373406
},
374407
{
375408
"command": "vscode-cmsis-debugger.corePeripherals.enablePeriodicUpdate",
376-
"when": "true"
409+
"when": "!corePeripherals.periodicUpdateEnabled"
377410
},
378411
{
379412
"command": "vscode-cmsis-debugger.corePeripherals.disablePeriodicUpdate",
380-
"when": "true"
413+
"when": "corePeripherals.periodicUpdateEnabled"
381414
},
382415
{
383416
"command": "vscode-cmsis-debugger.corePeripherals.expandAll",
@@ -413,22 +446,32 @@
413446
{
414447
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
415448
"when": "view == cmsis-debugger.liveWatch",
416-
"group": "navigation@3"
449+
"group": "navigation@4"
417450
},
418451
{
419452
"command": "vscode-cmsis-debugger.liveWatch.refresh",
420453
"when": "view == cmsis-debugger.liveWatch",
421454
"group": "navigation@2"
422455
},
456+
{
457+
"command": "vscode-cmsis-debugger.liveWatch.disablePeriodicUpdate",
458+
"when": "view == cmsis-debugger.liveWatch && liveWatch.periodicUpdateEnabled",
459+
"group": "navigation@3"
460+
},
461+
{
462+
"command": "vscode-cmsis-debugger.liveWatch.enablePeriodicUpdate",
463+
"when": "view == cmsis-debugger.liveWatch && !liveWatch.periodicUpdateEnabled",
464+
"group": "navigation@3"
465+
},
423466
{
424467
"command": "vscode-cmsis-debugger.componentViewer.expandAll",
425468
"when": "view == cmsis-debugger.componentViewer",
426-
"group": "navigation@3"
469+
"group": "navigation@4"
427470
},
428471
{
429472
"command": "vscode-cmsis-debugger.corePeripherals.expandAll",
430473
"when": "view == cmsis-debugger.corePeripherals",
431-
"group": "navigation@3"
474+
"group": "navigation@4"
432475
},
433476
{
434477
"command": "vscode-cmsis-debugger.componentViewer.filterTree",
@@ -449,6 +492,26 @@
449492
"command": "vscode-cmsis-debugger.corePeripherals.clearFilter",
450493
"when": "view == cmsis-debugger.corePeripherals && corePeripherals.filterActive",
451494
"group": "navigation@2"
495+
},
496+
{
497+
"command": "vscode-cmsis-debugger.componentViewer.disablePeriodicUpdate",
498+
"when": "view == cmsis-debugger.componentViewer && componentViewer.periodicUpdateEnabled",
499+
"group": "navigation@3"
500+
},
501+
{
502+
"command": "vscode-cmsis-debugger.componentViewer.enablePeriodicUpdate",
503+
"when": "view == cmsis-debugger.componentViewer && !componentViewer.periodicUpdateEnabled",
504+
"group": "navigation@3"
505+
},
506+
{
507+
"command": "vscode-cmsis-debugger.corePeripherals.disablePeriodicUpdate",
508+
"when": "view == cmsis-debugger.corePeripherals && corePeripherals.periodicUpdateEnabled",
509+
"group": "navigation@3"
510+
},
511+
{
512+
"command": "vscode-cmsis-debugger.corePeripherals.enablePeriodicUpdate",
513+
"when": "view == cmsis-debugger.corePeripherals && !corePeripherals.periodicUpdateEnabled",
514+
"group": "navigation@3"
452515
}
453516
],
454517
"view/item/context": [
@@ -570,7 +633,48 @@
570633
}
571634
}
572635
}
573-
]
636+
],
637+
"configuration": {
638+
"title": "CMSIS Debugger",
639+
"properties": {
640+
"vscode-cmsis-debugger.viewState": {
641+
"type": "object",
642+
"markdownDescription": "Persisted dynamic view state per debug configuration.",
643+
"additionalProperties": {
644+
"type": "object",
645+
"additionalProperties": false,
646+
"properties": {
647+
"componentViewer": {
648+
"type": "object",
649+
"markdownDescription": "Persisted dynamic view state for the Component Viewer.",
650+
"additionalProperties": false,
651+
"properties": {
652+
"periodicUpdateEnabled": { "type": "boolean" },
653+
"filterPattern": { "type": "string" }
654+
}
655+
},
656+
"corePeripherals": {
657+
"type": "object",
658+
"markdownDescription": "Persisted dynamic view state for the Core Peripherals view.",
659+
"additionalProperties": false,
660+
"properties": {
661+
"periodicUpdateEnabled": { "type": "boolean" },
662+
"filterPattern": { "type": "string" }
663+
}
664+
},
665+
"cpuStatesEnabled": {
666+
"type": "boolean",
667+
"markdownDescription": "Persisted CPU time enable/disable state."
668+
},
669+
"liveWatchPeriodicUpdateEnabled": {
670+
"type": "boolean",
671+
"markdownDescription": "Persisted Live Watch periodic update enable/disable state."
672+
}
673+
}
674+
}
675+
}
676+
}
677+
}
574678
},
575679
"scripts": {
576680
"prepare": "npm run build",

src/cbuild-run/cbuild-run-reader.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,7 @@ export class CbuildRunReader {
108108
return pnameProcessors.map(p => p.pname!);
109109
}
110110

111+
public getTargetType(): string | undefined {
112+
return this.cbuildRun?.['target-type'];
113+
}
111114
}

src/debug-session/__test__/debug-session.factory.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ export type TestInvalidatedEvent = {
3131
};
3232

3333
export type Session = {
34-
session: { id: string };
35-
getCbuildRun: () => Promise<{ getScvdFilePaths: () => string[] } | undefined>;
34+
session: { id: string; configuration?: { name: string } };
35+
getCbuildRun: () => Promise<{ getScvdFilePaths: () => string[]; getTargetType: () => string | undefined } | undefined>;
36+
getConfigStateKey: () => Promise<string>;
3637
getPname: () => Promise<string | undefined>;
3738
refreshTimer: { onRefresh: (cb: OnRefreshCallback) => void };
3839
targetState?: TargetState;
@@ -111,11 +112,13 @@ export const debugSessionFactory = (
111112
// Ensure same object returned for multiple calls to getCbuildRun.
112113
const cbuildRunMock = hasCbuildRun ? {
113114
getContents: jest.fn(),
114-
getScvdFilePaths: () => paths
115+
getScvdFilePaths: () => paths,
116+
getTargetType: jest.fn<string | undefined, []>(() => undefined),
115117
} : undefined;
116118
return {
117-
session: { id },
118-
getCbuildRun: async () => cbuildRunMock,
119+
session: { id, configuration: { name: id } },
120+
getCbuildRun: jest.fn().mockResolvedValue(cbuildRunMock),
121+
getConfigStateKey: jest.fn().mockResolvedValue(id),
119122
getPname: async () => pname,
120123
refreshTimer: {
121124
onRefresh: jest.fn(),

src/debug-session/gdbtarget-debug-session.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ export class GDBTargetDebugSession {
109109
return pname;
110110
}
111111

112+
public async getConfigStateKey(): Promise<string> {
113+
const cbuildRun = await this.getCbuildRun();
114+
const targetType = cbuildRun?.getTargetType();
115+
const configStateKey = targetType ? `${targetType}::${this.session.configuration.name}` : this.session.configuration.name;
116+
return configStateKey;
117+
}
118+
112119
/**
113120
* Check if first stop attempt for session is done by 'terminate' request.
114121
* Notes:

src/desktop/extension.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { GenericCommands } from '../features/generic-commands';
2727
import { ComponentViewer } from '../views/component-viewer/component-viewer';
2828
import { ComponentViewerTreeDataProvider } from '../views/component-viewer/component-viewer-tree-view';
2929
import { CorePeripherals } from '../views/core-peripherals/core-peripherals';
30+
import { clearAllViewState } from '../views/dynamic-view-states';
3031

3132
const BUILTIN_TOOLS_PATHS = [
3233
'tools/pyocd/pyocd',
@@ -85,6 +86,19 @@ export const activate = async (context: vscode.ExtensionContext): Promise<void>
8586
canCompleteActivation = false;
8687
}
8788

89+
// Register reset dynamic view state command
90+
context.subscriptions.push(
91+
vscode.commands.registerCommand('vscode-cmsis-debugger.resetDynamicViewState', async () => {
92+
await clearAllViewState();
93+
await Promise.all([
94+
cpuStates.resetViewState(),
95+
componentViewer.resetViewState(),
96+
corePeripherals.resetViewState(),
97+
liveWatchTreeDataProvider.resetViewState(),
98+
]);
99+
})
100+
);
101+
88102
if (!canCompleteActivation) {
89103
logger.debug('CMSIS Debugger activation incomplete');
90104
// Let promise float, we reload the window.

src/features/cpu-states/cpu-states-statusbar-item.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export class CpuStatesStatusBarItem {
6666
}
6767

6868
protected async handleItemCommand(): Promise<void> {
69+
const cpuEnabled = this.cpuStates?.isEnabled ?? true;
6970
const items: QuickPickHandlerItem[] = [
7071
{
7172
label: 'CPU Time',
@@ -76,7 +77,18 @@ export class CpuStatesStatusBarItem {
7677
label: 'Reset CPU Time',
7778
detail: 'Reset CPU execution time and history',
7879
handler: () => vscode.commands.executeCommand(CpuStatesCommands.resetCpuTimeHistoryID)
79-
}
80+
},
81+
cpuEnabled
82+
? {
83+
label: 'Disable CPU Timer',
84+
detail: 'Stop collecting CPU execution time',
85+
handler: () => vscode.commands.executeCommand(CpuStatesCommands.disableCpuTimer)
86+
}
87+
: {
88+
label: 'Enable CPU Timer',
89+
detail: 'Start collecting CPU execution time',
90+
handler: () => vscode.commands.executeCommand(CpuStatesCommands.enableCpuTimer)
91+
}
8092
];
8193
const selection = await vscode.window.showQuickPick(items);
8294
if (!selection) {

0 commit comments

Comments
 (0)