diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 6ccb6a91..ed84f009 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -944,13 +944,14 @@ var EditSession = function(text, mode) { this.$getDisplayTokens = function(str) { var arr = []; - var tabSize = this.getTabSize(); + var tabSize; for (var i = 0; i < str.length; i++) { var c = str.charCodeAt(i); // Tab if (c == 9) { arr.push(TAB); + tabSize = this.getScreenTabSize(arr.length); for (var n = 1; n < tabSize; n++) { arr.push(TAB_SPACE); } @@ -990,7 +991,7 @@ var EditSession = function(text, mode) { var c = str.charCodeAt(i); // tab if (c == 9) { - screenColumn += tabSize; + screenColumn += this.getScreenTabSize(screenColumn); } // CJK characters else if ( @@ -1103,6 +1104,13 @@ var EditSession = function(text, mode) { return this.screenToDocumentPosition(screenRow, screenColumn).column; }; + /** + * Returns the width of a tab character at screenColumn. + */ + this.getScreenTabSize = function(screenColumn) { + return this.$tabSize - screenColumn % this.$tabSize; + }; + this.screenToDocumentPosition = function(row, column) { var line; var docRow; @@ -1131,7 +1139,8 @@ var EditSession = function(text, mode) { line = this.getLine(docRow).substring(docColumn); } - var tabSize = this.getTabSize(); + var tabSize, + screenColumn = 0; for(var i = 0; i < line.length; i++) { var c = line.charCodeAt(i); @@ -1139,8 +1148,10 @@ var EditSession = function(text, mode) { docColumn += 1; // tab if (c == 9) { + tabSize = this.getScreenTabSize(screenColumn); if (remaining >= tabSize) { remaining -= tabSize; + screenColumn += tabSize; } else { remaining = 0; docColumn -= 1; @@ -1154,6 +1165,7 @@ var EditSession = function(text, mode) { c >= 0xF900 && c <= 0xFAFF || c >= 0x3400 && c <= 0x4DBF ) { + screenColumn += 2; if (remaining >= 2) { remaining -= 2; } else { @@ -1161,6 +1173,7 @@ var EditSession = function(text, mode) { docColumn -= 1; } } else { + screenColumn += 2; remaining -= 1; } } else { diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 43f24baa..7c22548f 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -160,18 +160,21 @@ var Text = function(parentEl) { return true; }; + this.$tabStrings = []; this.$computeTabString = function() { var tabSize = this.session.getTabSize(); - if (this.showInvisibles) { - var halfTab = (tabSize) / 2; - this.$tabString = "" - + new Array(Math.floor(halfTab)).join(" ") - + this.TAB_CHAR - + new Array(Math.ceil(halfTab)+1).join(" ") - + ""; - } else { - this.$tabString = new Array(tabSize+1).join(" "); + var tabStr = this.$tabStrings = [0]; + for (var i = 1; i < tabSize + 1; i++) { + if (this.showInvisibles) { + tabStr.push("" + + this.TAB_CHAR + + new Array(i).join(" ") + + ""); + } else { + tabStr.push(new Array(i+1).join(" ")); + } } + }; this.updateLines = function(config, firstRow, lastRow) { @@ -295,17 +298,41 @@ var Text = function(parentEl) { var spaceReplace = " "; } - var _self = this; - var characterWidth = this.config.characterWidth; + var _self = this, + characterWidth = this.config.characterWidth, + screenColumn = 0; + function addToken(token, value) { var output = value - .replace(/&/g, "&") - .replace(/" + c + "" + } + }) +// .replace(/\t/g, function(c, idx) { +// idx += screenColumnOld; +// var tabSize = _self.session.getScreenTabSize(idx); +// screenColumn += tabSize - 1; +// return _self.$tabStrings[tabSize]; +// }) +// .replace(/&/g, "&") +// .replace(/" + c + "" - }); +// .replace(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c) { +// screenColumn += 1; +// return "" + c + "" +// }); + screenColumn += value.length; if (!_self.$textToken[token.type]) { var classes = "ace_" + token.type.replace(/\./g, " ace_"); @@ -344,7 +371,9 @@ var Text = function(parentEl) { "
"); + split ++; + screenColumn = 0; splitChars = splits[split] || Number.MAX_VALUE; } if (value.length != 0) {