TextEditorEdit.replace是异步的,如何在代码完成时执行代码?

时间:2017-07-12 00:44:13

标签: visual-studio-code vscode-extensions

当我开发this VS Code extension时,我不得不将光标移动到我使用vscode.window.activeTextEditor.edit方法创建的一行,但后来当我尝试移动时,我意识到该行不存在游标,所以我不得不放一个setTimeout来尝试移动光标:

let editor: TextEditor = vscode.window.activeTextEditor;
let selections: Selection[] = editor.selections;
let doc: TextDocument = editor.document;

editor.edit(function (edit: TextEditorEdit): void {
    selections.forEach((selection: Selection, index: number) => {
        for (let i = selection.start.line; i <= selection.end.line; i++) {
            let selLine: TextLine = doc.lineAt(i);
            let insertPos: Range = selLine.range;
            let insertLineText: string = selLine.text;

            // This is async :(
            edit.replace(insertPos, insertSemicolon(insertLineText, newLine));
        }
    });

    if (newLine) {
        // Move cursor to the next line
        setTimeout(() => {
            vscode.commands.executeCommand("cursorMove", {
                to: "down",
                by: "wrappedLine",
                select: false,
                value: 1
            }).then(() => {
                vscode.commands.executeCommand("cursorMove", {
                    to: "wrappedLineEnd",
                    by: "wrappedLine",
                    select: false
                })
            });
        }, 50);
    }
});

我知道这不是一个好习惯,因为我无法确定代码执行时该行是否存在,我只是想在编辑完成时找到执行此代码的方法替换一切。

1 个答案:

答案 0 :(得分:3)

您需要将光标操作移到编辑块之外。 TextEditor.edit中的回调构建了一组编辑,然后以异步方式应用。 edit会返回Thenable<boolean>以指示修改是否成功完成。

尝试类似:

let editor: TextEditor = vscode.window.activeTextEditor;
let selections: Selection[] = editor.selections;
let doc: TextDocument = editor.document;

editor.edit(function (edit: TextEditorEdit): void {
    selections.forEach((selection: Selection, index: number) => {
        for (let i = selection.start.line; i <= selection.end.line; i++) {
            let selLine: TextLine = doc.lineAt(i);
            let insertPos: Range = selLine.range;
            let insertLineText: string = selLine.text;

            edit.replace(insertPos, insertSemicolon(insertLineText, newLine));
        }
    });
}).then(success => {
    if (!success) {
        return
    }
     if (newLine) {
        // Move cursor to the next line
        ...
    }
})