Merge branch 'master' of https://github.com/ajaxorg/ace
Conflicts: lib/ace/commands/default_commands.js lib/ace/edit_session.js
This commit is contained in:
commit
d80f0fe66e
9 changed files with 257 additions and 182 deletions
|
|
@ -301,6 +301,10 @@ exports.launch = function(env) {
|
|||
env.editor.renderer.setHScrollBarAlwaysVisible(checked);
|
||||
});
|
||||
|
||||
bindCheckbox("soft_tab", function(checked) {
|
||||
env.editor.getSession().setUseSoftTabs(checked);
|
||||
});
|
||||
|
||||
function bindCheckbox(id, callback) {
|
||||
var el = document.getElementById(id);
|
||||
var onCheck = function() {
|
||||
|
|
|
|||
28
index.html
28
index.html
|
|
@ -71,7 +71,7 @@
|
|||
</td>
|
||||
<td align="right">
|
||||
<label for="show_hidden">Show Invisibles</label>
|
||||
<input type="checkbox" name="show_hidden" id="show_hidden">
|
||||
<input type="checkbox" name="show_hidden" id="show_hidden" checked>
|
||||
</td>
|
||||
<td align="right">
|
||||
<label for="show_hscroll">Persistent HScroll</label>
|
||||
|
|
@ -128,6 +128,10 @@
|
|||
<label for="show_print_margin">Show Print Margin</label>
|
||||
<input type="checkbox" id="show_print_margin" checked>
|
||||
</td>
|
||||
<td align="right">
|
||||
<label for="soft_tab">Use Soft Tab:</label>
|
||||
<input type="checkbox" id="soft_tab" checked>
|
||||
</td>
|
||||
<td align="right">
|
||||
<label for="highlight_selected_word">Highlight selected word</label>
|
||||
<input type="checkbox" id="highlight_selected_word" checked>
|
||||
|
|
@ -144,7 +148,7 @@
|
|||
<script type="text/editor" id="jstext">function foo(items) {
|
||||
for (var i=0; i<items.length; i++) {
|
||||
alert(items[i] + "juhu");
|
||||
}
|
||||
} // Real Tab.
|
||||
}
|
||||
// A magic character: >> ぁ <<
|
||||
</script>
|
||||
|
|
@ -329,8 +333,8 @@ print "\n";
|
|||
|
||||
</script>
|
||||
|
||||
<script type="text/editor" id="svgtext"><svg
|
||||
width="800" height="600"
|
||||
<script type="text/editor" id="svgtext"><svg
|
||||
width="800" height="600"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
onload="StartAnimation(evt)">
|
||||
|
||||
|
|
@ -380,14 +384,14 @@ print "\n";
|
|||
window.ShowAndGrowElement = ShowAndGrowElement
|
||||
]]></script>
|
||||
|
||||
<rect
|
||||
fill="#2e3436"
|
||||
fill-rule="nonzero"
|
||||
stroke-width="3"
|
||||
y="0"
|
||||
x="0"
|
||||
height="600"
|
||||
width="800"
|
||||
<rect
|
||||
fill="#2e3436"
|
||||
fill-rule="nonzero"
|
||||
stroke-width="3"
|
||||
y="0"
|
||||
x="0"
|
||||
height="600"
|
||||
width="800"
|
||||
id="rect3590"/>
|
||||
|
||||
<text
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ exports.startup = function() {
|
|||
});
|
||||
gcli.addCommand({
|
||||
name: "centerselection",
|
||||
bindKey: bindKey("Ctrl-L", "Ctrl-L"),
|
||||
bindKey: bindKey(null, "Ctrl-L"),
|
||||
exec: function(env, args, request) { env.editor.centerSelection(); }
|
||||
});
|
||||
gcli.addCommand({
|
||||
|
|
|
|||
|
|
@ -233,14 +233,14 @@ var EditSession = function(text, mode) {
|
|||
renderer: typeof type == "function" ? type : null,
|
||||
clazz : clazz,
|
||||
inFront: !!inFront
|
||||
}
|
||||
};
|
||||
|
||||
if (inFront) {
|
||||
this.$frontMarkers[id] = marker;
|
||||
this._dispatchEvent("changeFrontMarker")
|
||||
this._dispatchEvent("changeFrontMarker");
|
||||
} else {
|
||||
this.$backMarkers[id] = marker;
|
||||
this._dispatchEvent("changeBackMarker")
|
||||
this._dispatchEvent("changeBackMarker");
|
||||
}
|
||||
|
||||
return id;
|
||||
|
|
@ -348,16 +348,16 @@ var EditSession = function(text, mode) {
|
|||
this.setUseWorker = function(useWorker) {
|
||||
if (this.$useWorker == useWorker)
|
||||
return;
|
||||
|
||||
|
||||
if (useWorker && !this.$worker && window.Worker)
|
||||
this.$worker = mode.createWorker(this);
|
||||
|
||||
|
||||
if (!useWorker && this.$worker) {
|
||||
this.$worker.terminate();
|
||||
this.$worker = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.getUseWorker = function() {
|
||||
return this.$useWorker;
|
||||
};
|
||||
|
|
@ -414,17 +414,13 @@ var EditSession = function(text, mode) {
|
|||
var lines = this.doc.getAllLines();
|
||||
var longestLine = 0;
|
||||
var longestScreenLine = 0;
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
for ( var i = 0; i < lines.length; i++) {
|
||||
var len = lines[i].length;
|
||||
var line = lines[i],
|
||||
len = line.length,
|
||||
screenLen = this.$getStringScreenWidth(line);
|
||||
longestLine = Math.max(longestLine, len);
|
||||
|
||||
lines[i].replace(/\t/g, function(m) {
|
||||
len += tabSize-1;
|
||||
return m;
|
||||
});
|
||||
longestScreenLine = Math.max(longestScreenLine, len);
|
||||
longestScreenLine = Math.max(longestScreenLine, screenLen);
|
||||
}
|
||||
this.width = longestLine;
|
||||
|
||||
|
|
@ -443,14 +439,6 @@ var EditSession = function(text, mode) {
|
|||
return this.doc.getLine(row);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a line as it is displayed on screen. Tabs are replaced by spaces.
|
||||
*/
|
||||
this.getDisplayLine = function(row) {
|
||||
var tab = new Array(this.getTabSize()+1).join(" ");
|
||||
return this.doc.getLine(row).replace(/\t/g, tab);
|
||||
};
|
||||
|
||||
this.getLines = function(firstRow, lastRow) {
|
||||
return this.doc.getLines(firstRow, lastRow);
|
||||
};
|
||||
|
|
@ -591,11 +579,11 @@ var EditSession = function(text, mode) {
|
|||
deltas = deltas.map(function(delta) {
|
||||
var d = {
|
||||
range: delta.range
|
||||
}
|
||||
};
|
||||
if (delta.action == "insertText" || delta.action == "insertLines")
|
||||
d.action = "removeText"
|
||||
d.action = "removeText";
|
||||
else
|
||||
d.action = "insertText"
|
||||
d.action = "insertText";
|
||||
return d;
|
||||
}).reverse();
|
||||
|
||||
|
|
@ -612,7 +600,7 @@ var EditSession = function(text, mode) {
|
|||
isInsert: isInsert,
|
||||
start: isInsert ? delta.range.start : delta.range.end,
|
||||
end: isInsert ? delta.range.end : delta.range.start
|
||||
})
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (isInsert)
|
||||
|
|
@ -899,9 +887,9 @@ var EditSession = function(text, mode) {
|
|||
// and multipleWidth characters.
|
||||
var len = displayed.length;
|
||||
displayed.join("").
|
||||
// Get all the tabs.
|
||||
replace(/4/g, function(m) {
|
||||
len -= tabSize - 1;
|
||||
// Get all the tabs spaces.
|
||||
replace(/5/g, function(m) {
|
||||
len -= 1;
|
||||
}).
|
||||
// Get all the multipleWidth characters.
|
||||
replace(/2/g, function(m) {
|
||||
|
|
@ -943,40 +931,35 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
}
|
||||
return splits;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
for (var n = 1; n < tabSize; n++) {
|
||||
arr.push(TAB_SPACE);
|
||||
}
|
||||
}
|
||||
var c = str.charCodeAt(i);
|
||||
// Tab
|
||||
if (c == 9) {
|
||||
tabSize = this.getScreenTabSize(arr.length);
|
||||
arr.push(TAB);
|
||||
for (var n = 1; n < tabSize; n++) {
|
||||
arr.push(TAB_SPACE);
|
||||
}
|
||||
}
|
||||
// Space
|
||||
else if(c == 32) {
|
||||
arr.push(SPACE);
|
||||
}
|
||||
// CJK characters
|
||||
else if (
|
||||
c >= 0x3040 && c <= 0x309F || // Hiragana
|
||||
c >= 0x30A0 && c <= 0x30FF || // Katakana
|
||||
c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs
|
||||
c >= 0xF900 && c <= 0xFAFF ||
|
||||
c >= 0x3400 && c <= 0x4DBF
|
||||
) {
|
||||
// full width characters
|
||||
else if (isFullWidth(c)) {
|
||||
arr.push(CHAR, CHAR_EXT);
|
||||
} else {
|
||||
arr.push(CHAR);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the width of the a string on the screen while assuming that
|
||||
|
|
@ -989,28 +972,22 @@ var EditSession = function(text, mode) {
|
|||
var screenColumn = 0;
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
for (var i=0; i<str.length; i++) {
|
||||
var c = str.charCodeAt(i);
|
||||
// tab
|
||||
if (c == 9) {
|
||||
screenColumn += tabSize;
|
||||
}
|
||||
// CJK characters
|
||||
else if (
|
||||
c >= 0x3040 && c <= 0x309F || // Hiragana
|
||||
c >= 0x30A0 && c <= 0x30FF || // Katakana
|
||||
c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs
|
||||
c >= 0xF900 && c <= 0xFAFF ||
|
||||
c >= 0x3400 && c <= 0x4DBF
|
||||
) {
|
||||
for (var i=0; i<str.length; i++) {
|
||||
var c = str.charCodeAt(i);
|
||||
// tab
|
||||
if (c == 9) {
|
||||
screenColumn += this.getScreenTabSize(screenColumn);
|
||||
}
|
||||
// full width characters
|
||||
else if (isFullWidth(c)) {
|
||||
screenColumn += 2;
|
||||
} else {
|
||||
screenColumn += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
screenColumn += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return screenColumn;
|
||||
}
|
||||
return screenColumn;
|
||||
};
|
||||
|
||||
this.getRowHeight = function(config, row) {
|
||||
var rows;
|
||||
|
|
@ -1021,7 +998,7 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
return rows * config.lineHeight;
|
||||
}
|
||||
};
|
||||
|
||||
this.getScreenLastRowColumn = function(screenRow, returnDocPosition) {
|
||||
if (!this.$useWrapMode) {
|
||||
|
|
@ -1055,7 +1032,7 @@ var EditSession = function(text, mode) {
|
|||
|
||||
var screenRow = this.documentToScreenRow(docRow, docColumn);
|
||||
return this.getScreenLastRowColumn(screenRow, true);
|
||||
}
|
||||
};
|
||||
|
||||
this.getScreenFirstRowColumn = function(screenRow) {
|
||||
if (!this.$useWrapMode) {
|
||||
|
|
@ -1106,6 +1083,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;
|
||||
|
|
@ -1120,21 +1104,22 @@ var EditSession = function(text, mode) {
|
|||
} else {
|
||||
var wrapData = this.$wrapData;
|
||||
|
||||
var docRow = 0;
|
||||
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
|
||||
row -= wrapData[docRow].length + 1;
|
||||
docRow ++;
|
||||
}
|
||||
var docRow = 0;
|
||||
while (docRow < linesCount && row >= wrapData[docRow].length + 1) {
|
||||
row -= wrapData[docRow].length + 1;
|
||||
docRow ++;
|
||||
}
|
||||
|
||||
if (docRow >= linesCount) {
|
||||
docRow = linesCount-1
|
||||
row = wrapData[docRow].length;
|
||||
docRow = linesCount-1;
|
||||
row = wrapData[docRow].length;
|
||||
}
|
||||
docColumn = wrapData[docRow][row - 1] || 0;
|
||||
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);
|
||||
|
||||
|
|
@ -1142,21 +1127,17 @@ 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;
|
||||
}
|
||||
}
|
||||
// CJK characters
|
||||
else if (
|
||||
c >= 0x3040 && c <= 0x309F || // Hiragana
|
||||
c >= 0x30A0 && c <= 0x30FF || // Katakana
|
||||
c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs
|
||||
c >= 0xF900 && c <= 0xFAFF ||
|
||||
c >= 0x3400 && c <= 0x4DBF
|
||||
) {
|
||||
// full width characters
|
||||
else if (isFullWidth(c)) {
|
||||
if (remaining >= 2) {
|
||||
remaining -= 2;
|
||||
} else {
|
||||
|
|
@ -1164,6 +1145,7 @@ var EditSession = function(text, mode) {
|
|||
docColumn -= 1;
|
||||
}
|
||||
} else {
|
||||
screenColumn += 1;
|
||||
remaining -= 1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1173,8 +1155,8 @@ var EditSession = function(text, mode) {
|
|||
|
||||
// Clamp docColumn.
|
||||
if (this.$useWrapMode) {
|
||||
column = wrapData[docRow][row]
|
||||
if (docColumn >= column) {
|
||||
column = wrapData[docRow][row];
|
||||
if (docColumn >= column) {
|
||||
// We remove one character at the end such that the docColumn
|
||||
// position returned is not associated to the next row on the
|
||||
// screen.
|
||||
|
|
@ -1228,11 +1210,11 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
return [screenRow, screenRowOffset];
|
||||
}
|
||||
};
|
||||
|
||||
this.documentToScreenRow = function(docRow, docColumn) {
|
||||
return this.$documentToScreenRow(docRow, docColumn)[0];
|
||||
}
|
||||
};
|
||||
|
||||
this.documentToScreenPosition = function(pos, column) {
|
||||
var str;
|
||||
|
|
@ -1291,6 +1273,41 @@ var EditSession = function(text, mode) {
|
|||
screenRows += this.$wrapData[row].length + 1;
|
||||
}
|
||||
return screenRows;
|
||||
};
|
||||
|
||||
function isFullWidth(c) {
|
||||
return c >= 0x1100 && c <= 0x115F ||
|
||||
c >= 0x11A3 && c <= 0x11A7 ||
|
||||
c >= 0x11FA && c <= 0x11FF ||
|
||||
c >= 0x2329 && c <= 0x232A ||
|
||||
c >= 0x2E80 && c <= 0x2E99 ||
|
||||
c >= 0x2E9B && c <= 0x2EF3 ||
|
||||
c >= 0x2F00 && c <= 0x2FD5 ||
|
||||
c >= 0x2FF0 && c <= 0x2FFB ||
|
||||
c >= 0x3000 && c <= 0x303E ||
|
||||
c >= 0x3041 && c <= 0x3096 ||
|
||||
c >= 0x3099 && c <= 0x30FF ||
|
||||
c >= 0x3105 && c <= 0x312D ||
|
||||
c >= 0x3131 && c <= 0x318E ||
|
||||
c >= 0x3190 && c <= 0x31BA ||
|
||||
c >= 0x31C0 && c <= 0x31E3 ||
|
||||
c >= 0x31F0 && c <= 0x321E ||
|
||||
c >= 0x3220 && c <= 0x3247 ||
|
||||
c >= 0x3250 && c <= 0x32FE ||
|
||||
c >= 0x3300 && c <= 0x4DBF ||
|
||||
c >= 0x4E00 && c <= 0xA48C ||
|
||||
c >= 0xA490 && c <= 0xA4C6 ||
|
||||
c >= 0xA960 && c <= 0xA97C ||
|
||||
c >= 0xAC00 && c <= 0xD7A3 ||
|
||||
c >= 0xD7B0 && c <= 0xD7C6 ||
|
||||
c >= 0xD7CB && c <= 0xD7FB ||
|
||||
c >= 0xF900 && c <= 0xFAFF ||
|
||||
c >= 0xFE10 && c <= 0xFE19 ||
|
||||
c >= 0xFE30 && c <= 0xFE52 ||
|
||||
c >= 0xFE54 && c <= 0xFE66 ||
|
||||
c >= 0xFE68 && c <= 0xFE6B ||
|
||||
c >= 0xFF01 && c <= 0xFF60 ||
|
||||
c >= 0xFFE0 && c <= 0xFFE6;
|
||||
}
|
||||
|
||||
}).call(EditSession.prototype);
|
||||
|
|
|
|||
|
|
@ -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(" ")
|
||||
+ this.TAB_CHAR
|
||||
+ new Array(Math.ceil(halfTab)+1).join(" ")
|
||||
+ "</span>";
|
||||
} 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("<span class='ace_invisible'>"
|
||||
+ this.TAB_CHAR
|
||||
+ new Array(i).join(" ")
|
||||
+ "</span>");
|
||||
} else {
|
||||
tabStr.push(new Array(i+1).join(" "));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.updateLines = function(config, firstRow, lastRow) {
|
||||
|
|
@ -277,35 +280,37 @@ var Text = function(parentEl) {
|
|||
};
|
||||
|
||||
this.$renderLine = function(stringBuilder, row, tokens) {
|
||||
if (this.showInvisibles) {
|
||||
var self = this;
|
||||
var spaceRe = /( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g;
|
||||
var spaceReplace = function(space) {
|
||||
if (space.charCodeAt(0) == 32)
|
||||
return new Array(space.length+1).join(" ");
|
||||
else {
|
||||
var space = new Array(space.length+1).join(self.SPACE_CHAR);
|
||||
return "<span class='ace_invisible'>" + space + "</span>";
|
||||
}
|
||||
var _self = this,
|
||||
characterWidth = this.config.characterWidth,
|
||||
screenColumn = 0;
|
||||
|
||||
};
|
||||
}
|
||||
else {
|
||||
var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g;
|
||||
var spaceReplace = " ";
|
||||
}
|
||||
|
||||
var _self = this;
|
||||
var characterWidth = this.config.characterWidth;
|
||||
function addToken(token, value) {
|
||||
var output = value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.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(/\t|&|<|( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])|[\u1100-\u115F]|[\u11A3-\u11A7]|[\u11FA-\u11FF]|[\u2329-\u232A]|[\u2E80-\u2E99]|[\u2E9B-\u2EF3]|[\u2F00-\u2FD5]|[\u2FF0-\u2FFB]|[\u3000-\u303E]|[\u3041-\u3096]|[\u3099-\u30FF]|[\u3105-\u312D]|[\u3131-\u318E]|[\u3190-\u31BA]|[\u31C0-\u31E3]|[\u31F0-\u321E]|[\u3220-\u3247]|[\u3250-\u32FE]|[\u3300-\u4DBF]|[\u4E00-\uA48C]|[\uA490-\uA4C6]|[\uA960-\uA97C]|[\uAC00-\uD7A3]|[\uD7B0-\uD7C6]|[\uD7CB-\uD7FB]|[\uF900-\uFAFF]|[\uFE10-\uFE19]|[\uFE30-\uFE52]|[\uFE54-\uFE66]|[\uFE68-\uFE6B]|[\uFF01-\uFF60]|[\uFFE0-\uFFE6]/g, function(c, a, b, tabIdx, idx4) {
|
||||
if (c.charCodeAt(0) == 32) {
|
||||
return new Array(c.length+1).join(" ");
|
||||
} else if (c == "\t") {
|
||||
var tabSize = _self.session.
|
||||
getScreenTabSize(screenColumn + tabIdx);
|
||||
screenColumn += tabSize - 1;
|
||||
return _self.$tabStrings[tabSize];
|
||||
} else if (c == "&") {
|
||||
return "&";
|
||||
} else if (c == "<") {
|
||||
return "<";
|
||||
} else if (c.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)) {
|
||||
if (this.showInvisibles) {
|
||||
var space = new Array(c.length+1).join(self.SPACE_CHAR);
|
||||
return "<span class='ace_invisible'>" + space + "</span>";
|
||||
} else {
|
||||
return " "
|
||||
}
|
||||
} else {
|
||||
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 +349,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) {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ oop.inherits(Mode, TextMode);
|
|||
args[0] = split[1];
|
||||
return this.$css[method].apply(this.$css, args);
|
||||
}
|
||||
|
||||
|
||||
return defaultHandler ? defaultHandler() : undefined;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -45,24 +45,52 @@ var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightR
|
|||
var RubyHighlightRules = function() {
|
||||
|
||||
var builtinFunctions = lang.arrayToMap(
|
||||
("abort|Array|at_exit|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|eval|exec|exit|exit!" +
|
||||
"fail|Float|fork|format|gets|global_variables|gsub|gsub!|Integer|lambda|load|local_variables|loop|open|p|print|" +
|
||||
"printf|proc|putc|puts|raise|rand|readline|readlines|require|scan|select|set_trace_func|sleep|split|sprintf|srand|" +
|
||||
"String|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|" +
|
||||
"atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan").split("|")
|
||||
("abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|" +
|
||||
"assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|" +
|
||||
"assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|" +
|
||||
"assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|" +
|
||||
"assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|" +
|
||||
"assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|" +
|
||||
"attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|" +
|
||||
"caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|" +
|
||||
"exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|" +
|
||||
"gsub!|get_via_redirect|h|host!|https?|https!|include|Integer|lambda|link_to|" +
|
||||
"link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|" +
|
||||
"p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|" +
|
||||
"raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|" +
|
||||
"set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|" +
|
||||
"throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|" +
|
||||
"render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|" +
|
||||
"content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|" +
|
||||
"fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|" +
|
||||
"time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|" +
|
||||
"select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|" +
|
||||
"file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|" +
|
||||
"protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|" +
|
||||
"send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|" +
|
||||
"validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|" +
|
||||
"validates_inclusion_of|validates_numericality_of|validates_with|validates_each|" +
|
||||
"authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|" +
|
||||
"filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" +
|
||||
"translate|localize|extract_locale_from_tld|t|l|caches_page|expire_page|caches_action|expire_action|" +
|
||||
"cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" +
|
||||
"has_many|has_one|belongs_to|has_and_belongs_to_many").split("|")
|
||||
);
|
||||
|
||||
var keywords = lang.arrayToMap(
|
||||
("alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|" +
|
||||
"if|in|__LINE__|module|next|not|or|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield").split("|")
|
||||
("alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" +
|
||||
"__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" +
|
||||
"redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield").split("|")
|
||||
);
|
||||
|
||||
var buildinConstants = lang.arrayToMap(
|
||||
("true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING").split("|")
|
||||
("true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" +
|
||||
"RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING").split("|")
|
||||
);
|
||||
|
||||
var builtinVariables = lang.arrayToMap(
|
||||
("\$DEBUG|\$defout|\$FILENAME|\$LOAD_PATH|\$SAFE|\$stdin|\$stdout|\$stderr|\$VERBOSE").split("|")
|
||||
("\$DEBUG|\$defout|\$FILENAME|\$LOAD_PATH|\$SAFE|\$stdin|\$stdout|\$stderr|\$VERBOSE|" +
|
||||
"$!|root_url|flash|session|cookies|params|request|response|logger").split("|")
|
||||
);
|
||||
|
||||
// regexp must not have capturing parentheses. Use (?:) instead.
|
||||
|
|
@ -86,6 +114,18 @@ var RubyHighlightRules = function() {
|
|||
}, {
|
||||
token : "string", // single line
|
||||
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
|
||||
}, {
|
||||
token : "string", // backtick string
|
||||
regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"
|
||||
}, {
|
||||
token : "variable.instancce", // instance variable
|
||||
regex : "@{1,2}(?:[a-zA-Z_]|\d)+"
|
||||
}, {
|
||||
token : "variable.class", // class name
|
||||
regex : "[A-Z](?:[a-zA-Z_]|\d)+"
|
||||
}, {
|
||||
token : "string", // symbol
|
||||
regex : "[:](?:[a-zA-Z]|\d)+"
|
||||
}, {
|
||||
token : "constant.numeric", // hex
|
||||
regex : "0[xX][0-9a-fA-F]+\\b"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ var Selection = function(session) {
|
|||
this.clearSelection();
|
||||
this.selectionLead = this.doc.createAnchor(0, 0);
|
||||
this.selectionAnchor = this.doc.createAnchor(0, 0);
|
||||
|
||||
|
||||
var _self = this;
|
||||
this.selectionLead.on("change", function(e) {
|
||||
_self._dispatchEvent("changeCursor");
|
||||
|
|
@ -59,7 +59,7 @@ var Selection = function(session) {
|
|||
if (e.old.row == e.value.row)
|
||||
_self.$updateDesiredColumn();
|
||||
});
|
||||
|
||||
|
||||
this.selectionAnchor.on("change", function() {
|
||||
if (!_self.$isEmpty)
|
||||
_self._dispatchEvent("changeSelection");
|
||||
|
|
@ -382,19 +382,14 @@ var Selection = function(session) {
|
|||
};
|
||||
|
||||
this.moveCursorBy = function(rows, chars) {
|
||||
if (this.session.getUseWrapMode()) {
|
||||
var screenPos = this.session.documentToScreenPosition(
|
||||
this.selectionLead.row,
|
||||
this.selectionLead.column
|
||||
);
|
||||
var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column;
|
||||
var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol);
|
||||
|
||||
this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0);
|
||||
} else {
|
||||
var docColumn = (chars == 0 && this.$desiredColumn) || this.selectionLead.column;
|
||||
this.moveCursorTo(this.selectionLead.row + rows, docColumn + chars, chars == 0);
|
||||
}
|
||||
var screenPos = this.session.documentToScreenPosition(
|
||||
this.selectionLead.row,
|
||||
this.selectionLead.column
|
||||
);
|
||||
var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column;
|
||||
var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol);
|
||||
|
||||
this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0);
|
||||
};
|
||||
|
||||
this.moveCursorToPosition = function(position) {
|
||||
|
|
@ -408,11 +403,9 @@ var Selection = function(session) {
|
|||
};
|
||||
|
||||
this.moveCursorToScreen = function(row, column, preventUpdateDesiredColumn) {
|
||||
if (this.session.getUseWrapMode()) {
|
||||
var pos = this.session.screenToDocumentPosition(row, column);
|
||||
row = pos.row;
|
||||
column = pos.column;
|
||||
}
|
||||
var pos = this.session.screenToDocumentPosition(row, column);
|
||||
row = pos.row;
|
||||
column = pos.column;
|
||||
this.moveCursorTo(row, column, preventUpdateDesiredColumn);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -140,18 +140,19 @@ var Test = {
|
|||
assert.equal(session.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(session.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(session.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 9);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 15);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 19);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 8);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 14);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 16);
|
||||
|
||||
session.setTabSize(2);
|
||||
|
||||
assert.equal(session.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(session.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(session.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 7);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 13);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 15);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 6);
|
||||
assert.equal(session.documentToScreenColumn(0, 7), 7);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 12);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 14);
|
||||
},
|
||||
|
||||
"test: convert document to screen coordinates with leading tabs": function() {
|
||||
|
|
@ -179,7 +180,7 @@ var Test = {
|
|||
session.setUseWrapMode(true);
|
||||
session.setWrapLimitRange(2, 2);
|
||||
session.adjustWrapLimit(80);
|
||||
|
||||
|
||||
assert.position(session.documentToScreenPosition(0, 1), 1, 0);
|
||||
assert.position(session.documentToScreenPosition(0, 2), 2, 0);
|
||||
assert.position(session.documentToScreenPosition(0, 4), 2, 1);
|
||||
|
|
@ -194,10 +195,20 @@ var Test = {
|
|||
assert.equal(session.screenToDocumentColumn(0, 5), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 6), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 7), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 8), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 9), 6);
|
||||
assert.equal(session.screenToDocumentColumn(0, 8), 6);
|
||||
assert.equal(session.screenToDocumentColumn(0, 9), 7);
|
||||
assert.equal(session.screenToDocumentColumn(0, 15), 12);
|
||||
assert.equal(session.screenToDocumentColumn(0, 19), 13);
|
||||
assert.equal(session.screenToDocumentColumn(0, 19), 16);
|
||||
|
||||
session.setTabSize(2);
|
||||
|
||||
assert.equal(session.screenToDocumentColumn(0, 0), 0);
|
||||
assert.equal(session.screenToDocumentColumn(0, 4), 4);
|
||||
assert.equal(session.screenToDocumentColumn(0, 5), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 6), 6);
|
||||
assert.equal(session.screenToDocumentColumn(0, 12), 12);
|
||||
assert.equal(session.screenToDocumentColumn(0, 13), 12);
|
||||
assert.equal(session.screenToDocumentColumn(0, 14), 13);
|
||||
},
|
||||
|
||||
"test: screenToDocument with soft wrap and multi byte characters": function() {
|
||||
|
|
@ -217,7 +228,7 @@ var Test = {
|
|||
session = new EditSession(["ぁ a"]);
|
||||
session.setUseWrapMode(true);
|
||||
session.adjustWrapLimit(80);
|
||||
|
||||
|
||||
assert.position(session.screenToDocumentPosition(0, 1), 0, 0);
|
||||
assert.position(session.screenToDocumentPosition(0, 2), 0, 1);
|
||||
assert.position(session.screenToDocumentPosition(0, 3), 0, 2);
|
||||
|
|
@ -227,13 +238,12 @@ var Test = {
|
|||
|
||||
"test: wrapLine split function" : function() {
|
||||
var splits;
|
||||
var computeWrapSplits = EditSession.prototype.$computeWrapSplits;
|
||||
var c = 0;
|
||||
|
||||
function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {
|
||||
wrapLimit = wrapLimit || 12;
|
||||
tabSize = tabSize || 4;
|
||||
splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize);
|
||||
var splits = EditSession.prototype.$computeWrapSplits(line, wrapLimit, tabSize);
|
||||
// console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
|
||||
assert.ok(splits.length == assertEqual.length);
|
||||
for (var i = 0; i < splits.length; i++) {
|
||||
|
|
@ -297,7 +307,7 @@ var Test = {
|
|||
|
||||
assert.equal(session.$getDisplayTokens("\t").length, 4);
|
||||
assert.equal(session.$getDisplayTokens("abc").length, 3);
|
||||
assert.equal(session.$getDisplayTokens("abc\t").length, 7);
|
||||
assert.equal(session.$getDisplayTokens("abc\t").length, 4);
|
||||
},
|
||||
|
||||
"test issue 83": function() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue