代码镜像:获取更改文本

时间:2013-11-02 16:29:26

标签: javascript codemirror

使用Code Mirror,我需要将更改事件数据映射到包含以下内容的元组列表:

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

我目前正在监听change事件,可以处理输入更改,但必须为删除,选择移动和撤消操作编写特定的解决方案。

是否有更可靠的方法适用于标准事件?

修改

添加当前作品

多思考一下,我只关心文档中的第一个(就位置而言)变化。以下是我目前的工作:

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
};

这不正确。并非所有事件类型都得到处理,许多情况如行终止符也无法正确处理或不断处理。非常感谢另一种选择。

1 个答案:

答案 0 :(得分:1)

要在编辑之前获取文字,您可以使用beforeChange event。 比文本提取非常简单。 beforeChange也有很好的属性,因为每次更改都会触发它(与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);
});

如果您需要更改后的文本,则必须在更改后的坐标系中计算to。幸运的是,这很容易:

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

希望这有效,我没有时间正确测试它。