Update Ace.

This commit is contained in:
bootstraponline
2012-06-18 12:32:27 -06:00
parent c0564a1467
commit 7aca7fa0ec
22 changed files with 505 additions and 183 deletions
@@ -72,22 +72,22 @@ exports.commands = [{
readOnly: true readOnly: true
}, { }, {
name: "fold", name: "fold",
bindKey: bindKey("Alt-L", "Alt-L"), bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
exec: function(editor) { editor.session.toggleFold(false); }, exec: function(editor) { editor.session.toggleFold(false); },
readOnly: true readOnly: true
}, { }, {
name: "unfold", name: "unfold",
bindKey: bindKey("Alt-Shift-L", "Alt-Shift-L"), bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
exec: function(editor) { editor.session.toggleFold(true); }, exec: function(editor) { editor.session.toggleFold(true); },
readOnly: true readOnly: true
}, { }, {
name: "foldall", name: "foldall",
bindKey: bindKey("Alt-0", "Alt-0"), bindKey: bindKey("Alt-0", "Command-Option-0"),
exec: function(editor) { editor.session.foldAll(); }, exec: function(editor) { editor.session.foldAll(); },
readOnly: true readOnly: true
}, { }, {
name: "unfoldall", name: "unfoldall",
bindKey: bindKey("Alt-Shift-0", "Alt-Shift-0"), bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
exec: function(editor) { editor.session.unfold(); }, exec: function(editor) { editor.session.unfold(); },
readOnly: true readOnly: true
}, { }, {
@@ -110,17 +110,17 @@ exports.commands = [{
readOnly: true readOnly: true
}, { }, {
name: "overwrite", name: "overwrite",
bindKey: bindKey("Insert", "Insert"), bindKey: "Insert",
exec: function(editor) { editor.toggleOverwrite(); }, exec: function(editor) { editor.toggleOverwrite(); },
readOnly: true readOnly: true
}, { }, {
name: "selecttostart", name: "selecttostart",
bindKey: bindKey("Ctrl-Shift-Home|Alt-Shift-Up", "Command-Shift-Up"), bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
exec: function(editor) { editor.getSelection().selectFileStart(); }, exec: function(editor) { editor.getSelection().selectFileStart(); },
readOnly: true readOnly: true
}, { }, {
name: "gotostart", name: "gotostart",
bindKey: bindKey("Ctrl-Home|Ctrl-Up", "Command-Home|Command-Up"), bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
exec: function(editor) { editor.navigateFileStart(); }, exec: function(editor) { editor.navigateFileStart(); },
readOnly: true readOnly: true
}, { }, {
@@ -137,13 +137,13 @@ exports.commands = [{
readOnly: true readOnly: true
}, { }, {
name: "selecttoend", name: "selecttoend",
bindKey: bindKey("Ctrl-Shift-End|Alt-Shift-Down", "Command-Shift-Down"), bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"),
exec: function(editor) { editor.getSelection().selectFileEnd(); }, exec: function(editor) { editor.getSelection().selectFileEnd(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
readOnly: true readOnly: true
}, { }, {
name: "gotoend", name: "gotoend",
bindKey: bindKey("Ctrl-End|Ctrl-Down", "Command-End|Command-Down"), bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
exec: function(editor) { editor.navigateFileEnd(); }, exec: function(editor) { editor.navigateFileEnd(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
readOnly: true readOnly: true
@@ -233,43 +233,53 @@ exports.commands = [{
readOnly: true readOnly: true
}, { }, {
name: "selectpagedown", name: "selectpagedown",
bindKey: bindKey("Shift-PageDown", "Shift-PageDown"), bindKey: "Shift-PageDown",
exec: function(editor) { editor.selectPageDown(); }, exec: function(editor) { editor.selectPageDown(); },
readOnly: true readOnly: true
}, { }, {
name: "pagedown", name: "pagedown",
bindKey: bindKey(null, "PageDown"), bindKey: bindKey(null, "Option-PageDown"),
exec: function(editor) { editor.scrollPageDown(); }, exec: function(editor) { editor.scrollPageDown(); },
readOnly: true readOnly: true
}, { }, {
name: "gotopagedown", name: "gotopagedown",
bindKey: bindKey("PageDown", "Option-PageDown|Ctrl-V"), bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
exec: function(editor) { editor.gotoPageDown(); }, exec: function(editor) { editor.gotoPageDown(); },
readOnly: true readOnly: true
}, { }, {
name: "selectpageup", name: "selectpageup",
bindKey: bindKey("Shift-PageUp", "Shift-PageUp"), bindKey: "Shift-PageUp",
exec: function(editor) { editor.selectPageUp(); }, exec: function(editor) { editor.selectPageUp(); },
readOnly: true readOnly: true
}, { }, {
name: "pageup", name: "pageup",
bindKey: bindKey(null, "PageUp"), bindKey: bindKey(null, "Option-PageUp"),
exec: function(editor) { editor.scrollPageUp(); }, exec: function(editor) { editor.scrollPageUp(); },
readOnly: true readOnly: true
}, { }, {
name: "gotopageup", name: "gotopageup",
bindKey: bindKey("PageUp", "Option-PageUp"), bindKey: "PageUp",
exec: function(editor) { editor.gotoPageUp(); }, exec: function(editor) { editor.gotoPageUp(); },
readOnly: true readOnly: true
}, {
name: "scrollup",
bindKey: bindKey("Ctrl-Up", null),
exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
readOnly: true
}, {
name: "scrolldown",
bindKey: bindKey("Ctrl-Down", null),
exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
readOnly: true
}, { }, {
name: "selectlinestart", name: "selectlinestart",
bindKey: bindKey("Shift-Home", "Shift-Home"), bindKey: "Shift-Home",
exec: function(editor) { editor.getSelection().selectLineStart(); }, exec: function(editor) { editor.getSelection().selectLineStart(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
readOnly: true readOnly: true
}, { }, {
name: "selectlineend", name: "selectlineend",
bindKey: bindKey("Shift-End", "Shift-End"), bindKey: "Shift-End",
exec: function(editor) { editor.getSelection().selectLineEnd(); }, exec: function(editor) { editor.getSelection().selectLineEnd(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
readOnly: true readOnly: true
@@ -285,10 +295,15 @@ exports.commands = [{
readOnly: true readOnly: true
}, { }, {
name: "jumptomatching", name: "jumptomatching",
bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"), bindKey: bindKey("Ctrl-P", "Ctrl-P"),
exec: function(editor) { editor.jumpToMatching(); }, exec: function(editor) { editor.jumpToMatching(); },
multiSelectAction: "forEach", multiSelectAction: "forEach",
readOnly: true readOnly: true
}, {
name: "selecttomatching",
bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
exec: function(editor) { editor.jumpToMatching(true); },
readOnly: true
}, },
// commands disabled in readOnly mode // commands disabled in readOnly mode
@@ -309,6 +324,11 @@ exports.commands = [{
bindKey: bindKey("Ctrl-D", "Command-D"), bindKey: bindKey("Ctrl-D", "Command-D"),
exec: function(editor) { editor.removeLines(); }, exec: function(editor) { editor.removeLines(); },
multiSelectAction: "forEach" multiSelectAction: "forEach"
}, {
name: "duplicateSelection",
bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
exec: function(editor) { editor.duplicateSelection(); },
multiSelectAction: "forEach"
}, { }, {
name: "togglecomment", name: "togglecomment",
bindKey: bindKey("Ctrl-/", "Command-/"), bindKey: bindKey("Ctrl-/", "Command-/"),
@@ -348,7 +368,7 @@ exports.commands = [{
exec: function(editor) { editor.redo(); } exec: function(editor) { editor.redo(); }
}, { }, {
name: "copylinesup", name: "copylinesup",
bindKey: bindKey("Ctrl-Alt-Up", "Command-Option-Up"), bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
exec: function(editor) { editor.copyLinesUp(); } exec: function(editor) { editor.copyLinesUp(); }
}, { }, {
name: "movelinesup", name: "movelinesup",
@@ -356,7 +376,7 @@ exports.commands = [{
exec: function(editor) { editor.moveLinesUp(); } exec: function(editor) { editor.moveLinesUp(); }
}, { }, {
name: "copylinesdown", name: "copylinesdown",
bindKey: bindKey("Ctrl-Alt-Down", "Command-Option-Down"), bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
exec: function(editor) { editor.copyLinesDown(); } exec: function(editor) { editor.copyLinesDown(); }
}, { }, {
name: "movelinesdown", name: "movelinesdown",
@@ -827,7 +827,8 @@ var EditSession = function(text, mode) {
try { try {
module = require(mode); module = require(mode);
} catch (e) {}; } catch (e) {};
if (module) // sometimes require returns empty object (this bug is present in requirejs 2 as well)
if (module && module.Mode)
return done(module); return done(module);
// set mode to text until loading is finished // set mode to text until loading is finished
@@ -40,6 +40,7 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var TokenIterator = require("../token_iterator").TokenIterator; var TokenIterator = require("../token_iterator").TokenIterator;
var Range = require("../range").Range;
/** /**
* class BracketMatch * class BracketMatch
@@ -76,15 +77,56 @@ function BracketMatch() {
if (charBeforeCursor == "") return null; if (charBeforeCursor == "") return null;
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
if (!match) { if (!match)
return null; return null;
if (match[1])
return this.$findClosingBracket(match[1], position);
else
return this.$findOpeningBracket(match[2], position);
};
this.getBracketRange = function(pos) {
var line = this.getLine(pos.row);
var before = true, range;
var chr = line.charAt(pos.column-1);
var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
if (!match) {
chr = line.charAt(pos.column);
pos.column++;
match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
before = false;
} }
if (!match)
return null;
if (match[1]) { if (match[1]) {
return this.$findClosingBracket(match[1], position); var bracketPos = this.$findClosingBracket(match[1], pos);
} else { if (!bracketPos)
return this.$findOpeningBracket(match[2], position); return null;
range = Range.fromPoints(pos, bracketPos);
if (!before) {
range.end.column++;
range.start.column--;
} }
range.cursor = range.end;
} else {
var bracketPos = this.$findOpeningBracket(match[2], pos);
if (!bracketPos)
return null;
range = Range.fromPoints(bracketPos, pos);
if (!before) {
range.start.column++;
range.end.column--;
}
range.cursor = range.start;
}
if (!before)
pos.column--;
return range;
}; };
this.$brackets = { this.$brackets = {
@@ -1348,6 +1348,24 @@ var Editor = function(renderer, session) {
this.clearSelection(); this.clearSelection();
}; };
this.duplicateSelection = function() {
var sel = this.selection;
var doc = this.session;
var range = sel.getRange();
if (range.isEmpty()) {
var row = range.start.row;
doc.duplicateLines(row, row);
} else {
var reverse = sel.isBackwards()
var point = sel.isBackwards() ? range.start : range.end;
var endPoint = doc.insert(point, doc.getTextRange(range), false);
range.start = point;
range.end = endPoint;
sel.setSelectionRange(range, reverse)
}
};
/** related to: EditSession.moveLinesDown /** related to: EditSession.moveLinesDown
* Editor.moveLinesDown() -> Number * Editor.moveLinesDown() -> Number
* + (Number): On success, it returns -1. * + (Number): On success, it returns -1.
@@ -1660,8 +1678,11 @@ var Editor = function(renderer, session) {
**/ **/
this.centerSelection = function() { this.centerSelection = function() {
var range = this.getSelectionRange(); var range = this.getSelectionRange();
var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2); var pos = {
this.renderer.scrollToLine(line, true); row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
}
this.renderer.alignCursor(pos, 0.5);
}; };
/** related to: Selection.getCursor /** related to: Selection.getCursor
@@ -1746,22 +1767,35 @@ var Editor = function(renderer, session) {
* Moves the cursor's row and column to the next matching bracket. * Moves the cursor's row and column to the next matching bracket.
* *
**/ **/
this.jumpToMatching = function() { this.jumpToMatching = function(select) {
var cursor = this.getCursorPosition(); var cursor = this.getCursorPosition();
var pos = this.session.findMatchingBracket(cursor);
if (!pos) { var range = this.session.getBracketRange(cursor);
cursor.column += 1; if (!range) {
pos = this.session.findMatchingBracket(cursor); range = editor.find({
} needle: /[{}()\[\]]/g,
if (!pos) { preventScroll:true,
cursor.column -= 2; start: {row: cursor.row, column: cursor.column - 1}
pos = this.session.findMatchingBracket(cursor); });
if (!range)
return;
var pos = range.start;
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
range = this.session.getBracketRange(pos);
} }
pos = range && range.cursor || pos;
if (pos) { if (pos) {
if (select) {
if (range && range.isEqual(editor.getSelectionRange()))
this.clearSelection();
else
this.selection.selectTo(pos.row, pos.column);
} else {
this.clearSelection(); this.clearSelection();
this.moveCursorTo(pos.row, pos.column); this.moveCursorTo(pos.row, pos.column);
} }
}
}; };
/** /**
@@ -52,7 +52,7 @@ var baseStyles = require("../requirejs/text!./static.css");
* @returns {object} An object containing: html, css * @returns {object} An object containing: html, css
*/ */
exports.render = function(input, mode, theme, lineStart) { exports.render = function(input, mode, theme, lineStart, disableGutter) {
lineStart = parseInt(lineStart || 1, 10); lineStart = parseInt(lineStart || 1, 10);
var session = new EditSession(""); var session = new EditSession("");
@@ -74,7 +74,8 @@ exports.render = function(input, mode, theme, lineStart) {
for(var ix = 0; ix < length; ix++) { for(var ix = 0; ix < length; ix++) {
var lineTokens = session.getTokens(ix); var lineTokens = session.getTokens(ix);
stringBuilder.push("<div class='ace_line'>"); stringBuilder.push("<div class='ace_line'>");
// stringBuilder.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'>" + (ix + lineStart) + "</span>"); if (!disableGutter)
stringBuilder.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'>" + (ix + lineStart) + "</span>");
textLayer.$renderLine(stringBuilder, 0, lineTokens, true); textLayer.$renderLine(stringBuilder, 0, lineTokens, true);
stringBuilder.push("</div>"); stringBuilder.push("</div>");
} }
@@ -246,7 +246,6 @@ var TextInput = function(parentNode, host) {
}); });
this.focus = function() { this.focus = function() {
host.onFocus();
reset(); reset();
text.focus(); text.focus();
}; };
@@ -281,6 +280,8 @@ var TextInput = function(parentNode, host) {
if (host.renderer.$keepTextAreaAtCursor) if (host.renderer.$keepTextAreaAtCursor)
host.renderer.$keepTextAreaAtCursor = null; host.renderer.$keepTextAreaAtCursor = null;
// on windows context menu is opened after mouseup
if (useragent.isGecko && useragent.isWin)
event.capture(host.container, function(e) { event.capture(host.container, function(e) {
text.style.left = e.clientX - 2 + "px"; text.style.left = e.clientX - 2 + "px";
text.style.top = e.clientY - 2 + "px"; text.style.top = e.clientY - 2 + "px";
@@ -300,27 +300,27 @@ module.exports = {
case "(": case "(":
case "{": case "{":
case "[": case "[":
var cursor = editor.getCursorPosition() var cursor = editor.getCursorPosition();
var end = editor.session.$findClosingBracket(param, cursor, /paren/) var end = editor.session.$findClosingBracket(param, cursor, /paren/);
if (!end) if (!end)
return; return;
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/) var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
if (!start) if (!start)
return; return;
start.column ++; start.column ++;
editor.selection.setSelectionRange(Range.fromPoints(start, end)) editor.selection.setSelectionRange(Range.fromPoints(start, end));
break break;
case "'": case "'":
case "\"": case '"':
case "/": case "/":
var end = find(editor, param, 1) var end = find(editor, param, 1);
if (!end) if (!end)
return; return;
var start = find(editor, param, -1) var start = find(editor, param, -1);
if (!start) if (!start)
return; return;
editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start)) editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start));
break break;
} }
} }
}, },
@@ -93,7 +93,7 @@ exports.preventDefault = function(e) {
exports.getButton = function(e) { exports.getButton = function(e) {
if (e.type == "dblclick") if (e.type == "dblclick")
return 0; return 0;
else if (e.type == "contextmenu") if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
return 2; return 2;
// DOM Event // DOM Event
@@ -191,6 +191,22 @@ var JavaScriptHighlightRules = function() {
], ],
regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
next: "function_arguments" next: "function_arguments"
}, { // match stuff like: Sound.play = function play() { }
token : [
"storage.type",
"punctuation.operator",
"entity.name.function",
"text",
"keyword.operator",
"text",
"storage.type",
"text",
"entity.name.function",
"text",
"paren.lparen"
],
regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",
next: "function_arguments"
}, { // match regular function like: function myFunc(arg) { } }, { // match regular function like: function myFunc(arg) { }
token : [ token : [
"storage.type", "storage.type",
@@ -0,0 +1,53 @@
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var JsxHighlightRules = require("./jsx_highlight_rules").JsxHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
function Mode() {
this.$tokenizer = new Tokenizer(new JsxHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
}
oop.inherits(Mode, TextMode);
(function() {
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
var tokens = tokenizedLine.tokens;
if (tokens.length && tokens[tokens.length-1].type == "comment") {
return indent;
}
if (state == "start") {
var match = line.match(/^.*[\{\(\[]\s*$/);
if (match) {
indent += tab;
}
}
return indent;
};
this.checkOutdent = function(state, line, input) {
return this.$outdent.checkOutdent(line, input);
};
this.autoOutdent = function(state, doc, row) {
this.$outdent.autoOutdent(doc, row);
};
}).call(Mode.prototype);
exports.Mode = Mode;
});
@@ -0,0 +1,122 @@
define(function(require, exports, module) {
var oop = require("../lib/oop");
var lang = require("../lib/lang");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var JsxHighlightRules = function() {
var keywords = lang.arrayToMap(
("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|default|while|function|this|" +
"if|throw|" +
"delete|in|try|" +
"class|extends|super|import|from|into|implements|interface|static|mixin|override|abstract|final|" +
"number|int|string|boolean|variant|" +
"log|assert").split("|")
);
var buildinConstants = lang.arrayToMap(
("null|true|false|NaN|Infinity|__FILE__|__LINE__|undefined").split("|")
);
var reserved = lang.arrayToMap(
("debugger|with|" +
"const|export|" +
"let|private|public|yield|protected|" +
"extern|native|as|operator|__fake__|__readonly__").split("|")
);
var identifierRe = "[a-zA-Z_][a-zA-Z0-9_]*\\b";
this.$rules = {
"start" : [
{
token : "comment",
regex : "\\/\\/.*$"
},
DocCommentHighlightRules.getStartRule("doc-start"),
{
token : "comment", // multi line comment
regex : "\\/\\*",
merge : true,
next : "comment"
}, {
token : "string.regexp",
regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"
}, {
token : "string", // single line
regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
}, {
token : "string", // single line
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
}, {
token : "constant.numeric", // hex
regex : "0[xX][0-9a-fA-F]+\\b"
}, {
token : "constant.numeric", // float
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, {
token : "constant.language.boolean",
regex : "(?:true|false)\\b"
}, {
token : [
"storage.type",
"text",
"entity.name.function"
],
regex : "(function)(\\s+)(" + identifierRe + ")"
}, {
token : function(value) {
if (value == "this")
return "variable.language";
else if (value == "function")
return "storage.type";
else if (keywords.hasOwnProperty(value) || reserved.hasOwnProperty(value))
return "keyword";
else if (buildinConstants.hasOwnProperty(value))
return "constant.language";
else if (/^_?[A-Z][a-zA-Z0-9_]*$/.test(value))
return "language.support.class";
else
return "identifier";
},
// TODO: Unicode escape sequences
// TODO: Unicode identifiers
regex : identifierRe
}, {
token : "keyword.operator",
regex : "!|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
}, {
token : "punctuation.operator",
regex : "\\?|\\:|\\,|\\;|\\."
}, {
token : "paren.lparen",
regex : "[[({<]"
}, {
token : "paren.rparen",
regex : "[\\])}>]"
}, {
token : "text",
regex : "\\s+"
}
],
"comment" : [
{
token : "comment", // closing comment
regex : ".*?\\*\\/",
next : "start"
}, {
token : "comment", // comment spanning whole line
merge : true,
regex : ".+"
}
]
};
this.embedRules(DocCommentHighlightRules, "doc-",
[ DocCommentHighlightRules.getEndRule("start") ]);
};
oop.inherits(JsxHighlightRules, TextHighlightRules);
exports.JsxHighlightRules = JsxHighlightRules;
});
@@ -0,0 +1,22 @@
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var HtmlMode = require("./html").Mode;
var LuaMode = require("./lua").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var LuaPageHighlightRules = require("./luapage_highlight_rules").LuaPageHighlightRules;
var Mode = function() {
var highlighter = new LuaPageHighlightRules();
this.$tokenizer = new Tokenizer(new LuaPageHighlightRules().getRules());
this.$embeds = highlighter.getEmbeds();
this.createModeDelegates({
"lua-": LuaMode
});
};
oop.inherits(Mode, HtmlMode);
exports.Mode = Mode;
});
@@ -0,0 +1,42 @@
// LuaPage implements the LuaPage markup as described by the Kepler Project's CGILua
// documentation: http://keplerproject.github.com/cgilua/manual.html#templates
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
var LuaHighlightRules = require("./lua_highlight_rules").LuaHighlightRules;
var LuaPageHighlightRules = function() {
this.$rules = new HtmlHighlightRules().getRules();
for (var i in this.$rules) {
this.$rules[i].unshift({
token: "keyword",
regex: "<\\%\\=?",
next: "lua-start"
}, {
token: "keyword",
regex: "<\\?lua\\=?",
next: "lua-start"
});
}
this.embedRules(LuaHighlightRules, "lua-", [
{
token: "keyword",
regex: "\\%>",
next: "start"
},
{
token: "keyword",
regex: "\\?>",
next: "start"
}
]);
};
oop.inherits(LuaPageHighlightRules, HtmlHighlightRules);
exports.LuaPageHighlightRules = LuaPageHighlightRules;
});
@@ -80,7 +80,7 @@ var MarkdownHighlightRules = function() {
return "markup.heading." + value.length; return "markup.heading." + value.length;
}, },
regex : "^#{1,6}" regex : "^#{1,6}"
}, github_embed("javascript", "js-"), }, github_embed("(?:javascript|js)", "js-"),
github_embed("xml", "xml-"), github_embed("xml", "xml-"),
github_embed("html", "html-"), github_embed("html", "html-"),
github_embed("css", "css-"), github_embed("css", "css-"),
@@ -90,7 +90,7 @@ function DefaultHandlers(mouseHandler) {
// 2: contextmenu, 1: linux paste // 2: contextmenu, 1: linux paste
editor.textInput.onContextMenu(ev.domEvent); editor.textInput.onContextMenu(ev.domEvent);
return ev.stop(); return; // stopping event here breaks contextmenu on ff mac
} }
// if this click caused the editor to be focused should not clear the // if this click caused the editor to be focused should not clear the
@@ -109,14 +109,9 @@ function DefaultHandlers(mouseHandler) {
// a selection. // a selection.
this.startSelect(pos); this.startSelect(pos);
} else if (inSelection) { } else if (inSelection) {
var e = ev.domEvent;
if ((e.ctrlKey || e.altKey)) {
this.startDrag();
} else {
this.mousedownEvent.time = (new Date()).getTime(); this.mousedownEvent.time = (new Date()).getTime();
this.setState("dragWait"); this.setState("dragWait");
} }
}
this.captureMouse(ev); this.captureMouse(ev);
return ev.preventDefault(); return ev.preventDefault();
@@ -146,8 +141,9 @@ function DefaultHandlers(mouseHandler) {
} else if (cmp == 1) { } else if (cmp == 1) {
anchor = this.$clickSelection.start; anchor = this.$clickSelection.start;
} else { } else {
cursor = this.$clickSelection.end; var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
anchor = this.$clickSelection.start; cursor = orientedRange.cursor;
anchor = orientedRange.anchor;
} }
editor.selection.setSelectionAnchor(anchor.row, anchor.column); editor.selection.setSelectionAnchor(anchor.row, anchor.column);
} }
@@ -175,8 +171,9 @@ function DefaultHandlers(mouseHandler) {
cursor = range.end; cursor = range.end;
anchor = range.start; anchor = range.start;
} else { } else {
cursor = this.$clickSelection.end; var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
anchor = this.$clickSelection.start; cursor = orientedRange.cursor;
anchor = orientedRange.anchor;
} }
editor.selection.setSelectionAnchor(anchor.row, anchor.column); editor.selection.setSelectionAnchor(anchor.row, anchor.column);
} }
@@ -221,7 +218,7 @@ function DefaultHandlers(mouseHandler) {
this.startSelect(); this.startSelect();
}; };
this.dragWait = function() { this.dragWait = function(e) {
var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
var time = (new Date()).getTime(); var time = (new Date()).getTime();
var editor = this.editor; var editor = this.editor;
@@ -229,7 +226,7 @@ function DefaultHandlers(mouseHandler) {
if (distance > DRAG_OFFSET) { if (distance > DRAG_OFFSET) {
this.startSelect(); this.startSelect();
} else if (time - this.mousedownEvent.time > editor.getDragDelay()) { } else if (time - this.mousedownEvent.time > editor.getDragDelay()) {
this.startDrag() this.startDrag();
} }
}; };
@@ -277,12 +274,21 @@ function DefaultHandlers(mouseHandler) {
this.onDoubleClick = function(ev) { this.onDoubleClick = function(ev) {
var pos = ev.getDocumentPosition(); var pos = ev.getDocumentPosition();
var editor = this.editor; var editor = this.editor;
var session = editor.session
var range = session.getBracketRange(pos);
if (range) {
if (range.isEmpty()) {
range.start.column--;
range.end.column++;
}
this.$clickSelection = range;
this.setState("select");
return;
}
this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column);
this.setState("selectByWords"); this.setState("selectByWords");
editor.moveCursorToPosition(pos);
editor.selection.selectWord();
this.$clickSelection = editor.getSelectionRange();
}; };
this.onTripleClick = function(ev) { this.onTripleClick = function(ev) {
@@ -334,4 +340,16 @@ function calcDistance(ax, ay, bx, by) {
return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
} }
function calcRangeOrientation(range, cursor) {
if (range.start.row == range.end.row)
var cmp = 2 * cursor.column - range.start.column - range.end.column;
else
var cmp = 2 * cursor.row - range.start.row - range.end.row;
if (cmp < 0)
return {cursor: range.start, anchor: range.end};
else
return {cursor: range.end, anchor: range.start};
}
}); });
@@ -40,6 +40,7 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var event = require("../lib/event"); var event = require("../lib/event");
var useragent = require("../lib/useragent");
/* /*
* Custom Ace mouse event * Custom Ace mouse event
@@ -130,9 +131,9 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
return this.domEvent.shiftKey; return this.domEvent.shiftKey;
}; };
this.getAccelKey = function() { this.getAccelKey = useragent.isMac
return this.domEvent.ctrlKey || this.domEvent.metaKey ; ? function() { return this.domEvent.metaKey; }
}; : function() { return this.domEvent.ctrlKey; };
}).call(MouseEvent.prototype); }).call(MouseEvent.prototype);
@@ -130,12 +130,12 @@ var MouseHandler = function(editor) {
renderer.$keepTextAreaAtCursor = null; renderer.$keepTextAreaAtCursor = null;
var self = this; var self = this;
var onMouseSelection = function(e) { var onMouseMove = function(e) {
self.x = e.clientX; self.x = e.clientX;
self.y = e.clientY; self.y = e.clientY;
}; };
var onMouseSelectionEnd = function(e) { var onCaptureEnd = function(e) {
clearInterval(timerId); clearInterval(timerId);
self[self.state + "End"] && self[self.state + "End"](e); self[self.state + "End"] && self[self.state + "End"](e);
self.$clickSelection = null; self.$clickSelection = null;
@@ -145,12 +145,12 @@ var MouseHandler = function(editor) {
} }
}; };
var onSelectionInterval = function() { var onCaptureInterval = function() {
self[self.state] && self[self.state](); self[self.state] && self[self.state]();
} }
event.capture(this.editor.container, onMouseSelection, onMouseSelectionEnd); event.capture(this.editor.container, onMouseMove, onCaptureEnd);
var timerId = setInterval(onSelectionInterval, 20); var timerId = setInterval(onCaptureInterval, 20);
}; };
}).call(MouseHandler.prototype); }).call(MouseHandler.prototype);
@@ -53,18 +53,14 @@ function onMouseDown(e) {
var ctrl = e.getAccelKey(); var ctrl = e.getAccelKey();
var button = e.getButton(); var button = e.getButton();
if (e.editor.inMultiSelectMode && button == 2) {
e.editor.textInput.onContextMenu(e.domEvent);
return;
}
if (!ctrl && !alt) { if (!ctrl && !alt) {
if (e.editor.inMultiSelectMode) { if (button == 0 && e.editor.inMultiSelectMode)
if (button == 0) {
e.editor.exitMultiSelectMode(); e.editor.exitMultiSelectMode();
} else if (button == 2) {
var editor = e.editor;
var selectionEmpty = editor.selection.isEmpty();
editor.textInput.onContextMenu({x: e.clientX, y: e.clientY}, selectionEmpty);
event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
e.stop();
}
}
return; return;
} }
@@ -90,7 +90,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
* [start.row/start.column] -> [end.row/end.column] * [start.row/start.column] -> [end.row/end.column]
* *
**/ **/
this.toString = function() { this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column + return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]"); "] -> [" + this.end.row + "/" + this.end.column + "]");
@@ -1,127 +1,57 @@
/* CSS style content from github's default pygments highlighter template. */ /* CSS style content from github's default pygments highlighter template.
Cursor and selection styles from textmate.css. */
.ace-github .ace_editor { .ace-github .ace_editor {
color: #333; color: #333;
background-color: #F8F8F8; background-color: #F8F8F8;
border: 1px solid #CCC; border: 1px solid #CCC;
/* Must use font and not font-family and font-size or the body
font property will override. Also requires important to override ace sty le.*/
font: 13px 'Bitstream Vera Sans Mono', Courier, monospace !important; font: 13px 'Bitstream Vera Sans Mono', Courier, monospace !important;
/* needs !important to set line hight given conflicting ace styles. */
line-height: 19px !important; line-height: 19px !important;
overflow: auto; overflow: auto;
padding: 6px 10px; padding: 6px 10px;
border-radius: 3px; border-radius: 3px;
/* defaults to absolute which causes all code to overlap. */
position: relative; position: relative;
margin-bottom: 15px; margin-bottom: 15px;
} }
/* k = keyword */
.ace-github .ace_keyword { .ace-github .ace_keyword {
font-weight: bold; font-weight: bold;
} }
/*
ss = ace_string
- example ':initial' in example.rb
- Ace is unable to differentiate between
ruby symbols and strings.
s2 = ace_string
*/
.ace-github .ace_string { .ace-github .ace_string {
color: #D14; color: #D14;
} }
/*
nn = ace_variable ace_class
nc = ace_variable ace_class
no = ace_variable ace_class
Ace does not differentiate between nc and no
although pygments does.
see: ruby_func_def.rb
teal from 'no' seems most common so
use that color.
*/
.ace-github .ace_variable.ace_class { .ace-github .ace_variable.ace_class {
color: teal; color: teal;
} }
/* mi = ace_constant ace_numeric */
.ace-github .ace_constant.ace_numeric { .ace-github .ace_constant.ace_numeric {
color: #099; color: #099;
} }
/*
n = ace_identifier
nf = ace_identifier
nn = ace_identifer
Ace thinks java imports are identifiers...
Ace identifies many more identifiers than pygments tags as 'nf'.
Pygments is much better at recognizing individual elements.
Only highlight identifier if it's after a keyword or paren.
- prevents highlighting arguments as functions
- see 'argh, aaahaa' in ruby_func_def.rb
- prevents highlighting methods within method bodies
- see 'ruby!' in ruby_func_def.rb
*/
/*.ace-github .ace_keyword + .ace_identifier,
.ace-github .ace_paren + .ace_identifier {
color: #900;
font-weight: bold;
} */
/* c1 = ace_comment
condensed_ruby.rb */
.ace-github .ace_comment { .ace-github .ace_comment {
color: #998; color: #998;
font-style: italic; font-style: italic;
} }
/*
nb = ace_support ace_function
condensed_ruby.rb
nb = ace_variable ace_language
'self' in condensed_ruby.rb
*/
/*.ace-github .ace_support.ace_function,
ace_support ace_function highlights strange things such as 'Short' in java.
*/
.ace-github .ace_variable.ace_language { .ace-github .ace_variable.ace_language {
color: #0086B3; color: #0086B3;
} }
/* o = ace_paren ace_rparen
o = ace_paren ace_lparen
'[]' in condensed_ruby.rb
*/
.ace-github .ace_paren.ace_lparen, .ace-github .ace_paren.ace_lparen,
.ace-github .ace_paren.ace_rparen { .ace-github .ace_paren.ace_rparen {
font-weight: bold; font-weight: bold;
} }
/*
kp = ace_constant ace_language ace_boolean
*/
.ace-github .ace_constant.ace_language.ace_boolean { .ace-github .ace_constant.ace_language.ace_boolean {
font-weight: bold; font-weight: bold;
} }
/*
sr = ace_string ace_regexp
Sometimes ace will fail to recognize regexps.
*/
.ace-github .ace_string.ace_regexp { .ace-github .ace_string.ace_regexp {
color: #009926; color: #009926;
font-weight: normal; font-weight: normal;
} }
/* vi = ace_variable ace_instancce */
.ace-github .ace_variable.ace_instancce { .ace-github .ace_variable.ace_instancce {
color: teal; color: teal;
} }
@@ -129,3 +59,24 @@ ace_support ace_function highlights strange things such as 'Short' in java.
.ace-github .ace_constant.ace_language { .ace-github .ace_constant.ace_language {
font-weight: bold; font-weight: bold;
} }
.ace-github .ace_text-layer {
cursor: text;
}
.ace-github .ace_cursor {
border-left: 2px solid black;
}
.ace-github .ace_cursor.ace_overwrite {
border-left: 0px;
border-bottom: 1px solid black;
}
.ace-github .ace_marker-layer .ace_selection {
background: rgb(181, 213, 255);
}
.ace-github.multiselect .ace_selection.start {
box-shadow: 0 0 3px 0px white;
border-radius: 2px;
}
@@ -467,14 +467,14 @@ var VirtualRenderer = function(container, theme) {
return; return;
if (!gutterReady) { if (!gutterReady) {
var ch = this.$gutterLayer.element.children var lineEl, ch = this.$gutterLayer.element.children;
var oldEl = ch[this.$gutterLineHighlight - this.layerConfig.firstRow]; var index = this.$gutterLineHighlight - this.layerConfig.firstRow;
if (oldEl) if (index >= 0 && (lineEl = ch[index]))
dom.removeCssClass(oldEl, "ace_gutter_active_line"); dom.removeCssClass(lineEl, "ace_gutter_active_line");
var newEl = ch[i - this.layerConfig.firstRow]; index = i - this.layerConfig.firstRow;
if (newEl) if (index >= 0 && (lineEl = ch[index]))
dom.addCssClass(newEl, "ace_gutter_active_line"); dom.addCssClass(lineEl, "ace_gutter_active_line");
} }
this.$gutterLayer.removeGutterDecoration(this.$gutterLineHighlight, "ace_gutter_active_line"); this.$gutterLayer.removeGutterDecoration(this.$gutterLineHighlight, "ace_gutter_active_line");
@@ -56,14 +56,17 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
workerUrl = require.nameToUrl("ace/worker/worker_sourcemint"); workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
} else { } else {
// We are running in RequireJS. // We are running in RequireJS.
workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_")); // nameToUrl is renamed to toUrl in requirejs 2
if (require.nameToUrl && !require.toUrl)
require.toUrl = require.nameToUrl;
workerUrl = this.$normalizePath(require.toUrl("ace/worker/worker", null, "_"));
} }
this.$worker = new Worker(workerUrl); this.$worker = new Worker(workerUrl);
var tlns = {}; var tlns = {};
for (var i=0; i<topLevelNamespaces.length; i++) { for (var i=0; i<topLevelNamespaces.length; i++) {
var ns = topLevelNamespaces[i]; var ns = topLevelNamespaces[i];
var path = this.$normalizePath(require.nameToUrl(ns, null, "_").replace(/.js$/, "")); var path = this.$normalizePath(require.toUrl(ns, null, "_").replace(/.js$/, ""));
tlns[ns] = path; tlns[ns] = path;
} }