@@ -14,6 +14,8 @@ import {
1414 FileType ,
1515 Position ,
1616 ProviderResult ,
17+ TabInputNotebook ,
18+ TabInputText ,
1719 TextDocument ,
1820 TextDocumentContentProvider ,
1921 ThemeIcon ,
@@ -52,7 +54,7 @@ import {
5254 FileManipulationEvent ,
5355} from "./types" ;
5456import {
55- getEditorTabForItem ,
57+ getEditorTabsForItem ,
5658 getFileStatement ,
5759 isContainer as getIsContainer ,
5860} from "./utils" ;
@@ -285,23 +287,62 @@ class ContentDataProvider
285287 name : string ,
286288 ) : Promise < Uri | undefined > {
287289 const closing = closeFileIfOpen ( item ) ;
288- if ( ! ( await closing ) ) {
290+ const removedTabUris = await closing ;
291+ if ( ! removedTabUris ) {
289292 return ;
290293 }
291294
292295 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 ] ) =>
299314 this . _onDidManipulateFile . fire ( {
300315 type : "rename" ,
301- uri : item . vscUri ,
316+ uri,
302317 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 ;
305346 }
306347 }
307348
@@ -697,10 +738,26 @@ class ContentDataProvider
697738
698739export default ContentDataProvider ;
699740
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+ } ) ;
704760 }
761+
705762 return true ;
706763} ;
0 commit comments