diff --git a/lib/ace/document.js b/lib/ace/document.js index 9766763d..bf30aa3b 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -895,9 +895,13 @@ var Document = function(text, mode) { else { var lenBefore = value.length; value = value.trimLeft(); + // True if value has some content. This content goes directly // after the last split. - if (value.length != 0) { + // If there is no content but we are in the last tabLine, we + // already know that there is no following tabLine and we can + // shortcut by using this if instead of the following else. + if (value.length != 0 || i == tabLine.length - 1) { documentColumn = lastSplitColumn += lenBefore - value.length; screenColumn += value.length; documentColumn += 1; // The tab after this for-loop. @@ -974,28 +978,7 @@ var Document = function(text, mode) { }; this.screenToDocumentColumn = function(row, screenColumn) { - var tabSize = this.getTabSize(); - - var docColumn = 0; - var remaining = screenColumn; - - var line = this.getLine(row).split("\t"); - for (var i=0; i= len + tabSize) { - remaining -= (len + tabSize); - docColumn += (len + 1); - } - else if (remaining > len){ - docColumn += len; - break; - } - else { - docColumn += remaining; - break; - } - } - return docColumn; + return this.screenToDocumentPosition(row, screenColumn).column; }; this.screenToDocumentRow = function(row) { @@ -1014,24 +997,50 @@ var Document = function(text, mode) { }; this.screenToDocumentPosition = function(row, column) { + var line; + var docRow; + var docColumn; + var remaining = column; if (!this.$useWrapMode) { - return { - row: row, - column: this.screenToDocumentColumn(row, column) + docRow = row; + docColumn = 0; + line = this.getLine(docRow).split("\t"); + } else { + var wrapData = this.$wrapData, linesCount = this.lines.length; + + docRow = 0; + while (docRow < linesCount && row >= wrapData[docRow].length + 1) { + row -= wrapData[docRow].length + 1; + docRow ++; + } + + if (docRow >= this.lines.length) { + return { + row: docRow, + column: 0 + }; + } + docColumn = wrapData[docRow][row - 1] || 0; + line = this.getLine(docRow).substring(docColumn).split("\t"); + } + + var tabSize = this.getTabSize(); + for (var i=0; i= len + tabSize) { + remaining -= (len + tabSize); + docColumn += (len + 1); + } + else if (remaining > len){ + docColumn += len; + break; + } + else { + docColumn += remaining; + break; } } - var wrapData = this.$wrapData, linesCount = this.lines.length; - - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - var docColumn = column + - (docRow < linesCount ? wrapData[docRow][row - 1] || 0 : 0); - // Clamp docColumn. if (docRow < linesCount && wrapData[docRow][row]) { docColumn = Math.min(docColumn, wrapData[docRow][row]); @@ -1046,25 +1055,7 @@ var Document = function(text, mode) { }; this.documentToScreenColumn = function(row, docColumn) { - var tabSize = this.getTabSize(); - - var screenColumn = 0; - var remaining = docColumn; - - var line = this.getLine(row).split("\t"); - for (var i=0; i len) { - remaining -= (len + 1); - screenColumn += len + tabSize; - } - else { - screenColumn += remaining; - break; - } - } - - return screenColumn; + return this.documentToScreenPosition(row, docColumn).column; }; this.documentToScreenRow = function(row) { @@ -1091,16 +1082,28 @@ var Document = function(text, mode) { } this.documentToScreenPosition = function(row, column) { + var str; + var tabSize = this.getTabSize(); + if (!this.$useWrapMode) { + str = this.getLine(row).substring(0, column); + column += (str.split("\t").length - 1) * (tabSize - 1); return { row: row, - column: this.documentToScreenColumn(row, column) - } + column: column + }; } var screenRow = this.documentToScreenRow(row); + if (row >= this.lines.length) { + return { + row: screenRow, + column: 0 + }; + } var screenColumn = column; var wrapRowData = this.$wrapData[row]; - for (var split = 0; wrapRowData && split < wrapRowData.length; split++) { + var split; + for (split = 0; wrapRowData && split < wrapRowData.length; split++) { if (column > wrapRowData[split]) { screenColumn = column - wrapRowData[split]; screenRow ++; @@ -1109,6 +1112,9 @@ var Document = function(text, mode) { } } + str = this.getLine(row).substring(wrapRowData[split - 1] || 0, column); + screenColumn += (str.split("\t").length - 1) * (tabSize - 1); + return { row: screenRow, column: screenColumn diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index 30a52de7..9791ffb8 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -58,10 +58,8 @@ var Cursor = function(parentEl) { }; this.setCursor = function(position, overwrite) { - this.position = { - row : position.row, - column : this.doc.documentToScreenColumn(position.row, position.column) - }; + this.position = + this.doc.documentToScreenPosition(position.row, position.column); if (overwrite) { dom.addCssClass(this.cursor, "ace_overwrite"); } else { @@ -109,8 +107,7 @@ var Cursor = function(parentEl) { }; } - var pos = this.doc.documentToScreenPosition(this.position.row, - this.position.column); + var pos = this.position; var cursorLeft = Math.round(pos.column * this.config.characterWidth); var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * this.config.lineHeight;