@@ -11,15 +11,22 @@ import {
1111 KeybindingRegistry ,
1212} from './contribution' ;
1313import { nls } from '@theia/core/lib/common' ;
14- import { ApplicationShell } from '@theia/core/lib/browser' ;
15- import { timeout } from '@theia/core/lib/common/promise-util' ;
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' ;
1617
1718@injectable ( )
1819export class SaveAsSketch extends SketchContribution {
1920
2021 @inject ( ApplicationShell )
2122 protected readonly applicationShell : ApplicationShell ;
2223
24+ @inject ( EditorManager )
25+ protected readonly editorManager : EditorManager ;
26+
27+ @inject ( WindowService )
28+ protected readonly windowService : WindowService ;
29+
2330 registerCommands ( registry : CommandRegistry ) : void {
2431 registry . registerCommand ( SaveAsSketch . Commands . SAVE_AS_SKETCH , {
2532 execute : ( args ) => this . saveAs ( args ) ,
@@ -93,11 +100,12 @@ export class SaveAsSketch extends SketchContribution {
93100 if ( ! destinationUri ) {
94101 return false ;
95102 }
96- await this . applicationShell . saveAll ( ) ;
97- await timeout ( 20 ) ;
98103 const workspaceUri = await this . sketchService . copy ( sketch , {
99104 destinationUri,
100105 } ) ;
106+ if ( workspaceUri ) {
107+ await this . saveOntoCopiedSketch ( sketch . mainFileUri , sketch . uri , workspaceUri ) ;
108+ }
101109 if ( workspaceUri && openAfterMove ) {
102110 if ( wipeOriginal || ( openAfterMove && execOnlyIfTemp ) ) {
103111 try {
@@ -108,12 +116,48 @@ export class SaveAsSketch extends SketchContribution {
108116 /* NOOP: from time to time, it's not possible to wipe the old resource from the temp dir on Windows */
109117 }
110118 }
119+ this . windowService . setSafeToShutDown ( ) ;
111120 this . workspaceService . open ( new URI ( workspaceUri ) , {
112121 preserveWindow : true ,
113122 } ) ;
114123 }
115124 return ! ! workspaceUri ;
116125 }
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+ }
117161}
118162
119163export namespace SaveAsSketch {
0 commit comments