VSCode扩展名-如何更改文件的文本

时间:2018-12-02 23:45:24

标签: visual-studio-code vscode-extensions

我有一个扩展名,可以捕获打开文件的文本并对其进行更改。更改文字后,如何将其放回VSCode中显示的文件中?

    // this method is called when your extension is activated
    // your extension is activated the very first time the command is executed
    export function activate(context: vscode.ExtensionContext) {

        // Use the console to output diagnostic information (console.log) and errors (console.error)
        // This line of code will only be executed once when your extension is activated
        console.log('Congratulations, your extension "myExtension" is now active!');
        console.log(process.versions);

        // The command has been defined in the package.json file
        // Now provide the implementation of the command with  registerCommand
        // The commandId parameter must match the command field in package.json
        let disposable = vscode.commands.registerCommand('extension.myExtension', () => {
            // The code you place here will be executed every time your command is executed

            let activeEditor = vscode.window.activeTextEditor;
            if (!activeEditor) {
                return;
            }
            let text = activeEditor.document.getText();

            getAsyncApi(text).then( (textToInsertIntoDoc) => {

                let finaldoc = insertTextIntoDoc(text, textToInsertIntoDoc);

                // not what I want - just used to see new text
                vscode.window.showInformationMessage(textToInsertIntoDoc);
            });

        });

        context.subscriptions.push(disposable);
    }

4 个答案:

答案 0 :(得分:2)

您可以在此处使用的API为TextEditor.edit,其定义为

edit(callback: (editBuilder: TextEditorEdit) => void, options?: {   undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;

它要求将回调作为第一个参数,并且在回调中,您可以通过访问editBuilder对文档进行编辑。

我在https://github.com/Microsoft/vscode-extension-samples/tree/master/document-editing-sample中放了一个示例扩展名,它可以颠倒当前选择中的内容,这基本上是一个简单的用法TextEditor.edit

答案 1 :(得分:1)

由于我在上述答案中提到的问题,我最终编写了一个快速的函数,该函数可以进行多光标友好的插入,并且如果选择为空,则它不会保留随后选择的插入文本(即具有与您按下 CTRL + V 或在键盘上键入文本等相同的直观行为。

调用很简单:

// x is the cursor index, it can be safely ignored if you don't need it.
InsertText(x => 'Hello World'); 

实施:

function InsertText(getText: (i:number) => string, i: number = 0, wasEmpty: boolean = false) {

    let activeEditor = vscode.window.activeTextEditor;
    if (!activeEditor) { return; }

    let sels = activeEditor.selections;

    if (i > 0 && wasEmpty)
    {
        sels[i - 1] = new vscode.Selection(sels[i - 1].end, sels[i - 1].end);
        activeEditor.selections = sels; // required or the selection updates will be ignored! ?
    }

    if (i < 0 || i >= sels.length) { return; }

    let isEmpty = sels[i].isEmpty;
    activeEditor.edit(edit => edit.replace(sels[i], getText(i))).then(x => {

        InsertText(getText, i + 1, isEmpty);
    });
}

答案 2 :(得分:1)

这是Rebornix扩展示例(包含在Microsoft扩展示例集合中)的主要功能的修订版,该功能处理您提出的选择问题。它会反转选择内容(保留选择内容),或者如果选择为空,则会在该选择下的光标下方反转单词,而不会保留任何选择内容。离开选择通常很有意义,但是您可以添加代码以删除选择。

    let disposable = vscode.commands.registerCommand('extension.reverseWord', function () {
        // Get the active text editor
        const editor = vscode.window.activeTextEditor;

        if (editor) {
            const document = editor.document;
            editor.edit(editBuilder => {
                editor.selections.forEach(sel => {
                    const range = sel.isEmpty ? document.getWordRangeAtPosition(sel.start) || sel : sel;
                    let word = document.getText(range);
                    let reversed = word.split('').reverse().join('');
                    editBuilder.replace(range, reversed);
                })
            }) // apply the (accumulated) replacement(s) (if multiple cursors/selections)
        }
    });

尽管我可以通过将.selection设置为似乎不适用于.selections[i]的新的空选择来删除单个选择。但是您可以进行多个更改,而无需首先进行选择。

您不想做的是通过代码进行选择,只是通过代码来更改文本。用户做出选择,而您没有做出选择(除非该功能的最终目的是做出选择)。

我遇到这个问题,是在寻找一种应用textEdit[]数组的方法(通常由provideDocumentRangeFormattingEdits回调函数返回)。如果您在数组中构建更改,则可以使用自己的函数将其应用于文档:

        const { activeTextEditor } = vscode.window;

        if (activeTextEditor) {
            const { document } = activeTextEditor;
            if (document) {
                /*
                  build your textEdits similarly to the above with insert, delete, replace 
                  but not within an editBuilder arrow function
                const textEdits: vscode.TextEdit[] = [];
                textEdits.push(vscode.TextEdit.replace(...));
                textEdits.push(vscode.TextEdit.insert(...));
                */

                const workEdits = new vscode.WorkspaceEdit();
                workEdits.set(document.uri, textEdits); // give the edits
                vscode.workspace.applyEdit(workEdits); // apply the edits
            }
        }

所以这是将编辑应用于文档的另一种方法。即使我使editBuilder示例在不选择文本的情况下也可以正常工作,但在其他情况下,我还是遇到了选择问题。 WorkspaceEdit不会选择更改。

答案 3 :(得分:1)

以下代码段将解决您的问题:

short