2017-07-12 1 views
2

Pendant que je développais this VS Code extension, j'ai dû déplacer le curseur sur une ligne que j'ai créée avec la méthode vscode.window.activeTextEditor.edit, mais ensuite j'ai réalisé que la ligne n'existait pas lorsque j'ai essayé de déplacer le curseur, donc j'ai dû mettre un setTimeout pour essayer de déplacer le curseur:TextEditorEdit.replace est asynchrone, comment exécuter du code quand il est fini?

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

Comme je sais que ce n'est pas une bonne pratique, parce que je ne peux pas être sûr que la ligne sera là quand le code est exécuté, je suis en train de trouver un moyen pour exécuter ce code uniquement lorsque l'édition est terminée pour tout remplacer.

Répondre

2

Vous devez déplacer les opérations du curseur en dehors du bloc d'édition. Le rappel dans TextEditor.edit génère un ensemble de modifications qui sont ensuite appliquées de manière asynchrone. edit renvoie Thenable<boolean> pour indiquer si les modifications se sont terminées avec succès.

Essayez quelque chose comme:

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 
     ... 
    } 
}) 
+0

Merci! Cela a fonctionné comme je le voulais :) –