This is an automated email from the ASF dual-hosted git repository.

rstrickland pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git


The following commit(s) were added to refs/heads/main by this push:
     new db8ddf7  Replaced HexView with Data Editor
db8ddf7 is described below

commit db8ddf731782dfd8fd8bd5b54d30bf4d14cc599a
Author: stricklandrbls <[email protected]>
AuthorDate: Wed Jan 3 13:54:19 2024 -0600

    Replaced HexView with Data Editor
    
    - Removed instances of the HexView and replaced with the Data Editor.
    - Added revised DFDLDebugger <--> Data Editor Extension/UI message
      structure.
    
    Closes #790
    Closes #905
---
 .../org.apache.daffodil.debugger/ParseSuite.scala  |   4 +-
 package.json                                       |  24 +-
 src/adapter/extension.ts                           |   3 -
 src/classes/vscode-launch.ts                       |   2 +-
 src/daffodilDebugger/daffodil.ts                   |  52 ++++
 src/dataEditor/dataEditorClient.ts                 |  71 +++--
 .../include/server/ServerInfo.ts}                  |  32 +--
 .../include/server/heartbeat/HeartBeatInfo.ts      |  36 +++
 src/hexView.ts                                     | 286 ---------------------
 src/infoset.ts                                     |   2 +-
 src/launchWizard/launchWizard.js                   |  10 +-
 src/launchWizard/launchWizard.ts                   |  12 +-
 .../DataDisplays/CustomByteDisplay/BinaryData.ts   |   6 +-
 .../CustomByteDisplay/DataLineFeed.svelte          |   6 +-
 .../CustomByteDisplay/DataValue.svelte             |   9 +
 .../ByteCategories/CategoryIndications.ts          |  18 +-
 .../src/utilities/ByteCategories/IByteCategory.ts  |  12 +-
 .../src/utilities/ByteCategories/IIndication.ts    |   7 +-
 src/svelte/src/utilities/highlights.ts             |  27 +-
 src/tests/README.md                                |   2 +-
 src/tests/suite/daffodil.test.ts                   |   1 -
 src/tests/suite/utils.test.ts                      |   2 +-
 src/utils.ts                                       |  21 +-
 23 files changed, 225 insertions(+), 420 deletions(-)

diff --git 
a/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala 
b/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
index 50811e4..c8917b2 100644
--- a/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
+++ b/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
@@ -37,7 +37,7 @@ class ParseSuite extends FunSuite {
   val stopOnEntry = true
   val useExistingServer = false
   val trace = true
-  val openHexView = false
+  val openDataEditor = false
   val openInfosetView = false
   val openInfosetDiffView = false
   val daffodilDebugClasspath = ""
@@ -185,7 +185,7 @@ class ParseSuite extends FunSuite {
     testJsonObject.addProperty("stopOnEntry", stopOnEntry)
     testJsonObject.addProperty("useExistingServer", useExistingServer)
     testJsonObject.addProperty("trace", trace)
-    testJsonObject.addProperty("openHexView", openHexView)
+    testJsonObject.addProperty("openDataEditor", openDataEditor)
     testJsonObject.addProperty("openInfosetView", openInfosetView)
     testJsonObject.addProperty("openInfosetDiffView", openInfosetDiffView)
     testJsonObject.addProperty("daffodilDebugClasspath", 
daffodilDebugClasspath)
diff --git a/package.json b/package.json
index daf9516..a48a9cd 100644
--- a/package.json
+++ b/package.json
@@ -145,11 +145,6 @@
           "command": "launch.config",
           "group": "navigation@1"
         },
-        {
-          "command": "hexview.display",
-          "when": "resourceLangId == dfdl",
-          "group": "navigation@4"
-        },
         {
           "command": "infoset.display",
           "when": "resourceLangId == dfdl",
@@ -269,13 +264,6 @@
         "category": "Daffodil Debug",
         "enablement": "inDebugMode"
       },
-      {
-        "command": "hexview.display",
-        "title": "Display the hex view",
-        "category": "Daffodil Debug",
-        "enablement": "inDebugMode",
-        "icon": "$(file-binary)"
-      },
       {
         "command": "infoset.display",
         "title": "Display the infoset view",
@@ -399,9 +387,9 @@
                 "description": "Enable connection to running DAP Server",
                 "default": false
               },
-              "openHexView": {
+              "openDataEditor": {
                 "type": "boolean",
-                "description": "Open hexview on debug start",
+                "description": "Open data editor on debug start",
                 "default": false
               },
               "openInfosetView": {
@@ -477,7 +465,7 @@
               "path": "${command:AskForTDMLPath}"
             },
             "debugServer": 4711,
-            "openHexView": false,
+            "openDataEditor": false,
             "openInfosetView": false,
             "openInfosetDiffView": false,
             "daffodilDebugClasspath": "",
@@ -521,7 +509,7 @@
                 "path": "${command:AskForTDMLPath}"
               },
               "debugServer": 4711,
-              "openHexView": false,
+              "openDataEditor": false,
               "openInfosetView": false,
               "openInfosetDiffView": false,
               "daffodilDebugClasspath": "",
@@ -609,9 +597,9 @@
             "description": "Port debug server running on",
             "default": 4711
           },
-          "openHexView": {
+          "openDataEditor": {
             "type": "boolean",
-            "description": "Open hexview on debug start",
+            "description": "Open data editor on debug start",
             "default": false
           },
           "openInfosetView": {
diff --git a/src/adapter/extension.ts b/src/adapter/extension.ts
index 8526a2c..06d9777 100644
--- a/src/adapter/extension.ts
+++ b/src/adapter/extension.ts
@@ -6,7 +6,6 @@
 'use strict'
 
 import * as vscode from 'vscode'
-import * as hexView from '../hexView'
 import * as position from '../position'
 import { ProviderResult } from 'vscode'
 import { DaffodilDebugSession } from './daffodilDebug'
@@ -38,11 +37,9 @@ export class InlineDebugAdapterFactory
   implements vscode.DebugAdapterDescriptorFactory
 {
   context: vscode.ExtensionContext
-  hexViewer: hexView.DebuggerHexView
 
   constructor(context: vscode.ExtensionContext) {
     this.context = context
-    this.hexViewer = new hexView.DebuggerHexView(context)
   }
 
   createDebugAdapterDescriptor(
diff --git a/src/classes/vscode-launch.ts b/src/classes/vscode-launch.ts
index cd56f24..e6454d9 100644
--- a/src/classes/vscode-launch.ts
+++ b/src/classes/vscode-launch.ts
@@ -34,7 +34,7 @@ export interface VSCodeLaunchConfigArgs {
   stopOnEntry: boolean
   useExistingServer: boolean
   trace: boolean
-  openHexView: boolean
+  openDataEditor: boolean
   openInfosetView: boolean
   openInfosetDiffView: boolean
   daffodilDebugClasspath: string
diff --git a/src/daffodilDebugger/daffodil.ts b/src/daffodilDebugger/daffodil.ts
index 77d67ea..f9e2fbd 100644
--- a/src/daffodilDebugger/daffodil.ts
+++ b/src/daffodilDebugger/daffodil.ts
@@ -17,6 +17,7 @@
 
 import * as fs from 'fs'
 import { parse as jsoncParse } from 'jsonc-parser'
+import { DebugSession, DebugSessionCustomEvent, debug } from 'vscode'
 
 export const dataEvent = 'daffodil.data'
 export interface DaffodilData {
@@ -59,3 +60,54 @@ export interface BuildInfo {
 export function getDaffodilVersion(filePath: fs.PathLike) {
   return jsoncParse(fs.readFileSync(filePath).toString())['daffodilVersion']
 }
+
+export interface IDaffodilEvent {
+  readonly type: DaffodilEventType
+  readonly body: DaffodilDataType
+}
+
+export type DaffodilEventType =
+  | 'daffodil.data'
+  | 'daffodil.infoset'
+  | 'daffodil.config'
+export type DaffodilDataType = DaffodilData | InfosetEvent | ConfigEvent
+export type DaffodilDataTypeMap = {
+  'daffodil.data': DaffodilData
+  'daffodil.infoset': InfosetEvent
+  'daffodil.config': ConfigEvent
+}
+export class DaffodilDebugEvent<
+  E extends DaffodilEventType,
+  B extends DaffodilDataTypeMap[E],
+> implements DebugSessionCustomEvent
+{
+  readonly session: DebugSession
+  constructor(
+    readonly event: E,
+    readonly body: B
+  ) {
+    this.session = debug.activeDebugSession!
+  }
+  asEditorMessage(): { command: string; data: any } {
+    return {
+      command: this.event,
+      data: this.body,
+    }
+  }
+}
+
+export function extractDaffodilEvent<
+  E extends DaffodilEventType,
+  B extends DaffodilDataTypeMap[E],
+>(e: DebugSessionCustomEvent): DaffodilDebugEvent<E, B> | undefined {
+  if (e.session.type !== 'dfdl') return undefined
+  const eventType = e.event as E
+  const body = e.body as B
+  return new DaffodilDebugEvent(eventType, body)
+}
+
+export function extractDaffodilData<
+  E extends DaffodilEventType,
+>(editorMessage: { command: string; data: any }): DaffodilDataTypeMap[E] {
+  return editorMessage.data as DaffodilDataTypeMap[E]
+}
diff --git a/src/dataEditor/dataEditorClient.ts 
b/src/dataEditor/dataEditorClient.ts
index 03f9eb8..ab8ba86 100644
--- a/src/dataEditor/dataEditorClient.ts
+++ b/src/dataEditor/dataEditorClient.ts
@@ -44,7 +44,6 @@ import {
   getSessionCount,
   getViewportData,
   IOFlags,
-  IServerHeartbeat,
   IServerInfo,
   modifyViewport,
   numAscii,
@@ -79,6 +78,12 @@ import {
 import net from 'net'
 import * as vscode from 'vscode'
 import os from 'os'
+import {
+  HeartbeatInfo,
+  IHeartbeatInfo,
+} from './include/server/heartbeat/HeartBeatInfo'
+import { ServerInfo } from './include/server/ServerInfo'
+import { extractDaffodilEvent } from '../daffodilDebugger/daffodil'
 
 // 
*****************************************************************************
 // global constants
@@ -99,39 +104,6 @@ const MAX_LOG_FILES: number = 5 // Maximum number of log 
files to keep TODO: mak
 const OMEGA_EDIT_MAX_PORT: number = 65535
 const OMEGA_EDIT_MIN_PORT: number = 1024
 
-// 
*****************************************************************************
-// file-scoped types
-// 
*****************************************************************************
-
-class ServerInfo implements IServerInfo {
-  serverHostname: string = 'unknown' // hostname
-  serverProcessId: number = 0 // process id
-  serverVersion: string = 'unknown' // server version
-  jvmVersion: string = 'unknown' // jvm version
-  jvmVendor: string = 'unknown' // jvm vendor
-  jvmPath: string = 'unknown' // jvm path
-  availableProcessors: number = 0 // available processors
-}
-
-interface IHeartbeatInfo extends IServerHeartbeat {
-  omegaEditPort: number // Ωedit server port
-  serverInfo: IServerInfo // server info that remains constant
-}
-
-class HeartbeatInfo implements IHeartbeatInfo {
-  omegaEditPort: number = 0 // Ωedit server port
-  latency: number = 0 // latency in ms
-  serverCommittedMemory: number = 0 // committed memory in bytes
-  serverCpuCount: number = 0 // cpu count
-  serverCpuLoadAverage: number = 0 // cpu load average
-  serverMaxMemory: number = 0 // max memory in bytes
-  serverTimestamp: number = 0 // timestamp in ms
-  serverUptime: number = 0 // uptime in ms
-  serverUsedMemory: number = 0 // used memory in bytes
-  sessionCount: number = 0 // session count
-  serverInfo: IServerInfo = new ServerInfo()
-}
-
 // 
*****************************************************************************
 // file-scoped variables
 // 
*****************************************************************************
@@ -172,7 +144,6 @@ export class DataEditorClient implements vscode.Disposable {
   private omegaSessionId = ''
   private sendHeartbeatIntervalId: NodeJS.Timeout | number | undefined =
     undefined
-
   constructor(
     protected context: vscode.ExtensionContext,
     private view: string,
@@ -180,14 +151,24 @@ export class DataEditorClient implements 
vscode.Disposable {
     fileToEdit: string = ''
   ) {
     const column =
-      vscode.window.activeTextEditor &&
-      vscode.window.activeTextEditor.viewColumn
-        ? vscode.window.activeTextEditor?.viewColumn
-        : vscode.ViewColumn.Active
+      fileToEdit !== '' ? vscode.ViewColumn.Two : vscode.ViewColumn.Active
     this.panel = vscode.window.createWebviewPanel(this.view, title, column, {
       enableScripts: true,
       retainContextWhenHidden: true,
     })
+
+    this.context.subscriptions.push(
+      vscode.debug.onDidReceiveDebugSessionCustomEvent(async (e) => {
+        const debugEvent = e
+        const eventAsEditorMessage = extractDaffodilEvent(debugEvent)
+        if (eventAsEditorMessage === undefined) return
+
+        const forwardAs = eventAsEditorMessage.asEditorMessage()
+
+        await this.panel.webview.postMessage(forwardAs)
+      })
+    )
+
     this.panel.webview.onDidReceiveMessage(this.messageReceiver, this)
     this.svelteWebviewInitializer = new SvelteWebviewInitializer(context)
     this.svelteWebviewInitializer.initialize(this.view, this.panel.webview)
@@ -821,7 +802,15 @@ export class DataEditorClient implements vscode.Disposable 
{
 // 
*****************************************************************************
 // file-scoped functions
 // 
*****************************************************************************
-
+function cleanFileToEditStr(fileToEdit: string): string {
+  let rootPath = vscode.workspace.workspaceFolders
+    ? vscode.workspace.workspaceFolders[0].uri.fsPath
+    : vscode.Uri.parse('').fsPath
+  fileToEdit = fileToEdit.includes('${workspaceFolder}')
+    ? fileToEdit.replace('${workspaceFolder}', rootPath)
+    : fileToEdit
+  return fileToEdit
+}
 async function createDataEditorWebviewPanel(
   ctx: vscode.ExtensionContext,
   fileToEdit: string
@@ -851,7 +840,7 @@ async function createDataEditorWebviewPanel(
       'heartbeat did not receive a server version'
     )
   }
-
+  fileToEdit = cleanFileToEditStr(fileToEdit)
   const dataEditorView = new DataEditorClient(
     ctx,
     'dataEditor',
diff --git a/src/svelte/src/utilities/ByteCategories/IIndication.ts 
b/src/dataEditor/include/server/ServerInfo.ts
similarity index 55%
copy from src/svelte/src/utilities/ByteCategories/IIndication.ts
copy to src/dataEditor/include/server/ServerInfo.ts
index 7a6dede..39ec764 100644
--- a/src/svelte/src/utilities/ByteCategories/IIndication.ts
+++ b/src/dataEditor/include/server/ServerInfo.ts
@@ -15,28 +15,14 @@
  * limitations under the License.
  */
 
-export interface IByteIndication {
-  selector(): string
-  equals(categoryArg: IByteIndication): boolean
-}
-
-class NullIndication implements IByteIndication {
-  equals(categoryArg: IByteIndication): boolean {
-    return this.selector() === categoryArg.selector()
-  }
-  selector(): string {
-    return 'none'
-  }
-}
+import { IServerInfo } from '@omega-edit/client'
 
-export class ByteIndication implements IByteIndication {
-  constructor(private _selector: string) {}
-  equals(categoryArg: IByteIndication): boolean {
-    return this.selector() === categoryArg.selector()
-  }
-  selector(): string {
-    return this._selector.toLowerCase()
-  }
+export class ServerInfo implements IServerInfo {
+  serverHostname: string = 'unknown'
+  serverProcessId: number = 0
+  serverVersion: string = 'unknown'
+  jvmVersion: string = 'unknown'
+  jvmVendor: string = 'unknown'
+  jvmPath: string = 'unknown'
+  availableProcessors: number = 0
 }
-
-export const NoIndication: NullIndication = new NullIndication()
diff --git a/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts 
b/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
new file mode 100644
index 0000000..4825158
--- /dev/null
+++ b/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { IServerHeartbeat, IServerInfo } from '@omega-edit/client'
+import { ServerInfo } from '../ServerInfo'
+
+export interface IHeartbeatInfo extends IServerHeartbeat {
+  omegaEditPort: number // Ωedit server port
+  serverInfo: IServerInfo // server info that remains constant
+}
+export class HeartbeatInfo {
+  omegaEditPort: number = 0 // Ωedit server port
+  latency: number = 0 // latency in ms
+  serverCommittedMemory: number = 0 // committed memory in bytes
+  serverCpuCount: number = 0 // cpu count
+  serverCpuLoadAverage: number = 0 // cpu load average
+  serverMaxMemory: number = 0 // max memory in bytes
+  serverTimestamp: number = 0 // timestamp in ms
+  serverUptime: number = 0 // uptime in ms
+  serverUsedMemory: number = 0 // used memory in bytes
+  sessionCount: number = 0 // session count
+  serverInfo: IServerInfo = new ServerInfo()
+}
diff --git a/src/hexView.ts b/src/hexView.ts
deleted file mode 100644
index bd8661d..0000000
--- a/src/hexView.ts
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import * as vscode from 'vscode'
-import * as daf from './daffodilDebugger'
-import * as fs from 'fs'
-import * as hexy from 'hexy'
-import XDGAppPaths from 'xdg-app-paths'
-const xdgAppPaths = XDGAppPaths({ name: 'daffodil-dap' })
-import { onDebugStartDisplay } from './utils'
-
-export class DebuggerHexView {
-  context: vscode.ExtensionContext
-  dataFile: string = ''
-  hexFile: string = vscode.workspace.workspaceFolders
-    ? `${vscode.workspace.workspaceFolders[0].uri.fsPath}/datafile-hex`
-    : `${xdgAppPaths.data()}/datafile-hex`
-  hexString: string = ''
-  bytePos1b: number = -1
-  decorator: vscode.TextEditorDecorationType =
-    vscode.window.createTextEditorDecorationType({})
-
-  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)
-    )
-    context.subscriptions.push(
-      vscode.commands.registerCommand('hexview.display', async () => {
-        await this.openHexFile()
-      })
-    )
-    this.context = context
-
-    this.decorator = vscode.window.createTextEditorDecorationType({
-      gutterIconPath: this.context.asAbsolutePath('./images/arrow.svg'),
-      gutterIconSize: 'contain',
-      color: 'black',
-      backgroundColor: 'yellow',
-    })
-  }
-
-  // Method for getting the decorator
-  getDecorator(hexLength, dataPositon) {
-    this.decorator.dispose() // needed to reset decorator
-
-    if (hexLength !== dataPositon) {
-      this.decorator = vscode.window.createTextEditorDecorationType({
-        gutterIconPath: this.context.asAbsolutePath('./images/arrow.svg'),
-        gutterIconSize: 'contain',
-        color: 'black',
-        backgroundColor: 'yellow',
-      })
-    }
-    return this.decorator
-  }
-
-  // Method for deleting files
-  deleteFile(fileName) {
-    if (fs.existsSync(fileName)) {
-      if (fileName === this.hexFile) {
-        this.closeHexFile()
-      }
-
-      fs.unlink(fileName, function (err) {
-        if (err) {
-          vscode.window.showInformationMessage(
-            `error code: ${err.code} - ${err.message}`
-          )
-        }
-      })
-    }
-  }
-
-  // Overriden onTerminatedDebugSession method
-  onTerminatedDebugSession(session: vscode.DebugSession) {
-    if (session.type === 'dfdl') {
-      this.decorator.dispose()
-      this.dataFile = ''
-      this.bytePos1b = -1
-    }
-  }
-
-  // Overriden onDebugSessionCustomEvent method
-  onDebugSessionCustomEvent(e: vscode.DebugSessionCustomEvent) {
-    if (e.session.type === 'dfdl') {
-      switch (e.event) {
-        case daf.configEvent:
-          this.setDataFile(e.body)
-          break
-        case daf.dataEvent:
-          this.onDisplayHex(e.session, e.body)
-          break
-      }
-
-      let hexFileOpened = false
-
-      vscode.window.visibleTextEditors.forEach((editor) => {
-        if (editor.document.fileName === this.hexFile) {
-          hexFileOpened = true
-        }
-      })
-
-      if (!hexFileOpened) {
-        onDebugStartDisplay(['hex-view'])
-      }
-    }
-  }
-
-  // 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()
-      this.hexString = '' // make sure no data from previous runs is carried 
over
-    }
-  }
-
-  // Method for extracting the data file used
-  setDataFile(cfg: daf.ConfigEvent) {
-    this.dataFile = cfg.launchArgs.dataPath
-  }
-
-  // Method for getting the selection range
-  getSelectionRange(): [vscode.Range, number] {
-    let lineNum = Math.floor((this.bytePos1b - 1) / 16)
-    let paddingForSpaces =
-      this.bytePos1b - 1 > 0 ? (this.bytePos1b - lineNum * 16 - 1) * 2 : 0
-    let paddingForLine =
-      this.bytePos1b - 16 > 0 ? this.bytePos1b - lineNum * 16 : this.bytePos1b
-    let dataPositon = 9 + paddingForLine + paddingForSpaces
-    let start = new vscode.Position(lineNum, dataPositon)
-    let end = new vscode.Position(lineNum, dataPositon + 2)
-    return [new vscode.Range(start, end), lineNum]
-  }
-
-  // Method for updating the line selected in the hex file using the current 
data position
-  updateSelectedDataPosition() {
-    let hexEditor = vscode.window.activeTextEditor
-    let [range, lineNum] = this.getSelectionRange()
-    let hexLength = this.hexString.split('\n')[lineNum]
-      ? this.hexString.split('\n')[lineNum].length
-      : this.bytePos1b
-
-    vscode.window.visibleTextEditors.forEach((editior) => {
-      if (editior.document.fileName === this.hexFile) {
-        hexEditor = editior
-        return
-      }
-    })
-
-    if (!hexEditor) {
-      return
-    }
-    hexEditor.selection = new vscode.Selection(range.start, range.end)
-    hexEditor.setDecorations(this.getDecorator(hexLength, this.bytePos1b), [
-      range,
-    ])
-    hexEditor.revealRange(range)
-  }
-
-  // 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() {
-    let [range, _] = this.getSelectionRange()
-    let hexLength = this.hexString.split('\n')[this.bytePos1b - 1]
-      ? this.hexString.split('\n')[this.bytePos1b - 1].length
-      : this.bytePos1b
-    vscode.workspace.openTextDocument(this.hexFile).then((doc) => {
-      vscode.window
-        .showTextDocument(doc, {
-          selection: range,
-          viewColumn: vscode.ViewColumn.Two,
-          preserveFocus: true,
-          preview: false,
-        })
-        .then((editor) => {
-          editor.setDecorations(this.getDecorator(hexLength, this.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: daf.DaffodilData) {
-    if (!vscode.workspace.workspaceFolders) {
-      return
-    }
-
-    this.bytePos1b = body.bytePos1b
-
-    let file = fs.readFileSync(this.dataFile)
-    let hex = hexy.hexy(file)
-    let hexLines = hex.split('\n')
-
-    // Format hex code to make the file look nicer
-    hexLines.forEach((h) => {
-      if (h) {
-        let splitHex = h.split(':')
-        let dataLocations = splitHex[1].split(' ')
-
-        this.hexString += splitHex[0] + ': '
-        for (var i = 1; i < dataLocations.length - 2; i++) {
-          let middle = Math.floor(dataLocations[i].length / 2)
-          this.hexString +=
-            dataLocations[i].substring(0, middle).toUpperCase() +
-            ' ' +
-            dataLocations[i].substring(middle).toUpperCase() +
-            ' '
-        }
-        this.hexString += '\t' + dataLocations[dataLocations.length - 1] + '\n'
-      }
-    })
-
-    // Create file that holds path to data file used
-    if (!fs.existsSync(this.hexFile)) {
-      fs.writeFile(this.hexFile, this.hexString, function (err) {
-        if (err) {
-          vscode.window.showInformationMessage(
-            `error code: ${err.code} - ${err.message}`
-          )
-        }
-      })
-    }
-
-    // Only update position if hex file is opened
-    if (this.checkIfHexFileOpened()) {
-      this.updateSelectedDataPosition()
-    }
-
-    let hexLength = this.hexString.split('\n')[this.bytePos1b - 1]
-      ? this.hexString.split('\n')[this.bytePos1b - 1].length
-      : 0
-
-    if (hexLength === 0) {
-      this.closeHexFile()
-    }
-  }
-}
diff --git a/src/infoset.ts b/src/infoset.ts
index 9f704bb..278fd8d 100644
--- a/src/infoset.ts
+++ b/src/infoset.ts
@@ -69,7 +69,7 @@ export async function activate(ctx: vscode.ExtensionContext) {
   ctx.subscriptions.push(
     vscode.debug.onDidStartDebugSession((s) => {
       sid = s.id
-      onDebugStartDisplay(['infoset-view', 'infoset-diff-view'])
+      onDebugStartDisplay(['infoset-view', 'infoset-diff-view', 'data-editor'])
     })
   )
   ctx.subscriptions.push(
diff --git a/src/launchWizard/launchWizard.js b/src/launchWizard/launchWizard.js
index de8849a..1f5b1c7 100644
--- a/src/launchWizard/launchWizard.js
+++ b/src/launchWizard/launchWizard.js
@@ -59,7 +59,7 @@ function getConfigValues() {
   const tdmlName = document.getElementById('tdmlName').value
   const tdmlDescription = document.getElementById('tdmlDescription').value
   const tdmlPath = document.getElementById('tdmlPath').value
-  const openHexView = document.getElementById('openHexView').checked
+  const openDataEditor = document.getElementById('openDataEditor').checked
   const openInfosetDiffView = document.getElementById(
     'openInfosetDiffView'
   ).checked
@@ -93,7 +93,7 @@ function getConfigValues() {
     tdmlName,
     tdmlDescription,
     tdmlPath,
-    openHexView,
+    openDataEditor,
     openInfosetDiffView,
     openInfosetView,
     schema,
@@ -288,7 +288,7 @@ function save() {
         trace: configValues.trace,
         stopOnEntry: configValues.stopOnEntry,
         useExistingServer: configValues.useExistingServer,
-        openHexView: configValues.openHexView,
+        openDataEditor: configValues.openDataEditor,
         openInfosetView: configValues.openInfosetView,
         openInfosetDiffView: configValues.openInfosetDiffView,
         daffodilDebugClasspath: configValues.daffodilDebugClasspath,
@@ -344,7 +344,7 @@ function copyConfig() {
         trace: configValues.trace,
         stopOnEntry: configValues.stopOnEntry,
         useExistingServer: configValues.useExistingServer,
-        openHexView: configValues.openHexView,
+        openDataEditor: configValues.openDataEditor,
         openInfosetView: configValues.openInfosetView,
         openInfosetDiffView: configValues.openInfosetDiffView,
         daffodilDebugClasspath: configValues.daffodilDebugClasspath,
@@ -405,7 +405,7 @@ async function updateConfigValues(config) {
     config['tdmlConfig'] && config.tdmlConfig['path']
       ? config.tdmlConfig['path']
       : config.tdmlPath
-  document.getElementById('openHexView').checked = config.openHexView
+  document.getElementById('openDataEditor').checked = config.openDataEditor
   document.getElementById('openInfosetDiffView').checked =
     config.openInfosetDiffView
   document.getElementById('openInfosetView').checked = config.openInfosetView
diff --git a/src/launchWizard/launchWizard.ts b/src/launchWizard/launchWizard.ts
index 7443bdf..cab7dde 100644
--- a/src/launchWizard/launchWizard.ts
+++ b/src/launchWizard/launchWizard.ts
@@ -364,7 +364,7 @@ class LaunchWizard {
     }
   }
 
-  // Method to set html for the hex view
+  // Method to set html for the data editor
   getWebViewContent(selectedConfigNumber: number | undefined = undefined) {
     const scriptUri = vscode.Uri.parse(
       this.ctx.asAbsolutePath('./src/launchWizard/launchWizard.js')
@@ -415,7 +415,7 @@ class LaunchWizard {
       ? 'visibility: hidden;'
       : 'visibility: visible;'
 
-    let openHexView = defaultValues.openHexView ? 'checked' : ''
+    let openDataEditor = defaultValues.openDataEditor ? 'checked' : ''
     let openInfosetDiffView = defaultValues.openInfosetDiffView ? 'checked' : 
''
     let openInfosetView = defaultValues.openInfosetView ? 'checked' : ''
     let stopOnEntry = defaultValues.stopOnEntry ? 'checked' : ''
@@ -638,10 +638,10 @@ class LaunchWizard {
         </p>
       </div>
 
-      <div id="openHexViewDiv" class="setting-div" 
onclick="check('openHexView')">
-        <p>Open Hex View:</p>
-        <label class="container">Open hexview on debug start.
-          <input type="checkbox" id="openHexView" ${openHexView}>
+      <div id="openDataEditorDiv" class="setting-div" 
onclick="check('openDataEditor')">
+        <p>Open Data Editor:</p>
+        <label class="container">Open data editor on debug start.
+          <input type="checkbox" id="openDataEditor" ${openDataEditor}>
           <span class="checkmark"></span>
         </label>
       </div>
diff --git 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
index 6da7477..6d75cd6 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
@@ -111,9 +111,11 @@ export class ViewportDataStore_t extends 
SimpleWritable<ViewportData_t> {
 
   public upperFetchBoundary(bytesPerRow: BytesPerRow): number {
     const store = this.storeData()
+    const displayByteCount = get(dataDislayLineAmount) * bytesPerRow
     const boundary =
-      store.fileOffset + store.length - get(dataDislayLineAmount) * bytesPerRow
-
+      store.length >= displayByteCount
+        ? store.fileOffset + store.length - displayByteCount
+        : store.length
     return boundary
   }
 
diff --git 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
index 065aed3..5c5a94c 100644
--- 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
+++ 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
@@ -66,7 +66,7 @@ limitations under the License.
   import {
     viewportByteIndicators,
     categoryCSSSelectors,
-  } from '../../../utilities/highlights'
+      } from '../../../utilities/highlights'
   import { bytesPerRow } from '../../../stores'
   export let awaitViewportSeek: boolean
   export let dataRadix: RadixValues = 16
@@ -534,6 +534,10 @@ limitations under the License.
             ) as HTMLDivElement
         }
         break
+      case 'daffodil.data':
+        const { bytePos1b } = msg.data.data
+        viewportByteIndicators.updateDebuggerPosIndication( bytePos1b - 1 )
+        break
     }
   })
 
diff --git 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
index e839ff1..d6ae3ea 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
@@ -82,6 +82,15 @@ limitations under the License.
   div.byte.replacement {
     border-color: var(--color-replace-result);
   }
+  @keyframes byteBlink {
+    0% {background-color: initial;}
+    100% {background-color: indianred;}
+  }
+  div.byte.bytepos1b {
+    animation-name: byteBlink;
+    animation-duration: 0.5s;
+    animation-iteration-count: infinite;
+  }
   div.byte:hover {
     border-color: var(--color-secondary-mid);
     cursor: pointer;
diff --git a/src/svelte/src/utilities/ByteCategories/CategoryIndications.ts 
b/src/svelte/src/utilities/ByteCategories/CategoryIndications.ts
index 72e57fc..ac99eea 100644
--- a/src/svelte/src/utilities/ByteCategories/CategoryIndications.ts
+++ b/src/svelte/src/utilities/ByteCategories/CategoryIndications.ts
@@ -15,14 +15,24 @@
  * limitations under the License.
  */
 
-import { CategoryOne, type ByteCategory, CategoryTwo } from './IByteCategory'
+import {
+  CategoryOne,
+  type ByteCategory,
+  CategoryTwo,
+  DebuggerCategory,
+} from './IByteCategory'
 
 class ByteIndicationCategories {
   private _categories: {
     [key: string]: ByteCategory
   } = {}
   private _bitsUtilized: number = 0
+  public categoryList(): ByteCategory[] {
+    let ret: ByteCategory[] = []
+    for (let key in this._categories) ret.push(this._categories[key])
 
+    return ret
+  }
   public addIndicationCategory(category: ByteCategory) {
     if (this._bitsUtilized + category.bitLength() > 8)
       throw new Error('Category addition would exceed bit limit')
@@ -109,6 +119,6 @@ class ByteIndicationCategories {
 }
 
 export const ViewportByteCategories = new ByteIndicationCategories()
-ViewportByteCategories.addIndicationCategory(CategoryOne).addIndicationCategory(
-  CategoryTwo
-)
+ViewportByteCategories.addIndicationCategory(CategoryOne)
+  .addIndicationCategory(CategoryTwo)
+  .addIndicationCategory(DebuggerCategory)
diff --git a/src/svelte/src/utilities/ByteCategories/IByteCategory.ts 
b/src/svelte/src/utilities/ByteCategories/IByteCategory.ts
index 55b29fa..7be1eef 100644
--- a/src/svelte/src/utilities/ByteCategories/IByteCategory.ts
+++ b/src/svelte/src/utilities/ByteCategories/IByteCategory.ts
@@ -60,7 +60,7 @@ export class ByteCategory implements IByteCategory {
       : this._indicators[index]
   }
   indexOf(selectorName: string) {
-    const target = selectorName
+    const target = selectorName.toLowerCase()
     let ret = -1
 
     this._indicators.forEach((categoryObj, i) => {
@@ -72,13 +72,17 @@ export class ByteCategory implements IByteCategory {
   }
   contains(selectorName: string): boolean {
     for (let i = 0; i < this._indicators.length; i++)
-      if (this._indicators[i].selector() == selectorName) return true
+      if (this._indicators[i].selector() == selectorName.toLowerCase())
+        return true
     return false
   }
 }
 
-export const CategoryOne = new ByteCategory('one', 4)
+export const CategoryOne = new ByteCategory('one', 2)
 CategoryOne.addIndication('selected')
 
-export const CategoryTwo = new ByteCategory('two', 4)
+export const CategoryTwo = new ByteCategory('two', 2)
 CategoryTwo.addIndication('searchresult').addIndication('replacement')
+
+export const DebuggerCategory = new ByteCategory('debugger', 2)
+DebuggerCategory.addIndication('bytePos1b')
diff --git a/src/svelte/src/utilities/ByteCategories/IIndication.ts 
b/src/svelte/src/utilities/ByteCategories/IIndication.ts
index 7a6dede..6e7b5e1 100644
--- a/src/svelte/src/utilities/ByteCategories/IIndication.ts
+++ b/src/svelte/src/utilities/ByteCategories/IIndication.ts
@@ -30,12 +30,15 @@ class NullIndication implements IByteIndication {
 }
 
 export class ByteIndication implements IByteIndication {
-  constructor(private _selector: string) {}
+  private _selector: string
+  constructor(selector: string) {
+    this._selector = selector.toLowerCase()
+  }
   equals(categoryArg: IByteIndication): boolean {
     return this.selector() === categoryArg.selector()
   }
   selector(): string {
-    return this._selector.toLowerCase()
+    return this._selector
   }
 }
 
diff --git a/src/svelte/src/utilities/highlights.ts 
b/src/svelte/src/utilities/highlights.ts
index 4442a6d..f765362 100644
--- a/src/svelte/src/utilities/highlights.ts
+++ b/src/svelte/src/utilities/highlights.ts
@@ -83,6 +83,7 @@ class ViewportByteIndications extends 
SimpleWritable<Uint8Array> {
       })
     }
   }
+
   public updateSelectionIndications(selectionData: SelectionData_t) {
     const category1 = ViewportByteCategories.category('one')
     const start = selectionData.startOffset
@@ -120,6 +121,15 @@ class ViewportByteIndications extends 
SimpleWritable<Uint8Array> {
       })
     }
   }
+
+  public updateDebuggerPosIndication(bytePos: number) {
+    this.store.update((indications) => {
+      ViewportByteCategories.clearAndSetIf(indications, 'bytePos1b', (_, i) => 
{
+        return i === bytePos
+      })
+      return indications
+    })
+  }
 }
 
 export const viewportByteIndicators = new ViewportByteIndications()
@@ -143,16 +153,13 @@ function generateSelectionCategoryParition(
 
 export function categoryCSSSelectors(byteIndicationValue: number): string {
   let ret = ''
-  const CategoryOneSelector = ViewportByteCategories.categoryCSSSelector(
-    ViewportByteCategories.category('one'),
-    byteIndicationValue
-  )
-  const CategoryTwoSelector = ViewportByteCategories.categoryCSSSelector(
-    ViewportByteCategories.category('two'),
-    byteIndicationValue
-  )
-
-  ret += CategoryOneSelector + ' ' + CategoryTwoSelector
+  ViewportByteCategories.categoryList().forEach((category) => {
+    const categorysCSSSelector = ViewportByteCategories.categoryCSSSelector(
+      category,
+      byteIndicationValue
+    )
+    if (categorysCSSSelector != 'none') ret += categorysCSSSelector + ' '
+  })
 
   return ret
 }
diff --git a/src/tests/README.md b/src/tests/README.md
index c715987..1627e3f 100644
--- a/src/tests/README.md
+++ b/src/tests/README.md
@@ -43,7 +43,7 @@
 - [ ] verify source highlighting
 - [ ] verify code completion
 - [ ] verify breakpoints
-- [ ] verify hex view
+- [ ] verify data editor
 - [ ] verify InfoSet view
 - [ ] verify InfoSet diff
 - [ ] verify InfoSet output in supported formats
diff --git a/src/tests/suite/daffodil.test.ts b/src/tests/suite/daffodil.test.ts
index d29d4e7..91343ff 100644
--- a/src/tests/suite/daffodil.test.ts
+++ b/src/tests/suite/daffodil.test.ts
@@ -194,7 +194,6 @@ suite('Daffodfil', () => {
   suite('debug specifc commands', () => {
     const debugSpecificCmds = [
       'extension.dfdl-debug.toggleFormatting',
-      'hexview.display',
       'infoset.display',
       'infoset.diff',
       'infoset.save',
diff --git a/src/tests/suite/utils.test.ts b/src/tests/suite/utils.test.ts
index 41534ae..7c46035 100644
--- a/src/tests/suite/utils.test.ts
+++ b/src/tests/suite/utils.test.ts
@@ -45,7 +45,7 @@ suite('Utils Test Suite', () => {
     stopOnEntry: true,
     useExistingServer: false,
     trace: true,
-    openHexView: false,
+    openDataEditor: false,
     openInfosetView: false,
     openInfosetDiffView: false,
     daffodilDebugClasspath: '',
diff --git a/src/utils.ts b/src/utils.ts
index 320fa58..3545167 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -47,22 +47,27 @@ export function setCurrentConfig(
 }
 
 // Function to run vscode command and catch the error to not cause other issues
-export function runCommand(command: string) {
-  vscode.commands.executeCommand(command).then(undefined, (err) => {
+export function runCommand(command: string, params?: any) {
+  const vscodeError = (err) => {
     vscode.window.showInformationMessage(err)
-  })
+  }
+
+  if (!params)
+    vscode.commands.executeCommand(command).then(undefined, vscodeError)
+  else
+    vscode.commands.executeCommand(command, params).then(undefined, 
vscodeError)
 }
 
 // Function for checking if config specifies if either the
-// infoset, infoset diff or hex view needs to be opened
+// infoset, infoset diff or data editor needs to be opened
 export async function onDebugStartDisplay(viewsToCheck: string[]) {
   let config = getCurrentConfig()
 
   viewsToCheck.forEach(async (viewToCheck) => {
     switch (viewToCheck) {
-      case 'hex-view':
-        if (config.openHexView) {
-          runCommand('hexview.display')
+      case 'data-editor':
+        if (config.openDataEditor) {
+          runCommand('extension.data.edit', config.data)
         }
         break
       case 'infoset-view':
@@ -104,7 +109,7 @@ export function getConfig(jsonArgs: object): 
vscode.DebugConfiguration {
     stopOnEntry: defaultConf.get('stopOnEntry', true),
     useExistingServer: defaultConf.get('useExistingServer', false),
     trace: defaultConf.get('trace', true),
-    openHexView: defaultConf.get('openHexView', false),
+    openDataEditor: defaultConf.get('openDataEditor', false),
     openInfosetView: defaultConf.get('openInfosetView', false),
     openInfosetDiffView: defaultConf.get('openInfosetDiffView', false),
     daffodilDebugClasspath: defaultConf.get('daffodilDebugClasspath', ''),


Reply via email to