Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft Monaco Editor in browser get value of line

I have been working through using the browser based version of the Microsoft Monaco Editor, I can't find any documentation or any examples in the playground that tell you how to get the value of a specific line of in the editor.

For example:

class Example {
    private m:number;

    public met(): string {
        return "Hello world!";
    }
}

Line 2 would be private m:number;.

How would you get the value of that line or even part of the line and then change it's value using code. I want to put that action into a keyboard shortcut.

like image 276
Jesse Avatar asked Jul 30 '16 12:07

Jesse


People also ask

How do I get the selected text in Monaco editor?

getSelection(). toString(). This will get the selected text anywhere in the window, including the monaco control.

How do I use Monaco editor in Chrome?

Open editor using Right Click -> Edit with Monaco Editor or [CMD / CTRL] + Left Click on an editable element. The original content element will be continuously updated with changes from the Monaco editor. To close the editor either hit escape, or click the shadowbox around it.


2 Answers

Getting the content of a line is actually very easy: IModel.getLineContent()

line = model.getLineContent(3);

Note that the line numbers start with 1 when using getLineContent().

Replacing the text is a bit more complicated, but you could apply edit operations:

  • Through the editor: IStandaloneCodeEditor.executeEdits
  • Through the model: IModel.applyEdits() and IModel.pushEditOperations().

The applyEdits won't add the edits to the undo stack and is thus discouraged. However all three use the same interface for the actual changes: IIdentifiedSingleEditOperation so the actual calls won't be very different, so I'll just show it with pushEditOperations():

model.pushEditOperations(
    [],
    [
        {
            forceMoveMarkers: true,
            identifier: "mychange",
            range: {
                startLineNumber: lineNo,
                endLineNumber: lineNo,
                startColumn: 1,
                endColumn: line.length + 1,
            },
            text: "this will be the new text there"
        },
    ],
    []
);

If you want to test it out on the Monaco playground I used this code (adapted from the "Adding Actions" example):

var editor = monaco.editor.create(document.getElementById("container"), {
    value: [
        '',
        'class Example {',
        '\tprivate m:number;',
        '',
        '\tpublic met(): string {',
        '\t\treturn "Hello world!";',
        '\t}',
        '}'
    ].join('\n'),
    language: "typescript"
});
var model = editor.getModel();

editor.addAction({
    id: 'my-unique-id',
    label: 'Replace the second line',
    keybindings: [ monaco.KeyMod.CtrlCmd | monaco.KeyCode.F10 ],
    contextMenuGroupId: 'custom',
    contextMenuOrder: 1,
    run: function(ed) {
        var lineNo = 3;
        var line = model.getLineContent(lineNo);
        console.log("These were the contents of the second line before I replaced them:", line);
        model.pushEditOperations(
            [],
            [
                {
                    forceMoveMarkers: true,
                    identifier: "mychange",
                    range: {
                        startLineNumber: lineNo,
                        endLineNumber: lineNo,
                        startColumn: 1,
                        endColumn: line.length + 1,
                    },
                    text: "this will be the new text there"
                },
            ],
            []
        );
    }
});

In this case you can run the action by:

  • pressing Ctrl + F10
  • by right-clicking on the editor and selecting "Replace the second line" (at least if you haven't hidden the editors context menu).
like image 127
MSeifert Avatar answered Oct 19 '22 00:10

MSeifert


I think there is no such built-in feature in monaco as I do not found it. but i am doing that using following code:

editor.addAction({
        id: 'some_id',
        label: 'label',
        keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_C],
        run: function(ed) {
            var position = ed.getPosition();
            var text = ed.getValue(position);
            var splitedText=text.split("\n");
            var line = splitedText[position.lineNumber-1];

            // now you have current line
            // you can also get any other line
            // and do something with that line

            splitedText[position.lineNumber-1]= _newLineText_
            ed.setValue(splitedText.join("\n"));
            ed.setPosition(position); // to return the pointer to the a position before editing text

            return null;
        },
        enablement: {
            textFocus: true,
        }
    });

this method is good for small file but for large file the whole editor will re highlights and that a bad thing.

like image 1
Nauman Umer Avatar answered Oct 19 '22 00:10

Nauman Umer