Skip to content

Commit 11961bb

Browse files
authored
Save all open editors before running Save As (arduino#939)
* Save all open editors before running `Save As` * Only save unsaved changes to new sketch
1 parent 2be1fac commit 11961bb

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

arduino-ide-extension/src/browser/contributions/save-as-sketch.ts

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { injectable } from 'inversify';
1+
import { inject, injectable } from 'inversify';
22
import * as remote from '@theia/core/electron-shared/@electron/remote';
33
import * as dateFormat from 'dateformat';
44
import { ArduinoMenus } from '../menu/arduino-menus';
@@ -11,9 +11,22 @@ import {
1111
KeybindingRegistry,
1212
} from './contribution';
1313
import { nls } from '@theia/core/lib/common';
14+
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
15+
import { EditorManager } from '@theia/editor/lib/browser';
16+
import { WindowService } from '@theia/core/lib/browser/window/window-service';
1417

1518
@injectable()
1619
export class SaveAsSketch extends SketchContribution {
20+
21+
@inject(ApplicationShell)
22+
protected readonly applicationShell: ApplicationShell;
23+
24+
@inject(EditorManager)
25+
protected readonly editorManager: EditorManager;
26+
27+
@inject(WindowService)
28+
protected readonly windowService: WindowService;
29+
1730
registerCommands(registry: CommandRegistry): void {
1831
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
1932
execute: (args) => this.saveAs(args),
@@ -90,6 +103,9 @@ export class SaveAsSketch extends SketchContribution {
90103
const workspaceUri = await this.sketchService.copy(sketch, {
91104
destinationUri,
92105
});
106+
if (workspaceUri) {
107+
await this.saveOntoCopiedSketch(sketch.mainFileUri, sketch.uri, workspaceUri);
108+
}
93109
if (workspaceUri && openAfterMove) {
94110
if (wipeOriginal || (openAfterMove && execOnlyIfTemp)) {
95111
try {
@@ -100,12 +116,48 @@ export class SaveAsSketch extends SketchContribution {
100116
/* NOOP: from time to time, it's not possible to wipe the old resource from the temp dir on Windows */
101117
}
102118
}
119+
this.windowService.setSafeToShutDown();
103120
this.workspaceService.open(new URI(workspaceUri), {
104121
preserveWindow: true,
105122
});
106123
}
107124
return !!workspaceUri;
108125
}
126+
127+
private async saveOntoCopiedSketch(mainFileUri: string, sketchUri: string, newSketchUri: string): Promise<void> {
128+
const widgets = this.applicationShell.widgets;
129+
const snapshots = new Map<string, object>();
130+
for (const widget of widgets) {
131+
const saveable = Saveable.getDirty(widget);
132+
const uri = NavigatableWidget.getUri(widget);
133+
const uriString = uri?.toString();
134+
let relativePath: string;
135+
if (uri && uriString!.includes(sketchUri) && saveable && saveable.createSnapshot) {
136+
// The main file will change its name during the copy process
137+
// We need to store the new name in the map
138+
if (mainFileUri === uriString) {
139+
const lastPart = new URI(newSketchUri).path.base + uri.path.ext;
140+
relativePath = '/' + lastPart;
141+
} else {
142+
relativePath = uri.toString().substring(sketchUri.length);
143+
}
144+
snapshots.set(relativePath, saveable.createSnapshot());
145+
}
146+
}
147+
await Promise.all(Array.from(snapshots.entries()).map(async ([path, snapshot]) => {
148+
const widgetUri = new URI(newSketchUri + path);
149+
try {
150+
const widget = await this.editorManager.getOrCreateByUri(widgetUri);
151+
const saveable = Saveable.get(widget);
152+
if (saveable && saveable.applySnapshot) {
153+
saveable.applySnapshot(snapshot);
154+
await saveable.save();
155+
}
156+
} catch (e) {
157+
console.error(e);
158+
}
159+
}));
160+
}
109161
}
110162

111163
export namespace SaveAsSketch {

0 commit comments

Comments
 (0)