Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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.