Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

405
Views
VSCode API: Editor.edit editbuilder.replace fails without reason (possibly due to formatting?)

In my extension I want to edit the document on a few specific document edits.

My actual use case is a bit complicated so I have created a minimal example. The code below listens for any document edit. If the word "hello" exists in the edit (i.e. the user pasted some code that contains the word "hello") then we replace the change range with the pasted text but just make it upper case.

We also console.log if the edit was successful, and any potential reason the edit was rejected.

vscode.workspace.onDidChangeTextDocument(event => {
    for (const change of event.contentChanges) {
        if (change.text.includes("hello")) {
            activeEditor.edit(editBuilder => {
                editBuilder.replace(change.range, change.text.toUpperCase());
            }).then(
                value => console.log("SUCCESS: "+value),
                reason => console.log("FAIL REASON: "+reason),
            );
        }
    }
});

A working example would be selecting some text in a document and pasting in the text const hello = 5;. As expected, the extension replaces the text with CONST HELLO = 5; and logs SUCCESS: true.

But when I paste in some text that automatically get formatted I run into problems. If I were to paste in:

    const hello = 5;
    const lol = 10;
    const lmao = 20;

Including all the whitespaces/tabs, then vscode wants to "format" or correct my lines, i.e. remove the whitespace. So the resulting text will be:

const hello = 5;
const lol = 10;
const lmao = 20;

The extension tries to make it uppercase still but only prints SUCCESS: false. No reason is logged at all; the reject function is not executed.

Why does the edit not succeed? Should I await the other edits somehow or keep re-trying the edit until it succeeds? Am I logging the rejection incorrectly?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

One solution is just to "keep trying again". I do not like this solution, but it is a solution nevertheless, and it currently works for my use-case.

    async function makeReplaceEdit(range: vscode.Range, text: string, maxRetries = 10) {
        for (let i = 0; i <= maxRetries; i++) {
            const editor = vscode.window.activeTextEditor;
            if (!editor) return;

            const success = await editor.edit(editBuilder => {
                editBuilder.replace(
                    range,
                    text
                );
            }, { undoStopBefore: false, undoStopAfter: false });

            if (success) break;
        }
    };

    vscode.workspace.onDidChangeTextDocument((event) => {

        // See if any change contained "hello"        
        let foundHello = false;
        for (const change of event.contentChanges) {
            if (change.text.includes("hello")) {
                foundHello = true;
            }
        }

        if (foundHello) {
            console.log("inside1");
            const editor = vscode.window.activeTextEditor;
            if (!editor) return;
            makeReplaceEdit(editor.document.lineAt(0).range, "Change");
        }
    });
about 4 years ago · Juan Pablo Isaza Report

0

In case it helps, here is code I use - I found it better to have the editBuilder outside the loop. I think you can adapt it for your purposes:

    editor.edit( (editBuilder) => {

      // put your for (const change of event.contentChanges) {} here

      for (const match of matches) {
        resolvedReplace = variables.buildReplace(args, "replace", match, editor.selection, null, index);

        const matchStartPos = document.positionAt(match.index);
        const matchEndPos = document.positionAt(match.index + match[0].length);
        const matchRange = new vscode.Range(matchStartPos, matchEndPos);

        editBuilder.replace(matchRange, resolvedReplace);
      }
    }).then(success => {
        if (!success) {
            return;
        }
        if (success) {  ... do something here if you need to }
    });

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!