Final iteration of wrapMode + folding: Addind unit tests, fixing bugs.
This commit is contained in:
parent
0687d8a5e8
commit
825cf26478
6 changed files with 129 additions and 53 deletions
12
demo/demo.js
12
demo/demo.js
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ var UndoManager = function() {
|
|||
this.$undoStack.push(deltas);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.reset = function() {
|
||||
this.$undoStack = [];
|
||||
this.$redoStack = [];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue