Skip to content

Commit 72352b6

Browse files
committed
adding a context menu to live watch
Adding copy expression command to context menu Adding tests for copy expression Adding a new mock for clipboard
1 parent 90481f7 commit 72352b6

File tree

9 files changed

+405
-90
lines changed

9 files changed

+405
-90
lines changed

__mocks__/vscode.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,17 @@ module.exports = {
7171
warn: jest.fn(),
7272
error: jest.fn(),
7373
})),
74+
registerTreeDataProvider: jest.fn(() => ({ dispose: jest.fn() })),
7475
showWarningMessage: jest.fn(),
7576
createStatusBarItem: jest.fn(),
7677
showQuickPick: jest.fn(),
7778
},
79+
env: {
80+
clipboard: {
81+
readText: jest.fn(),
82+
writeText: jest.fn()
83+
}
84+
},
7885
workspace: {
7986
getConfiguration: jest.fn(() => ({
8087
get: jest.fn(),

media/trace-and-live-dark.svg

Lines changed: 61 additions & 0 deletions
Loading

media/trace-and-live-light.svg

Lines changed: 58 additions & 0 deletions
Loading

package.json

Lines changed: 95 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,17 @@
5151
"activitybar": [
5252
{
5353
"id": "cmsis-debugger",
54-
"title": "CMSIS Debug",
55-
"icon": "$(rocket)"
54+
"title": "Trace and Live View",
55+
"icon": "media/trace-and-live-dark.svg"
5656
}
5757
]
5858
},
5959
"views": {
6060
"cmsis-debugger": [
6161
{
6262
"id": "cmsis-debugger.liveWatch",
63-
"name": "Live Watch"
63+
"name": "Live Watch",
64+
"icon": "media/trace-and-live-light.svg"
6465
}
6566
]
6667
},
@@ -80,29 +81,39 @@
8081
"when": "inDebugMode"
8182
},
8283
{
83-
"command": "cmsis-debugger.liveWatch.add",
84+
"command": "vscode-cmsis-debugger.liveWatch.add",
8485
"title": "Add Expression",
85-
"icon": "$(add)"
86+
"icon": "$(add)",
87+
"category": "Live Watch"
8688
},
8789
{
88-
"command": "cmsis-debugger.liveWatch.deleteAll",
90+
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
8991
"title": "Delete All Expressions",
90-
"icon": "$(close-all)"
92+
"icon": "$(close-all)",
93+
"category": "Live Watch"
9194
},
9295
{
93-
"command": "cmsis-debugger.liveWatch.delete",
96+
"command": "vscode-cmsis-debugger.liveWatch.delete",
9497
"title": "Delete Expression",
95-
"icon": "$(close)"
98+
"icon": "$(close)",
99+
"category": "Live Watch"
96100
},
97101
{
98-
"command": "cmsis-debugger.liveWatch.refresh",
102+
"command": "vscode-cmsis-debugger.liveWatch.refresh",
99103
"title": "Refresh",
100-
"icon": "$(refresh)"
104+
"icon": "$(refresh)",
105+
"category": "Live Watch"
101106
},
102107
{
103-
"command": "cmsis-debugger.liveWatch.modify",
108+
"command": "vscode-cmsis-debugger.liveWatch.modify",
104109
"title": "Modify Expression",
105-
"icon": "$(pencil)"
110+
"icon": "$(pencil)",
111+
"category": "Live Watch"
112+
},
113+
{
114+
"command": "vscode-cmsis-debugger.liveWatch.copy",
115+
"title": "Copy Expression",
116+
"category": "Live Watch"
106117
}
107118
],
108119
"menus": {
@@ -114,35 +125,101 @@
114125
{
115126
"command": "vscode-cmsis-debugger.resetCpuTimeHistory",
116127
"when": "inDebugMode"
128+
},
129+
{
130+
"command": "vscode-cmsis-debugger.liveWatch.add",
131+
"when": "true"
132+
},
133+
{
134+
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
135+
"when": "true"
136+
},
137+
{
138+
"command": "vscode-cmsis-debugger.liveWatch.refresh",
139+
"when": "inDebugMode"
140+
},
141+
{
142+
"command": "vscode-cmsis-debugger.liveWatch.modify",
143+
"when": "false"
144+
},
145+
{
146+
"command": "vscode-cmsis-debugger.liveWatch.delete",
147+
"when": "false"
148+
},
149+
{
150+
"command": "vscode-cmsis-debugger.liveWatch.copy",
151+
"when": "false"
117152
}
118153
],
119154
"view/title": [
120155
{
121-
"command": "cmsis-debugger.liveWatch.add",
156+
"command": "vscode-cmsis-debugger.liveWatch.add",
157+
"when": "view == cmsis-debugger.liveWatch"
158+
},
159+
{
160+
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
161+
"when": "view == cmsis-debugger.liveWatch"
162+
},
163+
{
164+
"command": "vscode-cmsis-debugger.liveWatch.refresh",
165+
"when": "view == cmsis-debugger.liveWatch"
166+
},
167+
{
168+
"command": "vscode-cmsis-debugger.liveWatch.add",
122169
"when": "view == cmsis-debugger.liveWatch",
123170
"group": "navigation@1"
124171
},
125172
{
126-
"command": "cmsis-debugger.liveWatch.deleteAll",
173+
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
127174
"when": "view == cmsis-debugger.liveWatch",
128175
"group": "navigation@3"
129176
},
130177
{
131-
"command": "cmsis-debugger.liveWatch.refresh",
178+
"command": "vscode-cmsis-debugger.liveWatch.refresh",
132179
"when": "view == cmsis-debugger.liveWatch",
133180
"group": "navigation@2"
134181
}
135182
],
136183
"view/item/context": [
137184
{
138-
"command": "cmsis-debugger.liveWatch.modify",
185+
"command": "vscode-cmsis-debugger.liveWatch.modify",
139186
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
140187
"group": "inline@1"
141188
},
142189
{
143-
"command": "cmsis-debugger.liveWatch.delete",
190+
"command": "vscode-cmsis-debugger.liveWatch.delete",
144191
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
145192
"group": "inline@2"
193+
},
194+
{
195+
"command": "vscode-cmsis-debugger.liveWatch.modify",
196+
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
197+
"group": "contextMenuG1@2"
198+
},
199+
{
200+
"command": "vscode-cmsis-debugger.liveWatch.delete",
201+
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
202+
"group": "contextMenuG1@4"
203+
},
204+
{
205+
"command": "vscode-cmsis-debugger.liveWatch.add",
206+
"when": "view == cmsis-debugger.liveWatch",
207+
"group": "contextMenuG1@1"
208+
},
209+
{
210+
"command": "vscode-cmsis-debugger.liveWatch.deleteAll",
211+
"when": "view == cmsis-debugger.liveWatch",
212+
"group": "contextMenuG2@1"
213+
},
214+
{
215+
"command": "vscode-cmsis-debugger.liveWatch.refresh",
216+
"when": "view == cmsis-debugger.liveWatch",
217+
"group": "contextMenuG2@2"
218+
},
219+
{
220+
"command": "vscode-cmsis-debugger.liveWatch.copy",
221+
"when": "view == cmsis-debugger.liveWatch && viewItem == expression",
222+
"group": "contextMenuG1@3"
146223
}
147224
]
148225
},

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,18 @@ describe('GDBTargetDebugSession', () => {
5959

6060
it('evaluates a global expression without active stack frame and returns a value', async () => {
6161
// Only mock relevant properties, return value is body of EvaluateResponse
62-
(debugSession.customRequest as jest.Mock).mockReturnValueOnce({ result: '1234567' });
62+
(debugSession.customRequest as jest.Mock).mockReturnValueOnce({ result: '1234567', variableReference: 0 });
6363
const result = await gdbTargetSession.evaluateGlobalExpression('myGlobalVariable');
64-
expect(result).toEqual('1234567');
64+
expect(result).toEqual({ result: '1234567', variableReference: 0 });
6565
expect(debugSession.customRequest as jest.Mock).toHaveBeenCalledWith('evaluate', { expression: 'myGlobalVariable', frameId: 0, context: 'hover' });
6666
});
6767

6868
it('evaluates a global expression with active stack frame and returns a value', async () => {
6969
// Only mock relevant properties, return value is body of EvaluateResponse
70-
(debugSession.customRequest as jest.Mock).mockReturnValueOnce({ result: '1234567' });
70+
(debugSession.customRequest as jest.Mock).mockReturnValueOnce({ result: '1234567', variableReference: 0 });
7171
(vscode.debug.activeStackItem as unknown) = { session: debugSession, threadId: 1, frameId: 2 };
7272
const result = await gdbTargetSession.evaluateGlobalExpression('myGlobalVariable');
73-
expect(result).toEqual('1234567');
73+
expect(result).toEqual({ result: '1234567', variableReference: 0 });
7474
expect(debugSession.customRequest as jest.Mock).toHaveBeenCalledWith('evaluate', { expression: 'myGlobalVariable', frameId: 2, context: 'hover' });
7575
// restore default
7676
(vscode.debug.activeStackItem as unknown) = undefined;

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ export class GDBTargetDebugSession {
5454
this._cbuildRunParsePromise = undefined;
5555
}
5656

57-
public async evaluateGlobalExpression(expression: string, context = 'hover'): Promise<string> {
57+
/** Function returns string only in case of failure */
58+
public async evaluateGlobalExpression(expression: string, context = 'hover'): Promise<DebugProtocol.EvaluateResponse['body'] | string> {
5859
try {
5960
const frameId = (vscode.debug.activeStackItem as vscode.DebugStackFrame)?.frameId ?? 0;
6061
const args: DebugProtocol.EvaluateArguments = {
@@ -63,7 +64,7 @@ export class GDBTargetDebugSession {
6364
context: context
6465
};
6566
const response = await this.session.customRequest('evaluate', args) as DebugProtocol.EvaluateResponse['body'];
66-
return response.result;
67+
return response;
6768
} catch (error: unknown) {
6869
const errorMessage = (error as Error)?.message;
6970
logger.debug(`Session '${this.session.name}': Failed to evaluate global expression '${expression}' - '${errorMessage}'`);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ export class CpuStates {
215215

216216
protected async getFrequency(): Promise<number|undefined> {
217217
const result = await this.activeSession?.evaluateGlobalExpression('SystemCoreClock');
218-
const frequencyString = result?.match(/\d+/) ? result : undefined;
218+
if (typeof result == 'string') {
219+
return undefined;
220+
}
221+
const frequencyString = result?.result.match(/\d+/) ? result.result : undefined;
219222
if (!frequencyString) {
220223
return undefined;
221224
}

0 commit comments

Comments
 (0)