diff --git a/lib/ace/document.js b/lib/ace/document.js index 4d4d757d..28ff3537 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -140,16 +140,16 @@ var Document = function(text) { * **/ this.getNewLineCharacter = function() { - switch (this.$newLineMode) { + switch (this.$newLineMode) { case "windows": - return "\r\n"; + return "\r\n"; case "unix": - return "\n"; + return "\n"; - case "auto": - return this.$autoNewLine; - } + default: + return this.$autoNewLine; + } }; this.$autoNewLine = "\n"; @@ -592,6 +592,60 @@ var Document = function(text) { } }; + /** + * Converts an index position in a document to a `{row, column}` object. + * + * Index refers to the "absolute position" of a character in the document. For example: + * + * ```javascript + * var x = 0; // 10 characters, plus one for newline + * var y = -1; + * ``` + * + * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second. + * + * @param {Number} index An index to convert + * @param {Number} startRow=0 The row from which to start the conversion + * @returns {Object} A `{row, column}` object of the `index` position + */ + this.indexToPosition = function(index, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + for (var i = startRow || 0, l = lines.length; i < l; i++) { + index -= lines[i].length + newlineLength; + if (index < 0) + return {row: i, column: index + lines[i].length + newlineLength}; + } + return {row: l-1, column: lines[l-1].length}; + }; + + /** + * Converts the `{row, column}` position in a document to the character's index. + * + * Index refers to the "absolute position" of a character in the document. For example: + * + * ```javascript + * var x = 0; // 10 characters, plus one for newline + * var y = -1; + * ``` + * + * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second. + * + * @param {Object} pos The `{row, column}` to convert + * @param {Number} startRow=0 The row from which to start the conversion + * @returns {Number} The index position in the document + */ + this.positionToIndex = function(pos, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + var index = 0; + var row = Math.min(pos.row, lines.length); + for (var i = startRow || 0; i < row; ++i) + index += lines[i].length; + + return index + newlineLength * i + pos.column; + }; + }).call(Document.prototype); exports.Document = Document; diff --git a/lib/ace/mode/json_worker.js b/lib/ace/mode/json_worker.js index bb72a7ac..9c233d77 100644 --- a/lib/ace/mode/json_worker.js +++ b/lib/ace/mode/json_worker.js @@ -50,7 +50,7 @@ oop.inherits(JsonWorker, Mirror); try { var result = parse(value); } catch (e) { - var pos = this.charToDocumentPosition(e.at-1); + var pos = this.doc.indexToPosition(e.at-1); this.sender.emit("error", { row: pos.row, column: pos.column, @@ -62,35 +62,6 @@ oop.inherits(JsonWorker, Mirror); this.sender.emit("ok"); }; - this.charToDocumentPosition = function(charPos) { - var i = 0; - var len = this.doc.getLength(); - var nl = this.doc.getNewLineCharacter().length; - - if (!len) { - return { row: 0, column: 0}; - } - - var lineStart = 0; - while (i < len) { - var line = this.doc.getLine(i); - var lineLength = line.length + nl; - if (lineStart + lineLength > charPos) - return { - row: i, - column: charPos - lineStart - }; - - lineStart += lineLength; - i += 1; - } - - return { - row: i-1, - column: line.length - }; - }; - }).call(JsonWorker.prototype); }); diff --git a/lib/ace/mode/lua.js b/lib/ace/mode/lua.js index e1a6143a..91d85de8 100644 --- a/lib/ace/mode/lua.js +++ b/lib/ace/mode/lua.js @@ -66,7 +66,7 @@ oop.inherits(Mode, TextMode); var level = 0; // Support single-line blocks by decrementing the indent level if // an ending token is found - for (var i in tokens){ + for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (token.type == "keyword") { if (token.value in indentKeywords) {