Make EditSession.getScreenLength work with folded lines.

This commit is contained in:
Julian Viereck 2011-04-23 02:43:57 +02:00
commit cc795cd0e5
2 changed files with 126 additions and 16 deletions

View file

@ -1116,13 +1116,18 @@ var EditSession = function(text, mode) {
* - array[0]: The documentRow equivalent.
* - array[1]: The screenRowOffset to the first documentRow on the screen.
*/
this.$screenToDocumentRow = function(row) {
this.$screenToDocumentRow = function(screenRow, column) {
if (!this.$useWrapMode) {
return [row, 0];
// for (var row = 0; row < screenRow; i++) {
//
// }
return [screenRow, 0];
}
// TODO: WrapMode + Code Folding.
var wrapData = this.$wrapData, linesCount = this.getLength();
var docRow = 0;
var docRow = 0,
row = screenRow;
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
row -= wrapData[docRow].length + 1;
docRow ++;
@ -1241,9 +1246,26 @@ var EditSession = function(text, mode) {
*/
this.$documentToScreenRow = function(docRow, docColumn) {
if (!this.$useWrapMode) {
return [docRow, 0];
var row = docRow;
row -= this.getFoldedRowLength(0, docRow - 1);
if (this.isRowFolded(docRow)) {
var folds = this.getFoldData(docRow),
idx = 0;
if (folds[0].end.row == docRow) {
idx += 1;
}
for (idx; idx < folds.length; idx++) {
}
}
return [row, 0];
}
// TODO: WrapMode + Folding
var wrapData = this.$wrapData;
var screenRow = 0;
@ -1285,6 +1307,13 @@ var EditSession = function(text, mode) {
column = pos.column;
}
// NEW CODE PATH:
var res = this.doc2Screen(row, column);
return {
row: res[0],
column: res[1]
};
if (!this.$useWrapMode) {
str = this.getLine(row).substring(0, column);
column = this.$getStringScreenWidth(str);
@ -1309,6 +1338,7 @@ var EditSession = function(text, mode) {
var screenColumn;
var screenRowOffset = rowData[1];
// TODO: WrapMode + Code Folding.
str = this.getLine(row).substring(
wrapRowData[screenRowOffset - 1] || 0, column);
screenColumn = this.$getStringScreenWidth(str);
@ -1320,14 +1350,17 @@ var EditSession = function(text, mode) {
};
this.getScreenLength = function() {
var length = this.getLength();
if (!this.$useWrapMode) {
return this.getLength();
screenRows = length;
} else {
var screenRows = 0;
for (var row = 0; row < this.$wrapData.length; row++) {
screenRows += this.$wrapData[row].length + 1;
}
}
var screenRows = 0;
for (var row = 0; row < this.$wrapData.length; row++) {
screenRows += this.$wrapData[row].length + 1;
}
screenRows -= this.getFoldedRowLength(0, length - 1);
return screenRows;
}
@ -1370,7 +1403,6 @@ var EditSession = function(text, mode) {
c >= 0xFFE0 && c <= 0xFFE6;
};
// == Folding Code ========================================================
/**
@ -1381,6 +1413,8 @@ var EditSession = function(text, mode) {
this.range = range;
this.start = range.start;
this.end = range.end;
this.sameLine = range.start.row == range.end.row;
}
/**
@ -1401,10 +1435,19 @@ var EditSession = function(text, mode) {
foldData[startRow].push(fold);
// Mark all lines folded by this fold as folded.
for (var row = startRow + 1; row <= endRow; row++) {
for (var row = startRow + 1; row < endRow; row++) {
foldData[row] = fold;
}
// If this fold folds more then one line, then add the fold at the
// beginning of the foldData[endRow] as well.
if (!fold.sameLine) {
if (!Array.isArray(foldData[endRow])) {
foldData[endRow] = [];
}
foldData[endRow].splice(0, 0, fold);
}
// TODO: Recalculate wrapData
// TODO: Recalculate width etc.
// TODO: Mark as dirty etc.
@ -1424,7 +1467,7 @@ var EditSession = function(text, mode) {
this.getRowLastFold = function(docRow) {
var fold = this.$foldData[docRow];
if (!fold) {
return false;
return null;
} else if (Array.isArray(fold)) {
return fold[fold.length - 1];
} else {
@ -1432,6 +1475,22 @@ var EditSession = function(text, mode) {
}
};
this.getRowFirstFold = function(docRow, skipLastWrap) {
var fold = this.$foldData[docRow];
if (!fold) {
return null;
} else if (Array.isArray(fold)) {
if (skipLastWrap) {
if (fold[0].row.start != docRow) {
return fold[1] || null;
}
}
return fold[0];
} else {
return fold;
}
};
this.getRowFoldEnd = function(docRow) {
return (this.$foldData[docRow]
? this.getRowLastFold(docRow).end.row
@ -1447,10 +1506,59 @@ var EditSession = function(text, mode) {
return !fold || Array.isArray(fold);
};
this.getRowFoldData = function(docRow) {
this.getFoldData = function(docRow) {
return this.$foldData[docRow];
}
/**
* Returns the number of folded lines between start and end row.
*/
this.getFoldedRowLength = function(start, end) {
var row = start;
var count = 0;
while (row <= end) {
row = this.findRowFoldedForward(row, end);
if (row != null) {
var fold = this.getRowLastFold(row);
if (!fold.sameLine) {
if (row == start) {
count += fold.end.row - start;
} else {
count += fold.end.row - fold.start.row;
}
row = fold.end.row + 1;
}
} else {
break;
}
}
return count;
};
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);
exports.EditSession = EditSession;

View file

@ -417,7 +417,7 @@ var Text = function(parentEl) {
this.$renderFoldLine = function(stringBuilder, row, tokens) {
var session = this.session,
folds = session.getRowFoldData(row);
folds = session.getFoldData(row);
var renderTokens = [];
@ -473,8 +473,10 @@ var Text = function(parentEl) {
if (fold.start.row != fold.end.row) {
row = fold.end.row;
tokens = this.tokenizer.getTokens(row, row)[0].tokens;
folds = session.getRowFoldData(row);
i = -1;
folds = session.getFoldData(row);
// Skip the first fold as it's only referencing to the current
// fold that is already rendered.
i = 0;
}
lastCol = fold.end.column;