1616
1717import * as React from 'react' ;
1818import { BigIntMemoryRange , Endianness , isWithin , toHexStringWithRadixMarker , toOffset } from '../../common/memory-range' ;
19- import { FullNodeAttributes } from '../utils/view-types' ;
19+ import { Disposable , FullNodeAttributes } from '../utils/view-types' ;
2020import { ColumnContribution , TableRenderOptions } from './column-contribution-service' ;
2121import { decorationService } from '../decorations/decoration-service' ;
2222import type { MemorySizeOptions } from '../components/memory-table' ;
@@ -25,28 +25,40 @@ import { Memory } from '../../common/memory';
2525import { HOST_EXTENSION } from 'vscode-messenger-common' ;
2626import { messenger } from '../view-messenger' ;
2727import { writeMemoryType } from '../../common/messaging' ;
28- import { DebugProtocol } from '@vscode/debugprotocol' ;
2928import { InputText } from 'primereact/inputtext' ;
29+ import { EventEmitter } from '../utils/events' ;
30+
31+ function getSelectionEdit ( ) : BigIntMemoryRange | undefined {
32+ const selectionRange = document . getSelection ( ) ;
33+ if ( ! selectionRange ) { return ; }
34+ const anchorWord = selectionRange . anchorNode ?. parentElement ?. closest < HTMLSpanElement > ( '.single-word' ) ;
35+ const focusWord = selectionRange . focusNode ?. parentElement ?. closest < HTMLSpanElement > ( '.single-word' ) ;
36+ if ( ! anchorWord ?. dataset . address || ! focusWord ?. dataset . address ) { return ; }
37+ const anchorAddress = BigInt ( anchorWord . dataset . address ) ;
38+ const focusAddress = BigInt ( focusWord . dataset . address ) ;
39+ const startAddress = anchorAddress <= focusAddress ? anchorAddress : focusAddress ;
40+ const endAddress = ( anchorAddress < focusAddress ? focusAddress : anchorAddress ) + 1n ;
41+ return { startAddress, endAddress } ;
42+ }
3043
3144export class DataColumn implements ColumnContribution {
3245 static CLASS_NAME = 'column-data' ;
46+ private static onEditRequestedEmitter = new EventEmitter < BigIntMemoryRange > ( ) ;
47+ public static onEditRequested = this . onEditRequestedEmitter . event ;
3348
3449 readonly id = 'data' ;
3550 readonly className = DataColumn . CLASS_NAME ;
3651 readonly label = 'Data' ;
3752 readonly priority = 1 ;
3853
39- render ( range : BigIntMemoryRange , memory : Memory , options : TableRenderOptions ) : React . ReactNode {
40- return < EditableDataColumnRow range = { range } memory = { memory } options = { options } /> ;
54+ static editCurrentSelection ( ) : void {
55+ const toEdit = getSelectionEdit ( ) ;
56+ if ( ! toEdit ) { return ; }
57+ this . onEditRequestedEmitter . fire ( toEdit ) ;
4158 }
4259
43- protected writeMemory = async ( writeArguments : DebugProtocol . WriteMemoryArguments ) : Promise < void > => {
44- await messenger . sendRequest ( writeMemoryType , HOST_EXTENSION , writeArguments ) ;
45- } ;
46-
47- protected applyEndianness < T > ( group : T [ ] , options : TableRenderOptions ) : T [ ] {
48- // Assume data from the DAP comes in Big Endian so we need to revert the order if we use Little Endian
49- return options . endianness === Endianness . Big ? group : group . reverse ( ) ;
60+ render ( range : BigIntMemoryRange , memory : Memory , options : TableRenderOptions ) : React . ReactNode {
61+ return < EditableDataColumnRow range = { range } memory = { memory } options = { options } /> ;
5062 }
5163}
5264
@@ -63,6 +75,15 @@ export interface EditableDataColumnRowState {
6375export class EditableDataColumnRow extends React . Component < EditableDataColumnRowProps , EditableDataColumnRowState > {
6476 state : EditableDataColumnRowState = { } ;
6577 protected inputText = React . createRef < HTMLInputElement > ( ) ;
78+ protected toDisposeOnUnmount ?: Disposable ;
79+
80+ componentDidMount ( ) : void {
81+ this . toDisposeOnUnmount = DataColumn . onEditRequested ( this . setSelectionEdit ) ;
82+ }
83+
84+ componentWillUnmount ( ) : void {
85+ this . toDisposeOnUnmount ?. dispose ( ) ;
86+ }
6687
6788 render ( ) : React . ReactNode {
6889 return this . renderGroups ( ) ;
@@ -117,7 +138,7 @@ export class EditableDataColumnRow extends React.Component<EditableDataColumnRow
117138 bytes . push ( this . renderEightBits ( memory , currentAddress , i ) ) ;
118139 }
119140 this . applyEndianness ( bytes , options ) ;
120- return < span className = 'single-word' key = { currentAddress . toString ( 16 ) } > { bytes } </ span > ;
141+ return < span className = 'single-word' data-address = { currentAddress . toString ( ) } key = { currentAddress . toString ( 16 ) } > { bytes } </ span > ;
121142 }
122143
123144 protected renderEightBits ( memory : Memory , currentAddress : bigint , offset : number ) : React . ReactNode {
@@ -168,11 +189,11 @@ export class EditableDataColumnRow extends React.Component<EditableDataColumnRow
168189 ref = { this . inputText }
169190 maxLength = { characters }
170191 defaultValue = { defaultValue }
192+ onBlur = { this . onBlur }
171193 onKeyDown = { this . onKeyDown }
172194 autoFocus
173195 style = { style }
174- onBlur = { this . onBlur }
175- > </ InputText > ;
196+ /> ;
176197 }
177198
178199 protected onBlur : React . FocusEventHandler < HTMLInputElement > = ( ) => {
@@ -200,8 +221,15 @@ export class EditableDataColumnRow extends React.Component<EditableDataColumnRow
200221 this . setState ( { editedRange : { startAddress, endAddress } } ) ;
201222 } ;
202223
224+ protected setSelectionEdit = ( editedRange : BigIntMemoryRange ) : void => {
225+ if ( isWithin ( editedRange . startAddress , this . props . range ) ) {
226+ const endAddress = editedRange . endAddress <= this . props . range . endAddress ? editedRange . endAddress : this . props . range . endAddress ;
227+ this . setState ( { editedRange : { startAddress : editedRange . startAddress , endAddress } } ) ;
228+ }
229+ } ;
230+
203231 protected disableEdit ( ) : void {
204- this . setState ( { } ) ;
232+ this . setState ( { editedRange : undefined } ) ;
205233 }
206234
207235 protected async submitChanges ( ) : Promise < void > {
0 commit comments