diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index b72d1fbb..d0f5212b 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1045,15 +1045,16 @@ var EditSession = function(text, mode) { return screenColumn; } - this.getRowHeight = function(config, row) { - var rows; + this.getRowLength = function(row) { if (!this.$useWrapMode || !this.$wrapData[row]) { - rows = 1; + return 1; } else { - rows = this.$wrapData[row].length + 1; + return this.$wrapData[row].length + 1; } + } - return rows * config.lineHeight; + this.getRowHeight = function(config, row) { + return this.getRowLength(row) * config.lineHeight; } this.getScreenLastRowColumn = function(screenRow, returnDocPosition) { @@ -1291,9 +1292,130 @@ var EditSession = function(text, mode) { } this.documentToScreenRow = function(docRow, docColumn) { - return this.$documentToScreenRow(docRow, docColumn)[0]; + // NEW CODE PATH: + var res = this.doc2Screen(docRow, docColumn); + return res[0]; + // return this.$documentToScreenRow(docRow, docColumn)[0]; } + this.$buildWrappedTextLine = function(row, endRow, endColumn) { + var textLine = ""; + + // Build a one line string for the current fold sequence that starts + // at foldStartRow. + + while_loop: + while (true) { + var folds = this.getFoldData(row); + var line = this.getLine(row); + + var lastEnd = 0; + var startIdx = 0; + if (folds[0].start.row != row) { + startIdx = 1; + lastEnd = folds[0].end.column; + } + fold = null; + for (var i = startIdx; i < folds.length; i++) { + fold = folds[i]; + // STOP + if (row == endRow) { + if (endColumn <= fold.start.column) { + textLine += line.substring(lastEnd, endColumn); + break while_loop; + } else if (!fold.sameLine || endColumn < fold.end.column) { + textLine += line.substring(lastEnd, fold.start.column); + break while_loop; + } + } + textLine += line.substring(lastEnd, fold.start.column); + textLine += fold.placeholder; + if (fold.sameLine) { + lastEnd = fold.end.column; + } else { + row = fold.end.row; + // STOP + if (row == endRow && endColumn <= fold.end.column) { + break while_loop; + } + } + } + if (row > endRow) { + break; + } + if (row == endRow && (!fold || fold.sameLine)) { + if (fold) { + textLine += line.substring(lastEnd, endColumn); + } + break; + } + } + return textLine; + } + + this.doc2Screen = function(docRow, docColumn) { + var screenRow = 0, + screenColumn = 0, + foldStartRow = null, + fold = null; + + // Clamp the docRow position in case it's inside of a folded block. + if (!this.isRowVisible(docRow)) { + // As the line is not visible, getFoldData will return only a + // single fold and also not an array. + fold = this.getFoldData(docRow); + docRow = fold.start.row; + docColumn = fold.start.column; + fold = null; + } + + for (var row = 0; row < docRow; row++) { + var fold = this.getRowLastFold(row); + if (fold && !fold.sameLine) { + if (foldStartRow == null) { + foldStartRow = row; + } + row = fold.end.row - 1; + } else { + screenRow += this.getRowLength(row); + foldStartRow = null; + } + } + + var textLine = ""; + + // Check if the final row we want to reach is inside of some folds. + if (!this.isRowFolded(docRow)) { + foldStartRow = null; + } else if (!foldStartRow) { + foldStartRow = docRow; + } + + var wrapDataRow; + if (foldStartRow) { + textLine = this.$buildWrappedTextLine( + foldStartRow, docRow, docColumn); + } else { + textLine = this.getLine(docRow).substring(0, docColumn); + foldStartRow = docRow; + } + + if (this.$useWrapMode) { + var wrapData = this.$wrapData[wrapDataRow]; + var screenRowOffset = 0; + while (docColumn >= wrapData[screenRowOffset]) { + screenRow ++; + screenRowOffset++; + } + textLine = textLine.substring( + wrapData[screenRowOffset - 1] || 0, textLine.length); + } + return [screenRow, this.$getStringScreenWidth(textLine), textLine]; + // return { + // row: screenRow, + // column: screenColumn + // } + this.documentToScreenPosition = function(pos, column) { var str; var tabSize = this.getTabSize();