CodeMirror2: How to format insert content?

Is it possible to format the inserted content after an event such as "onPaste" in CodeMirror2? - I want to postpone the contents of the clipboard after pasting. I already know with JavaScript that it is not possible to access the buffer.

So, I think there is no way to create a context menu with cut / copy / paste functions? - Can I create my own JS buffer or is there an existing solution?

Thank! Lex

+5
source share
4 answers

CodeMirror has its own inputRead event, so you can do this:

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" "paste" (http://codemirror.net/doc/manual.html#events), :

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

Andavtage - , event.preventDefault(); .

- . . clipboard.js codemirror 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();
});
+3

, , inputRead, . , :

class CodeMirrorExt {
    // This function returns a callback to be used with codemirror 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;
+1

It took me a little time to figure this out, so if this helps anyone, here's how I intercept the inserts and replace each tab with two spaces:

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

Using js-beautify , you can decorate the value of the editor during an event pastewith the .CodeMirrorfollowing:

$(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 } ) );
});

Keep in mind that when inserting text into the editor, it listens for the first indent, so if your first line is indented, all other lines will be indented accordingly.

eg:

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

All Articles