Get fold EditSession.screenToDocument working + unit tested

This commit is contained in:
Julian Viereck 2011-04-24 22:37:03 +02:00
commit 068e289f17
3 changed files with 83 additions and 262 deletions

View file

@ -149,7 +149,7 @@ exports.launch = function(env) {
// BEGING TESTING // BEGING TESTING
var Range = require("ace/range").Range; var Range = require("ace/range").Range;
// docs.js.addFold(new Range(0, 13, 0, 18), "args..."); 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(2, 20, 2, 25), "bar...");
docs.js.addFold(new Range(1, 10, 2, 10), "foo..."); docs.js.addFold(new Range(1, 10, 2, 10), "foo...");
window.s = docs.js; window.s = docs.js;

View file

@ -1000,11 +1000,11 @@ var EditSession = function(text, mode) {
arr.push(TAB_SPACE); arr.push(TAB_SPACE);
} }
} }
// Space // Space
else if(c == 32) { else if(c == 32) {
arr.push(SPACE); arr.push(SPACE);
} }
// full width characters // full width characters
else if (isFullWidth(c)) { else if (isFullWidth(c)) {
arr.push(CHAR, CHAR_EXT); arr.push(CHAR, CHAR_EXT);
} else { } else {
@ -1014,47 +1014,6 @@ var EditSession = function(text, mode) {
return arr; return arr;
} }
this.$getStringDisplayData = function(str, maxScreenColumn, column, offset) {
if (maxScreenColumn == null) {
maxScreenColumn = str.length * Math.max(this.getTabSize(), 2);
}
column = column || 0;
var arr = [],
tabSize,
c;
for (column; column < str.length; column++) {
c = str.charCodeAt(column);
// Tab
if (c == 9) {
tabSize = this.getScreenTabSize(arr.length + offset);
arr.push(TAB);
for (var n = 1; n < tabSize; n++) {
arr.push(TAB_SPACE);
}
}
// Space
else if(c == 32) {
arr.push(SPACE);
}
// full width characters
else if (isFullWidth(c)) {
arr.push(CHAR, CHAR_EXT);
} else {
arr.push(CHAR);
}
if ((arr.length + offset) > maxScreenColumn) {
column --;
break;
}
}
return {
tokens: arr,
column: column
};
}
/** /**
* Calculates the width of the a string on the screen while assuming that * Calculates the width of the a string on the screen while assuming that
* the string starts at the first column on the screen. * the string starts at the first column on the screen.
@ -1069,29 +1028,30 @@ var EditSession = function(text, mode) {
return [0, 0]; return [0, 0];
} }
if (maxScreenColumn == null) { if (maxScreenColumn == null) {
maxScreenColumn = str.length * Math.max(this.getTabSize(), 2); maxScreenColumn = screenColumn +
str.length * Math.max(this.getTabSize(), 2);
} }
screenColumn = screenColumn || 0; screenColumn = screenColumn || 0;
var c; var c, column;
for (column = 0; column < str.length; column++) { for (column = 0; column < str.length; column++) {
c = str.charCodeAt(column); c = str.charCodeAt(column);
// tab // tab
if (c == 9) { if (c == 9) {
screenColumn += this.getScreenTabSize(screenColumn); screenColumn += this.getScreenTabSize(screenColumn);
} }
// full width characters // full width characters
else if (isFullWidth(c)) { else if (isFullWidth(c)) {
screenColumn += 2; screenColumn += 2;
} else { } else {
screenColumn += 1; screenColumn += 1;
} }
if (screenColumn > maxScreenColumn) { if (screenColumn > maxScreenColumn) {
break break
} }
} }
return [screenColumn, column]; return [screenColumn, column];
} }
this.getRowLength = function(row) { this.getRowLength = function(row) {
@ -1160,32 +1120,6 @@ var EditSession = function(text, mode) {
} }
}; };
/**
*
* @returns array
* - array[0]: The documentRow equivalent.
* - array[1]: The screenRowOffset to the first documentRow on the screen.
*/
this.$screenToDocumentRow = function(screenRow, column) {
if (!this.$useWrapMode) {
// for (var row = 0; row < screenRow; i++) {
//
// }
return [screenRow, 0];
}
// TODO: WrapMode + Code Folding.
var wrapData = this.$wrapData, linesCount = this.getLength();
var docRow = 0,
row = screenRow;
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
row -= wrapData[docRow].length + 1;
docRow ++;
}
return [docRow, row];
};
/** /**
* Returns the width of a tab character at screenColumn. * Returns the width of a tab character at screenColumn.
*/ */
@ -1233,12 +1167,14 @@ var EditSession = function(text, mode) {
var data, str; var data, str;
if (placeholder) { if (placeholder) {
data = this.$getStringScreenWidth(placeholder, null, walkScreenColumn); data = this.$getStringScreenWidth(placeholder, null, walkScreenColumn);
if (data[0] > screenColumn) { if (data[0] > screenColumn || data[1] == 0) {
return true; // Stop walk. return true; // Stop walk.
} }
docColumn += data[1]; docColumn += data[1];
} else { } else {
docColumn = lastColumn;
if (isNewRow) { if (isNewRow) {
docRow = row;
line = this.getLine(row); line = this.getLine(row);
} }
str = line.substring(lastColumn, column); str = line.substring(lastColumn, column);
@ -1248,8 +1184,8 @@ var EditSession = function(text, mode) {
return true; // Stop walk. return true; // Stop walk.
} }
} }
walkScreenColumn += data[0]; walkScreenColumn = data[0];
}.bind(this)); }.bind(this), foldLine.end.row, this.getLine(foldLine.end.row).length);
} else { } else {
line = this.getLine(docRow); line = this.getLine(docRow);
splits = this.$wrapData[docRow]; splits = this.$wrapData[docRow];
@ -1294,99 +1230,8 @@ var EditSession = function(text, mode) {
row: ret[0], row: ret[0],
column: ret[1] column: ret[1]
}; };
var line;
var docRow;
var docColumn;
var remaining = column;
var linesCount = this.getLength();
if (!this.$useWrapMode) {
docRow = row >= linesCount? linesCount-1 : (row < 0 ? 0 : row);
row = 0;
docColumn = 0;
line = this.getLine(docRow);
} else {
var wrapData = this.$wrapData;
var docRow = 0;
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
row -= wrapData[docRow].length + 1;
docRow ++;
}
if (docRow >= linesCount) {
docRow = linesCount-1
row = wrapData[docRow].length;
}
docColumn = wrapData[docRow][row - 1] || 0;
line = this.getLine(docRow).substring(docColumn);
}
var tabSize,
screenColumn = 0;
docColumn += this.$getStringScreenWidth(line, column)[1];
// Clamp docColumn.
if (this.$useWrapMode) {
column = wrapData[docRow][row]
if (docColumn >= column) {
// We remove one character at the end such that the docColumn
// position returned is not associated to the next row on the
// screen.
docColumn = column - 1;
}
} else if (line) {
docColumn = Math.min(docColumn, line.length);
}
return {
row: docRow,
column: docColumn
};
}; };
// this.$buildFoldedTextLine = function(foldLine, endRow, endColumn) {
// var textLine = "";
//
// // Build a one line string for the current fold sequence that starts
// // at foldStartRow.
// var lastEnd = 0,
// line = this.getLine(foldLine.start.row),
// comp,
// folds = foldLine.folds,
// fold;
//
// for (var i = 0; i < folds.length; i++) {
// fold = folds[i];
//
// comp = fold.compare(endRow, endColumn);
// // This fold is after the endRow/Column.
// if (comp == -1) {
// textLine += line.substring(lastEnd, endColumn);
// return textLine;
// }
// // The endRow/Column is inside of the current fold.
// else if (comp == 0) {
// textLine += line.substring(lastEnd, fold.start.column);
// return textLine;
// }
//
// textLine += line.substring(lastEnd, fold.start.column);
// textLine += fold.placeholder;
//
// if (fold.sameLine) {
// lastEnd = fold.end.column;
// } else {
// row = fold.end.row;
//
// line = this.getLine(row);
// lastEnd = fold.end.column;
// }
// }
// textLine += line.substring(lastEnd, endColumn);
// return textLine;
// }
this.doc2Screen = function(docRow, docColumn) { this.doc2Screen = function(docRow, docColumn) {
var screenRow = 0, var screenRow = 0,
screenColumn = 0, screenColumn = 0,
@ -1747,30 +1592,6 @@ var EditSession = function(text, mode) {
: docRow) : docRow)
}; };
// this.findRowFoldedForward = function(start, limit) {
// if (limit == null) {
// limit = this.getLength();
// }
// for (var row = start; row != limit; row++) {
// if (this.isRowFolded(row)) {
// return row;
// }
// }
// return null;
// }
//
// this.findRowFoldedBackwards = function(start, limit) {
// if (limit == null) {
// limit = -1;
// }
// for (var row = start; row != limit; row--) {
// if (this.isRowFolded(row)) {
// return row;
// }
// }
// return null;
// }
}).call(EditSession.prototype); }).call(EditSession.prototype);
exports.EditSession = EditSession; exports.EditSession = EditSession;

View file

@ -65,66 +65,6 @@ function createFoldTestSession() {
return session; return session;
} }
var foldTests = {
"fold-same-row": [
[0, 0, 0, 0],
[0, 13, 0, 13],
[0, 14, 0, 13],
[0, 17, 0, 13],
[0, 18, 0, 20],
[0, 19, 0, 20]
],
"fold-on-some-other-row": [
[1, 0, 1, 0],
[1, 10, 1, 10],
[1, 11, 1, 10],
[1, 99, 1, 10],
[2, 0, 1, 10],
[2, 9, 1, 10],
[2, 10, 1, 16],
[2, 11, 1, 17]
],
"fold-in-the-same-row+fold-other-row": [
[2, 19, 1, 25],
[2, 20, 1, 26],
[2, 21, 1, 26],
[2, 24, 1, 26],
[2, 25, 1, 32],
[2, 26, 1, 33],
[2, 99, 1, 40],
],
"fold-after": [
[3, 0, 2, 0]
]
};
function runFoldTests(unitFunc) {
var session = createFoldTestSession();
function assertScreen2Doc(screenRow, screenCol, docRow, docCol) {
assert.position(
session.screenToDocumentPosition(docRow, docCol),
screenRow, screenCol
);
}
var foldTests = this.foldTests,
tests, test, testArray;
for (tests in foldTests) {
testArray = foldTests[tests];
for (var i = 0; i < testArray.length; i++) {
test = testArray[i];
unitFunc(test[0], test[1], test[2], test[3]);
}
}
}
module.exports = { module.exports = {
"test: find matching opening bracket" : function() { "test: find matching opening bracket" : function() {
@ -432,23 +372,83 @@ module.exports = {
}, },
"test fold documentToScreen": function() { "test fold documentToScreen": function() {
var session = createFoldTestSession();
function assertDoc2Screen(docRow, docCol, screenRow, screenCol) { function assertDoc2Screen(docRow, docCol, screenRow, screenCol) {
assert.position( assert.position(
session.documentToScreenPosition(docRow, docCol), session.documentToScreenPosition(docRow, docCol),
screenRow, screenCol screenRow, screenCol
); );
} }
runFoldTests(assertDoc2Screen);
// One fold ending in the same row.
assertDoc2Screen(0, 0, 0, 0);
assertDoc2Screen(0, 13, 0, 13);
assertDoc2Screen(0, 14, 0, 13);
assertDoc2Screen(0, 17, 0, 13);
assertDoc2Screen(0, 18, 0, 20);
// Fold ending on some other row.
assertDoc2Screen(1, 0, 1, 0);
assertDoc2Screen(1, 10, 1, 10);
assertDoc2Screen(1, 11, 1, 10);
assertDoc2Screen(1, 99, 1, 10);
assertDoc2Screen(2, 0, 1, 10);
assertDoc2Screen(2, 9, 1, 10);
assertDoc2Screen(2, 10, 1, 16);
assertDoc2Screen(2, 11, 1, 17);
// Fold in the same row with fold over more then one row in the same row.
assertDoc2Screen(2, 19, 1, 25);
assertDoc2Screen(2, 20, 1, 26);
assertDoc2Screen(2, 21, 1, 26);
assertDoc2Screen(2, 24, 1, 26);
assertDoc2Screen(2, 25, 1, 32);
assertDoc2Screen(2, 26, 1, 33);
assertDoc2Screen(2, 99, 1, 40);
// Test one position after the folds. Should be all like normal.
assertDoc2Screen(3, 0, 2, 0);
}, },
"test fold screenToDocument": function() { "test fold screenToDocument": function() {
var session = createFoldTestSession();
function assertScreen2Doc(docRow, docCol, screenRow, screenCol) { function assertScreen2Doc(docRow, docCol, screenRow, screenCol) {
assert.position( assert.position(
session.screenToDocumentPosition(screenRow, screenCol), session.screenToDocumentPosition(screenRow, screenCol),
docRow, docCol docRow, docCol
); );
} }
runFoldTests(assertScreen2Doc);
// One fold ending in the same row.
assertScreen2Doc(0, 0, 0, 0);
assertScreen2Doc(0, 13, 0, 13);
assertScreen2Doc(0, 13, 0, 14);
assertScreen2Doc(0, 18, 0, 20);
assertScreen2Doc(0, 19, 0, 21);
// Fold ending on some other row.
assertScreen2Doc(1, 0, 1, 0);
assertScreen2Doc(1, 10, 1, 10);
assertScreen2Doc(1, 10, 1, 11);
assertScreen2Doc(1, 10, 1, 15);
assertScreen2Doc(2, 10, 1, 16);
assertScreen2Doc(2, 11, 1, 17);
// Fold in the same row with fold over more then one row in the same row.
assertScreen2Doc(2, 19, 1, 25);
assertScreen2Doc(2, 20, 1, 26);
assertScreen2Doc(2, 20, 1, 27);
assertScreen2Doc(2, 20, 1, 31);
assertScreen2Doc(2, 25, 1, 32);
assertScreen2Doc(2, 26, 1, 33);
assertScreen2Doc(2, 33, 1, 99);
// Test one position after the folds. Should be all like normal.
assertScreen2Doc(3, 0, 2, 0);
} }
}; };