@@ -15,7 +15,7 @@ declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...a
15
15
export type Entry = File | Directory ;
16
16
17
17
export class FileSystemProvider implements vscode . FileSystemProvider {
18
- public root = new Directory ( "" , "" ) ;
18
+ private superRoot = new Directory ( "" , "" ) ;
19
19
20
20
public readonly onDidChangeFile : vscode . Event < vscode . FileChangeEvent [ ] > ;
21
21
@@ -86,9 +86,9 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
86
86
)
87
87
. map ( ( item : StudioOpenDialog ) => {
88
88
const name = item . Name ;
89
- const fullName = folder === "" ? name : csp ? folder + name : folder + "/" + name ;
90
89
if ( item . Type === "10" || item . Type === "9" ) {
91
90
if ( ! parent . entries . has ( name ) ) {
91
+ const fullName = folder === "" ? name : csp ? folder + name : folder + "/" + name ;
92
92
parent . entries . set ( name , new Directory ( name , fullName ) ) ;
93
93
}
94
94
return [ name , vscode . FileType . Directory ] ;
@@ -99,7 +99,15 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
99
99
if ( ! csp ) {
100
100
return results ;
101
101
}
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 ;
103
111
} )
104
112
. catch ( ( error ) => {
105
113
if ( error ) {
@@ -283,18 +291,30 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
283
291
if ( fileName . startsWith ( "." ) ) {
284
292
return ;
285
293
}
294
+ if ( ! fileName . includes ( "." ) ) {
295
+ throw new Error ( `${ csp ? "Folder" : "Package" } deletion not implemented` ) ;
296
+ }
286
297
const api = new AtelierAPI ( uri ) ;
287
298
return api . deleteDoc ( fileName ) . then (
288
- ( response ) => {
299
+ async ( response ) => {
289
300
if ( response . result . ext ) {
290
301
fireOtherStudioAction ( OtherStudioAction . DeletedDocument , uri , response . result . ext ) ;
291
302
}
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 ) ;
298
318
} ,
299
319
( error ) => {
300
320
if ( error . statusCode === 200 && error . errorText !== "" ) {
@@ -306,7 +326,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
306
326
}
307
327
308
328
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" ) ;
310
330
return ;
311
331
}
312
332
@@ -318,17 +338,23 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
318
338
319
339
// Fetch entry (a file or directory) from cache, else from server
320
340
private async _lookup ( uri : vscode . Uri ) : Promise < Entry > {
341
+ const api = new AtelierAPI ( uri ) ;
321
342
if ( uri . path === "/" ) {
322
- const api = new AtelierAPI ( uri ) ;
323
343
await api
324
344
. serverInfo ( )
325
345
. then ( )
326
346
. catch ( ( ) => {
327
347
throw vscode . FileSystemError . Unavailable ( `${ uri . toString ( ) } is unavailable` ) ;
328
348
} ) ;
329
349
}
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
+ }
330
357
const parts = uri . path . split ( "/" ) ;
331
- let entry : Entry = this . root ;
332
358
for ( let i = 0 ; i < parts . length ; i ++ ) {
333
359
const part = parts [ i ] ;
334
360
if ( ! part ) {
@@ -339,10 +365,8 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
339
365
child = entry . entries . get ( part ) ;
340
366
// If the last element of path is dotted and is one we haven't already cached as a directory
341
367
// 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 ) ;
346
370
}
347
371
}
348
372
if ( ! child ) {
0 commit comments