Skip to content
Permalink
Browse files
Hex View Fix (#56)
* Fix issue where highlighted text and icon get stuck on a line, will now move down to the end of the file

* remove html and make it hex

* Move location of hex-file. Updated hexView so that if hexView is already create/opened on debug session start it will be closed then deleted, then once the hex file is remade from the data file it gets opened up. Remove setting of white text for selections.

* Select proper line in hex view when position updates.

Fixes #61.

Co-authored-by: Adam Rosien <adam@rosien.net>
  • Loading branch information
Shanedell and arosien committed Aug 4, 2021
1 parent 2d81fc0 commit edc753e7df356c83824d12536447c776c0ad7688
Showing 5 changed files with 104 additions and 87 deletions.
@@ -8,4 +8,5 @@ daffodil-debug.txt
.DS_Store
daffodil-debugger*
*.debug
*infoset*
*infoset*
datafile-hex
@@ -6,7 +6,7 @@

import * as vscode from 'vscode';
import * as path from 'path';
import * as htmlView from './hexview/htmlView';
import * as hexView from './hexview/hexView';
import { WorkspaceFolder, DebugConfiguration, ProviderResult, CancellationToken } from 'vscode';
import { DaffodilDebugSession } from './daffodilDebug';
import { getDebugger, getDataFileFromFolder } from './daffodilDebugger';
@@ -84,7 +84,7 @@ export function activateDaffodilDebug(context: vscode.ExtensionContext, factory?
});

// Create file that holds path to data file used
fs.writeFile(`${xdgAppPaths.data()}/.dataFile`, dataFile, function(err){
await fs.writeFile(`${xdgAppPaths.data()}/.dataFile`, dataFile, function(err){
if (err) {
vscode.window.showInformationMessage(`error code: ${err.code} - ${err.message}`);
}
@@ -312,11 +312,11 @@ export const workspaceFileAccessor: FileAccessor = {

class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory {
context: vscode.ExtensionContext;
htmlViewer: htmlView.DebuggerHtmlView;
hexViewer: hexView.DebuggerHexView;

constructor(context: vscode.ExtensionContext) {
this.context = context;
this.htmlViewer = new htmlView.DebuggerHtmlView(context);
this.hexViewer = new hexView.DebuggerHexView(context);
}

createDebugAdapterDescriptor(_session: vscode.DebugSession): ProviderResult<vscode.DebugAdapterDescriptor> {
@@ -6,7 +6,7 @@

import * as Net from 'net';
import * as vscode from 'vscode';
import * as htmlView from './hexview/htmlView';
import * as htmlView from './hexview/hexView';
import { randomBytes } from 'crypto';
import { tmpdir } from 'os';
import { join } from 'path';
@@ -53,11 +53,11 @@ export function deactivate() {

class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescriptorFactory {
context: vscode.ExtensionContext;
htmlViewer: htmlView.DebuggerHtmlView;
htmlViewer: htmlView.DebuggerHexView;

constructor(context: vscode.ExtensionContext) {
this.context = context;
this.htmlViewer = new htmlView.DebuggerHtmlView(context);
this.htmlViewer = new htmlView.DebuggerHexView(context);
}

// The following use of a DebugAdapter factory shows how to control what debug adapter executable is used.
@@ -89,11 +89,11 @@ class DaffodilDebugAdapterServerDescriptorFactory implements vscode.DebugAdapter

private server?: Net.Server;
context: vscode.ExtensionContext;
htmlViewer: htmlView.DebuggerHtmlView;
htmlViewer: htmlView.DebuggerHexView;

constructor(context: vscode.ExtensionContext) {
this.context = context;
this.htmlViewer = new htmlView.DebuggerHtmlView(context);
this.htmlViewer = new htmlView.DebuggerHexView(context);
}

createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
@@ -121,11 +121,11 @@ class DaffodilDebugAdapterNamedPipeServerDescriptorFactory implements vscode.Deb

private server?: Net.Server;
context: vscode.ExtensionContext;
htmlViewer: htmlView.DebuggerHtmlView;
htmlViewer: htmlView.DebuggerHexView;

constructor(context: vscode.ExtensionContext) {
this.context = context;
this.htmlViewer = new htmlView.DebuggerHtmlView(context);
this.htmlViewer = new htmlView.DebuggerHexView(context);
}

createDebugAdapterDescriptor(session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
@@ -1,50 +1,47 @@
import * as vscode from "vscode";
import { DisplayHtmlRequest } from "./types";
import { DaffodilData } from "./types";
import * as fs from "fs";
import * as hexy from "hexy";
import XDGAppPaths from 'xdg-app-paths';
const xdgAppPaths = XDGAppPaths({"name": "dapodil"});

export class DebuggerHtmlView {
export class DebuggerHexView {
context: vscode.ExtensionContext;
dataFile: string = "";
hexFile: string = `${xdgAppPaths.data()}/.data-hex`;
hexFile: string = vscode.workspace.workspaceFolders ? `${vscode.workspace.workspaceFolders[0].uri.fsPath}/datafile-hex` : `${xdgAppPaths.data()}/datafile-hex`;
arrowIconFileCreated: boolean = false;
hexFileOpened: boolean = false;
workspaceConfUpdated: boolean = false;
originalSelectionColor: string = "";
decorator: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType({
color: "white",
gutterIconPath: `${xdgAppPaths.data()}/.arrow.svg`,
gutterIconSize: 'contain'
});

constructor(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(this.onTerminatedDebugSession, this));
context.subscriptions.push(vscode.debug.onDidReceiveDebugSessionCustomEvent(this.onDebugSessionCustomEvent, this));
context.subscriptions.push(vscode.debug.onDidStartDebugSession(this.onDidStartDebugSession, this));
this.context = context;
}

// Method for getting the decorator
getDecorator() {
getDecorator(hexLength, dataPositon) {
this.decorator.dispose(); // needed to reset decorator
this.decorator = vscode.window.createTextEditorDecorationType({
color: "white",
gutterIconPath: `${xdgAppPaths.data()}/.arrow.svg`,
gutterIconSize: 'contain'
});

if (hexLength !== dataPositon) {
this.decorator = vscode.window.createTextEditorDecorationType({
gutterIconPath: `${xdgAppPaths.data()}/.arrow.svg`,
gutterIconSize: 'contain'
});
}
return this.decorator;
}

// Method for deleting files
deleteFile(fileName) {
if (fs.existsSync(fileName)) {
if (fileName === this.hexFile) {
vscode.window.visibleTextEditors.forEach(editior => {
if (editior.document.fileName === this.hexFile) {
editior.hide(); // method is deprecated but is only way to close specific editor not just the active one
}
});
this.closeHexFile();
}

fs.unlink(fileName, function (err) {
@@ -58,11 +55,14 @@ export class DebuggerHtmlView {
// Overriden onTerminatedDebugSession method
onTerminatedDebugSession(session: vscode.DebugSession) {
if (session.type === 'dfdl') {
this.deleteFile(this.hexFile);
this.deleteFile(`${xdgAppPaths.data()}/.dataFile`);
this.deleteFile(`${xdgAppPaths.data()}/.arrow.svg`);
vscode.window.visibleTextEditors.forEach(editior => {
if (editior.document.fileName === this.hexFile) {
editior.hide(); // method is deprecated but is only way to close specific editor not just the active one
}
});
this.dataFile = "";
this.hexFileOpened = false;
this.updateWorkbenchConfig(true); // reset workbench config
this.workspaceConfUpdated = false;
this.originalSelectionColor = "";
@@ -79,31 +79,25 @@ export class DebuggerHtmlView {
}
}

// Override onDidStartDebugSession method
onDidStartDebugSession(session: vscode.DebugSession) {
// On debug session make sure hex file is deleted and not opened
if (session.type === 'dfdl') {
this.closeHexFile();
this.deleteFile(this.hexFile);
this.decorator.dispose();
}
}

// Method for retrieving the data file used
async setDataFile() {
let config = vscode.workspace.getConfiguration("launch", vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri : vscode.Uri.parse(""));
let values = config.get('configurations', "");
let dataFile = `${xdgAppPaths.data()}/.dataFile`;

// If no config exists get the data file path from the .dataFile or prompt user to go to select it via file explorer
// Else just grab the dataFile path from the config data attribute
if (values.length === 0) {
let dataFile = `${xdgAppPaths.data()}/.dataFile`;

if (fs.existsSync(dataFile)) {
this.dataFile = fs.readFileSync(dataFile).toString();
}
else { // should never be hit but is here as a fail safe
this.dataFile = await vscode.window.showOpenDialog({
canSelectMany: false, openLabel: 'Select',
canSelectFiles: true, canSelectFolders: false
})
.then(fileUri => {
if (fileUri && fileUri[0]) {
return fileUri[0].fsPath;
}
return "";
});
}
// If no config exists or data file exists get the data file path from the .dataFile
if (values.length === 0 || fs.existsSync(dataFile)) {
this.dataFile = fs.readFileSync(dataFile).toString();
}
else {
if (values[0]["data"].includes("${workspaceFolder}") && vscode.workspace.workspaceFolders) {
@@ -115,30 +109,14 @@ export class DebuggerHtmlView {
}
}

// Method to open the hex file via text editor, selecting the line at the current data position
openHexFile(body: DisplayHtmlRequest, hex: string) {
let range = new vscode.Range(new vscode.Position(body.bytePos1b-1, 0), new vscode.Position(body.bytePos1b-1, hex.split("\n")[body.bytePos1b-1].length));
vscode.workspace.openTextDocument(this.hexFile).then(doc => {
vscode.window.showTextDocument(doc, {
selection: range,
viewColumn: vscode.ViewColumn.Beside,
preserveFocus: true, preview: false
})
.then(editor => {
editor.setDecorations(
this.getDecorator(),
[range]
);
});
});

this.hexFileOpened = true;
}

// Method for updating the line selected in the hex file using the current data position
updateSelectedDataPosition(body: DisplayHtmlRequest, hex: string) {
updateSelectedDataPosition(body: DaffodilData, hex: string) {
let hexEditor = vscode.window.activeTextEditor;
let range = new vscode.Range(new vscode.Position(body.bytePos1b-1, 0), new vscode.Position(body.bytePos1b-1, hex.split("\n")[body.bytePos1b-1].length));
let lineNum = (body.bytePos1b-1) / 16;
let start = new vscode.Position(lineNum, 0);
let end = new vscode.Position(lineNum, hex.split("\n")[lineNum] ? hex.split("\n")[lineNum].length : 0);
let range = new vscode.Range(start, end);
let hexLength = hex.split("\n")[lineNum] ? hex.split("\n")[lineNum].length : body.bytePos1b;

vscode.window.visibleTextEditors.forEach(editior => {
if (editior.document.fileName === this.hexFile) {
@@ -150,12 +128,8 @@ export class DebuggerHtmlView {
if (!hexEditor) {
return;
}
hexEditor.selection = new vscode.Selection(
new vscode.Position(body.bytePos1b-1, 0),
new vscode.Position(body.bytePos1b-1, hex.split("\n")[body.bytePos1b-1].length)
);

hexEditor.setDecorations(this.getDecorator(), [range]);
hexEditor.selection = new vscode.Selection(range.start, range.end);
hexEditor.setDecorations(this.getDecorator(hexLength, body.bytePos1b), [range]);
hexEditor.revealRange(range);
}

@@ -196,8 +170,50 @@ export class DebuggerHtmlView {
</g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>`);
}

// Method to close hexFile if opened in editor
closeHexFile() {
vscode.window.visibleTextEditors.forEach(editior => {
if (editior.document.fileName === this.hexFile) {
editior.hide();
}
});
}

// Method to open the hex file via text editor, selecting the line at the current data position
openHexFile(body: DaffodilData, hex: string) {
let range = new vscode.Range(
new vscode.Position(body.bytePos1b-1, 0),
new vscode.Position(body.bytePos1b-1, hex.split("\n")[body.bytePos1b-1] ? hex.split("\n")[body.bytePos1b-1].length : 0)
);
let hexLength = hex.split("\n")[body.bytePos1b-1] ? hex.split("\n")[body.bytePos1b-1].length : body.bytePos1b;
vscode.workspace.openTextDocument(this.hexFile).then(doc => {
vscode.window.showTextDocument(doc, {
selection: range,
viewColumn: vscode.ViewColumn.Three,
preserveFocus: true, preview: false
})
.then(editor => {
editor.setDecorations(
this.getDecorator(hexLength, body.bytePos1b),
[range]
);
});
});
}

// Method to see hexFile is opened
checkIfHexFileOpened() {
let result = false;
vscode.window.visibleTextEditors.forEach(editior => {
if (editior.document.fileName === this.hexFile) {
result = true;
}
});
return result;
}

// Method to display the hex of the current data position sent from the debugger
async onDisplayHex(session: vscode.DebugSession, body: DisplayHtmlRequest) {
async onDisplayHex(session: vscode.DebugSession, body: DaffodilData) {
if (!vscode.workspace.workspaceFolders) {
return;
}
@@ -229,11 +245,17 @@ export class DebuggerHtmlView {
}

// Open up hex document
if (!this.hexFileOpened) {
if (!this.checkIfHexFileOpened()) {
this.openHexFile(body, hex);
}
else {
this.updateSelectedDataPosition(body, hex);
}

let hexLength = hex.split("\n")[body.bytePos1b-1] ? hex.split("\n")[body.bytePos1b-1].length : 0;

if (hexLength === 0) {
this.closeHexFile();
}
}
}
@@ -1,9 +1,3 @@
import { ViewColumn } from "vscode";

export interface DisplayHtmlRequest {
title: string;
position: ViewColumn;
html: string;
reveal: boolean;
export interface DaffodilData {
bytePos1b: number;
}

0 comments on commit edc753e

Please sign in to comment.