Final iteration of wrapMode + folding: Addind unit tests, fixing bugs.

This commit is contained in:
Julian Viereck 2011-04-28 15:53:50 +02:00
commit 825cf26478
6 changed files with 129 additions and 53 deletions

View file

@ -150,13 +150,13 @@ exports.launch = function(env) {
// BEGING TESTING
var Range = require("ace/range").Range;
docs.js.addFold(new Range(0, 13, 0, 18), "args...");
docs.js.addFold(new Range(2, 20, 2, 25), "bar...");
docs.js.addFold(new Range(1, 10, 2, 10), "foo...");
docs.js.addFold("args...", new Range(0, 13, 0, 18));
docs.js.addFold("bar...", new Range(2, 20, 2, 25));
docs.js.addFold("foo...", new Range(1, 10, 2, 10));
docs.svg.addFold(new Range(1, 0, 7, 0), "fold...");
docs.svg.addFold("fold...", new Range(1, 0, 7, 0));
docs.plain.addFold(new Range(0, 90, 2, 30), "fold");
docs.plain.addFold("fold", new Range(0, 90, 2, 30));
window.s = docs.plain;
window.e = env.editor;
setTimeout(function() {
@ -481,7 +481,7 @@ exports.launch = function(env) {
range = env.editor.selection.getRange(),
placeHolder = session.getTextRange(range).substring(0, 3) + "...";
session.addFold(range, placeHolder);
session.addFold(placeHolder, range);
}
});

View file

@ -1006,6 +1006,7 @@ var EditSession = function(text, mode) {
var foldLine;
var row = firstRow;
lastRow = Math.min(lastRow, lines.length - 1);
while (row <= lastRow) {
foldLine = this.getFoldLine(row);
if (!foldLine) {
@ -1030,8 +1031,14 @@ var EditSession = function(text, mode) {
tokens = tokens.concat(walkTokens);
}.bind(this),
foldLine.end.row,
lines[foldLine.end.row].length
lines[foldLine.end.row].length + 1
);
// Remove spaces/tabs from the back of the token array.
while (tokens.length != 0
&& tokens[tokens.length - 1] >= SPACE)
{
tokens.pop();
}
}
wrapData[row] =
this.$computeWrapSplits(tokens, wrapLimit, tabSize);
@ -1096,24 +1103,9 @@ var EditSession = function(text, mode) {
}
// === ELSE ===
// Search for the first non space/tab token backwards.
for (split; split != lastSplit - 1; split--) {
if (tokens[split] >= SPACE) {
split++;
break;
}
}
// If we found one, then add the split.
if (split > lastSplit) {
addSplit(split);
continue;
}
// === ELSE ===
split = lastSplit + wrapLimit;
// No space or tab around? Well, force a split then.
// Check if the split position is inside of a placeholder.
// Placeholder are not splitable!
// Check if split is inside of a placeholder. Placeholder are
// not splitable. Therefore, seek the beginning of the placeholder
// and try to place the split beofre the placeholder's start.
if (tokens[split] == PLACEHOLDER_START
|| tokens[split] == PLACEHOLDER_BODY)
{
@ -1140,8 +1132,7 @@ var EditSession = function(text, mode) {
// placeholder. So, let's seek for the end of the placeholder.
split = lastSplit + wrapLimit;
for (split; split < tokens.length; split++) {
if (tokens[split] != PLACEHOLDER_START &&
tokens[split] != PLACEHOLDER_BODY)
if (tokens[split] != PLACEHOLDER_BODY)
{
break;
}
@ -1159,8 +1150,23 @@ var EditSession = function(text, mode) {
}
// === ELSE ===
// The split is inside of a CHAR or CHAR_EXT token. Forcing
// a split here is all right.
// Search for the first non space/tab/placeholder token backwards.
for (split; split != lastSplit - 1; split--) {
if (tokens[split] >= PLACEHOLDER_START) {
split++;
break;
}
}
// If we found one, then add the split.
if (split > lastSplit) {
addSplit(split);
continue;
}
// === ELSE ===
split = lastSplit + wrapLimit;
// The split is inside of a CHAR or CHAR_EXT token and no space
// around -> force a split.
addSplit(lastSplit + wrapLimit);
}
return splits;

View file

@ -123,22 +123,19 @@ function FoldLine(foldData, folds) {
for (var i = 0; i < folds.length; i++) {
fold = folds[i];
comp = fold.range.compareEnd(endRow, endColumn);
comp = fold.range.compareStart(endRow, endColumn);
// This fold is after the endRow/Column.
if (comp == -1) {
callback(null, endRow, endColumn, lastEnd, isNewRow);
return;
}
// The endRow/Column is inside of the current fold.
else if (comp == 0) {
callback(null, endRow, fold.start.column, lastEnd, isNewRow);
return;
}
stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
stop = stop || callback(fold.placeholder, null, null, lastEnd);
stop = !stop && callback(fold.placeholder, null, null, lastEnd);
if (stop) {
// If the user requested to stop the walk or endRow/endColumn is
// inside of this fold (comp == 0), then end here.
if (stop || comp == 0) {
return;
}

View file

@ -38,6 +38,7 @@
define(function(require, exports, module) {
var Range = require("ace/range").Range;
var FoldLine = require("ace/edit_session/fold_line").FoldLine;
/**
@ -212,11 +213,19 @@ function Folding() {
/**
* Adds a new fold.
*/
this.addFold = function(range, placeholder) {
var startRow = range.start.row,
endRow = range.end.row,
foldData = this.$foldData,
foldRow = null;
this.addFold = function(placeholder, startRow, startColumn, endRow, endColumn) {
var range;
// Normalize parameters.
if (!(startRow instanceof Range)) {
range = new Range(startRow, startColumn, endRow, endColumn);
} else {
range = startRow;
startRow = range.start.row;
endRow = range.end.row;
}
var foldData = this.$foldData;
var foldRow = null;
var foldLine;
var fold = new Fold(range, placeholder);

View file

@ -61,9 +61,9 @@ function createFoldTestSession() {
];
var session = new EditSession(lines.join("\n"));
session.setUndoManager(new UndoManager());
session.addFold(new Range(0, 13, 0, 18), "args...");
session.addFold(new Range(1, 10, 2, 10), "foo...");
session.addFold(new Range(2, 20, 2, 25), "bar...");
session.addFold("args...", new Range(0, 13, 0, 18));
session.addFold("foo...", new Range(1, 10, 2, 10));
session.addFold("bar...", new Range(2, 20, 2, 25));
return session;
}
@ -697,7 +697,7 @@ module.exports = {
function assertArray(a, b) {
assert.ok(a.length == b.length);
for (var i = 0; i < a.length; i++) {
assert.ok(a[i] == b[i]);
assert.equal(a[i], b[i]);
}
}
@ -707,6 +707,11 @@ module.exports = {
line2 && assertArray(wrapData[2], line2);
}
function removeFoldAssertWrap(docRow, docColumn, line0, line1, line2) {
session.removeFold(session.getFoldAt(docRow, docColumn));
assertWrap(line0, line1, line2);
}
var lines = [
"foo bar foo bar",
"foo bar foo bar",
@ -714,19 +719,78 @@ module.exports = {
];
var session = new EditSession(lines.join("\n"));
var wrapData = session.$wrapData;
session.setUseWrapMode(true);
session.$wrapLimit = 7;
session.$updateWrapData(0, 2);
var wrapData = session.$wrapData;
assertWrap([7], [7], [7]);
session.addFold(new Range(0, 13, 0, 18), "args...");
// Do a simple assertion without folds to check basic functionallity.
assertWrap([8], [8], [8]);
// --- Do in line folding ---
// Adding a fold. The split position is inside of the fold. As placeholder
// are not splitable, the split should be before the split.
session.addFold("woot", 0, 4, 0, 16);
assertWrap([4], [8], [8]);
// Remove the fold again which should reset the wrapData.
removeFoldAssertWrap(0, 4, [8], [8], [8]);
session.addFold("woot", 0, 6, 0, 9);
assertWrap([6, 13], [8], [8]);
removeFoldAssertWrap(0, 6, [8], [8], [8]);
// The fold fits into the wrap limit - no split expected.
session.addFold("woot", 0, 3, 0, 16);
assertWrap([], [8], [8]);
removeFoldAssertWrap(0, 4, [8], [8], [8]);
// Fold after split position should be all fine.
session.addFold("woot", 0, 8, 0, 16);
assertWrap([8], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
// Fold's placeholder is far too long for wrapSplit.
session.addFold("woot0123456789", 0, 8, 0, 16);
assertWrap([8], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
// Fold's placeholder is far too long for wrapSplit
// + content at the end of the line
session.addFold("woot0123456789", 0, 7, 0, 8);
assertWrap([7, 21], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot0123456789", 0, 7, 0, 8);
session.addFold("woot0123456789", 0, 8, 0, 9);
assertWrap([7, 21, 35], [8], [8]);
session.removeFold(session.getFoldAt(0, 7));
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot0123456789", 0, 7, 0, 8);
session.addFold("woot0123456789", 0, 14, 0, 16);
assertWrap([7, 21, 27], [8], [8]);
session.removeFold(session.getFoldAt(0, 7));
removeFoldAssertWrap(0, 14, [8], [8], [8]);
// --- Do some multiline folding ---
// Add a fold over two lines. Note, that the wrapData[1] stays the
// same. This is an implementation detail and expected behavior.
session.addFold("woot", 0, 8, 1, 16);
assertWrap([8], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot", 0, 9, 1, 11);
assertWrap([8, 14], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 9, [8], [8], [8]);
session.addFold("woot", 0, 9, 1, 16);
assertWrap([8], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 9, [8], [8], [8]);
session.addFold(new Range(1, 10, 2, 10), "foo...");
session.addFold(new Range(2, 20, 2, 25), "bar...");
return session;
}
};

View file

@ -66,7 +66,7 @@ var UndoManager = function() {
this.$undoStack.push(deltas);
}
};
this.reset = function() {
this.$undoStack = [];
this.$redoStack = [];