First iteration of implementing real real tabs

This commit is contained in:
Julian Viereck 2011-03-18 23:30:25 +01:00
commit 1a5a071c7d
2 changed files with 62 additions and 20 deletions

View file

@ -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 {

View file

@ -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 = "<span class='ace_invisible'>"
+ new Array(Math.floor(halfTab)).join("&#160;")
+ this.TAB_CHAR
+ new Array(Math.ceil(halfTab)+1).join("&#160;")
+ "</span>";
} else {
this.$tabString = new Array(tabSize+1).join("&#160;");
var tabStr = this.$tabStrings = [0];
for (var i = 1; i < tabSize + 1; i++) {
if (this.showInvisibles) {
tabStr.push("<span class='ace_invisible'>"
+ this.TAB_CHAR
+ new Array(i).join("&#160;")
+ "</span>");
} else {
tabStr.push(new Array(i+1).join("&#160;"));
}
}
};
this.updateLines = function(config, firstRow, lastRow) {
@ -295,17 +298,41 @@ var Text = function(parentEl) {
var spaceReplace = "&#160;";
}
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, "&amp;")
.replace(/</g, "&lt;")
.replace(/\t|&|<|[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c, idx) {
if (c == "\t") {
var tabSize = _self.session.
getScreenTabSize(screenColumn + idx);
screenColumn += tabSize - 1;
return _self.$tabStrings[tabSize];
} else if (c == "&") {
return "&amp";
} else if (c == "<") {
return "&lt;";
} else {
screenColumn += 1;
return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
}
})
// .replace(/\t/g, function(c, idx) {
// idx += screenColumnOld;
// var tabSize = _self.session.getScreenTabSize(idx);
// screenColumn += tabSize - 1;
// return _self.$tabStrings[tabSize];
// })
// .replace(/&/g, "&amp;")
// .replace(/</g, "&lt;")
.replace(spaceRe, spaceReplace)
.replace(/\t/g, _self.$tabString)
.replace(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c) {
return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
});
// .replace(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]/g, function(c) {
// screenColumn += 1;
// return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
// });
screenColumn += value.length;
if (!_self.$textToken[token.type]) {
var classes = "ace_" + token.type.replace(/\./g, " ace_");
@ -344,7 +371,9 @@ var Text = function(parentEl) {
"<div style='height:",
this.config.lineHeight, "px",
"'>");
split ++;
screenColumn = 0;
splitChars = splits[split] || Number.MAX_VALUE;
}
if (value.length != 0) {