Skip to content

Commit a81a748

Browse files
authored
Live watch fixes (#612)
* Selecting only parent nodes for delete command * Adding support for showing child elements in memory inspector
1 parent b66dc73 commit a81a748

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
"editor/context": [
140140
{
141141
"command": "vscode-cmsis-debugger.liveWatch.addToLiveWatchFromTextEditor",
142-
"when": "editorTextFocus && resourceScheme == file",
142+
"when": "editorTextFocus",
143143
"group": "z_commands"
144144
}
145145
],
@@ -239,12 +239,12 @@
239239
"view/item/context": [
240240
{
241241
"command": "vscode-cmsis-debugger.liveWatch.modify",
242-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
242+
"when": "view == cmsis-debugger.liveWatch && viewItem == parentExpression",
243243
"group": "inline@1"
244244
},
245245
{
246246
"command": "vscode-cmsis-debugger.liveWatch.delete",
247-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
247+
"when": "view == cmsis-debugger.liveWatch && viewItem == parentExpression",
248248
"group": "inline@2"
249249
},
250250
{
@@ -254,17 +254,17 @@
254254
},
255255
{
256256
"command": "vscode-cmsis-debugger.liveWatch.modify",
257-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
257+
"when": "view == cmsis-debugger.liveWatch && viewItem == parentExpression",
258258
"group": "contextMenuG1@2"
259259
},
260260
{
261261
"command": "vscode-cmsis-debugger.liveWatch.copy",
262-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
262+
"when": "view == cmsis-debugger.liveWatch",
263263
"group": "contextMenuG1@3"
264264
},
265265
{
266266
"command": "vscode-cmsis-debugger.liveWatch.delete",
267-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
267+
"when": "view == cmsis-debugger.liveWatch && viewItem == parentExpression",
268268
"group": "contextMenuG1@4"
269269
},
270270
{
@@ -279,7 +279,7 @@
279279
},
280280
{
281281
"command": "vscode-cmsis-debugger.liveWatch.showInMemoryInspector",
282-
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
282+
"when": "view == cmsis-debugger.liveWatch",
283283
"group": "contextMenuG3@1"
284284
}
285285
]

src/views/live-watch/live-watch.test.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,22 @@ describe('LiveWatchTreeDataProvider', () => {
154154
expect(parent.children.length).toBe(0);
155155
});
156156

157-
it('getTreeItem returns correct TreeItem', () => {
158-
const node = makeNode('expression', { result: 'value', variablesReference: 1 }, 1);
157+
it('returns correct TreeItem for parent nodes', () => {
158+
const node = makeNode('expression', { result: 'value', variablesReference: 0 }, 1);
159159
const item = liveWatchTreeDataProvider.getTreeItem(node);
160160
expect(item.label).toBe('expression = ');
161161
expect(item.description).toBe('value');
162-
expect(item.contextValue).toBe('expression');
162+
expect(item.contextValue).toBe('parentExpression');
163+
});
164+
165+
it('returns correct TreeItem for leaf nodes', () => {
166+
// Create a child node within a parent node
167+
const parent = makeNode('parentExpression', { result: 'parentValue', variablesReference: 1 }, 1);
168+
const child = makeNode('childExpression', { result: 'childValue', variablesReference: 0 }, 2, parent);
169+
const item = liveWatchTreeDataProvider.getTreeItem(child);
170+
expect(item.label).toBe('childExpression = ');
171+
expect(item.description).toBe('childValue');
172+
expect(item.contextValue).toBe('childExpression');
163173
});
164174
});
165175

@@ -220,14 +230,18 @@ describe('LiveWatchTreeDataProvider', () => {
220230

221231
it('AddFromSelection adds selected text as new live watch expression to roots', async () => {
222232
jest.spyOn(liveWatchTreeDataProvider as any, 'evaluate').mockResolvedValue({ result: '5678', variablesReference: 0 });
223-
// Mock the active text editor with a selection whose active position returns a word range
224-
const fakeRange = { start: { line: 0, character: 0 }, end: { line: 0, character: 10 } };
233+
// Mock the active text editor with fake range
234+
const fakeRange = { start: { line: 0, character: 0 }, end: { line: 0, character: 17 } };
225235
const mockEditor: any = {
226236
document: {
227-
getWordRangeAtPosition: jest.fn().mockReturnValue(fakeRange),
228-
getText: jest.fn().mockReturnValue('selected-expression')
237+
getText: jest.fn().mockReturnValue('selected-expression'),
238+
getWordRangeAtPosition: jest.fn().mockReturnValue(fakeRange)
229239
},
230-
selection: { active: { line: 0, character: 5 } }
240+
selection: {
241+
active: { line: 0, character: 5 },
242+
start: { line: 0, character: 0 },
243+
end: { line: 0, character: 17 }
244+
}
231245
};
232246
(vscode.window as any).activeTextEditor = mockEditor;
233247
await (liveWatchTreeDataProvider as any).handleAddFromSelectionCommand();
@@ -238,6 +252,25 @@ describe('LiveWatchTreeDataProvider', () => {
238252
expect(roots[0].expression).toBe('selected-expression');
239253
expect(roots[0].value.result).toBe('5678');
240254
});
255+
256+
it('AddFromSelection does nothing when selection spans multiple lines', async () => {
257+
const mockEditor: any = {
258+
document: {
259+
getText: jest.fn().mockReturnValue('multi-line\nselection'),
260+
getWordRangeAtPosition: jest.fn().mockReturnValue(undefined)
261+
},
262+
selection: {
263+
active: { line: 0, character: 5 },
264+
start: { line: 0, character: 0 },
265+
end: { line: 1, character: 9 }
266+
}
267+
};
268+
(vscode.window as any).activeTextEditor = mockEditor;
269+
await (liveWatchTreeDataProvider as any).handleAddFromSelectionCommand();
270+
const roots = (liveWatchTreeDataProvider as any).roots;
271+
expect(mockEditor.document.getWordRangeAtPosition).toHaveBeenCalledWith(mockEditor.selection.active);
272+
expect(roots.length).toBe(0);
273+
});
241274
});
242275

243276
describe('refresh', () => {

src/views/live-watch/live-watch.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
8383
public getTreeItem(element: LiveWatchNode): vscode.TreeItem {
8484
const item = new vscode.TreeItem(element.expression + ' = ');
8585
item.description = element.value.result;
86-
item.contextValue = 'expression';
8786
item.tooltip = element.value.type ?? '';
8887
item.collapsibleState = element.value.variablesReference !== 0 ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None;
88+
item.contextValue = element.parent ? 'childExpression' : 'parentExpression';
8989
return item;
9090
}
9191

@@ -228,7 +228,7 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
228228
if (!payload || !payload.variable) {
229229
return;
230230
}
231-
await this.addToRoots(payload.variable.name);
231+
await this.addToRoots(payload.variable.evaluateName ?? payload.variable.name);
232232
}
233233

234234
private async handleShowInMemoryInspector(node: LiveWatchNode) {
@@ -244,14 +244,14 @@ export class LiveWatchTreeDataProvider implements vscode.TreeDataProvider<LiveWa
244244
const args = {
245245
sessionId: this._activeSession?.session.id,
246246
container: {
247-
name: node.expression,
247+
name: node.value.evaluateName ?? node.expression,
248248
variablesReference: node.value.variablesReference
249249
},
250250
variable: {
251-
name: node.expression,
251+
name: node.value.evaluateName ?? node.expression,
252252
value: node.value.result,
253253
variablesReference: node.value.variablesReference,
254-
memoryReference: `&(${node.expression})`
254+
memoryReference: `&(${node.value.evaluateName ?? node.expression})`
255255
}
256256
};
257257
await vscode.commands.executeCommand('memory-inspector.show-variable', args);

0 commit comments

Comments
 (0)