Skip to content

Commit

Permalink
add ability to save segments of the file (#800)
Browse files Browse the repository at this point in the history
scholarsmate committed Dec 4, 2023
1 parent 03b51b5 commit 8ba1714
Showing 5 changed files with 149 additions and 7 deletions.
100 changes: 100 additions & 0 deletions src/dataEditor/dataEditorClient.ts
Original file line number Diff line number Diff line change
@@ -18,14 +18,17 @@
import fs from 'fs'
import {
ALL_EVENTS,
beginSessionTransaction,
clear,
CountKind,
createSession,
createSimpleFileLogger,
createViewport,
del,
destroySession,
edit,
EditorClient,
endSessionTransaction,
EventSubscriptionRequest,
getClient,
getClientVersion,
@@ -489,6 +492,22 @@ export class DataEditorClient implements vscode.Disposable {
}
break

case MessageCommand.saveSegment:
{
const uri = await vscode.window.showSaveDialog({
title: 'Save Segment',
saveLabel: 'Save',
})
if (uri && uri.fsPath) {
await this.saveFileSegment(
uri.fsPath,
message.data.offset,
message.data.length
)
}
}
break

case MessageCommand.requestEditedData:
{
const [selectionData, selectionDisplay] = fillRequestData(message)
@@ -578,6 +597,87 @@ export class DataEditorClient implements vscode.Disposable {
}
}

private async saveFileSegment(
fileToSave: string,
offset: number,
length: number
) {
// if the file to save is the same as the file being edited then we can save the file with a single transaction to
// trim the file to contain only the desired segment, preserving session state
if (this.fileToEdit === fileToSave) {
const computedFileSize = await getComputedFileSize(this.omegaSessionId)
if (offset === 0) {
if (offset + length !== computedFileSize) {
// delete from length to the end of the file
await del(this.omegaSessionId, length, computedFileSize - length)
await this.sendChangesInfo()
}
} else if (offset + length === computedFileSize) {
// delete from 0 to offset
await del(this.omegaSessionId, 0, offset)
await this.sendChangesInfo()
} else {
// delete from length to the end of the file and from 0 to offset in a single transaction
await beginSessionTransaction(this.omegaSessionId)
await del(
this.omegaSessionId,
offset + length,
computedFileSize - length
)
await del(this.omegaSessionId, 0, offset)
await endSessionTransaction(this.omegaSessionId)
await this.sendChangesInfo()
}
// save the segment to the file using the typical save method
await this.saveFile(fileToSave)
} else {
let saved = false
let cancelled = false

// try to save the file with overwrite
const saveResponse = await saveSession(
this.omegaSessionId,
fileToSave,
IOFlags.IO_FLG_OVERWRITE,
offset,
length
)
if (saveResponse.getSaveStatus() === SaveStatus.MODIFIED) {
// the file was modified since the session was created, query user to overwrite the modified file
if (
(await vscode.window.showInformationMessage(
'File has been modified since being opened overwrite the file anyway?',
{ modal: true },
'Yes',
'No'
)) === 'Yes'
) {
// the user decided to overwrite the file, try to save again with force overwrite
const saveResponse2 = await saveSession(
this.omegaSessionId,
fileToSave,
IOFlags.IO_FLG_FORCE_OVERWRITE,
offset,
length
)
saved = saveResponse2.getSaveStatus() === SaveStatus.SUCCESS
} else {
cancelled = true
}
} else {
saved = saveResponse.getSaveStatus() === SaveStatus.SUCCESS
}

if (saved) {
vscode.window.showInformationMessage(`Saved: ${this.fileToEdit}`)
} else if (cancelled) {
vscode.window.showInformationMessage(`Cancelled save: ${fileToSave}`)
} else {
vscode.window.showErrorMessage(`Failed to save: ${fileToSave}`)
}
}
}

private async saveFile(fileToSave: string) {
let saved = false
let cancelled = false
22 changes: 16 additions & 6 deletions src/svelte/src/components/DataMetrics/DataMetrics.svelte
Original file line number Diff line number Diff line change
@@ -129,6 +129,16 @@ limitations under the License.
link.click()
}
function saveSegmentAs() {
vscode.postMessage({
command: MessageCommand.saveSegment,
data: {
offset: startOffset,
length: length,
},
})
}
function requestSessionProfile(startOffset: number, length: number) {
setStatusMessage(
`Profiling bytes from ${startOffset} to ${startOffset + length}...`,
@@ -493,13 +503,13 @@ limitations under the License.
</label>
</div>
<hr />
<Button
fn={handleCsvProfileDownload}
description="Download profiled data as .csv"
>
<Button fn={handleCsvProfileDownload} description="Download profiled data as .csv">
<span slot="left" class="btn-icon material-symbols-outlined">download</span>
<span>Profile&nbsp;as&nbsp;CSV</span></Button
>
<span>Profile&nbsp;as&nbsp;CSV</span></Button>
<Button fn={saveSegmentAs} description="Save segment as">
<span slot="left" class="btn-icon material-symbols-outlined">save_as</span>
<span slot="default">Save&nbsp;Segment&nbsp;As</span>
</Button>
<hr />
{#if statusMessage.length > 0}
<div class="message status">&nbsp;{statusMessage}&nbsp;</div>
3 changes: 3 additions & 0 deletions src/svelte/src/components/Header/fieldsets/FileMetrics.svelte
Original file line number Diff line number Diff line change
@@ -65,6 +65,9 @@ limitations under the License.
switch (msg.data.command) {
case MessageCommand.fileInfo:
{
// reset the profiler if changes have been made
isProfilerOpen = false
startOffset = length = 0
if ('fileName' in msg.data.data) {
$fileMetrics.name = msg.data.data.fileName
}
1 change: 1 addition & 0 deletions src/svelte/src/utilities/message.ts
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ export enum MessageCommand {
requestEditedData,
save,
saveAs,
saveSegment,
scrollViewport,
search,
replace,
30 changes: 29 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
@@ -412,7 +412,7 @@
jszip "^3.10.1"
semver "^7.5.2"

"@vscode/[email protected]", "@vscode/vsce@^2.20.1":
"@vscode/[email protected]":
version "2.22.0"
resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.22.0.tgz#1eb3ebc6b89581a150bb44dd7d731a064019b617"
integrity sha512-8df4uJiM3C6GZ2Sx/KilSKVxsetrTBBIUb3c0W4B1EWHcddioVs5mkyDKtMNP0khP/xBILVSzlXxhV+nm2rC9A==
@@ -440,6 +440,34 @@
optionalDependencies:
keytar "^7.7.0"

"@vscode/vsce@^2.20.1":
version "2.21.0"
resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.21.0.tgz#572e66db79cff383b9ac39f71710aa62e6392330"
integrity sha512-KuxYqScqUY/duJbkj9eE2tN2X/WJoGAy54hHtxT3ZBkM6IzrOg7H7CXGUPBxNlmqku2w/cAjOUSrgIHlzz0mbA==
dependencies:
azure-devops-node-api "^11.0.1"
chalk "^2.4.2"
cheerio "^1.0.0-rc.9"
commander "^6.2.1"
glob "^7.0.6"
hosted-git-info "^4.0.2"
jsonc-parser "^3.2.0"
leven "^3.1.0"
markdown-it "^12.3.2"
mime "^1.3.4"
minimatch "^3.0.3"
parse-semver "^1.1.1"
read "^1.0.7"
semver "^7.5.2"
tmp "^0.2.1"
typed-rest-client "^1.8.4"
url-join "^4.0.1"
xml2js "^0.5.0"
yauzl "^2.3.1"
yazl "^2.2.2"
optionalDependencies:
keytar "^7.7.0"

"@webassemblyjs/[email protected]", "@webassemblyjs/ast@^1.11.5":
version "1.11.6"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"

0 comments on commit 8ba1714

Please sign in to comment.