Skip to content

Commit c04bf42

Browse files
committed
Make checkpoints nameable in UI
We don't save the names, since persistent checkpoints rr-debugger/rr#3406 haven't been fully implemented yet. When it gets finished we can think about having persistent names as well.
1 parent 5d4389d commit c04bf42

File tree

4 files changed

+78
-55
lines changed

4 files changed

+78
-55
lines changed

modules/gdb-dap/debugSession.js

+2-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const EventEmitter = require("events");
66

77
// eslint-disable-next-line no-unused-vars
88
const net = require("node:net");
9-
const { toHexString, getAPI, uiSetAllStopComponent } = require("../utils/utils");
9+
const { toHexString, getAPI, uiSetAllStopComponent, ContextKeys } = require("../utils/utils");
1010
const { TerminatedEvent, OutputEvent, InitializedEvent } = require("@vscode/debugadapter");
1111
const { getExtensionPathOf } = require("../utils/sysutils");
1212
const { CustomRequests } = require("../debugSessionCustomRequests");
@@ -277,18 +277,14 @@ class MidasDAPSession extends DebugAdapter.DebugSession {
277277
}
278278
});
279279

280-
this.on("exit", (evt) => {
281-
this.dispose();
282-
});
283-
284280
this.on("error", (event) => {
285281
this.sendEvent(new DebugAdapter.OutputEvent(event.body, "console", event));
286282
});
287283

288284
}
289285

290286
dispose() {
291-
this.#checkpointsUI.tearDown();
287+
vscode.commands.executeCommand("setContext", ContextKeys.RRSession, false);
292288
this.disposeTerminal();
293289
super.dispose();
294290
}
@@ -468,7 +464,6 @@ class MidasDAPSession extends DebugAdapter.DebugSession {
468464

469465
// eslint-disable-next-line no-unused-vars
470466
disconnectRequest(response, args, request) {
471-
this.#checkpointsUI.tearDown();
472467
this.gdb.sendRequest(request, args);
473468
}
474469

modules/ui/checkpoints/checkpoints.js

+22-9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class CheckpointsViewProvider {
1313
*/
1414
constructor(extensionContext) {
1515
this.#extensionUri = extensionContext.extensionUri;
16+
this.checkpointIdToNameMap = new Map();
17+
1618
let setCheckpoint = registerCommand("midas.set-checkpoint", () => {
1719
vscode.debug.activeDebugSession.customRequest(CustomRequests.SetCheckpoint);
1820
});
@@ -33,18 +35,14 @@ class CheckpointsViewProvider {
3335

3436
updateCheckpoints(checkpoints, show = true) {
3537
if (this.#view) {
36-
if (show) this.#view.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders
37-
38+
if (show) this.#view.show?.(true);
39+
for(let cp of checkpoints) {
40+
cp.name = this.checkpointIdToNameMap.get(cp.id) ?? `${cp.where.path}:${cp.where.line}`;
41+
}
3842
this.#view.webview.postMessage({ type: UI_MESSAGES.UpdateCheckpoints, payload: checkpoints });
3943
}
4044
}
4145

42-
addCheckpoint(checkpoint) {
43-
if (this.#view) {
44-
this.#view.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders
45-
this.#view.webview.postMessage({ type: UI_MESSAGES.AddCheckpoint, payload: checkpoint });
46-
}
47-
}
4846
/**
4947
* Gets resource `resource` from the Checkpoints UI module.
5048
* @param {string} resource
@@ -69,6 +67,9 @@ class CheckpointsViewProvider {
6967
// eslint-disable-next-line no-unused-vars
7068
async resolveWebviewView(webviewView, context, token) {
7169
this.#view = webviewView;
70+
this.#view.onDidDispose(() => {
71+
this.checkpointIdToNameMap.clear();
72+
});
7273
webviewView.webview.options = {
7374
// Allow scripts in the webview
7475
enableScripts: true,
@@ -77,15 +78,27 @@ class CheckpointsViewProvider {
7778

7879
webviewView.webview.html = this.#createHTMLForWebView(webviewView.webview);
7980

80-
webviewView.webview.onDidReceiveMessage((data) => {
81+
webviewView.webview.onDidReceiveMessage(async (data) => {
8182
switch (data.type) {
8283
case UI_REQUESTS.DeleteCheckpoint: {
84+
this.checkpointIdToNameMap.delete(data.value);
8385
vscode.debug.activeDebugSession.customRequest(CustomRequests.DeleteCheckpoint, data.value);
8486
break;
8587
}
8688
case UI_REQUESTS.RunToCheckpoint:
8789
vscode.debug.activeDebugSession.customRequest(CustomRequests.RestartCheckpoint, data.value);
8890
break;
91+
case UI_REQUESTS.NameCheckpoint:
92+
const { checkpointId, name } = data.value;
93+
this.checkpointIdToNameMap.set(checkpointId, name);
94+
break;
95+
case UI_REQUESTS.GotoSourceLoc:
96+
const { path, line } = data.value;
97+
const doc = await vscode.workspace.openTextDocument(path);
98+
const editor = await vscode.window.showTextDocument(doc, { preview: false });
99+
const position = new vscode.Position(line, 0);
100+
editor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.InCenter);
101+
break;
89102
}
90103
});
91104
}

modules/ui/checkpoints/main.js

+52-38
Original file line numberDiff line numberDiff line change
@@ -6,60 +6,77 @@ function setupUI(protocol) {
66
(function () {
77
const vscode = acquireVsCodeApi();
88
function create_row(container, cp) {
9-
let name = document.createElement("span");
10-
name.textContent = `${cp.when}`;
11-
name.className = "checkpoints-list-when";
9+
const checkpointEventNumber = document.createElement("span");
10+
checkpointEventNumber.textContent = `${cp.when}`;
11+
checkpointEventNumber.className = "checkpoints-list-when";
12+
container.appendChild(checkpointEventNumber);
1213

13-
container.appendChild(name);
14+
const checkpointName = document.createElement("span");
15+
checkpointName.textContent = cp.name;
16+
checkpointName.className = "file-path";
17+
checkpointName.addEventListener("click", () => {
18+
const sourceLocPath = cp.where.path.split(" at ")[1];
1419

15-
let path = document.createElement("span");
16-
path.textContent = cp.where.path;
17-
path.className = "file-path";
18-
container.appendChild(path);
20+
if(sourceLocPath)
21+
vscode.postMessage({ type: UI_REQUESTS.GotoSourceLoc, value: { path: sourceLocPath, line: cp.where.line }});
22+
});
23+
24+
checkpointName.addEventListener("keydown", (event) => {
25+
if (event.keyCode === 13) {
26+
checkpointName.contentEditable = false;
27+
event.target.blur();
28+
}
29+
});
30+
31+
checkpointName.addEventListener("blur", (event) => {
32+
const payload = { checkpointId: cp.id, name: event.target.textContent };
33+
vscode.postMessage({ type: UI_MESSAGES.NameCheckpoint, value: payload });
34+
});
1935

20-
let action_bar = document.createElement("div");
21-
action_bar.className = "checkpoints-action-bar";
22-
let action_container = document.createElement("ul");
36+
checkpointName.id = `cp-${cp.id}`;
37+
38+
container.appendChild(checkpointName);
39+
40+
const actionBar = document.createElement("div");
41+
actionBar.className = "checkpoints-action-bar";
42+
let actionContainer = document.createElement("ul");
43+
44+
const editButton = document.createElement("li");
45+
editButton.className = "row-button codicon codicon-edit";
46+
47+
editButton.addEventListener("click", () => {
48+
checkpointName.contentEditable = true;
49+
checkpointName.focus();
50+
});
2351

24-
let play_button = document.createElement("li");
25-
play_button.className = "row-button codicon codicon-debug-continue";
52+
const playButton = document.createElement("li");
53+
playButton.className = "row-button codicon codicon-debug-continue";
2654

27-
play_button.addEventListener("click", () => {
55+
playButton.addEventListener("click", () => {
2856
vscode.postMessage({ type: UI_REQUESTS.RunToCheckpoint, value: container.dataset.checkpointId });
2957
});
3058

31-
let remove_button = document.createElement("li");
32-
remove_button.className = "row-button codicon codicon-chrome-close";
59+
const removeButton = document.createElement("li");
60+
removeButton.className = "row-button codicon codicon-chrome-close";
3361

34-
remove_button.addEventListener("click", () => {
62+
removeButton.addEventListener("click", () => {
3563
vscode.postMessage({ type: UI_REQUESTS.DeleteCheckpoint, value: container.dataset.checkpointId });
3664
});
3765

38-
action_container.appendChild(play_button);
39-
action_container.appendChild(remove_button);
40-
action_bar.appendChild(action_container);
41-
container.appendChild(action_bar);
42-
43-
let line = document.createElement("span");
44-
line.textContent = +cp.where.line;
45-
line.className = "checkpoints-count-badge";
46-
container.appendChild(line);
47-
// div.appendChild(container);
48-
// return div;
66+
actionContainer.appendChild(editButton);
67+
actionContainer.appendChild(playButton);
68+
actionContainer.appendChild(removeButton);
69+
actionBar.appendChild(actionContainer);
70+
container.appendChild(actionBar);
4971
}
50-
const oldState = { checkpoints: [] };
51-
/** @type {Array<CheckpointInfo>} */
52-
let checkpoints = oldState.checkpoints;
5372

54-
updateCheckpointsList(checkpoints);
5573

5674
// Handle messages sent from the extension to the webview
5775
window.addEventListener("message", (event) => {
5876
const message = event.data; // The json data that the extension sent
5977
switch (message.type) {
6078
case UI_MESSAGES.ClearCheckpoints: {
61-
checkpoints = [];
62-
updateCheckpointsList(checkpoints);
79+
updateCheckpointsList([]);
6380
break;
6481
}
6582
case UI_MESSAGES.RemovedCheckpoint: {
@@ -83,20 +100,17 @@ function setupUI(protocol) {
83100
for (const cp of checkpoints) {
84101
const row = document.createElement("div");
85102
row.className = "checkpoints-list-row";
86-
// row.role = "checkbox";
87-
//row.ariaChecked = true;
88103
row.dataIndex = idx;
89104
row.dataLastElement = idx == checkpoints.length - 1;
90105
row.dataset.index = idx;
91106
row.dataset.checkpointId = cp.id;
92107
row.ariaPosInSet = idx + 1;
108+
row.id = `cp-row-${cp.id}`;
93109
create_row(row, cp);
94110
cp_list.appendChild(row);
95111

96112
idx += 1;
97113
}
98-
// Update the saved state
99-
vscode.setState({ checkpoints: checkpoints });
100114
}
101115

102116
function removeCheckpoint(checkpointId) {

modules/ui/checkpoints/ui_protocol.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ const UI_MESSAGES = {
33
ClearCheckpoints: "clear-checkpoint",
44
RemovedCheckpoint: "removed-checkpoint",
55
UpdateCheckpoints: "update-checkpoints",
6+
NameCheckpoint: "name-checkpoint"
67
};
78

8-
const UI_REQUESTS = { DeleteCheckpoint: "delete-checkpoint", RunToCheckpoint: "run-to-checkpoint" };
9+
const UI_REQUESTS = { DeleteCheckpoint: "delete-checkpoint", RunToCheckpoint: "run-to-checkpoint", NameCheckpoint: "name-checkpoint", GotoSourceLoc: "goto-source-location"};
910

1011
module.exports.UI_MESSAGES = UI_MESSAGES;
1112
module.exports.UI_REQUESTS = UI_REQUESTS;

0 commit comments

Comments
 (0)