Skip to content

Commit

Permalink
Edit, move up/down. Add to Live Watch from variables window
Browse files Browse the repository at this point in the history
  • Loading branch information
haneefdm committed Mar 9, 2023
1 parent 2f8eb0a commit 1625574
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 21 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
ChangeLog
=========

# V1.9.2 - Major release only available as a Pre-release.
* Many features to Live Watch added
* You can now edit the expression
* You can move up/down the expression (they rotate if at edges)
* You can enable the global hex mode or use the hex mode on one expression at a time just like you can do it in the `WATCH` window
* To enable hex mode on a single expression, simply add a `,x` at the end of the expression. You can also do octal by using `,o`. However, this only works for the scalar variables and if it is a pinter or an array, it is not inherited by its children
* There is now a button on the `VARIABLES`, `WATCH` and `CORTEX LIVE WATCH` panels title bar to enable/disable Hex display mode globally. You can still override on individual expressions.
* Increased the number of threads (256) and frames (4K) you can have. Such limits should not even exist but it is an artifact of how VSCode works

# V1.9.1 - Major release only available as a Pre-release.
* Oops. The context menu in the Variables window for enable/disable Hex had disappeared.
# V1.9.1 - Major release only available as a Pre-release.
* The Registers Panel is now removed. We had deprecated this window a year ago as it would not give you accurate register values based on the Program/Thread/Frame. The accurate version of the Registers have been available in the VARIABLES panel for almost a year now.
* Fixed some issue when the Live Watch window was empty or variables added while there wasn't a debug session sometimes would not show
Expand Down
72 changes: 66 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.9.1",
"version": "1.9.2",
"preview": false,
"activationEvents": [
"onDebugResolve:cortex-debug",
Expand Down Expand Up @@ -420,6 +420,26 @@
"title": "Remove expression",
"icon": "$(close)"
},
{
"command": "cortex-debug.liveWatch.editExpr",
"title": "Edit expression",
"icon": "$(edit)"
},
{
"command": "cortex-debug.liveWatch.moveUp",
"title": "Move expression up",
"icon": "$(arrow-up)"
},
{
"command": "cortex-debug.liveWatch.moveDown",
"title": "Move expression down",
"icon": "$(arrow-down)"
},
{
"command": "cortex-debug.liveWatch.addToLiveWatch",
"title": "Add to Live Watch",
"icon": "$(plus)"
},
{
"category": "Cortex-Debug",
"command": "cortex-debug.examineMemory",
Expand Down Expand Up @@ -2889,6 +2909,21 @@
}
],
"view/item/context": [
{
"command": "cortex-debug.liveWatch.editExpr",
"when": "view == cortex-debug.liveWatch && viewItem == expression",
"group": "inline"
},
{
"command": "cortex-debug.liveWatch.moveUp",
"when": "view == cortex-debug.liveWatch && viewItem == expression",
"group": "inline"
},
{
"command": "cortex-debug.liveWatch.moveDown",
"when": "view == cortex-debug.liveWatch && viewItem == expression",
"group": "inline"
},
{
"command": "cortex-debug.liveWatch.removeExpr",
"when": "view == cortex-debug.liveWatch && viewItem == expression",
Expand All @@ -2900,17 +2935,42 @@
"command": "cortex-debug.liveWatch.addExpr",
"when": "view == cortex-debug.liveWatch",
"group": "navigation"
}
],
"debug/variables/title": [
},
{
"command": "cortex-debug.varHexModeTurnOn",
"when": "view == workbench.debug.variablesView && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && cortex-debug:variableUseNaturalFormat",
"group": "navigation"
},
{
"command": "cortex-debug.varHexModeTurnOff",
"when": "view == workbench.debug.variablesView && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && !cortex-debug:variableUseNaturalFormat",
"group": "navigation"
},
{
"command": "cortex-debug.varHexModeTurnOn",
"when": "inDebugMode && debugType == 'cortex-debug' && debugState == stopped && cortex-debug:variableUseNaturalFormat",
"when": "view == workbench.debug.watchExpressionsView && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && cortex-debug:variableUseNaturalFormat",
"group": "navigation"
},
{
"command": "cortex-debug.varHexModeTurnOff",
"when": "view == workbench.debug.watchExpressionsView && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && !cortex-debug:variableUseNaturalFormat",
"group": "navigation"
},
{
"command": "cortex-debug.varHexModeTurnOn",
"when": "view == cortex-debug.liveWatch && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && cortex-debug:variableUseNaturalFormat",
"group": "navigation"
},
{
"command": "cortex-debug.varHexModeTurnOff",
"when": "inDebugMode && debugType == 'cortex-debug' && debugState == stopped && !cortex-debug:variableUseNaturalFormat",
"when": "view == cortex-debug.liveWatch && inDebugMode && debugType == 'cortex-debug' && debugState == stopped && !cortex-debug:variableUseNaturalFormat",
"group": "navigation"
}
],
"debug/variables/context": [
{
"command": "cortex-debug.liveWatch.addToLiveWatch",
"when": "inDebugMode && debugType == 'cortex-debug' && debugState == stopped",
"group": "navigation"
}
]
Expand Down
4 changes: 2 additions & 2 deletions src/backend/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,9 @@ export class SymbolTable {

const secName = match[9].trim();
const size = parseInt(match[10], 16);
if ((size === 0) && ((secName === '*ABS*') || (secName === '*UND*'))) {
if ((secName === '*ABS*') || (secName === '*UND*')) {
// These are not true symbols, AFAIK and can be safely ignored as there can be hundreds of these
// junk symbols
// junk symbols. We already handled file names above
return true;
}

Expand Down
57 changes: 48 additions & 9 deletions src/frontend/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class CortexDebugExtension {

Reporting.activate(context);

this.initLiveWatcher();
this.liveWatchProvider = new LiveWatchTreeProvider(this.context);
this.liveWatchTreeView = vscode.window.createTreeView('cortex-debug.liveWatch', {
treeDataProvider: this.liveWatchProvider
});
Expand All @@ -90,6 +90,10 @@ export class CortexDebugExtension {

vscode.commands.registerCommand('cortex-debug.liveWatch.addExpr', this.addLiveWatchExpr.bind(this)),
vscode.commands.registerCommand('cortex-debug.liveWatch.removeExpr', this.removeLiveWatchExpr.bind(this)),
vscode.commands.registerCommand('cortex-debug.liveWatch.editExpr', this.editLiveWatchExpr.bind(this)),
vscode.commands.registerCommand('cortex-debug.liveWatch.addToLiveWatch', this.addToLiveWatch.bind(this)),
vscode.commands.registerCommand('cortex-debug.liveWatch.moveUp', this.moveUpLiveWatchExpr.bind(this)),
vscode.commands.registerCommand('cortex-debug.liveWatch.moveDown', this.moveDownLiveWatchExpr.bind(this)),

vscode.workspace.onDidChangeConfiguration(this.settingsChanged.bind(this)),
vscode.debug.onDidReceiveDebugSessionCustomEvent(this.receivedCustomEvent.bind(this)),
Expand Down Expand Up @@ -200,7 +204,11 @@ export class CortexDebugExtension {
try {
// Session may not have actually started according to VSCode but we know of it
if (this.isDebugging(s.session)) {
s.session.customRequest('set-var-format', { hex: isHex });
s.session.customRequest('set-var-format', { hex: isHex }).then(() => {
if (s.status === 'stopped') {
this.liveWatchProvider?.refresh(s.session);
}
});
if (s.status === 'stopped') {
foundStopped = true;
}
Expand Down Expand Up @@ -979,26 +987,57 @@ export class CortexDebugExtension {

private addLiveWatchExpr() {
vscode.window.showInputBox({
placeHolder: 'Enter a valid C/gdb expression. Must be a global variable type expression',
placeHolder: 'Enter a valid C/gdb expression. Must be a global variable expression',
ignoreFocusOut: true,
prompt: 'Enter Live Watch Expression'
}).then((v) => {
if (v) {
this.initLiveWatcher();
this.liveWatchProvider.addWatchExpr(v, vscode.debug.activeDebugSession);
}
});
}

private addToLiveWatch(arg: any) {
if (!arg || !arg.sessionId) {
return;
}
const mySession = CDebugSession.FindSessionById(arg.sessionId);
if (!mySession) {
vscode.window.showErrorMessage(`addToLiveWatch: Unknown debug session id ${arg.sessionId}`);
return;
}
console.log(arg);
const parent = arg.container;
const expr = arg.variable?.evaluateName;
if (parent && expr) {
const varRef = parent.variablesReference;
mySession.session.customRequest('is-global-or-static', {varRef: varRef}).then((result) => {
console.log(expr, varRef, result);
if (!result.success) {
vscode.window.showErrorMessage(`Cannot add ${expr} to Live Watch. Must be a global or static variable`);
} else {
this.liveWatchProvider.addWatchExpr(expr, vscode.debug.activeDebugSession);
}
}, (e) => {
console.log(e);
});
}
}

private removeLiveWatchExpr(node: any) {
this.initLiveWatcher();
this.liveWatchProvider.removeWatchExpr(node);
}

private initLiveWatcher() {
if (!this.liveWatchProvider) {
this.liveWatchProvider = new LiveWatchTreeProvider(this.context);
}
private editLiveWatchExpr(node: any) {
this.liveWatchProvider.editNode(node);
}

private moveUpLiveWatchExpr(node: any) {
this.liveWatchProvider.moveUpNode(node);
}

private moveDownLiveWatchExpr(node: any) {
this.liveWatchProvider.moveDownNode(node);
}
}

Expand Down
102 changes: 100 additions & 2 deletions src/frontend/views/live-watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,25 @@ export class LiveVariableNode extends BaseNode {
return node && (node.getParent() === undefined);
}

public rename(nm: string) {
if (this.isRootChild()) {
this.name = this.expr = nm;
}
}

public getName() {
return this.name;
}

public findName(str: string): LiveVariableNode | undefined {
for (const child of this.children || []) {
if (child.name === str) {
return child;
}
}
return undefined;
}

public getTreeItem(): TreeItem | Promise<TreeItem> {
const state = this.variablesReference || (this.children?.length > 0) ?
(this.children?.length > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed) : TreeItemCollapsibleState.None;
Expand Down Expand Up @@ -80,8 +99,8 @@ export class LiveVariableNode extends BaseNode {
return child;
}

public removeChild(obj: any) {
const node = obj as LiveVariableNode;
public removeChild(node: LiveVariableNode): boolean {
if (!node || !node.isRootChild()) { return false; }
let ix = 0;
for (const child of this.children || []) {
if (child.name === node.name) {
Expand All @@ -93,6 +112,47 @@ export class LiveVariableNode extends BaseNode {
return false;
}

public moveUpChild(node: LiveVariableNode): boolean {
if (!node || !node.isRootChild()) { return false; }
let ix = 0;
for (const child of this.children || []) {
if (child.name === node.name) {
if (ix > 0) {
const prev = this.children[ix - 1];
this.children[ix] = prev;
this.children[ix - 1] = child;
} else {
const first = this.children.shift();
this.children.push(first);
}
return true;
}
ix++;
}
return false;
}

public moveDownChild(node: LiveVariableNode): boolean {
if (!node || !node.isRootChild()) { return false; }
let ix = 0;
const last = this.children ? this.children.length - 1 : -1;
for (const child of this.children || []) {
if (child.name === node.name) {
if (ix !== last) {
const next = this.children[ix + 1];
this.children[ix] = next;
this.children[ix + 1] = child;
} else {
const last = this.children.pop();
this.children.unshift(last);
}
return true;
}
ix++;
}
return false;
}

public reset(valuesToo = true) {
this.session = undefined;
if (valuesToo) {
Expand Down Expand Up @@ -516,6 +576,44 @@ export class LiveWatchTreeProvider implements TreeDataProvider<LiveVariableNode>
}
}

public editNode(node: LiveVariableNode) {
if (!node.isRootChild()) {
return; // Should never happen
}
const opts: vscode.InputBoxOptions = {
placeHolder: 'Enter a valid C/gdb expression. Must be a global variable expression',
ignoreFocusOut: true,
value: node.getName(),
prompt: 'Enter Live Watch Expression'
};
vscode.window.showInputBox(opts).then((result) => {
result = result ? result.trim() : result;
if (result && (result !== node.getName())) {
if (this.variables.findName(result)) {
vscode.window.showInformationMessage(`Live Watch: Expression ${result} is already being watched`);
} else {
node.rename(result);
this.saveState();
this.refresh(LiveWatchTreeProvider.session);
}
}
});
}

public moveUpNode(node: LiveVariableNode) {
const parent = node?.getParent() as LiveVariableNode;
if (parent && parent.moveUpChild(node)) {
this.fire();
}
}

public moveDownNode(node: LiveVariableNode) {
const parent = node?.getParent() as LiveVariableNode;
if (parent && parent.moveDownChild(node)) {
this.fire();
}
}

public expandChildren(element: LiveVariableNode) {
if (element) {
element.expandChildren().then(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/live-watch-monitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DebugProtocol } from '@vscode/debugprotocol';
import { Handles } from '@vscode/debugadapter';
import { MI2 } from './backend/mi2/mi2';
import { ExtendedVariable, GDBDebugSession, RequestQueue } from './gdb';
import { decodeReference, ExtendedVariable, GDBDebugSession, RequestQueue } from './gdb';
import { MIError, VariableObject } from './backend/backend';
import * as crypto from 'crypto';
import { MINode } from './backend/mi_parse';
Expand Down Expand Up @@ -109,7 +109,7 @@ export class VariablesHandler {
threadId = frameId = -1;
args.frameId = undefined;
} else if (args.frameId !== undefined) {
[threadId, frameId] = GDBDebugSession.decodeReference(args.frameId);
[threadId, frameId] = decodeReference(args.frameId);
}

if (args.context !== 'repl') {
Expand Down

0 comments on commit 1625574

Please sign in to comment.