Skip to content

Commit 3b51517

Browse files
author
Colin Grant
committed
Can edit selection
1 parent fa03c27 commit 3b51517

File tree

6 files changed

+56
-16
lines changed

6 files changed

+56
-16
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@
121121
"title": "Apply Memory from File",
122122
"enablement": "memory-inspector.canWrite",
123123
"category": "Memory"
124+
},
125+
{
126+
"command": "memory-inspector.edit-current-selection",
127+
"title": "Edit currently selected memory",
128+
"enablement": "memory-inspector.canWrite && webviewId === memory-inspector.memory"
124129
}
125130
],
126131
"menus": {

src/common/messaging.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const resetMemoryViewSettingsType: NotificationType<void> = { method: 're
5151
export const setTitleType: NotificationType<string> = { method: 'setTitle' };
5252
export const memoryWrittenType: NotificationType<WrittenMemory> = { method: 'memoryWritten' };
5353
export const sessionContextChangedType: NotificationType<SessionContext> = { method: 'sessionContextChanged' };
54+
export const editSelectedMemoryType: NotificationType<void> = { method: 'editSelectedMemory' };
5455

5556
// Requests
5657
export const setOptionsType: RequestType<MemoryOptions, void> = { method: 'setOptions' };

src/plugin/memory-webview-main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
WriteMemoryArguments,
2929
WriteMemoryResult,
3030
applyMemoryType,
31+
editSelectedMemoryType,
3132
getVariablesType,
3233
getWebviewSelectionType,
3334
logMessageType,
@@ -70,6 +71,7 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider {
7071
public static ToggleRadixPrefixCommandType = `${manifest.PACKAGE_NAME}.toggle-radix-prefix`;
7172
public static ShowAdvancedDisplayConfigurationCommandType = `${manifest.PACKAGE_NAME}.show-advanced-display-options`;
7273
public static GetWebviewSelectionCommandType = `${manifest.PACKAGE_NAME}.get-webview-selection`;
74+
public static EditCurrentSelectionCommandType = `${manifest.PACKAGE_NAME}.edit-current-selection`;
7375

7476
protected messenger: Messenger;
7577
protected refreshOnStop: RefreshEnum;
@@ -110,6 +112,9 @@ export class MemoryWebview implements vscode.CustomReadonlyEditorProvider {
110112
this.messenger.sendNotification(showAdvancedOptionsType, ctx.messageParticipant, undefined);
111113
}),
112114
vscode.commands.registerCommand(MemoryWebview.GetWebviewSelectionCommandType, (ctx: WebviewContext) => this.getWebviewSelection(ctx.messageParticipant)),
115+
vscode.commands.registerCommand(MemoryWebview.EditCurrentSelectionCommandType, (ctx: WebviewContext) => {
116+
this.messenger.sendNotification(editSelectedMemoryType, ctx.messageParticipant, undefined);
117+
})
113118
);
114119
};
115120

src/webview/columns/column-contribution-service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export interface ColumnStatus {
4848

4949
export interface TableRenderOptions extends Omit<SerializedTableRenderOptions, 'columnOptions'> {
5050
columnOptions: ColumnStatus[];
51-
currentlyEditedRange?: BigIntMemoryRange;
5251
}
5352

5453
class ColumnContributionService {

src/webview/columns/data-column.tsx

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import * as React from 'react';
1818
import { BigIntMemoryRange, Endianness, isWithin, toHexStringWithRadixMarker, toOffset } from '../../common/memory-range';
19-
import { FullNodeAttributes } from '../utils/view-types';
19+
import { Disposable, FullNodeAttributes } from '../utils/view-types';
2020
import { ColumnContribution, TableRenderOptions } from './column-contribution-service';
2121
import { decorationService } from '../decorations/decoration-service';
2222
import type { MemorySizeOptions } from '../components/memory-table';
@@ -25,28 +25,40 @@ import { Memory } from '../../common/memory';
2525
import { HOST_EXTENSION } from 'vscode-messenger-common';
2626
import { messenger } from '../view-messenger';
2727
import { writeMemoryType } from '../../common/messaging';
28-
import { DebugProtocol } from '@vscode/debugprotocol';
2928
import { 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

3144
export 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 {
6375
export 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> {

src/webview/memory-webview-view.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
storeMemoryType,
4040
sessionContextChangedType,
4141
SessionContext,
42+
editSelectedMemoryType,
4243
} from '../common/messaging';
4344
import { AddressColumn } from './columns/address-column';
4445
import { AsciiColumn } from './columns/ascii-column';
@@ -135,6 +136,7 @@ class App extends React.Component<{}, MemoryAppState> {
135136
messenger.onRequest(getWebviewSelectionType, () => this.getWebviewSelection());
136137
messenger.onNotification(showAdvancedOptionsType, () => this.showAdvancedOptions());
137138
messenger.sendNotification(readyType, HOST_EXTENSION, undefined);
139+
messenger.onNotification(editSelectedMemoryType, () => DataColumn.editCurrentSelection());
138140
}
139141

140142
public componentDidUpdate(_: {}, prevState: MemoryAppState): void {

0 commit comments

Comments
 (0)