5

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

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

谢谢!leX

4

4 回答 4

4

我花了一点时间来解决这个问题,所以如果它对任何人有帮助,这就是我截取粘贴并将每个选项卡替换为 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);
  }
});
于 2019-06-17T22:57:39.833 回答
3

CodeMirror 具有本机“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); */
    }
});

还有其他事件“剪切”、“复制”和“粘贴”(http://codemirror.net/doc/manual.html#events)所以这将起作用:

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

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

目前我正在做类似的事情 - 挂钩复制/粘贴事件并进行一些替换。我找到了一种以编程方式将文本复制到剪贴板的解决方案。这是 此处讨论的clipboard.js codemirror 是否提供剪切、复制和粘贴 API?. 最棒的是您可以以编程方式触发点击事件(当我使用 ZeroClipboard 和跨浏览器 flash shim 时,这是一个问题),它会起作用!

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();
});
于 2016-04-03T16:34:55.423 回答
2

我发现的唯一解决方案是拦截偶数使用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;
于 2018-02-27T02:17:19.283 回答
1

使用js-beautifypaste您可以在事件期间美化 editors 值,.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
    }
于 2019-08-15T20:19:44.037 回答