Reputation: 884
I've been trying to figure out the best way to implement a "Save As" using the vscode extension API.
So far, here's the best I've got:
// First turn the path we were given into an absolute path
// Relative paths are interpreted as relative to the original file
const newFileAbsolutePath = path.isAbsolute(saveFileDetails.newPath) ?
saveFileDetails.newPath :
path.resolve(path.dirname(saveFileDetails.filePath), saveFileDetails.newPath);
// Create an "untitled-scheme" path so that VSCode will let us create a new file with a given path
const newFileUri = vscode.Uri.parse("untitled:" + newFileAbsolutePath);
// Now we need to copy the content of the current file,
// then create a new file at the given path, insert the content,
// save it and open the document
return vscode.workspace.openTextDocument(saveFileDetails.filePath)
.then((oldDoc) => {
return vscode.workspace.openTextDocument(newFileUri)
.then((newDoc) => {
return vscode.window.showTextDocument(newDoc, 1, false)
.then((editor) => {
return editor.edit((editBuilder) => {
editBuilder.insert(new vscode.Position(0, 0), oldDoc.getText());
})
.then(() => {
return newDoc.save()
.then(() => EditorOperationResponse.Completed);
});
});
});
});
We open the old doc, then open a new doc (which is an untitled document), then insert the old doc's text into the new doc and then save the new doc.
The new doc then closes (for some reason).
Anyone have any advice?
Upvotes: 1
Views: 1697
Reputation: 34158
It seems like this is a known issue and caused by the use of the untitled://
scheme:
TextDocument.save() closes untitled documents (#29156)
For now, you could work around it by just reopening the file again since you know the final URI (unlike in the case of the person who reported the issue).
newDoc.save().then((completed) => {
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
})
});
Unfortunatenly this does lead to a noticable "flicker"-effect. To avoid this, I'd suggest to simply bypass the VSCode API and use fs
for file IO, and only use vscode
for showing the file at the end. This also simplifies the code quite a bit:
import * as fs from 'fs';
function runCommand() {
// obtain newFileAbsolutePath / oldFileAbsolutePath
var oldDocText = fs.readFileSync(oldFileAbsolutePath);
fs.writeFileSync(newFileAbsolutePath, oldDocText);
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
});
}
Upvotes: 2