@@ -382,8 +382,73 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
382
382
) ;
383
383
}
384
384
385
- public rename ( oldUri : vscode . Uri , newUri : vscode . Uri , options : { overwrite : boolean } ) : void | Thenable < void > {
386
- throw new Error ( "Move / rename is not supported on server" ) ;
385
+ public async rename ( oldUri : vscode . Uri , newUri : vscode . Uri , options : { overwrite : boolean } ) : Promise < void > {
386
+ if ( ! oldUri . path . includes ( "." ) ) {
387
+ throw vscode . FileSystemError . NoPermissions ( "Cannot rename a package/folder" ) ;
388
+ }
389
+ if ( oldUri . path . split ( "." ) . pop ( ) . toLowerCase ( ) != newUri . path . split ( "." ) . pop ( ) . toLowerCase ( ) ) {
390
+ throw vscode . FileSystemError . NoPermissions ( "Cannot change a file's extension during rename" ) ;
391
+ }
392
+ if ( vscode . workspace . getWorkspaceFolder ( oldUri ) != vscode . workspace . getWorkspaceFolder ( newUri ) ) {
393
+ throw vscode . FileSystemError . NoPermissions ( "Cannot rename a file across workspace folders" ) ;
394
+ }
395
+ // Check if the destination exists
396
+ let newFileStat : vscode . FileStat ;
397
+ try {
398
+ newFileStat = await vscode . workspace . fs . stat ( newUri ) ;
399
+ if ( ! options . overwrite ) {
400
+ // If it does and we can't overwrite it, throw an error
401
+ throw vscode . FileSystemError . FileExists ( newUri ) ;
402
+ }
403
+ } catch ( error ) {
404
+ if ( error instanceof vscode . FileSystemError && error . code == "FileExists" ) {
405
+ // Re-throw the FileExists error
406
+ throw error ;
407
+ }
408
+ }
409
+ // Get the name of the new file
410
+ const newParams = new URLSearchParams ( newUri . query ) ;
411
+ const newCsp = newParams . has ( "csp" ) && [ "" , "1" ] . includes ( newParams . get ( "csp" ) ) ;
412
+ const newFileName = newCsp ? newUri . path : newUri . path . slice ( 1 ) . replace ( / \/ / g, "." ) ;
413
+ // Generate content for the new file
414
+ const newContent = generateFileContent ( newFileName , Buffer . from ( await vscode . workspace . fs . readFile ( oldUri ) ) ) ;
415
+ if ( newFileStat ) {
416
+ // We're overwriting an existing file so prompt the user to check it out
417
+ await fireOtherStudioAction ( OtherStudioAction . AttemptedEdit , newUri ) ;
418
+ }
419
+ // Write the new file
420
+ // This is going to attempt the write regardless of the user's response to the check out prompt
421
+ const api = new AtelierAPI ( oldUri ) ;
422
+ await api
423
+ . putDoc (
424
+ newFileName ,
425
+ {
426
+ ...newContent ,
427
+ mtime : Date . now ( ) ,
428
+ } ,
429
+ true
430
+ )
431
+ . catch ( ( error ) => {
432
+ // Throw all failures
433
+ if ( error . errorText && error . errorText !== "" ) {
434
+ throw vscode . FileSystemError . Unavailable ( error . errorText ) ;
435
+ }
436
+ throw vscode . FileSystemError . Unavailable ( error . message ) ;
437
+ } )
438
+ . then ( ( response ) => {
439
+ // New file has been written
440
+ if ( newFileStat != undefined && response && response . result . ext && response . result . ext [ 0 ] ) {
441
+ // We created a file
442
+ fireOtherStudioAction ( OtherStudioAction . CreatedNewDocument , newUri , response . result . ext [ 0 ] ) ;
443
+ fireOtherStudioAction ( OtherStudioAction . FirstTimeDocumentSave , newUri , response . result . ext [ 1 ] ) ;
444
+ }
445
+ // Sanity check that we find it there, then make client side update things
446
+ this . _lookupAsFile ( newUri ) . then ( ( ) => {
447
+ this . _fireSoon ( { type : vscode . FileChangeType . Changed , uri : newUri } ) ;
448
+ } ) ;
449
+ } ) ;
450
+ // Delete the old file
451
+ await vscode . workspace . fs . delete ( oldUri ) ;
387
452
}
388
453
389
454
public watch ( uri : vscode . Uri ) : vscode . Disposable {
0 commit comments