javascriptmonaco-editor

Set Replace Field programmatically in Find and Replace Action in Web Version of Monaco Editor


I’m working with the web version of the Monaco Editor and I’m trying to implement a find and replace functionality. I can successfully set the field of find text by creating a range selection, but I’m having trouble setting the replace text field.

Here’s what I have so far:

const value = `function hello() {
    alert('Hello world!');
}`;
const textToSearch = 'hello';
const textReplaceWith = 'world';

// Hover on each property to see its docs!
const myEditor = monaco.editor.create(document.getElementById("container"), {
    value,
    language: "javascript",
    automaticLayout: true,
});

const model = myEditor.getModel();
const range = model.findMatches(textToSearch)[0].range;
myEditor.setPosition({column: range.startColumn || 1, lineNumber: range.startLineNumber || 1});
myEditor.revealLine(range.startLineNumber || 1);
myEditor.setSelection(range);

// open find & replace panel
myEditor.getAction('editor.action.startFindReplaceAction').run()

I’ve looked through the Monaco Editor documentation and various forums but haven’t found a clear solution. Has anyone managed to set the replace text field in the find and replace action?

Any help or code examples would be greatly appreciated.


Solution

  • You could use the action editor.actions.findWithArgs instead of editor.action.startFindReplaceAction. This will allow you to pass arguments including the string you want to use to replace:

    myEditor.getAction('editor.actions.findWithArgs').run({replaceString: textReplaceWith})
    

    Here's a working demo.

    In theory you should be able to pass in the string you want to appear in the search field (as the searchString parameter) and not need to add the bit of code where you do the range selection, however I've not been able to get this to work unless the editor content is empty as it always selects the first word of the editor to put in the search field:

    const textToSearch = 'hello';
    const textReplaceWith = 'world';
    const myEditor = monaco.editor.create(document.getElementById("container"), {
        value,
        language: "javascript",
        automaticLayout: true,
    });
    
    /* Omit range selection code */
    // const model = myEditor.getModel();
    // const range = model.findMatches(textToSearch)[0].range;
    // myEditor.setPosition({column: range.startColumn || 1, lineNumber: range.startLineNumber || 1});
    // myEditor.revealLine(range.startLineNumber || 1);
    // myEditor.setSelection(range);
    
    // open find & replace panel
    myEditor.getAction('editor.actions.findWithArgs').run({
      searchString: textToSearch,
      replaceString: textReplaceWith
    })