diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 926491c1..b72d1fbb 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -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; diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index a11966ae..3a5abb8c 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -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;