@@ -14,6 +14,8 @@ import {
14
14
FileType ,
15
15
Position ,
16
16
ProviderResult ,
17
+ TabInputNotebook ,
18
+ TabInputText ,
17
19
TextDocument ,
18
20
TextDocumentContentProvider ,
19
21
ThemeIcon ,
@@ -52,7 +54,7 @@ import {
52
54
FileManipulationEvent ,
53
55
} from "./types" ;
54
56
import {
55
- getEditorTabForItem ,
57
+ getEditorTabsForItem ,
56
58
getFileStatement ,
57
59
isContainer as getIsContainer ,
58
60
} from "./utils" ;
@@ -285,23 +287,62 @@ class ContentDataProvider
285
287
name : string ,
286
288
) : Promise < Uri | undefined > {
287
289
const closing = closeFileIfOpen ( item ) ;
288
- if ( ! ( await closing ) ) {
290
+ const removedTabUris = await closing ;
291
+ if ( ! removedTabUris ) {
289
292
return ;
290
293
}
291
294
292
295
const newItem = await this . model . renameResource ( item , name ) ;
293
- if ( newItem ) {
294
- const newUri = newItem . vscUri ;
295
- if ( closing !== true ) {
296
- // File was open before rename, so re-open it
297
- commands . executeCommand ( "vscode.open" , newUri ) ;
298
- }
296
+ if ( ! newItem ) {
297
+ return ;
298
+ }
299
+
300
+ const newUri = newItem . vscUri ;
301
+ const oldUriToNewUriMap = [ [ item . vscUri , newUri ] ] ;
302
+ const newItemIsContainer = getIsContainer ( newItem ) ;
303
+ if ( closing !== true && ! newItemIsContainer ) {
304
+ commands . executeCommand ( "vscode.open" , newUri ) ;
305
+ }
306
+ const urisToOpen = getPreviouslyOpenedChildItems (
307
+ await this . getChildren ( newItem ) ,
308
+ ) ;
309
+ urisToOpen . forEach ( ( [ , newUri ] ) =>
310
+ commands . executeCommand ( "vscode.open" , newUri ) ,
311
+ ) ;
312
+ oldUriToNewUriMap . push ( ...urisToOpen ) ;
313
+ oldUriToNewUriMap . forEach ( ( [ uri , newUri ] ) =>
299
314
this . _onDidManipulateFile . fire ( {
300
315
type : "rename" ,
301
- uri : item . vscUri ,
316
+ uri,
302
317
newUri,
303
- } ) ;
304
- return newUri ;
318
+ } ) ,
319
+ ) ;
320
+ return newUri ;
321
+
322
+ function getPreviouslyOpenedChildItems ( childItems : ContentItem [ ] ) {
323
+ const loadChildItems = closing !== true && newItemIsContainer ;
324
+ if ( ! Array . isArray ( removedTabUris ) || ! loadChildItems ) {
325
+ return [ ] ;
326
+ }
327
+ // Here's where things get a little weird. When we rename folders in
328
+ // sas content, we _don't_ close those files. It doesn't matter since
329
+ // their path isn't hierarchical. In sas file system, the path is hierarchical,
330
+ // thus we need to re-open all the closed files. This does that by getting
331
+ // children and comparing the removedTabUris
332
+ const filteredChildItems = childItems
333
+ . map ( ( childItem ) => {
334
+ const matchingUri = removedTabUris . find ( ( uri ) =>
335
+ uri . path . endsWith ( childItem . name ) ,
336
+ ) ;
337
+ if ( ! matchingUri ) {
338
+ return ;
339
+ }
340
+
341
+ return [ matchingUri , childItem . vscUri ] ;
342
+ } )
343
+ . filter ( ( exists ) => exists ) ;
344
+
345
+ return filteredChildItems ;
305
346
}
306
347
}
307
348
@@ -697,10 +738,26 @@ class ContentDataProvider
697
738
698
739
export default ContentDataProvider ;
699
740
700
- const closeFileIfOpen = ( item : ContentItem ) => {
701
- const tab = getEditorTabForItem ( item ) ;
702
- if ( tab ) {
703
- return window . tabGroups . close ( tab ) ;
741
+ const closeFileIfOpen = ( item : ContentItem ) : Promise < Uri [ ] > | boolean => {
742
+ const tabs = getEditorTabsForItem ( item ) ;
743
+ if ( tabs . length > 0 ) {
744
+ return new Promise ( ( resolve , reject ) => {
745
+ Promise . all ( tabs . map ( ( tab ) => window . tabGroups . close ( tab ) ) )
746
+ . then ( ( ) =>
747
+ resolve (
748
+ tabs
749
+ . map (
750
+ ( tab ) =>
751
+ ( tab . input instanceof TabInputText ||
752
+ tab . input instanceof TabInputNotebook ) &&
753
+ tab . input . uri ,
754
+ )
755
+ . filter ( ( exists ) => exists ) ,
756
+ ) ,
757
+ )
758
+ . catch ( reject ) ;
759
+ } ) ;
704
760
}
761
+
705
762
return true ;
706
763
} ;
0 commit comments