如何在Monaco编辑器中插入文本?

21

我在我的应用程序中嵌入了一个 Monaco 代码编辑器。

我如何以编程方式在特定行插入文本?

var editor = monaco.editor.create(document.getElementById("container"), {
    value: "// First line\nfunction hello() {\n\talert('Hello world!');\n}\n// Last line",
    language: "javascript",

    lineNumbers: false,
    roundedSelection: false,
    scrollBeyondLastLine: false,
    readOnly: false,
    theme: "vs-dark",
});
// how do I do this?
editor.insertText("FOO");
5个回答

32

使用 Selection API 而不是 Position,可以得到更加健壮的解决方案。

var selection = editor.getSelection();
var id = { major: 1, minor: 1 };             
var text = "XXX";
var op = {identifier: id, range: selection, text: text, forceMoveMarkers: true};
editor.executeEdits("my-source", [op]);
如果编辑器中已有预先选定的文本,则插入将替换它,我认为这是正确的行为。

1
Selection 本身继承自 Range,因此无需重新创建。 - Eugene Pankov
仅当与用户操作直接相关时,才不是原帖要求的一部分,并且只有这样才是正确的。 - Chris Buck
为了更加健壮,应该使用getSelections(),因为monaco支持多行编辑/插入。 - Astor Bizard
在这个例子中,“my-source”到底是什么意思? - Ben
id和相关的identifer不是必需的;也可以使用var op = {range: selection, text: text, forceMoveMarkers: true};;请参阅https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.ICodeEditor.html#executeEdits - undefined

20

使用executeEdits API

var line = editor.getPosition();
var range = new monaco.Range(line.lineNumber, 1, line.lineNumber, 1);
var id = { major: 1, minor: 1 };             
var text = "FOO";
var op = {identifier: id, range: range, text: text, forceMoveMarkers: true};
editor.executeEdits("my-source", [op]);

3
想说一下,除了编辑器的executeEdits方法之外,模型还有一个名为pushEditOperations的方法。如果你有多个模型并且想更新不是编辑器当前模型的其中一个模型,这个方法非常有用。 - Benny Hinrichs

11

要在光标处插入文本,有一种非常简单的方法。 我经常使用它来创建片段工具栏:

editor.trigger('keyboard', 'type', {text: "test"});

如果选择了文本,它将替换该文本。

您也可以通过以下方式添加多行文本:

editor.trigger('keyboard', 'type', {text: `text on
multiple
line`});

1

我在使用React和TypeScript时遇到了一些问题,希望这篇文章能对其他人有所帮助。

import Editor, { Monaco, OnMount } from '@monaco-editor/react';
import { editor, languages } from 'monaco-editor';

...

const CustomEditor: React.FC = () => {

    const [monacoInstance, setMonacoInstance] = React.useState<editor.IStandaloneCodeEditor | null>(null);

    const insertText = (text: string) => {
        if (monacoInstance) {
            const selection = monacoInstance.getSelection();
            const id = { major: 1, minor: 1 };
            const op = {
                identifier: id,
                range: {
                    startLineNumber: selection?.selectionStartLineNumber || 1,
                    startColumn: selection?.selectionStartColumn || 1,
                    endLineNumber: selection?.endLineNumber || 1,
                    endColumn: selection?.endColumn || 1,
                },
                text,
                forceMoveMarkers: true,
            };
            monacoInstance.executeEdits('my-source', [op]);
        }
    };

    const editorMount: OnMount = (editorL: editor.IStandaloneCodeEditor) => {
        setMonacoInstance(editorL);
    };

...

        <Editor
            onMount={editorMount}

...

        <StyledButton // styled comp
            onClick={() => {insertText('inserted text');}}
        >
            insert text
        </StyledButton>

0
一个更自然的解决方案(如上所述)可以是使用 Monaco 自带的 executeEdits 方法,并使用具有行号和列号的特定范围,因为在示例中它们总是使用第一行。
const startLineNumber = 15 // Line number in which the content will start being typed
const startColumn = 5 // Column number in which the content will start being typed
const endLineNumber = 18 // Line number in which the text will finish
const endColumn = 25 
const text = "This is the new text" // The content going to be added


const range = new monaco.edito.Range(startLineNumber, startColumn, endLineNumber, endColumn); // It will go to the specific position of the editor

const id = { major: 1, minor: 1 }; // Required generic id

const editOperation = {identifier: id, range: range, text: text, forceMoveMarkers: true}; // The operation going to be performed

monaco.editor.executeEdits("custom-code", [ editOperation ]); // Runs the instruction


以上代码的好处是它可以添加、删除、更新和替换现有代码,因此它非常高效,最终用户会感觉自己在键入。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接