Code Mirror: Get Text Around Changes

こ雲淡風輕ζ 提交于 2019-12-11 09:45:01

问题


Using Code Mirror, I need to map change event data to a list of tuples containing:

(Text before change, Change text, Text after change)

I am currently listening on the change event and can handle input changes, but have to code specific solutions for deletions, selection movements, and undos.

Is there a more reliable approach that works with the standard events?

Edit

Adding current work.

Thinking a bit more, I only care about the first (in terms of position) change in a document. Here is what I currently do:

var docStart = {'line': 0, 'ch': 0},
    docEnd = {'line': Infinity, 'ch': Infinity};

// Just assume that we always have a single change and it is first
// for this example.
cm.on('change', function(cm, change) {        
    var start, end, text; switch (change.origin) {
    case '+delete':
        start = change.from;
        end = change.from;
        text = '';
        break;
    case 'undo':
        start = change.from;
        end = change.from;
        text = change.text.join('\n');
        break;
    case 'redo':
        start = change.from;
        end = {'line': change.to.line, 'ch': change.to.ch + 1};
        text = '';
        break;
    default:
        start = change.from;
        end = {'line': change.to.line, 'ch': change.to.ch + 1};
        text = change.text.join('\n');
        break;
    }

    var pre = cm.doc.getRange(docStart, start);
    var post = cm.doc.getRange(end, docEnd);

    [pre, text, post]; // output
};

This is not correct. Not all event types are handled and many cases like line terminators also are not handled correctly or constantly. An alternative would be greatly appreciated.


回答1:


To get text's before edit, you could use beforeChange event. Than the text fetching is pretty straightforward. beforeChange also has nice property, as it's fired for each change (no chaining as with change).

cm.on("beforeChange", function (cm, change) {
  var before = cm.getRange({ line: 0, ch: 0 }, change.from);
  var text = cm.getRange(change.from, change.to);
  var after = cm.getRange(change.to, { line: cm.lineCount() + 1, ch: 0 });
  console.log("before change", before, text, after);
});

If you need the text after change, than you have to calculate to in post-change coordinate system. Luckily it's quite easy still:

cm.on("change", function (cm, change) {
  var from = change.from;
  var text = change.text.join("\n");
  var removed = change.removed.join("\n");
  var to =  cm.posFromIndex(cm.indexFromPos(from) + text.length);

  var before = cm.getRange({ line: 0, ch: 0 }, from);
  var after = cm.getRange(to, { line: cm.lineCount() + 1, ch: 0 });

  console.log("after change", before, removed, text, after);
});

Hopes this works, I hadn't time to test it properly.



来源:https://stackoverflow.com/questions/19744118/code-mirror-get-text-around-changes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!