VSCode extension - how to alter file's text

后端 未结 4 1654
天涯浪人
天涯浪人 2021-02-20 12:56

I have an extension that grabs the open file\'s text and alters it. Once the text is altered, how do I put it back into the file that is displayed in VSCode?



        
4条回答
  •  我寻月下人不归
    2021-02-20 13:30

    This is a revision of the main function in Rebornix's extension sample (included with the set of Microsoft extension samples) that handles the selection issues you raised. It reverses the content of the selection(s) (leaving the selections) or if a selection is empty it will reverse the word under the cursor at that selection without leaving anything selected. It often makes sense to leave a selection, but you can add code to remove selection.

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

    Admittedly, while I could remove a single selection by setting .selection to a new empty selection that doesn't seem to work with .selections[i]. But you can make multiple changes without having selections in the first place.

    What you don't want to do is make a selection through code just to alter text through code. Users make selections, you don't (unless the end purpose of the function is to make a selection).

    I came to this question looking for a way to apply a textEdit[] array (which is normally returned by a provideDocumentRangeFormattingEdits callback function). If you build changes in the array you can apply them to your document in your own function:

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

    So that's another way to apply edits to a document. Even though I got the editBuilder sample to work correctly without selecting text, I have had problems with selections in other cases. WorkspaceEdit doesn't select the changes.

提交回复
热议问题