CodeMirror2:如何格式化粘贴的内容?

时间:2012-05-21 14:09:15

标签: javascript codemirror

是否可以在CodeMirror2中的“onPaste”之类的事件之后格式化插入的内容? - 我想在粘贴后缩进剪贴板中的内容。我已经知道使用JavaScript,无法访问剪贴板。

所以我认为创建带剪切/复制/粘贴功能的上下文菜单也没有可能吗? - 我可以创建自己的JS剪贴板还是有现成的解决方案?

谢谢! LEX

4 个答案:

答案 0 :(得分:2)

CodeMirror具有native" inputRead"事件,所以你可以这样做:

editor.on('inputRead', function(cm, event) {
    /* event -> object{
         origin: string, can be '+input', '+move' or 'paste'
             doc for origins >> http://codemirror.net/doc/manual.html#selection_origin
         from: object {line, ch},
         to: object {line, ch},
         removed: array of removed strings
         text: array of pasted strings
    } */
    if (event.origin == 'paste') {
        console.log(event.text);
        var text = event.text[0]; // pasted string
        var new_text = '['+text+']'; // any operations here
        cm.refresh();
        // my first idea was
        // note: for multiline strings may need more complex calculations
        cm.replaceRange(new_text, event.from, {line: event.from.line, ch: event.from.ch + text.length});
        // first solution did'nt work (before i guess to call refresh) so i tried that way, works too
        /* cm.execCommand('undo');
        cm.setCursor(event.from);
        cm.replaceSelection(new_text); */
    }
});

还有其他活动" cut"," copy"并且"粘贴" (http://codemirror.net/doc/manual.html#events)所以这将有效:

editor.on('paste', function(cm, event) { ... } );

Andavtage是你可以通过调用event.preventDefault()来取消事件;但是检索粘贴的文本是个问题。

目前我正在处理类似的事情 - 挂钩复制/粘贴事件并进行一些替换。我找到了以编程方式将文本复制到剪贴板的解决方案。这是clipboard.js 这里讨论Does codemirror provide Cut, Copy and Paste API?。最棒的是你可以通过编程方式触发点击事件(当我使用带有跨浏览器闪存垫片的ZeroClipboard时出现问题)它会起作用!

new Clipboard('.btn-copy', {
    text: function(trigger) {
        var text = editor.getValue(); // or editor.getSelection();
        return text.replace(/\s+/g,' ');
    }
});

editor.on('copy', function(cm, event) {
    $('.btn-copy').click();
    event.preventDefault();
});

答案 1 :(得分:1)

使用js-beautify可以在paste上的.CodeMirror事件期间美化编辑器的值,如下所示:

$(document).on('paste', '.CodeMirror', function(e) {
    var content = $(this).closest('.content');
    var editor = content[0].editor;

    // beautify the code
    editor.setValue( js_beautify( editor.getValue(), { indent_size: 2 } ) );
});

请注意,在将文本插入编辑器时,它会侦听第一个缩进,因此,如果第一行缩进,则所有其他行也会相应缩进。

例如:

    function something() { // if the start is indented like so,
        var blah = something; // next lines will follow
    }

答案 2 :(得分:0)

我找到的唯一解决方案是使用inputRead截取偶数,然后手动更改粘贴的内容。我做了一个你可以重用的通用功能:

class CodeMirrorExt {
    // This function returns a callback to be used with codemirror's inputRead event.
    // The intent is to intercept a pasted text, transform the pasted contents (each line) with the function
    // you provide, and then have that transformed content be what ends up in the editor.
    //
    // Usage example that cuts each pasted line to 10 chars:
    //
    // this.codemirror.on("inputRead", CodeMirrorExt.replaceTextOnPasteFunc((line) => {
    //     return line.slice(0, 10);
    // }));

    static replaceTextOnPasteFunc(transformFunc) {
        return ((doc, event) => {
            if (event.origin !== "paste") {
                return;
            }

            const firstText = event.text[0];
            const lineNum = event.from.line;
            const chNum = event.from.ch;

            const newTexts = event.text.map(transformFunc);

            newTexts.forEach((text, i) => {
                if (i == 0) {
                    doc.replaceRange(text, {line: lineNum, ch: chNum}, {line: lineNum, ch: chNum + firstText.length});
                }
                else {
                    doc.replaceRange(text, {line: lineNum + i, ch: 0}, {line: lineNum + i, ch: event.text[i].length});
                }
            })
        });
    }
}

export default CodeMirrorExt;

答案 3 :(得分:0)

花点时间解决这个问题,以防万一,这是我拦截粘贴并将每个选项卡替换为2个空格的方法:

editor.on("beforeChange", (cm, change) => {
  if(change.origin === "paste") {
    const newText = change.text.map(line => line.replace(/\t/g, "  "));
    change.update(null, null, newText);
  }
});