1

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

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

这是不正确的。并非所有事件类型都得到处理,并且许多情况(如行终止符)也没有正确或持续处理。一个替代方案将不胜感激。

4

1 回答 1

4

要在编辑前获取文本,您可以使用beforeChangeevent。比文本获取非常简单。 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);
});

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

于 2013-11-10T19:36:01.957 回答