Programmatically invoke Organize Imports and save the file afterwards

Viewed 218

What I'm doing is basically:

async function doItAll(ownEdits: Array<TextEdit>) {
    const editor: TextEditor = await getEditor();
    applyOwnChanges(editor, ownEdits);
    await commands.executeCommand('editor.action.organizeImports',
        editor.document.uri.path);
    await editor.document.save();
}

It all works, but the save happens before organizeImports finishes and I end up with a dirty editor, when the imports get modified.

I tripple checked that I didn't forget the await keyword, yet it works like it wasn't there.

This may be a bug or I may be doing or expecting something wrong. Am I?

2 Answers

Indeed organizeImports command returns before it actually updated the document.

As workaround use onDidChangeTextDocument to intercept when organizeImports is finished and your doc is ready for save.

const handler = vscode.workspace.onDidChangeTextDocument(doc => {
  if (doc.document.uri.path === editor.document.uri.path) {
    doc.document.save()
    handler.dispose()
  }
})

executeCommand is Thenable . So, the save() method should be moved inside thenable.

vscode.commands.executeCommand('editor.action.organizeImports', editor.document.uri.path).then(function(){
        await editor.document.save();
});

If the save still happens before organizeImports finishes then try to call the save method inside setTimeout(function(){....}, T).

 vscode.commands.executeCommand('editor.action.organizeImports', editor.document.uri.path).then(function(){
       setTimeout(function(){
            await editor.document.save();
       }, 500);
});
Related