Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Don't mutated makedSpans arrays

And add marker changes to the undo history, so that
un/redoing doesn't cause 'ghost' markers to appear.

Closes #882
  • Loading branch information...
commit 8c7ca5eaab16b8358d6dc86688dfe648f663f7fc 1 parent bcc832b
@marijnh marijnh authored
Showing with 40 additions and 24 deletions.
  1. +29 −18 lib/codemirror.js
  2. +11 −6 test/test.js
View
47 lib/codemirror.js
@@ -1508,17 +1508,21 @@ window.CodeMirror = (function() {
function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; }
TextMarker.prototype.clear = operation(function() {
- var min = Infinity, max = -Infinity;
+ var min, max, seen = {};
for (var i = 0; i < this.lines.length; ++i) {
- var line = this.lines[i];
- var span = getMarkedSpanFor(line.markedSpans, this, true);
- if (span.from != null || span.to != null) {
- var lineN = lineNo(line);
- min = Math.min(min, lineN); max = Math.max(max, lineN);
- }
+ var line = this.lines[i], lineN = lineNo(line);
+ seen[lineN] = newHL(line.text, line.markedSpans);
+ var span = getMarkedSpanFor(line.markedSpans, this);
+ if (span.from != null) min = lineN;
+ if (span.to != null) max = lineN;
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
}
- if (min != Infinity)
+ if (min != null) {
changes.push({from: min, to: max + 1});
+ var old = [];
+ for (var i = min; i <= max; ++i) old.push(seen[i]);
+ history.addChange(min, old.length, old, true);
+ }
this.lines.length = 0;
});
TextMarker.prototype.find = function() {
@@ -1541,24 +1545,27 @@ window.CodeMirror = (function() {
var marker = new TextMarker("range", className);
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
marker[opt] = options[opt];
- var curLine = from.line;
+ var curLine = from.line, old = [];
doc.iter(curLine, to.line + 1, function(line) {
var span = {from: curLine == from.line ? from.ch : null,
to: curLine == to.line ? to.ch : null,
marker: marker};
- (line.markedSpans || (line.markedSpans = [])).push(span);
+ old.push(newHL(line.text, line.markedSpans));
+ line.markedSpans = (line.markedSpans || []).concat([span]);
marker.lines.push(line);
++curLine;
});
changes.push({from: from.line, to: to.line + 1});
+ history.addChange(from.line, old.length, old, true);
return marker;
}
function setBookmark(pos) {
pos = clipPos(pos);
var marker = new TextMarker("bookmark"), line = getLine(pos.line);
+ history.addChange(pos.line, 1, [newHL(line.text, line.markedSpans)], true);
var span = {from: pos.ch, to: pos.ch, marker: marker};
- (line.markedSpans || (line.markedSpans = [])).push(span);
+ line.markedSpans = (line.markedSpans || []).concat([span]);
marker.lines.push(line);
return marker;
}
@@ -2355,16 +2362,20 @@ window.CodeMirror = (function() {
this.from = from; this.to = to; this.marker = marker;
}
- function getMarkedSpanFor(spans, marker, del) {
+ function getMarkedSpanFor(spans, marker) {
if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
- if (span.marker == marker) {
- if (del) spans.splice(i, 1);
- return span;
- }
+ if (span.marker == marker) return span;
}
}
+ function removeMarkedSpan(spans, span) {
+ var r;
+ for (var i = 0; i < spans.lenght; ++i)
+ if (spans[i] == span) (r || (r = [])).push(spans[i]);
+ return r;
+ }
+
function markedSpansBefore(old, startCh, endCh) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
@@ -2873,12 +2884,12 @@ window.CodeMirror = (function() {
this.closed = false;
}
History.prototype = {
- addChange: function(start, added, old) {
+ addChange: function(start, added, old, minor) {
this.undone.length = 0;
var time = +new Date, cur = lst(this.done), last = cur && lst(cur);
var dtime = time - this.time;
- if (this.compound && cur && !this.closed) {
+ if (cur && !this.closed && (this.compound || minor)) {
cur.push({start: start, added: added, old: old});
} else if (dtime > 400 || !last || this.closed ||
last.start > start + old.length || last.start + last.added < start) {
View
17 test/test.js
@@ -287,16 +287,21 @@ testCM("markTextMultiLine", function(cm) {
});
testCM("markTextUndo", function(cm) {
- var marker1 = cm.markText({line: 0, ch: 1}, {line: 0, ch: 3}, "CodeMirror-matchingbracket");
- var marker2 = cm.markText({line: 0, ch: 0}, {line: 2, ch: 1}, "CodeMirror-matchingbracket");
- var bookmark = cm.setBookmark({line: 1, ch: 5});
- cm.replaceRange("foo", {line: 0, ch: 2});
- cm.replaceRange("bar\baz\bug\n", {line: 2, ch: 0}, {line: 3, ch: 0});
+ var marker1, marker2, bookmark;
+ cm.compoundChange(function(){
+ marker1 = cm.markText({line: 0, ch: 1}, {line: 0, ch: 3}, "CodeMirror-matchingbracket");
+ marker2 = cm.markText({line: 0, ch: 0}, {line: 2, ch: 1}, "CodeMirror-matchingbracket");
+ bookmark = cm.setBookmark({line: 1, ch: 5});
+ });
+ cm.compoundChange(function(){
+ cm.replaceRange("foo", {line: 0, ch: 2});
+ cm.replaceRange("bar\baz\bug\n", {line: 2, ch: 0}, {line: 3, ch: 0});
+ });
cm.setValue("");
eq(marker1.find(), null); eq(marker2.find(), null); eq(bookmark.find(), null);
cm.undo();
eqPos(bookmark.find(), {line: 1, ch: 5});
- cm.undo(); cm.undo();
+ cm.undo();
var m1Pos = marker1.find(), m2Pos = marker2.find();
eqPos(m1Pos.from, {line: 0, ch: 1}); eqPos(m1Pos.to, {line: 0, ch: 3});
eqPos(m2Pos.from, {line: 0, ch: 0}); eqPos(m2Pos.to, {line: 2, ch: 1});
Please sign in to comment.
Something went wrong with that request. Please try again.