@@ -15,7 +15,7 @@ declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...a
1515export type Entry = File | Directory ;
1616
1717export class FileSystemProvider implements vscode . FileSystemProvider {
18- public root = new Directory ( "" , "" ) ;
18+ private superRoot = new Directory ( "" , "" ) ;
1919
2020 public readonly onDidChangeFile : vscode . Event < vscode . FileChangeEvent [ ] > ;
2121
@@ -86,9 +86,9 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
8686 )
8787 . map ( ( item : StudioOpenDialog ) => {
8888 const name = item . Name ;
89- const fullName = folder === "" ? name : csp ? folder + name : folder + "/" + name ;
9089 if ( item . Type === "10" || item . Type === "9" ) {
9190 if ( ! parent . entries . has ( name ) ) {
91+ const fullName = folder === "" ? name : csp ? folder + name : folder + "/" + name ;
9292 parent . entries . set ( name , new Directory ( name , fullName ) ) ;
9393 }
9494 return [ name , vscode . FileType . Directory ] ;
@@ -99,7 +99,15 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
9999 if ( ! csp ) {
100100 return results ;
101101 }
102- return results . concat ( cspSubfolders ) ;
102+ cspSubfolders . forEach ( ( value ) => {
103+ const name = value [ 0 ] ;
104+ if ( ! parent . entries . has ( name ) ) {
105+ const fullName = folder + name ;
106+ parent . entries . set ( name , new Directory ( name , fullName ) ) ;
107+ }
108+ results . push ( value ) ;
109+ } ) ;
110+ return results ;
103111 } )
104112 . catch ( ( error ) => {
105113 if ( error ) {
@@ -283,18 +291,30 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
283291 if ( fileName . startsWith ( "." ) ) {
284292 return ;
285293 }
294+ if ( ! fileName . includes ( "." ) ) {
295+ throw new Error ( `${ csp ? "Folder" : "Package" } deletion not implemented` ) ;
296+ }
286297 const api = new AtelierAPI ( uri ) ;
287298 return api . deleteDoc ( fileName ) . then (
288- ( response ) => {
299+ async ( response ) => {
289300 if ( response . result . ext ) {
290301 fireOtherStudioAction ( OtherStudioAction . DeletedDocument , uri , response . result . ext ) ;
291302 }
292- // Remove entry from our cache
293- this . _lookupParentDirectory ( uri ) . then ( ( parent ) => {
294- const name = path . basename ( uri . path ) ;
295- parent . entries . delete ( name ) ;
296- } ) ;
297- this . _fireSoon ( { type : vscode . FileChangeType . Deleted , uri } ) ;
303+ // Remove entry from our cache, plus any now-empty ancestor entries
304+ let thisUri = vscode . Uri . parse ( uri . toString ( ) , true ) ;
305+ const events : vscode . FileChangeEvent [ ] = [ ] ;
306+ while ( thisUri . path !== "/" ) {
307+ events . push ( { type : vscode . FileChangeType . Deleted , uri : thisUri } ) ;
308+ const parentDir = await this . _lookupParentDirectory ( thisUri ) ;
309+ const name = path . basename ( thisUri . path ) ;
310+ parentDir . entries . delete ( name ) ;
311+ if ( ! csp && parentDir . entries . size === 0 ) {
312+ thisUri = thisUri . with ( { path : path . posix . dirname ( thisUri . path ) } ) ;
313+ } else {
314+ break ;
315+ }
316+ }
317+ this . _fireSoon ( ...events ) ;
298318 } ,
299319 ( error ) => {
300320 if ( error . statusCode === 200 && error . errorText !== "" ) {
@@ -306,7 +326,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
306326 }
307327
308328 public rename ( oldUri : vscode . Uri , newUri : vscode . Uri , options : { overwrite : boolean } ) : void | Thenable < void > {
309- throw new Error ( "Not implemented" ) ;
329+ throw new Error ( "Move / rename is not implemented" ) ;
310330 return ;
311331 }
312332
@@ -318,17 +338,23 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
318338
319339 // Fetch entry (a file or directory) from cache, else from server
320340 private async _lookup ( uri : vscode . Uri ) : Promise < Entry > {
341+ const api = new AtelierAPI ( uri ) ;
321342 if ( uri . path === "/" ) {
322- const api = new AtelierAPI ( uri ) ;
323343 await api
324344 . serverInfo ( )
325345 . then ( )
326346 . catch ( ( ) => {
327347 throw vscode . FileSystemError . Unavailable ( `${ uri . toString ( ) } is unavailable` ) ;
328348 } ) ;
329349 }
350+ const config = api . config ;
351+ const rootName = `${ config . username } @${ config . host } :${ config . port } ${ config . pathPrefix } /${ config . ns . toUpperCase ( ) } ` ;
352+ let entry : Entry = this . superRoot . entries . get ( rootName ) ;
353+ if ( ! entry ) {
354+ entry = new Directory ( rootName , "" ) ;
355+ this . superRoot . entries . set ( rootName , entry ) ;
356+ }
330357 const parts = uri . path . split ( "/" ) ;
331- let entry : Entry = this . root ;
332358 for ( let i = 0 ; i < parts . length ; i ++ ) {
333359 const part = parts [ i ] ;
334360 if ( ! part ) {
@@ -339,10 +365,8 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
339365 child = entry . entries . get ( part ) ;
340366 // If the last element of path is dotted and is one we haven't already cached as a directory
341367 // then it is assumed to be a file.
342- if ( ( ! part . includes ( "." ) || i + 1 < parts . length ) && ! child ) {
343- const fullName = entry . name === "" ? part : entry . fullName + "/" + part ;
344- child = new Directory ( part , fullName ) ;
345- entry . entries . set ( part , child ) ;
368+ if ( ! child && ( ! part . includes ( "." ) || i + 1 < parts . length ) ) {
369+ throw vscode . FileSystemError . FileNotFound ( uri ) ;
346370 }
347371 }
348372 if ( ! child ) {
0 commit comments