Skip to content

Commit 70beb90

Browse files
authored
Implement isfs rename (#923)
1 parent 3fb6460 commit 70beb90

File tree

1 file changed

+67
-2
lines changed

1 file changed

+67
-2
lines changed

src/providers/FileSystemProvider/FileSystemProvider.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,73 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
382382
);
383383
}
384384

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);
387452
}
388453

389454
public watch(uri: vscode.Uri): vscode.Disposable {

0 commit comments

Comments
 (0)