diff --git a/ChangeLog.txt b/ChangeLog.txt
index 2b1f88bb..224f9326 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,13 @@
+2014.07.01 Version 1.1.4
+
+* New Features
+ - Highlight matching tags (Adam Jimenez)
+ - Improved jump to matching command (Adam Jimenez)
+
+* new language modes
+ - AppleScript (Yaogang Lian)
+ - Vala
+
2014.03.08 Version 1.1.3
* New Features
diff --git a/Makefile b/Makefile
index 95dcf964..29cf0495 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,6 @@ pre_build:
build: pre_build
./Makefile.dryice.js normal
./Makefile.dryice.js demo
- ./Makefile.dryice.js bm
# Minimal build: call Makefile.dryice.js only if our sources changed
basic: build/src/ace.js
diff --git a/Makefile.dryice.js b/Makefile.dryice.js
index 19ba9192..2bc36f8b 100755
--- a/Makefile.dryice.js
+++ b/Makefile.dryice.js
@@ -31,14 +31,12 @@
var fs = require("fs");
var path = require("path");
-if (!fs.existsSync)
- fs.existsSync = path.existsSync;
-else
- path.existsSync = fs.existsSync;
-var copy = require('dryice').copy;
+var copy = require('architect-build/copy');
+var build = require('architect-build/build');
var ACE_HOME = __dirname;
var BUILD_DIR = ACE_HOME + "/build";
+var CACHE = {};
function main(args) {
if (args.indexOf("updateModes") !== -1) {
@@ -49,7 +47,7 @@ function main(args) {
if (x[0] == "-" && x[1] != "-")
return "-" + x;
return x;
- });
+ }).filter(Boolean);
if (args[2] && (args[2][0] != "-" || args[2].indexOf("h") != -1))
type = args[2];
@@ -69,36 +67,22 @@ function main(args) {
ace();
} else if (type == "demo") {
demo();
- } else if (type == "bm") {
- bookmarklet();
} else if (type == "full") {
- demo(ace());
- bookmarklet();
+ ace();
+ demo();
} else if (type == "highlighter") {
- var project = buildAce({
- coreOnly: true,
- exportModule: "ace/ext/static_highlight",
- requires: ["ace/ext/static_highlight", "ace/theme/textmate"],
- readFilters: [copy.filter.moduleDefines, function(a) {
- console.log(a.substring(0, 2500))
- return a
- }]
- })
- copy({
- source: project.result,
- filter: getWriteFilters(project.options, "main"),
- dest: BUILD_DIR + "/static_highlight.js"
- });
+ // TODO
}
}
+}
+function showHelp(type) {
console.log("--- Ace Dryice Build Tool ---");
console.log("");
console.log("Options:");
console.log(" minimal Places necessary Ace files out in build dir; uses configuration flags below [default]");
console.log(" normal Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min");
console.log(" demo Runs demo build of Ace");
- console.log(" bm Runs bookmarklet build of Ace");
console.log(" full all of above");
console.log(" highlighter ");
console.log("args:");
@@ -109,91 +93,30 @@ function main(args) {
console.log(" --nc namespace require");
console.log(" --s shrinkwrap (combines all output files into one)");
console.log("");
- if (BUILD_DIR)
- console.log(" output generated in " + type + __dirname + "/" + BUILD_DIR)
-}
-
-function bookmarklet() {
- var targetDir = BUILD_DIR + "/textarea";
- copy({
- source: "build_support/editor_textarea.html",
- dest: targetDir + '/editor.html'
- });
- copy({
- source: "build_support/style.css",
- dest: targetDir + '/style.css'
- });
-
- buildAce({
- targetDir: targetDir + "/src",
- ns: "__ace_shadowed__",
- exportModule: "ace/ext/textarea",
- compress: false,
- noconflict: true,
- suffix: "",
- name: "ace-bookmarklet",
- workers: [],
- keybindings: []
- });
+ if (type)
+ console.log(" output for " + type + " generated in " + BUILD_DIR);
}
function ace() {
- console.log('# ace ---------');
-
- // uncompressed
- var project = buildAce({
- compress: false,
- noconflict: false
- });
- buildAce({
- compress: false,
- noconflict: true
- });
-
- // compressed
- buildAce({
- compress: true,
- noconflict: false
- });
- buildAce({
- compress: true,
- noconflict: true
- });
-
console.log('# ace License | Readme | Changelog ---------');
- copy({
- source: ACE_HOME + "/build_support/editor.html",
- dest: BUILD_DIR + "/editor.html"
- });
- copy({
- source: ACE_HOME + "/LICENSE",
- dest: BUILD_DIR + "/LICENSE"
- });
- copy({
- source: ACE_HOME + "/ChangeLog.txt",
- dest: BUILD_DIR + "/ChangeLog.txt"
- });
-
- return project;
+ copy.file(ACE_HOME + "/build_support/editor.html", BUILD_DIR + "/editor.html");
+ copy.file(ACE_HOME + "/LICENSE", BUILD_DIR + "/LICENSE");
+ copy.file(ACE_HOME + "/ChangeLog.txt", BUILD_DIR + "/ChangeLog.txt");
+
+ console.log('# ace ---------');
+ for (var i = 0; i < 4; i++)
+ buildAce({compress: i & 2, noconflict: i & 1});
}
-function demo(project) {
- project = project || buildAce({
- compress: false,
- noconflict: false,
- coreOnly: true
- });
+function demo() {
console.log('# kitchen sink ---------');
- var version, ref;
+ var version = "", ref = "";
try {
version = JSON.parse(fs.readFileSync(ACE_HOME + "/package.json")).version;
ref = fs.readFileSync(ACE_HOME + "/.git-ref").toString();
- } catch(e) {
- ref = "";
- version = "";
- }
+ } catch(e) {}
function changeComments(data) {
return (data
@@ -204,88 +127,54 @@ function demo(project) {
.replace("%version%", version)
.replace("%commit%", ref)
);
- };
-
- function fixDocPaths(data) {
- return data.replace(/"(demo|build)\//g, "\"");
}
-
- copy({
- source: ACE_HOME + "/kitchen-sink.html",
- dest: BUILD_DIR + "/kitchen-sink.html",
- filter: [changeComments, fixDocPaths]
- });
-
- copy({
- source: ACE_HOME + "/demo/kitchen-sink/styles.css",
- dest: BUILD_DIR + "/kitchen-sink/styles.css",
- filter: [ changeComments ]
- });
-
- fs.readdirSync(ACE_HOME +"/demo/kitchen-sink/docs/").forEach(function(x) {
- copy({
- source: ACE_HOME +"/demo/kitchen-sink/docs/" + x,
- dest: BUILD_DIR + "/kitchen-sink/docs/" + x
- });
- });
-
- var demo = copy.createDataObject();
-
- project.assumeAllFilesLoaded();
- copy({
- source: [{
- project: cloneProject(project),
- require: [ "kitchen-sink/demo" ]
- }],
- filter: getWriteFilters({filters:[fixDocPaths]}, "demo"),
- dest: demo
- });
-
- copy({
- source: demo,
- dest: BUILD_DIR + "/kitchen-sink/demo.js",
- });
-
- copyFileSync(ACE_HOME + "/demo/kitchen-sink/logo.png", BUILD_DIR + "/kitchen-sink/logo.png");
- fs.readdirSync(ACE_HOME + "/demo/").forEach(function(x) {
- if (/\s|requirejs/.test(x) || !/\.(js|html)$/.test(x))
- return;
- copy({
- source: ACE_HOME +"/demo/" + x,
- dest: BUILD_DIR + "/demo/" + x,
- filter: [function(source) {
- if (/\.(js)$/.test(x))
- return source;
- var removeRequireJS
- source = source.replace(/')}
- scripts.forEach(function(s) {
- s = s.replace(/"/g, "");
- if (s == "ace/ace") {
- comment("load ace")
- script("ace")
- } else {
- var extName = s.match(/[^/]*$/)[0];
- comment("load ace " + extName + " extension");
- script("ext-" + extName);
- }
- });
- result.push("')}
+ scripts.forEach(function(s) {
+ s = s.replace(/"/g, "");
+ if (s == "ace/ace") {
+ comment("load ace");
+ script("ace");
+ } else {
+ var extName = s.match(/[^/]*$/)[0];
+ comment("load ace " + extName + " extension");
+ script("ext-" + extName);
+ }
+ });
+ result.push("
+
diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js
index 0b35ca74..552b1e65 100644
--- a/demo/kitchen-sink/demo.js
+++ b/demo/kitchen-sink/demo.js
@@ -592,7 +592,7 @@ env.editSnippets = function() {
require("ace/ext/language_tools");
env.editor.setOptions({
enableBasicAutocompletion: true,
- enableLiveAutocompletion: true,
+ enableLiveAutocompletion: false,
enableSnippets: true
});
diff --git a/demo/kitchen-sink/docs/.gitignore b/demo/kitchen-sink/docs/.gitignore
new file mode 100644
index 00000000..56ec8fd9
--- /dev/null
+++ b/demo/kitchen-sink/docs/.gitignore
@@ -0,0 +1,11 @@
+# A sample .gitignore file.
+
+.buildlog
+.DS_Store
+.svn
+
+# Negated patterns:
+!foo.bar
+
+# Also ignore user settings...
+/.settings
diff --git a/demo/kitchen-sink/docs/vala.vala b/demo/kitchen-sink/docs/vala.vala
new file mode 100644
index 00000000..f9600286
--- /dev/null
+++ b/demo/kitchen-sink/docs/vala.vala
@@ -0,0 +1,21 @@
+using Gtk;
+
+int main (string[] args) {
+ Gtk.init (ref args);
+ var foo = new MyFoo>();
+
+ var window = new Window();
+ window.title = "Hello, World!";
+ window.border_width = 10;
+ window.window_position = WindowPosition.CENTER;
+ window.set_default_size(350, 70);
+ window.destroy.connect(Gtk.main_quit);
+
+ var label = new Label("Hello, World!");
+
+ window.add(label);
+ window.show_all();
+
+ Gtk.main();
+ return 0;
+}
\ No newline at end of file
diff --git a/demo/requirejs+build.html b/demo/requirejs+build.html
index 4a494063..72d50dbc 100644
--- a/demo/requirejs+build.html
+++ b/demo/requirejs+build.html
@@ -29,14 +29,20 @@
}
-
@@ -287,7 +281,7 @@
-
+
diff --git a/lib/ace/autocomplete.js b/lib/ace/autocomplete.js
index a2fea74f..13d140d9 100644
--- a/lib/ace/autocomplete.js
+++ b/lib/ace/autocomplete.js
@@ -101,12 +101,12 @@ var Autocomplete = function() {
this.changeTimer.cancel();
if (this.popup && this.popup.isOpen) {
- this.gatherCompletionsId = this.gatherCompletionsId + 1;
- }
-
- if (this.popup)
+ this.gatherCompletionsId += 1;
this.popup.hide();
-
+ }
+
+ if (this.base)
+ this.base.detach();
this.activated = false;
this.completions = this.base = null;
};
@@ -205,8 +205,7 @@ var Autocomplete = function() {
var line = session.getLine(pos.row);
var prefix = util.retrievePrecedingIdentifier(line, pos.column);
- this.base = editor.getCursorPosition();
- this.base.column -= prefix.length;
+ this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
var matches = [];
var total = editor.completers.length;
@@ -306,13 +305,7 @@ var Autocomplete = function() {
};
this.cancelContextMenu = function() {
- var stop = function(e) {
- this.editor.off("nativecontextmenu", stop);
- if (e && e.domEvent)
- event.stopEvent(e.domEvent);
- }.bind(this);
- setTimeout(stop, 10);
- this.editor.on("nativecontextmenu", stop);
+ this.editor.$mouseHandler.cancelContextMenu();
};
}).call(Autocomplete.prototype);
diff --git a/lib/ace/autocomplete/popup.js b/lib/ace/autocomplete/popup.js
index a0ab7604..a34ebf09 100644
--- a/lib/ace/autocomplete/popup.js
+++ b/lib/ace/autocomplete/popup.js
@@ -67,6 +67,7 @@ var AcePopup = function(parentNode) {
popup.renderer.setStyle("ace_autocomplete");
popup.setOption("displayIndentGuides", false);
+ popup.setOption("dragDelay", 150);
var noop = function(){};
@@ -178,7 +179,7 @@ var AcePopup = function(parentNode) {
if (typeof data == "string")
data = {value: data};
if (!data.caption)
- data.caption = data.value;
+ data.caption = data.value || data.name;
var last = -1;
var flag, c;
diff --git a/lib/ace/autocomplete/text_completer.js b/lib/ace/autocomplete/text_completer.js
index 6eebfc61..17a4bdad 100644
--- a/lib/ace/autocomplete/text_completer.js
+++ b/lib/ace/autocomplete/text_completer.js
@@ -68,7 +68,7 @@ define(function(require, exports, module) {
var wordList = Object.keys(wordScore);
callback(null, wordList.map(function(word) {
return {
- name: word,
+ caption: word,
value: word,
score: wordScore[word],
meta: "local"
diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js
index 77cdfc61..a150a76f 100644
--- a/lib/ace/commands/default_commands.js
+++ b/lib/ace/commands/default_commands.js
@@ -392,17 +392,23 @@ exports.commands = [{
readOnly: true
}, {
name: "jumptomatching",
- bindKey: bindKey("Ctrl-P", "Ctrl-Shift-P"),
+ bindKey: bindKey("Ctrl-P", "Ctrl-P"),
exec: function(editor) { editor.jumpToMatching(); },
multiSelectAction: "forEach",
readOnly: true
}, {
name: "selecttomatching",
- bindKey: bindKey("Ctrl-Shift-P", null),
+ bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
exec: function(editor) { editor.jumpToMatching(true); },
multiSelectAction: "forEach",
readOnly: true
-},
+}, {
+ name: "passKeysToBrowser",
+ bindKey: bindKey("null", "null"),
+ exec: function() {},
+ passEvent: true,
+ readOnly: true
+},
// commands disabled in readOnly mode
{
diff --git a/lib/ace/config.js b/lib/ace/config.js
index 1d927e45..f4e4c89a 100644
--- a/lib/ace/config.js
+++ b/lib/ace/config.js
@@ -153,7 +153,11 @@ function init(packaged) {
var scriptOptions = {};
var scriptUrl = "";
- var scripts = document.getElementsByTagName("script");
+ // Use currentScript.ownerDocument in case this file was loaded from imported document. (HTML Imports)
+ var currentScript = (document.currentScript || document._currentScript ); // native or polyfill
+ var currentDocument = currentScript && currentScript.ownerDocument || document;
+
+ var scripts = currentDocument.getElementsByTagName("script");
for (var i=0; i=0);
+ }else{
+ //find opening tag
+ do {
+ token = prevToken;
+ prevToken = iterator.stepBackward();
+
+ if(token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
+ if (prevToken.value==='<') {
+ depth++;
+ } else if( prevToken.value==='') {
+ depth--;
+ }
+ }
+ } while (prevToken && depth<=0);
+
+ //select tag again
+ iterator.stepForward();
+ }
+
+ if (!token) {
+ session.removeMarker(session.$tagHighlight);
+ session.$tagHighlight = null;
+ return;
+ }
+
+ var row = iterator.getCurrentTokenRow();
+ var column = iterator.getCurrentTokenColumn();
+ var range = new Range(row, column, row, column+token.value.length);
+
+ //remove range if different
+ if (session.$tagHighlight && range.compareRange(session.$backMarkers[session.$tagHighlight].range)!==0) {
+ session.removeMarker(session.$tagHighlight);
+ session.$tagHighlight = null;
+ }
+
+ if (range && !session.$tagHighlight)
+ session.$tagHighlight = session.addMarker(range, "ace_bracket", "text");
+ }, 50);
+ };
+
/**
*
* Brings the current `textInput` into focus.
@@ -651,6 +736,7 @@ var Editor = function(renderer, session) {
}
this.$highlightBrackets();
+ this.$highlightTags();
this.$updateHighlightActiveLine();
this._signal("changeSelection");
};
@@ -1915,24 +2001,157 @@ 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 or HTML tag.
*
**/
this.jumpToMatching = function(select) {
var cursor = this.getCursorPosition();
+ var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
+ var prevToken = iterator.getCurrentToken();
+ var token = prevToken;
- var range = this.session.getBracketRange(cursor);
- if (!range) {
- range = this.find({
- needle: /[{}()\[\]]/g,
- preventScroll:true,
- start: {row: cursor.row, column: cursor.column - 1}
- });
- if (!range)
+ if (!token)
+ token = iterator.stepForward();
+
+ if (!token)
+ return;
+
+ //get next closing tag or bracket
+ var matchType;
+ var found = false;
+ var depth = {};
+ var i = cursor.column - token.start;
+ var bracketType;
+ var brackets = {
+ ")": "(",
+ "(": "(",
+ "]": "[",
+ "[": "[",
+ "{": "{",
+ "}": "{"
+ };
+
+ do {
+ if (token.value.match(/[{}()\[\]]/g)) {
+ for (; i"
);
return;
@@ -496,10 +470,10 @@ function setupSettingPanel(settingDiv, settingOpener, editor, options) {
builder.push("");
}
- for (var option in options) {
+ for (var option in exports.defaultOptions) {
table.push("| ", desc[option], " | ");
table.push("");
- renderOption(table, option, optionValues[option], options[option]);
+ renderOption(table, option, optionValues[option], editor.getOption(option));
table.push(" |
");
}
table.push("");
@@ -532,12 +506,12 @@ function setupSettingPanel(settingDiv, settingOpener, editor, options) {
}
// Default startup options.
-exports.options = {
- mode: "text",
+exports.defaultOptions = {
+ mode: "javascript",
theme: "textmate",
- gutter: "false",
+ wrap: "off",
fontSize: "12px",
- softWrap: "off",
+ showGutter: "false",
keybindings: "ace",
showPrintMargin: "false",
useSoftTabs: "true",
diff --git a/lib/ace/ext/whitespace.js b/lib/ace/ext/whitespace.js
index a3c179f3..fdbf7360 100644
--- a/lib/ace/ext/whitespace.js
+++ b/lib/ace/ext/whitespace.js
@@ -46,7 +46,6 @@ exports.$detectIndentation = function(lines, fallback) {
if (!/^\s*[^*+\-\s]/.test(line))
continue;
- var tabs = line.match(/^\t*/)[0].length;
if (line[0] == "\t")
tabIndents++;
@@ -65,9 +64,6 @@ exports.$detectIndentation = function(lines, fallback) {
line = lines[i++];
}
- if (!stats.length)
- return;
-
function getScore(indent) {
var score = 0;
for (var i = indent; i < stats.length; i += indent)
@@ -82,7 +78,7 @@ exports.$detectIndentation = function(lines, fallback) {
for (var i = 1; i < 12; i++) {
if (i == 1) {
spaceIndents = getScore(i);
- var score = 1;
+ var score = stats.length && 1;
} else
var score = getScore(i) / spaceIndents;
@@ -99,7 +95,7 @@ exports.$detectIndentation = function(lines, fallback) {
if (tabIndents > spaceIndents + 1)
return {ch: "\t", length: tabLength};
- if (spaceIndents + 1 > tabIndents)
+ if (spaceIndents > tabIndents + 1)
return {ch: " ", length: tabLength};
};
diff --git a/lib/ace/ext/whitespace_test.js b/lib/ace/ext/whitespace_test.js
new file mode 100644
index 00000000..be4f360f
--- /dev/null
+++ b/lib/ace/ext/whitespace_test.js
@@ -0,0 +1,116 @@
+if (typeof process !== "undefined") {
+ require("amd-loader");
+ require("../test/mockdom");
+}
+
+define(function(require, exports, module) {
+"use strict";
+
+var assert = require("assert");
+var EditSession = require("../edit_session").EditSession;
+var whitespace = require("./whitespace");
+
+// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite
+module.exports = {
+ timeout: 10000,
+
+ "test tab detection": function(next) {
+ var s = new EditSession([
+ "define({",
+ "\tfoo:1,",
+ "\tbar:2,",
+ "\tbaz:{,",
+ "\t\tx:3",
+ "\t}",
+ "})"
+ ]);
+
+ var indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.equal(indent.ch, "\t");
+ assert.equal(indent.length, undefined);
+
+ s.insert({row: 0, column: 0}, " ");
+ indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.equal(indent.ch, "\t");
+ assert.equal(indent.length, 4);
+
+ s.setValue("");
+ indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.ok(!indent);
+
+ next();
+ },
+
+ "test empty session": function(next) {
+ var s = new EditSession([
+ "define({",
+ "foo:1,",
+ "})"
+ ]);
+ var indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.ok(!indent);
+ s.insert({row: 1, column: 0}, " x\n ");
+
+ indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.equal(indent.ch, " ");
+ assert.equal(indent.length, 4);
+
+ next();
+ },
+
+ "!test one line": function(next) {
+ var s = new EditSession([
+ "define({",
+ " foo:1,",
+ "})"
+ ]);
+ var indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.equal(indent.ch, " ");
+ assert.equal(indent.length, 4);
+
+ next();
+ },
+
+ "test 1 width indents": function(next) {
+ var s = new EditSession([
+ "define({",
+ " foo:1,",
+ "})",
+ "define({",
+ " bar:1,",
+ "})",
+ " t",
+ " t",
+ " t",
+ " t",
+ " t",
+ " t",
+ " t",
+ " t"
+ ]);
+ var indent = whitespace.$detectIndentation(s.doc.$lines);
+ // assert.equal(indent.ch, " ");
+ // assert.equal(indent.length, 4);
+
+ s = new EditSession([
+ "{",
+ " foo:1,",
+ " bar: {",
+ " baz:2",
+ " }",
+ "}"
+ ]);
+ indent = whitespace.$detectIndentation(s.doc.$lines);
+ assert.equal(indent.ch, " ");
+ assert.equal(indent.length, 1);
+
+ next();
+ },
+
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec();
+}
diff --git a/lib/ace/keyboard/textarea.js b/lib/ace/keyboard/textarea.js
new file mode 100644
index 00000000..470b2940
--- /dev/null
+++ b/lib/ace/keyboard/textarea.js
@@ -0,0 +1,82 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+var HashHandler = require("./hash_handler").HashHandler;
+exports.handler = new HashHandler();
+
+[{
+ bindKey: "Shift-Tab|Tab",
+ command: "passKeysToBrowser"
+}, {
+ bindKey: {win: "Ctrl-L", mac: "Cmd-L"},
+ command: "passKeysToBrowser"
+}, {
+ bindKey: {win: "Ctrl-G", mac: "Cmd-G"},
+ command: "gotoline"
+}, {
+ bindKey: {win: "Ctrl-T|Ctrl-Shift-T", mac: "Cmd-T|Cmd-Shift-T"},
+ command: "passKeysToBrowser"
+}, {
+ bindKey: {win: "Ctrl-G", mac: "Cmd-G"},
+ command: "passKeysToBrowser"
+}, {
+ bindKey: {win: "Ctrl-G", mac: "Cmd-G"},
+ command: "passKeysToBrowser"
+}, {
+ name: "golineup",
+ bindKey: {win: null, mac: "Ctrl-P"},
+}, {
+ name: "golinedown",
+ bindKey: {win: null, mac: "Ctrl-N"},
+}, {
+ name: "gotoleft",
+ bindKey: {win: null, mac: "Ctrl-B"},
+}, {
+ name: "gotoright",
+ bindKey: {win: null, mac: "Ctrl-F"},
+}, {
+ name: "gotolineend",
+ bindKey: {win: null, mac: "Ctrl-E"},
+}, {
+ name: "gotolinestart",
+ bindKey: {win: null, mac: "Ctrl-A"},
+}
+].forEach(function(k) {
+ var bindKey = k.bindKey;
+ if (typeof bindKey == "object")
+ bindKey = bindKey[exports.handler.platform];
+ exports.handler.bindKey(bindKey, k.command);
+});
+exports.handler.$id = "ace/keyboard/textarea";
+
+});
diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js
index fbf37786..ed213d70 100644
--- a/lib/ace/keyboard/textinput.js
+++ b/lib/ace/keyboard/textinput.js
@@ -428,13 +428,17 @@ var TextInput = function(parentNode, host) {
this.onContextMenu = function(e) {
afterContextMenu = true;
- if (!tempStyle)
- tempStyle = text.style.cssText;
-
- text.style.cssText = "z-index:100000;" + (useragent.isIE ? "opacity:0.1;" : "");
-
resetSelection(host.selection.isEmpty());
host._emit("nativecontextmenu", {target: host, domEvent: e});
+ this.moveToMouse(e, true);
+ };
+
+ this.moveToMouse = function(e, bringToFront) {
+ if (!tempStyle)
+ tempStyle = text.style.cssText;
+ text.style.cssText = (bringToFront ? "z-index:100000;" : "")
+ + (useragent.isIE ? "opacity:0.1;" : "");
+
var rect = host.container.getBoundingClientRect();
var style = dom.computedStyle(host.container);
var top = rect.top + (parseInt(style.borderTopWidth) || 0);
diff --git a/lib/ace/keyboard/vim/maps/operators.js b/lib/ace/keyboard/vim/maps/operators.js
index 350bbd05..6df55b0f 100644
--- a/lib/ace/keyboard/vim/maps/operators.js
+++ b/lib/ace/keyboard/vim/maps/operators.js
@@ -34,6 +34,7 @@ define(function(require, exports, module) {
var util = require("./util");
var registers = require("../registers");
+var Range = require("../../../range").Range;
module.exports = {
"d": {
@@ -90,15 +91,18 @@ module.exports = {
count = count || 1;
switch (param) {
case "c":
- for (var i = 0; i < count; i++) {
- editor.removeLines();
- util.insertMode(editor);
- }
-
+ editor.$blockScrolling++;
+ editor.selection.$moveSelection(function() {
+ editor.selection.moveCursorBy(count - 1, 0);
+ });
+ var rows = editor.$getSelectedRows();
+ range = new Range(rows.first, 0, rows.last, Infinity);
+ editor.session.remove(range);
+ editor.$blockScrolling--;
+ util.insertMode(editor);
break;
default:
if (range) {
-
// range.end.column ++;
editor.session.remove(range);
util.insertMode(editor);
diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js
index cd1b992d..37e038b5 100644
--- a/lib/ace/layer/marker.js
+++ b/lib/ace/layer/marker.js
@@ -93,7 +93,7 @@ var Marker = function(parentEl) {
this.drawSingleLineMarker(html, range, marker.clazz + " ace_start", config);
}
}
- this.element = dom.setInnerHtml(this.element, html.join(""));
+ this.element.innerHTML = html.join("");
};
this.$getTop = function(row, layerConfig) {
diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js
index 140700aa..748d2231 100644
--- a/lib/ace/layer/text.js
+++ b/lib/ace/layer/text.js
@@ -203,7 +203,7 @@ var Text = function(parentEl) {
html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
);
lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
- dom.setInnerHtml(lineElement, html.join(""));
+ lineElement.innerHTML = html.join("");
}
row++;
}
@@ -310,7 +310,7 @@ var Text = function(parentEl) {
row++;
}
- this.element = dom.setInnerHtml(this.element, html.join(""));
+ this.element.innerHTML = html.join("");
};
this.$textToken = {
diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js
index 39d115b4..612b6a34 100644
--- a/lib/ace/lib/event.js
+++ b/lib/ace/lib/event.js
@@ -85,7 +85,7 @@ exports.preventDefault = function(e) {
exports.getButton = function(e) {
if (e.type == "dblclick")
return 0;
- if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
+ if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
return 2;
// DOM Event
@@ -183,7 +183,7 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
if (!timer || isNewClick)
clicks = 1;
if (timer)
- clearTimeout(timer)
+ clearTimeout(timer);
timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
if (clicks == 1) {
diff --git a/lib/ace/lib/useragent.js b/lib/ace/lib/useragent.js
index e539dae3..0d1d9f4d 100644
--- a/lib/ace/lib/useragent.js
+++ b/lib/ace/lib/useragent.js
@@ -82,7 +82,7 @@ exports.isIE =
exports.isOldIE = exports.isIE && exports.isIE < 9;
// Is this Firefox or related?
-exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
+exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
// oldGecko == rev < 2.0
exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv\:(\d+)/)||[])[1], 10) < 4;
diff --git a/lib/ace/line_widgets.js b/lib/ace/line_widgets.js
index 94ad9ddf..9e384e0e 100644
--- a/lib/ace/line_widgets.js
+++ b/lib/ace/line_widgets.js
@@ -87,7 +87,6 @@ function LineWidgets(session) {
editor.widgetManager = this;
- editor.setOption("enableLineWidgets", true);
editor.renderer.on("beforeRender", this.measureWidgets);
editor.renderer.on("afterRender", this.renderWidgets);
};
diff --git a/lib/ace/mode/applescript.js b/lib/ace/mode/applescript.js
index 121b73eb..81bc3533 100644
--- a/lib/ace/mode/applescript.js
+++ b/lib/ace/mode/applescript.js
@@ -47,6 +47,7 @@ oop.inherits(Mode, TextMode);
(function() {
this.lineCommentStart = "--";
this.blockComment = {start: "(*", end: "*)"};
+ this.$id = "ace/mode/applescript";
// Extra logic goes here.
}).call(Mode.prototype);
diff --git a/lib/ace/mode/dart_highlight_rules.js b/lib/ace/mode/dart_highlight_rules.js
index 311acd90..750392f7 100644
--- a/lib/ace/mode/dart_highlight_rules.js
+++ b/lib/ace/mode/dart_highlight_rules.js
@@ -54,7 +54,7 @@ var DartHighlightRules = function() {
},
{
token: "keyword.other.import.dart",
- regex: "(?:\\b)(?:library|import|part|of)(?:\\b)"
+ regex: "(?:\\b)(?:library|import|export|part|of)(?:\\b)"
},
{
token : ["keyword.other.import.dart", "text"],
diff --git a/lib/ace/mode/gitignore.js b/lib/ace/mode/gitignore.js
new file mode 100644
index 00000000..fd9b04f4
--- /dev/null
+++ b/lib/ace/mode/gitignore.js
@@ -0,0 +1,19 @@
+
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var GitignoreHighlightRules = require("./gitignore_highlight_rules").GitignoreHighlightRules;
+
+var Mode = function() {
+ this.HighlightRules = GitignoreHighlightRules;
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+ this.$id = "ace/mode/gitignore";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
diff --git a/lib/ace/mode/gitignore_highlight_rules.js b/lib/ace/mode/gitignore_highlight_rules.js
new file mode 100644
index 00000000..cfa42afa
--- /dev/null
+++ b/lib/ace/mode/gitignore_highlight_rules.js
@@ -0,0 +1,31 @@
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var GitignoreHighlightRules = function() {
+ this.$rules = {
+ "start" : [
+ {
+ token : "comment",
+ regex : /^\s*#.*$/
+ }, {
+ token : "keyword", // negated patterns
+ regex : /^\s*!.*$/
+ }
+ ]
+ };
+
+ this.normalizeRules();
+};
+
+GitignoreHighlightRules.metaData = {
+ fileTypes: ['gitignore'],
+ name: 'Gitignore'
+};
+
+oop.inherits(GitignoreHighlightRules, TextHighlightRules);
+
+exports.GitignoreHighlightRules = GitignoreHighlightRules;
+});
diff --git a/lib/ace/mode/golang_highlight_rules.js b/lib/ace/mode/golang_highlight_rules.js
index 5bd40b44..2369c8cb 100644
--- a/lib/ace/mode/golang_highlight_rules.js
+++ b/lib/ace/mode/golang_highlight_rules.js
@@ -72,9 +72,6 @@ define(function(require, exports, module) {
}, {
token : "paren.rparen",
regex : "[\\])}]"
- }, {
- token: "invalid",
- regex: "\\s+$"
}, {
token : "text",
regex : "\\s+"
diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js
index fb2039b6..12590467 100644
--- a/lib/ace/mode/javascript/jshint.js
+++ b/lib/ace/mode/javascript/jshint.js
@@ -27,9 +27,9 @@ module.exports = {
},
{}],
2:[function(_dereq_,module,exports){
-// Underscore.js 1.4.4
+// Underscore.js 1.6.0
// http://underscorejs.org
-// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
+// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
@@ -37,7 +37,7 @@ module.exports = {
// Baseline setup
// --------------
- // Establish the root object, `window` in the browser, or `global` on the server.
+ // Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Save the previous value of the `_` variable.
@@ -50,11 +50,12 @@ module.exports = {
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
- var push = ArrayProto.push,
- slice = ArrayProto.slice,
- concat = ArrayProto.concat,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty;
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
@@ -93,7 +94,7 @@ module.exports = {
}
// Current version.
- _.VERSION = '1.4.4';
+ _.VERSION = '1.6.0';
// Collection Functions
// --------------------
@@ -102,20 +103,20 @@ module.exports = {
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
- if (obj == null) return;
+ if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
+ for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
}
}
+ return obj;
};
// Return the results of applying the iterator to each element.
@@ -125,7 +126,7 @@ module.exports = {
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
+ results.push(iterator.call(context, value, index, list));
});
return results;
};
@@ -181,10 +182,10 @@ module.exports = {
};
// Return the first value which passes a truth test. Aliased as `detect`.
- _.find = _.detect = function(obj, iterator, context) {
+ _.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) {
+ if (predicate.call(context, value, index, list)) {
result = value;
return true;
}
@@ -195,33 +196,33 @@ module.exports = {
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
- _.filter = _.select = function(obj, iterator, context) {
+ _.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results[results.length] = value;
+ if (predicate.call(context, value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
- _.reject = function(obj, iterator, context) {
+ _.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
- return !iterator.call(context, value, index, list);
+ return !predicate.call(context, value, index, list);
}, context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
- _.every = _.all = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
+ _.every = _.all = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
};
@@ -229,13 +230,13 @@ module.exports = {
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
- var any = _.some = _.any = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
+ var any = _.some = _.any = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
- if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
};
@@ -261,41 +262,37 @@ module.exports = {
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
- return _.map(obj, function(value){ return value[key]; });
+ return _.map(obj, _.property(key));
};
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
- _.where = function(obj, attrs, first) {
- if (_.isEmpty(attrs)) return first ? null : [];
- return _[first ? 'find' : 'filter'](obj, function(value) {
- for (var key in attrs) {
- if (attrs[key] !== value[key]) return false;
- }
- return true;
- });
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matches(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
- return _.where(obj, attrs, true);
+ return _.find(obj, _.matches(attrs));
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
- // See: https://bugs.webkit.org/show_bug.cgi?id=80797
+ // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
}
- if (!iterator && _.isEmpty(obj)) return -Infinity;
- var result = {computed : -Infinity, value: -Infinity};
+ var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed >= result.computed && (result = {value : value, computed : computed});
+ if (computed > lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
});
- return result.value;
+ return result;
};
// Return the minimum element (or element-based computation).
@@ -303,16 +300,19 @@ module.exports = {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
- if (!iterator && _.isEmpty(obj)) return Infinity;
- var result = {computed : Infinity, value: Infinity};
+ var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed < result.computed && (result = {value : value, computed : computed});
+ if (computed < lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
});
- return result.value;
+ return result;
};
- // Shuffle an array.
+ // Shuffle an array, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
@@ -325,19 +325,32 @@ module.exports = {
return shuffled;
};
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
- return _.isFunction(value) ? value : function(obj){ return obj[value]; };
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return value;
+ return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
- _.sortBy = function(obj, value, context) {
- var iterator = lookupIterator(value);
+ _.sortBy = function(obj, iterator, context) {
+ iterator = lookupIterator(iterator);
return _.pluck(_.map(obj, function(value, index, list) {
return {
- value : value,
- index : index,
- criteria : iterator.call(context, value, index, list)
+ value: value,
+ index: index,
+ criteria: iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
@@ -346,43 +359,46 @@ module.exports = {
if (a > b || a === void 0) return 1;
if (a < b || b === void 0) return -1;
}
- return left.index < right.index ? -1 : 1;
+ return left.index - right.index;
}), 'value');
};
// An internal function used for aggregate "group by" operations.
- var group = function(obj, value, context, behavior) {
- var result = {};
- var iterator = lookupIterator(value || _.identity);
- each(obj, function(value, index) {
- var key = iterator.call(context, value, index, obj);
- behavior(result, key, value);
- });
- return result;
+ var group = function(behavior) {
+ return function(obj, iterator, context) {
+ var result = {};
+ iterator = lookupIterator(iterator);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
- _.groupBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
- });
- };
+ _.groupBy = group(function(result, key, value) {
+ _.has(result, key) ? result[key].push(value) : result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, key, value) {
+ result[key] = value;
+ });
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
- _.countBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key) {
- if (!_.has(result, key)) result[key] = 0;
- result[key]++;
- });
- };
+ _.countBy = group(function(result, key) {
+ _.has(result, key) ? result[key]++ : result[key] = 1;
+ });
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
- iterator = iterator == null ? _.identity : lookupIterator(iterator);
+ iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
@@ -392,7 +408,7 @@ module.exports = {
return low;
};
- // Safely convert anything iterable into a real, live array.
+ // Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
@@ -414,7 +430,9 @@ module.exports = {
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ if ((n == null) || guard) return array[0];
+ if (n < 0) return [];
+ return slice.call(array, 0, n);
};
// Returns everything but the last entry of the array. Especially useful on
@@ -429,11 +447,8 @@ module.exports = {
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if (array == null) return void 0;
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
- return array[array.length - 1];
- }
+ if ((n == null) || guard) return array[array.length - 1];
+ return slice.call(array, Math.max(array.length - n, 0));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
@@ -451,8 +466,11 @@ module.exports = {
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
each(input, function(value) {
- if (_.isArray(value)) {
+ if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
@@ -461,7 +479,7 @@ module.exports = {
return output;
};
- // Return a completely flattened version of an array.
+ // Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
};
@@ -471,6 +489,16 @@ module.exports = {
return _.difference(array, slice.call(arguments, 1));
};
+ // Split an array into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(array, predicate) {
+ var pass = [], fail = [];
+ each(array, function(elem) {
+ (predicate(elem) ? pass : fail).push(elem);
+ });
+ return [pass, fail];
+ };
+
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
@@ -495,7 +523,7 @@ module.exports = {
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
- return _.uniq(concat.apply(ArrayProto, arguments));
+ return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
@@ -504,7 +532,7 @@ module.exports = {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
- return _.indexOf(other, item) >= 0;
+ return _.contains(other, item);
});
});
};
@@ -519,11 +547,10 @@ module.exports = {
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
- var args = slice.call(arguments);
- var length = _.max(_.pluck(args, 'length'));
+ var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
- results[i] = _.pluck(args, "" + i);
+ results[i] = _.pluck(arguments, '' + i);
}
return results;
};
@@ -534,7 +561,7 @@ module.exports = {
_.object = function(list, values) {
if (list == null) return {};
var result = {};
- for (var i = 0, l = list.length; i < l; i++) {
+ for (var i = 0, length = list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
@@ -552,17 +579,17 @@ module.exports = {
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
- var i = 0, l = array.length;
+ var i = 0, length = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
- i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+ i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
- for (; i < l; i++) if (array[i] === item) return i;
+ for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
@@ -588,11 +615,11 @@ module.exports = {
}
step = arguments[2] || 1;
- var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
- var range = new Array(len);
+ var range = new Array(length);
- while(idx < len) {
+ while(idx < length) {
range[idx++] = start;
start += step;
}
@@ -603,31 +630,50 @@ module.exports = {
// Function (ahem) Functions
// ------------------
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
- var args = slice.call(arguments, 2);
- return function() {
- return func.apply(context, args.concat(slice.call(arguments)));
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
};
};
// Partially apply a function by creating a version that has had some of its
- // arguments pre-filled, without changing its dynamic `this` context.
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
- var args = slice.call(arguments, 1);
+ var boundArgs = slice.call(arguments, 1);
return function() {
- return func.apply(this, args.concat(slice.call(arguments)));
+ var position = 0;
+ var args = boundArgs.slice();
+ for (var i = 0, length = args.length; i < length; i++) {
+ if (args[i] === _) args[i] = arguments[position++];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return func.apply(this, args);
};
};
- // Bind all of an object's methods to that object. Useful for ensuring that
- // all callbacks defined on an object belong to it.
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
- if (funcs.length === 0) funcs = _.functions(obj);
+ if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
@@ -656,17 +702,24 @@ module.exports = {
};
// Returns a function, that, when invoked, will only be triggered at most once
- // during a given window of time.
- _.throttle = function(func, wait) {
- var context, args, timeout, result;
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
var previous = 0;
+ options || (options = {});
var later = function() {
- previous = new Date;
+ previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
+ context = args = null;
};
return function() {
- var now = new Date;
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
@@ -675,7 +728,8 @@ module.exports = {
timeout = null;
previous = now;
result = func.apply(context, args);
- } else if (!timeout) {
+ context = args = null;
+ } else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
@@ -687,17 +741,34 @@ module.exports = {
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
- var timeout, result;
- return function() {
- var context = this, args = arguments;
- var later = function() {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+ if (last < wait) {
+ timeout = setTimeout(later, wait - last);
+ } else {
timeout = null;
- if (!immediate) result = func.apply(context, args);
- };
+ if (!immediate) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
var callNow = immediate && !timeout;
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- if (callNow) result = func.apply(context, args);
+ if (!timeout) {
+ timeout = setTimeout(later, wait);
+ }
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
return result;
};
};
@@ -719,11 +790,7 @@ module.exports = {
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
- return function() {
- var args = [func];
- push.apply(args, arguments);
- return wrapper.apply(this, args);
- };
+ return _.partial(wrapper, func);
};
// Returns a function that is the composition of a list of functions, each
@@ -741,7 +808,6 @@ module.exports = {
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
- if (times <= 0) return func();
return function() {
if (--times < 1) {
return func.apply(this, arguments);
@@ -754,31 +820,43 @@ module.exports = {
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
- _.keys = nativeKeys || function(obj) {
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
- var values = [];
- for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = new Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
return values;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
- var pairs = [];
- for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = new Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
return pairs;
};
// Invert the keys and values of an object. The values must be serializable.
_.invert = function(obj) {
var result = {};
- for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
return result;
};
@@ -829,7 +907,7 @@ module.exports = {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
+ if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
@@ -853,7 +931,7 @@ module.exports = {
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
@@ -895,6 +973,14 @@ module.exports = {
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))
+ && ('constructor' in a && 'constructor' in b)) {
+ return false;
+ }
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
@@ -911,13 +997,6 @@ module.exports = {
}
}
} else {
- // Objects with different constructors are not equivalent, but `Object`s
- // from different frames are.
- var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
- _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
- return false;
- }
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
@@ -1039,9 +1118,33 @@ module.exports = {
return value;
};
+ _.constant = function(value) {
+ return function () {
+ return value;
+ };
+ };
+
+ _.property = function(key) {
+ return function(obj) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+ _.matches = function(attrs) {
+ return function(obj) {
+ if (obj === attrs) return true; //avoid comparing an object to itself.
+ for (var key in attrs) {
+ if (attrs[key] !== obj[key])
+ return false;
+ }
+ return true;
+ }
+ };
+
// Run a function **n** times.
_.times = function(n, iterator, context) {
- var accum = Array(n);
+ var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
return accum;
};
@@ -1055,6 +1158,9 @@ module.exports = {
return min + Math.floor(Math.random() * (max - min + 1));
};
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() { return new Date().getTime(); };
+
// List of HTML entities for escaping.
var entityMap = {
escape: {
@@ -1062,8 +1168,7 @@ module.exports = {
'<': '<',
'>': '>',
'"': '"',
- "'": ''',
- '/': '/'
+ "'": '''
}
};
entityMap.unescape = _.invert(entityMap.escape);
@@ -1084,17 +1189,17 @@ module.exports = {
};
});
- // If the value of the named property is a function then invoke it;
- // otherwise, return it.
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
_.result = function(object, property) {
- if (object == null) return null;
+ if (object == null) return void 0;
var value = object[property];
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
- each(_.functions(obj), function(name){
+ each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
@@ -1252,6 +1357,18 @@ module.exports = {
});
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
}).call(this);
},
@@ -1353,6 +1470,7 @@ var JSHINT = (function () {
globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict')
immed : true, // if immediate invocations must be wrapped in parens
iterator : true, // if the `__iterator__` property should be allowed
+ jasmine : true, // Jasmine functions should be predefined
jquery : true, // if jQuery globals should be predefined
lastsemic : true, // if semicolons may be ommitted for the trailing
// statements inside of a one-line blocks.
@@ -1378,6 +1496,7 @@ var JSHINT = (function () {
proto : true, // if the `__proto__` property should be allowed
prototypejs : true, // if Prototype and Scriptaculous globals should be
// predefined
+ qunit : true, // if the QUnit environment globals should be predefined
rhino : true, // if the Rhino environment globals should be predefined
shelljs : true, // if ShellJS globals should be predefined
typed : true, // if typed array globals should be predefined
@@ -1570,7 +1689,7 @@ var JSHINT = (function () {
function combine(dest, src) {
Object.keys(src).forEach(function (name) {
- if (JSHINT.blacklist.hasOwnProperty(name)) return;
+ if (_.has(JSHINT.blacklist, name)) return;
dest[name] = src[name];
});
}
@@ -1584,6 +1703,10 @@ var JSHINT = (function () {
combine(predefined, vars.couch);
}
+ if (state.option.qunit) {
+ combine(predefined, vars.qunit);
+ }
+
if (state.option.rhino) {
combine(predefined, vars.rhino);
}
@@ -1626,6 +1749,10 @@ var JSHINT = (function () {
combine(predefined, vars.nonstandard);
}
+ if (state.option.jasmine) {
+ combine(predefined, vars.jasmine);
+ }
+
if (state.option.jquery) {
combine(predefined, vars.jquery);
}
@@ -2208,11 +2335,13 @@ var JSHINT = (function () {
if (state.tokens.next.id === "(end)")
error("E006", state.tokens.curr);
- if (state.option.asi &&
- (state.tokens.curr.id === "[" ||
- state.tokens.curr.id === "(" ||
- state.tokens.curr.id === "/") &&
- state.tokens.prev.line < state.tokens.curr.line)
+ var isDangerous =
+ state.option.asi &&
+ state.tokens.prev.line < state.tokens.curr.line &&
+ _.contains(["]", ")"], state.tokens.prev.id) &&
+ _.contains(["[", "("], state.tokens.curr.id);
+
+ if (isDangerous)
warning("W014", state.tokens.curr, state.tokens.curr.id);
advance();
@@ -2792,6 +2921,21 @@ var JSHINT = (function () {
}
}
+ function parseFinalSemicolon() {
+ if (state.tokens.next.id !== ";") {
+ if (!state.option.asi) {
+ // If this is the last statement in a block that ends on
+ // the same line *and* option lastsemic is on, ignore the warning.
+ // Otherwise, complain about missing semicolon.
+ if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
+ state.tokens.next.line !== state.tokens.curr.line) {
+ warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
+ }
+ }
+ } else {
+ advance(";");
+ }
+ }
function statement() {
var values;
@@ -2814,6 +2958,23 @@ var JSHINT = (function () {
res = false;
}
+ // detect a module import declaration
+ if (t.value === "module" && t.type === "(identifier)") {
+ if (peek().type === "(identifier)") {
+ if (!state.option.inESNext()) {
+ warning("W119", state.tokens.curr, "module");
+ }
+
+ advance("module");
+ var name = identifier();
+ addlabel(name, { type: "unused", token: state.tokens.curr });
+ advance("from");
+ advance("(string)");
+ parseFinalSemicolon();
+ return;
+ }
+ }
+
// detect a destructuring assignment
if (_.has(["[", "{"], t.value)) {
if (lookupBlockType().isDestAssign) {
@@ -2879,22 +3040,10 @@ var JSHINT = (function () {
} else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
warning("W031", t);
}
-
- if (state.tokens.next.id !== ";") {
- if (!state.option.asi) {
- // If this is the last statement in a block that ends on
- // the same line *and* option lastsemic is on, ignore the warning.
- // Otherwise, complain about missing semicolon.
- if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
- state.tokens.next.line !== state.tokens.curr.line) {
- warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
- }
- }
- } else {
- advance(";");
- }
+ parseFinalSemicolon();
}
+
// Restore the indentation.
indent = i;
@@ -5432,7 +5581,6 @@ var JSHINT = (function () {
FutureReservedWord("static", { es5: true, strictOnly: true });
FutureReservedWord("super", { es5: true });
FutureReservedWord("synchronized");
- FutureReservedWord("throws");
FutureReservedWord("transient");
FutureReservedWord("volatile");
@@ -8150,7 +8298,7 @@ exports.starSlash = /\*\//;
exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
// JavaScript URL (jx)
-exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
+exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
// Catches /* falls through */ comments (ft)
exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
@@ -8323,7 +8471,7 @@ exports.register = function (linter) {
// Warn about script URLs.
linter.on("String", function style_scanJavaScriptURLs(data) {
- var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
+ var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
if (linter.getOption("scripturl")) {
return;
@@ -8756,6 +8904,27 @@ exports.phantom = {
exports : true // v1.7+
};
+exports.qunit = {
+ asyncTest : false,
+ deepEqual : false,
+ equal : false,
+ expect : false,
+ module : false,
+ notDeepEqual : false,
+ notEqual : false,
+ notPropEqual : false,
+ notStrictEqual : false,
+ ok : false,
+ propEqual : false,
+ QUnit : false,
+ raises : false,
+ start : false,
+ stop : false,
+ strictEqual : false,
+ test : false,
+ "throws" : false
+};
+
exports.rhino = {
defineClass : false,
deserialize : false,
@@ -8875,7 +9044,7 @@ exports.mootools = {
Group : false,
Hash : false,
HtmlTable : false,
- Iframe : false,
+ IFrame : false,
IframeShim : false,
InputValidator: false,
instanceOf : false,
@@ -8962,6 +9131,23 @@ exports.mocha = {
teardown : false
};
+exports.jasmine = {
+ jasmine : false,
+ describe : false,
+ it : false,
+ xit : false,
+ beforeEach : false,
+ afterEach : false,
+ setFixtures : false,
+ loadFixtures: false,
+ spyOn : false,
+ expect : false,
+ // Jasmine 1.3
+ runs : false,
+ waitsFor : false,
+ waits : false
+};
+
},
{}],
10:[function(_dereq_,module,exports){
diff --git a/lib/ace/mode/php/php.js b/lib/ace/mode/php/php.js
index ed23f641..fd703ae2 100644
--- a/lib/ace/mode/php/php.js
+++ b/lib/ace/mode/php/php.js
@@ -717,34 +717,52 @@ PHP.Lexer = function( src, ini ) {
var re;
if ( curlyOpen > 0) {
- re = /^([^\\\$"{}\]\)]|\\.)+/g;
+ re = /^([^\\\$"{}\]\(\)\->]|\\.)+/g;
} else {
re = /^([^\\\$"{]|\\.|{[^\$]|\$(?=[^a-zA-Z_\x7f-\uffff]))+/g;;
}
+ var type, match2;
while(( match = result.match( re )) !== null ) {
-
-
if (result.length === 1) {
throw new Error(match);
}
+
+ type = 0;
-
-
- results.push([
- parseInt(( curlyOpen > 0 ) ? PHP.Constants.T_CONSTANT_ENCAPSED_STRING : PHP.Constants.T_ENCAPSED_AND_WHITESPACE, 10),
- match[ 0 ].replace(/\n/g,"\\n").replace(/\r/g,""),
- line
- ]);
+ if( curlyOpen > 0 ){
+ if( match2 = match[0].match(/^[\[\]\;\:\?\(\)\!\.\,\>\<\=\+\-\/\*\|\&\{\}\@\^\%\$\~]/) ){
+ results.push(match2[0]);
+ }else{
+ type = PHP.Constants.T_STRING;
+ }
+ }else{
+ type = PHP.Constants.T_ENCAPSED_AND_WHITESPACE;
+ }
+
+ if( type ){
+ results.push([
+ parseInt(type, 10),
+ match[ 0 ].replace(/\n/g,"\\n").replace(/\r/g,""),
+ line
+ ]);
+ }
line += match[ 0 ].split('\n').length - 1;
result = result.substring( match[ 0 ].length );
+ }
+ if( curlyOpen > 0 && result.match(/^\->/) !== null ) {
+ results.push([
+ parseInt(PHP.Constants.T_OBJECT_OPERATOR, 10),
+ '->',
+ line
+ ]);
+ result = result.substring( 2 );
}
if( result.match(/^{\$/) !== null ) {
-
results.push([
parseInt(PHP.Constants.T_CURLY_OPEN, 10),
"{",
diff --git a/lib/ace/mode/ruby.js b/lib/ace/mode/ruby.js
index 27bc6c38..76bc2d6f 100644
--- a/lib/ace/mode/ruby.js
+++ b/lib/ace/mode/ruby.js
@@ -74,14 +74,21 @@ oop.inherits(Mode, TextMode);
};
this.checkOutdent = function(state, line, input) {
- return /^\s+end$/.test(line + input) || /^\s+}$/.test(line + input) || /^\s+else$/.test(line + input);
+ return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input);
};
- this.autoOutdent = function(state, doc, row) {
- var indent = this.$getIndent(doc.getLine(row));
- var tab = doc.getTabString();
- if (indent.slice(-tab.length) == tab)
- doc.remove(new Range(row, indent.length-tab.length, row, indent.length));
+ this.autoOutdent = function(state, session, row) {
+ var line = session.getLine(row);
+ if (/}/.test(line))
+ return this.$outdent.autoOutdent(session, row);
+ var indent = this.$getIndent(line);
+ var prevLine = session.getLine(row - 1);
+ var prevIndent = this.$getIndent(prevLine);
+ var tab = session.getTabString();
+ if (prevIndent.length <= indent.length) {
+ if (indent.slice(-tab.length) == tab)
+ session.remove(new Range(row, indent.length-tab.length, row, indent.length));
+ }
};
this.$id = "ace/mode/ruby";
diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js
index 34a2a511..f04f1722 100644
--- a/lib/ace/mode/text.js
+++ b/lib/ace/mode/text.js
@@ -62,7 +62,7 @@ var Mode = function() {
this.getTokenizer = function() {
if (!this.$tokenizer) {
- this.$highlightRules = new this.HighlightRules();
+ this.$highlightRules = this.$highlightRules || new this.HighlightRules();
this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());
}
return this.$tokenizer;
diff --git a/lib/ace/mode/vala.js b/lib/ace/mode/vala.js
new file mode 100644
index 00000000..4ff8ab1a
--- /dev/null
+++ b/lib/ace/mode/vala.js
@@ -0,0 +1,105 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ THIS FILE WAS AUTOGENERATED BY mode.tmpl.js
+*/
+
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var Tokenizer = require("../tokenizer").Tokenizer;
+var ValaHighlightRules = require("./vala_highlight_rules").ValaHighlightRules;
+var FoldMode = require("./folding/cstyle").FoldMode;
+var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
+var CStyleFoldMode = require("./folding/cstyle").FoldMode;
+var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
+
+var Mode = function() {
+ this.HighlightRules = ValaHighlightRules;
+
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+ this.foldingRules = new CStyleFoldMode();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+ this.lineCommentStart = "//";
+ this.blockComment = {start: "/*", end: "*/"};
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
+ var tokens = tokenizedLine.tokens;
+ var endState = tokenizedLine.state;
+
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
+ return indent;
+ }
+
+ if (state == "start" || state == "no_regex") {
+ var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);
+ if (match) {
+ indent += tab;
+ }
+ } else if (state == "doc-start") {
+ if (endState == "start" || endState == "no_regex") {
+ return "";
+ }
+ var match = line.match(/^\s*(\/?)\*/);
+ if (match) {
+ if (match[1]) {
+ indent += " ";
+ }
+ indent += "* ";
+ }
+ }
+
+ 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);
+ };
+
+ // Extra logic goes here.
+ this.$id = "ace/mode/vala"
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
\ No newline at end of file
diff --git a/lib/ace/mode/vala_highlight_rules.js b/lib/ace/mode/vala_highlight_rules.js
new file mode 100644
index 00000000..f199426d
--- /dev/null
+++ b/lib/ace/mode/vala_highlight_rules.js
@@ -0,0 +1,457 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* This file was autogenerated from https://raw.githubusercontent.com/technosophos/Vala-TMBundle/master/Syntaxes/Vala.tmLanguage (uuid: ) */
+/****************************************************************************************
+ * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. *
+ * fileTypes *
+ ****************************************************************************************/
+
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var ValaHighlightRules = function() {
+ // regexp must not have capturing parentheses. Use (?:) instead.
+ // regexps are ordered -> the first match is used
+
+ this.$rules = { start:
+ [ { token:
+ [ 'meta.using.vala',
+ 'keyword.other.using.vala',
+ 'meta.using.vala',
+ 'storage.modifier.using.vala',
+ 'meta.using.vala',
+ 'punctuation.terminator.vala' ],
+ regex: '^(\\s*)(using)\\b(?:(\\s*)([^ ;$]+)(\\s*)((?:;)?))?' },
+ { include: '#code' } ],
+ '#all-types':
+ [ { include: '#primitive-arrays' },
+ { include: '#primitive-types' },
+ { include: '#object-types' } ],
+ '#annotations':
+ [ { token:
+ [ 'storage.type.annotation.vala',
+ 'punctuation.definition.annotation-arguments.begin.vala' ],
+ regex: '(@[^ (]+)(\\()',
+ push:
+ [ { token: 'punctuation.definition.annotation-arguments.end.vala',
+ regex: '\\)',
+ next: 'pop' },
+ { token:
+ [ 'constant.other.key.vala',
+ 'text',
+ 'keyword.operator.assignment.vala' ],
+ regex: '(\\w*)(\\s*)(=)' },
+ { include: '#code' },
+ { token: 'punctuation.seperator.property.vala', regex: ',' },
+ { defaultToken: 'meta.declaration.annotation.vala' } ] },
+ { token: 'storage.type.annotation.vala', regex: '@\\w*' } ],
+ '#anonymous-classes-and-new':
+ [ { token: 'keyword.control.new.vala',
+ regex: '\\bnew\\b',
+ push_disabled:
+ [ { token: 'text',
+ regex: '(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)',
+ TODO: 'FIXME: regexp doesn\'t have js equivalent',
+ originalRegex: '(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)',
+ next: 'pop' },
+ { token: [ 'storage.type.vala', 'text' ],
+ regex: '(\\w+)(\\s*)(?=\\[)',
+ push:
+ [ { token: 'text', regex: '}|(?=;|\\))', next: 'pop' },
+ { token: 'text',
+ regex: '\\[',
+ push:
+ [ { token: 'text', regex: '\\]', next: 'pop' },
+ { include: '#code' } ] },
+ { token: 'text',
+ regex: '{',
+ push:
+ [ { token: 'text', regex: '(?=})', next: 'pop' },
+ { include: '#code' } ] } ] },
+ { token: 'text',
+ regex: '(?=\\w.*\\()',
+ push:
+ [ { token: 'text',
+ regex: '(?<=\\))',
+ TODO: 'FIXME: regexp doesn\'t have js equivalent',
+ originalRegex: '(?<=\\))',
+ next: 'pop' },
+ { include: '#object-types' },
+ { token: 'text',
+ regex: '\\(',
+ push:
+ [ { token: 'text', regex: '\\)', next: 'pop' },
+ { include: '#code' } ] } ] },
+ { token: 'meta.inner-class.vala',
+ regex: '{',
+ push:
+ [ { token: 'meta.inner-class.vala', regex: '}', next: 'pop' },
+ { include: '#class-body' },
+ { defaultToken: 'meta.inner-class.vala' } ] } ] } ],
+ '#assertions':
+ [ { token:
+ [ 'keyword.control.assert.vala',
+ 'meta.declaration.assertion.vala' ],
+ regex: '\\b(assert|requires|ensures)(\\s)',
+ push:
+ [ { token: 'meta.declaration.assertion.vala',
+ regex: '$',
+ next: 'pop' },
+ { token: 'keyword.operator.assert.expression-seperator.vala',
+ regex: ':' },
+ { include: '#code' },
+ { defaultToken: 'meta.declaration.assertion.vala' } ] } ],
+ '#class':
+ [ { token: 'meta.class.vala',
+ regex: '(?=\\w?[\\w\\s]*(?:class|(?:@)?interface|enum|struct|namespace)\\s+\\w+)',
+ push:
+ [ { token: 'punctuation.section.class.end.vala',
+ regex: '}',
+ next: 'pop' },
+ { include: '#storage-modifiers' },
+ { include: '#comments' },
+ { token:
+ [ 'storage.modifier.vala',
+ 'meta.class.identifier.vala',
+ 'entity.name.type.class.vala' ],
+ regex: '(class|(?:@)?interface|enum|struct|namespace)(\\s+)([\\w\\.]+)' },
+ { token: 'storage.modifier.extends.vala',
+ regex: ':',
+ push:
+ [ { token: 'meta.definition.class.inherited.classes.vala',
+ regex: '(?={|,)',
+ next: 'pop' },
+ { include: '#object-types-inherited' },
+ { include: '#comments' },
+ { defaultToken: 'meta.definition.class.inherited.classes.vala' } ] },
+ { token:
+ [ 'storage.modifier.implements.vala',
+ 'meta.definition.class.implemented.interfaces.vala' ],
+ regex: '(,)(\\s)',
+ push:
+ [ { token: 'meta.definition.class.implemented.interfaces.vala',
+ regex: '(?=\\{)',
+ next: 'pop' },
+ { include: '#object-types-inherited' },
+ { include: '#comments' },
+ { defaultToken: 'meta.definition.class.implemented.interfaces.vala' } ] },
+ { token: 'meta.class.body.vala',
+ regex: '{',
+ push:
+ [ { token: 'meta.class.body.vala', regex: '(?=})', next: 'pop' },
+ { include: '#class-body' },
+ { defaultToken: 'meta.class.body.vala' } ] },
+ { defaultToken: 'meta.class.vala' } ],
+ comment: 'attempting to put namespace in here.' } ],
+ '#class-body':
+ [ { include: '#comments' },
+ { include: '#class' },
+ { include: '#enums' },
+ { include: '#methods' },
+ { include: '#annotations' },
+ { include: '#storage-modifiers' },
+ { include: '#code' } ],
+ '#code':
+ [ { include: '#comments' },
+ { include: '#class' },
+ { token: 'text',
+ regex: '{',
+ push:
+ [ { token: 'text', regex: '}', next: 'pop' },
+ { include: '#code' } ] },
+ { include: '#assertions' },
+ { include: '#parens' },
+ { include: '#constants-and-special-vars' },
+ { include: '#anonymous-classes-and-new' },
+ { include: '#keywords' },
+ { include: '#storage-modifiers' },
+ { include: '#strings' },
+ { include: '#all-types' } ],
+ '#comments':
+ [ { token: 'punctuation.definition.comment.vala',
+ regex: '/\\*\\*/' },
+ { include: 'text.html.javadoc' },
+ { include: '#comments-inline' } ],
+ '#comments-inline':
+ [ { token: 'punctuation.definition.comment.vala',
+ regex: '/\\*',
+ push:
+ [ { token: 'punctuation.definition.comment.vala',
+ regex: '\\*/',
+ next: 'pop' },
+ { defaultToken: 'comment.block.vala' } ] },
+ { token:
+ [ 'text',
+ 'punctuation.definition.comment.vala',
+ 'comment.line.double-slash.vala' ],
+ regex: '(\\s*)(//)(.*$)' } ],
+ '#constants-and-special-vars':
+ [ { token: 'constant.language.vala',
+ regex: '\\b(?:true|false|null)\\b' },
+ { token: 'variable.language.vala',
+ regex: '\\b(?:this|base)\\b' },
+ { token: 'constant.numeric.vala',
+ regex: '\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\\b' },
+ { token: [ 'keyword.operator.dereference.vala', 'constant.other.vala' ],
+ regex: '((?:\\.)?)\\b([A-Z][A-Z0-9_]+)(?!<|\\.class|\\s*\\w+\\s*=)\\b' } ],
+ '#enums':
+ [ { token: 'text',
+ regex: '^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))',
+ push:
+ [ { token: 'text', regex: '(?=;|})', next: 'pop' },
+ { token: 'constant.other.enum.vala',
+ regex: '\\w+',
+ push:
+ [ { token: 'meta.enum.vala', regex: '(?=,|;|})', next: 'pop' },
+ { include: '#parens' },
+ { token: 'text',
+ regex: '{',
+ push:
+ [ { token: 'text', regex: '}', next: 'pop' },
+ { include: '#class-body' } ] },
+ { defaultToken: 'meta.enum.vala' } ] } ] } ],
+ '#keywords':
+ [ { token: 'keyword.control.catch-exception.vala',
+ regex: '\\b(?:try|catch|finally|throw)\\b' },
+ { token: 'keyword.control.vala', regex: '\\?|:|\\?\\?' },
+ { token: 'keyword.control.vala',
+ regex: '\\b(?:return|break|case|continue|default|do|while|for|foreach|switch|if|else|in|yield|get|set|value)\\b' },
+ { token: 'keyword.operator.vala',
+ regex: '\\b(?:typeof|is|as)\\b' },
+ { token: 'keyword.operator.comparison.vala',
+ regex: '==|!=|<=|>=|<>|<|>' },
+ { token: 'keyword.operator.assignment.vala', regex: '=' },
+ { token: 'keyword.operator.increment-decrement.vala',
+ regex: '\\-\\-|\\+\\+' },
+ { token: 'keyword.operator.arithmetic.vala',
+ regex: '\\-|\\+|\\*|\\/|%' },
+ { token: 'keyword.operator.logical.vala', regex: '!|&&|\\|\\|' },
+ { token: 'keyword.operator.dereference.vala',
+ regex: '\\.(?=\\S)',
+ originalRegex: '(?<=\\S)\\.(?=\\S)' },
+ { token: 'punctuation.terminator.vala', regex: ';' },
+ { token: 'keyword.operator.ownership', regex: 'owned|unowned' } ],
+ '#methods':
+ [ { token: 'meta.method.vala',
+ regex: '(?!new)(?=\\w.*\\s+)(?=[^=]+\\()',
+ push:
+ [ { token: 'meta.method.vala', regex: '}|(?=;)', next: 'pop' },
+ { include: '#storage-modifiers' },
+ { token: [ 'entity.name.function.vala', 'meta.method.identifier.vala' ],
+ regex: '([\\~\\w\\.]+)(\\s*\\()',
+ push:
+ [ { token: 'meta.method.identifier.vala',
+ regex: '\\)',
+ next: 'pop' },
+ { include: '#parameters' },
+ { defaultToken: 'meta.method.identifier.vala' } ] },
+ { token: 'meta.method.return-type.vala',
+ regex: '(?=\\w.*\\s+\\w+\\s*\\()',
+ push:
+ [ { token: 'meta.method.return-type.vala',
+ regex: '(?=\\w+\\s*\\()',
+ next: 'pop' },
+ { include: '#all-types' },
+ { defaultToken: 'meta.method.return-type.vala' } ] },
+ { include: '#throws' },
+ { token: 'meta.method.body.vala',
+ regex: '{',
+ push:
+ [ { token: 'meta.method.body.vala', regex: '(?=})', next: 'pop' },
+ { include: '#code' },
+ { defaultToken: 'meta.method.body.vala' } ] },
+ { defaultToken: 'meta.method.vala' } ] } ],
+ '#namespace':
+ [ { token: 'text',
+ regex: '^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))',
+ push:
+ [ { token: 'text', regex: '(?=;|})', next: 'pop' },
+ { token: 'constant.other.namespace.vala',
+ regex: '\\w+',
+ push:
+ [ { token: 'meta.namespace.vala', regex: '(?=,|;|})', next: 'pop' },
+ { include: '#parens' },
+ { token: 'text',
+ regex: '{',
+ push:
+ [ { token: 'text', regex: '}', next: 'pop' },
+ { include: '#code' } ] },
+ { defaultToken: 'meta.namespace.vala' } ] } ],
+ comment: 'This is not quite right. See the class grammar right now' } ],
+ '#object-types':
+ [ { token: 'storage.type.generic.vala',
+ regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<',
+ push:
+ [ { token: 'storage.type.generic.vala',
+ regex: '>|[^\\w\\s,\\?<\\[()\\]]',
+ TODO: 'FIXME: regexp doesn\'t have js equivalent',
+ originalRegex: '>|[^\\w\\s,\\?<\\[(?:[,]+)\\]]',
+ next: 'pop' },
+ { include: '#object-types' },
+ { token: 'storage.type.generic.vala',
+ regex: '<',
+ push:
+ [ { token: 'storage.type.generic.vala',
+ regex: '>|[^\\w\\s,\\[\\]<]',
+ next: 'pop' },
+ { defaultToken: 'storage.type.generic.vala' } ],
+ comment: 'This is just to support <>\'s with no actual type prefix' },
+ { defaultToken: 'storage.type.generic.vala' } ] },
+ { token: 'storage.type.object.array.vala',
+ regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*(?=\\[)',
+ push:
+ [ { token: 'storage.type.object.array.vala',
+ regex: '(?=[^\\]\\s])',
+ next: 'pop' },
+ { token: 'text',
+ regex: '\\[',
+ push:
+ [ { token: 'text', regex: '\\]', next: 'pop' },
+ { include: '#code' } ] },
+ { defaultToken: 'storage.type.object.array.vala' } ] },
+ { token:
+ [ 'storage.type.vala',
+ 'keyword.operator.dereference.vala',
+ 'storage.type.vala' ],
+ regex: '\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*\\b)' } ],
+ '#object-types-inherited':
+ [ { token: 'entity.other.inherited-class.vala',
+ regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<',
+ push:
+ [ { token: 'entity.other.inherited-class.vala',
+ regex: '>|[^\\w\\s,<]',
+ next: 'pop' },
+ { include: '#object-types' },
+ { token: 'storage.type.generic.vala',
+ regex: '<',
+ push:
+ [ { token: 'storage.type.generic.vala',
+ regex: '>|[^\\w\\s,<]',
+ next: 'pop' },
+ { defaultToken: 'storage.type.generic.vala' } ],
+ comment: 'This is just to support <>\'s with no actual type prefix' },
+ { defaultToken: 'entity.other.inherited-class.vala' } ] },
+ { token:
+ [ 'entity.other.inherited-class.vala',
+ 'keyword.operator.dereference.vala',
+ 'entity.other.inherited-class.vala' ],
+ regex: '\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*)' } ],
+ '#parameters':
+ [ { token: 'storage.modifier.vala', regex: 'final' },
+ { include: '#primitive-arrays' },
+ { include: '#primitive-types' },
+ { include: '#object-types' },
+ { token: 'variable.parameter.vala', regex: '\\w+' } ],
+ '#parens':
+ [ { token: 'text',
+ regex: '\\(',
+ push:
+ [ { token: 'text', regex: '\\)', next: 'pop' },
+ { include: '#code' } ] } ],
+ '#primitive-arrays':
+ [ { token: 'storage.type.primitive.array.vala',
+ regex: '\\b(?:bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|int8|int16|int32|int64|uint8|uint16|uint32|uint64)(?:\\[\\])*\\b' } ],
+ '#primitive-types':
+ [ { token: 'storage.type.primitive.vala',
+ regex: '\\b(?:var|bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b',
+ comment: 'var is not really a primitive, but acts like one in most cases' } ],
+ '#storage-modifiers':
+ [ { token: 'storage.modifier.vala',
+ regex: '\\b(?:public|private|protected|internal|static|final|sealed|virtual|override|abstract|readonly|volatile|dynamic|async|unsafe|out|ref|weak|owned|unowned|const)\\b',
+ comment: 'Not sure about unsafe and readonly' } ],
+ '#strings':
+ [ { token: 'punctuation.definition.string.begin.vala',
+ regex: '@"',
+ push:
+ [ { token: 'punctuation.definition.string.end.vala',
+ regex: '"',
+ next: 'pop' },
+ { token: 'constant.character.escape.vala',
+ regex: '\\\\.|%[\\w\\.\\-]+|\\$(?:\\w+|\\([\\w\\s\\+\\-\\*\\/]+\\))' },
+ { defaultToken: 'string.quoted.interpolated.vala' } ] },
+ { token: 'punctuation.definition.string.begin.vala',
+ regex: '"',
+ push:
+ [ { token: 'punctuation.definition.string.end.vala',
+ regex: '"',
+ next: 'pop' },
+ { token: 'constant.character.escape.vala', regex: '\\\\.' },
+ { token: 'constant.character.escape.vala',
+ regex: '%[\\w\\.\\-]+' },
+ { defaultToken: 'string.quoted.double.vala' } ] },
+ { token: 'punctuation.definition.string.begin.vala',
+ regex: '\'',
+ push:
+ [ { token: 'punctuation.definition.string.end.vala',
+ regex: '\'',
+ next: 'pop' },
+ { token: 'constant.character.escape.vala', regex: '\\\\.' },
+ { defaultToken: 'string.quoted.single.vala' } ] },
+ { token: 'punctuation.definition.string.begin.vala',
+ regex: '"""',
+ push:
+ [ { token: 'punctuation.definition.string.end.vala',
+ regex: '"""',
+ next: 'pop' },
+ { token: 'constant.character.escape.vala',
+ regex: '%[\\w\\.\\-]+' },
+ { defaultToken: 'string.quoted.triple.vala' } ] } ],
+ '#throws':
+ [ { token: 'storage.modifier.vala',
+ regex: 'throws',
+ push:
+ [ { token: 'meta.throwables.vala', regex: '(?={|;)', next: 'pop' },
+ { include: '#object-types' },
+ { defaultToken: 'meta.throwables.vala' } ] } ],
+ '#values':
+ [ { include: '#strings' },
+ { include: '#object-types' },
+ { include: '#constants-and-special-vars' } ] }
+
+ this.normalizeRules();
+};
+
+ValaHighlightRules.metaData = {
+ comment: 'Based heavily on the Java bundle\'s language syntax. TODO:\n* Closures\n* Delegates\n* Properties: Better support for properties.\n* Annotations\n* Error domains\n* Named arguments\n* Array slicing, negative indexes, multidimensional\n* construct blocks\n* lock blocks?\n* regex literals\n* DocBlock syntax highlighting. (Currently importing javadoc)\n* Folding rule for comments.\n',
+ fileTypes: [ 'vala' ],
+ foldingStartMarker: '(\\{\\s*(//.*)?$|^\\s*// \\{\\{\\{)',
+ foldingStopMarker: '^\\s*(\\}|// \\}\\}\\}$)',
+ name: 'Vala',
+ scopeName: 'source.vala' }
+
+
+oop.inherits(ValaHighlightRules, TextHighlightRules);
+
+exports.ValaHighlightRules = ValaHighlightRules;
+});
\ No newline at end of file
diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js
index 8a9adcf7..e7a31540 100644
--- a/lib/ace/mouse/default_handlers.js
+++ b/lib/ace/mouse/default_handlers.js
@@ -109,12 +109,15 @@ function DefaultHandlers(mouseHandler) {
var editor = this.editor;
// allow double/triple click handlers to change selection
var shiftPressed = this.mousedownEvent.getShiftKey();
- if (shiftPressed) {
- editor.selection.selectToPosition(pos);
- }
- else if (!this.$clickSelection) {
- editor.selection.moveToPosition(pos);
- }
+ setTimeout(function(){
+ if (shiftPressed) {
+ editor.selection.selectToPosition(pos);
+ }
+ else if (!this.$clickSelection) {
+ editor.selection.moveToPosition(pos);
+ }
+ this.select();
+ }.bind(this), 0);
if (editor.renderer.scroller.setCapture) {
editor.renderer.scroller.setCapture();
}
@@ -213,7 +216,6 @@ function DefaultHandlers(mouseHandler) {
this.setState("selectByWords");
}
this.$clickSelection = range;
- this[this.state] && this[this.state](ev);
};
this.onTripleClick = function(ev) {
@@ -221,8 +223,13 @@ function DefaultHandlers(mouseHandler) {
var editor = this.editor;
this.setState("selectByLines");
- this.$clickSelection = editor.selection.getLineRange(pos.row);
- this[this.state] && this[this.state](ev);
+ var range = editor.getSelectionRange();
+ if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
+ this.$clickSelection = editor.selection.getLineRange(range.start.row);
+ this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
+ } else {
+ this.$clickSelection = editor.selection.getLineRange(pos.row);
+ }
};
this.onQuadClick = function(ev) {
diff --git a/lib/ace/mouse/mouse_handler.js b/lib/ace/mouse/mouse_handler.js
index c7573e94..9cf26721 100644
--- a/lib/ace/mouse/mouse_handler.js
+++ b/lib/ace/mouse/mouse_handler.js
@@ -40,13 +40,18 @@ var DragdropHandler = require("./dragdrop_handler").DragdropHandler;
var config = require("../config");
var MouseHandler = function(editor) {
+ var _self = this;
this.editor = editor;
new DefaultHandlers(this);
new DefaultGutterHandler(this);
new DragdropHandler(this);
- var focusEditor = function(e) { editor.focus() };
+ var focusEditor = function(e) {
+ if (!editor.isFocused() && editor.textInput)
+ editor.textInput.moveToMouse(e);
+ editor.focus()
+ };
var mouseTarget = editor.renderer.getMouseEventTarget();
event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
@@ -74,6 +79,21 @@ var MouseHandler = function(editor) {
editor.focus();
return event.preventDefault(e);
});
+
+ editor.on("mousemove", function(e){
+ if (_self.state || _self.$dragDelay || !_self.$dragEnabled)
+ return;
+
+ var char = editor.renderer.screenToTextCoordinates(e.x, e.y);
+ var range = editor.session.selection.getRange();
+ var renderer = editor.renderer;
+
+ if (!range.isEmpty() && range.insideStart(char.row, char.column)) {
+ renderer.setCursorStyle("default");
+ } else {
+ renderer.setCursorStyle("");
+ }
+ });
};
(function() {
@@ -157,11 +177,22 @@ var MouseHandler = function(editor) {
var timerId = setInterval(onCaptureInterval, 20);
};
this.releaseMouse = null;
+ this.cancelContextMenu = function() {
+ var stop = function(e) {
+ if (e && e.domEvent && e.domEvent.type != "contextmenu")
+ return;
+ this.editor.off("nativecontextmenu", stop);
+ if (e && e.domEvent)
+ event.stopEvent(e.domEvent);
+ }.bind(this);
+ setTimeout(stop, 10);
+ this.editor.on("nativecontextmenu", stop);
+ };
}).call(MouseHandler.prototype);
config.defineOptions(MouseHandler.prototype, "mouseHandler", {
scrollSpeed: {initialValue: 2},
- dragDelay: {initialValue: 150},
+ dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},
dragEnabled: {initialValue: true},
focusTimout: {initialValue: 0},
tooltipFollowsMouse: {initialValue: true}
diff --git a/lib/ace/mouse/mouse_handler_test.js b/lib/ace/mouse/mouse_handler_test.js
index 96374d71..571acdac 100644
--- a/lib/ace/mouse/mouse_handler_test.js
+++ b/lib/ace/mouse/mouse_handler_test.js
@@ -58,15 +58,17 @@ module.exports = {
next();
},
- "test: double tap. issue #956" : function() {
+ "test: double tap. issue #956" : function(done) {
// mouse up fired immediately after mouse down
var target = this.editor.renderer.getMouseEventTarget();
target.dispatchEvent(MouseEvent("down", {x: 1, y: 1}));
target.dispatchEvent(MouseEvent("up", {x: 1, y: 1}));
target.dispatchEvent(MouseEvent("down", {x: 1, y: 1, detail: 2}));
target.dispatchEvent(MouseEvent("up", {x: 1, y: 1, detail: 2}));
-
- assert.equal(this.editor.getSelectedText(), "Juhu");
+ setTimeout(function() {
+ assert.equal(this.editor.getSelectedText(), "Juhu");
+ done();
+ }.bind(this));
}
};
diff --git a/lib/ace/mouse/multi_select_handler.js b/lib/ace/mouse/multi_select_handler.js
index 88dc6668..8d6af6b5 100644
--- a/lib/ace/mouse/multi_select_handler.js
+++ b/lib/ace/mouse/multi_select_handler.js
@@ -31,6 +31,7 @@
define(function(require, exports, module) {
var event = require("../lib/event");
+var useragent = require("../lib/useragent");
// mouse
function isSamePoint(p1, p2) {
@@ -41,19 +42,26 @@ function onMouseDown(e) {
var ev = e.domEvent;
var alt = ev.altKey;
var shift = ev.shiftKey;
- var ctrl = e.getAccelKey();
+ var ctrl = ev.ctrlKey;
+ var accel = e.getAccelKey();
var button = e.getButton();
+
+ if (ctrl && useragent.isMac)
+ button = ev.button;
if (e.editor.inMultiSelectMode && button == 2) {
e.editor.textInput.onContextMenu(e.domEvent);
return;
}
- if (!ctrl && !alt) {
+ if (!ctrl && !alt && !accel) {
if (button === 0 && e.editor.inMultiSelectMode)
e.editor.exitMultiSelectMode();
return;
}
+
+ if (button !== 0)
+ return;
var editor = e.editor;
var selection = editor.selection;
@@ -62,38 +70,37 @@ function onMouseDown(e) {
var cursor = selection.getCursor();
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
-
var mouseX = e.x, mouseY = e.y;
var onMouseSelection = function(e) {
mouseX = e.clientX;
mouseY = e.clientY;
};
-
- var blockSelect = function() {
- var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
- var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
-
- if (isSamePoint(screenCursor, newCursor)
- && isSamePoint(cursor, selection.selectionLead))
- return;
- screenCursor = newCursor;
-
- editor.selection.moveToPosition(cursor);
- editor.renderer.scrollCursorIntoView();
-
- editor.removeSelectionMarkers(rectSel);
- rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
- rectSel.forEach(editor.addSelectionMarker, editor);
- editor.updateSelectionMarkers();
- };
var session = editor.session;
var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
var screenCursor = screenAnchor;
-
+ var selectionMode;
+ if (editor.$mouseHandler.$enableJumpToDef) {
+ if (ctrl && alt || accel && alt)
+ selectionMode = "add";
+ else if (alt)
+ selectionMode = "block";
+ } else {
+ if (accel && !alt) {
+ selectionMode = "add";
+ if (!isMultiSelect && shift)
+ return;
+ } else if (alt) {
+ selectionMode = "block";
+ }
+ }
+
+ if (selectionMode && useragent.isMac && ev.ctrlKey) {
+ editor.$mouseHandler.cancelContextMenu();
+ }
- if (ctrl && !alt && !shift && button === 0) {
+ if (selectionMode == "add") {
if (!isMultiSelect && inSelection)
return; // dragging
@@ -104,44 +111,86 @@ function onMouseDown(e) {
var oldRange = selection.rangeList.rangeAtPoint(pos);
+
editor.$blockScrolling++;
+ editor.inVirtualSelectionMode = true;
+
+ if (shift) {
+ oldRange = null;
+ range = selection.ranges[0];
+ editor.removeSelectionMarker(range);
+ }
editor.once("mouseup", function() {
var tmpSel = selection.toOrientedRange();
if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
selection.substractPoint(tmpSel.cursor);
else {
- if (range) {
+ if (shift) {
+ selection.substractPoint(range.cursor);
+ } else if (range) {
editor.removeSelectionMarker(range);
selection.addRange(range);
}
selection.addRange(tmpSel);
}
editor.$blockScrolling--;
+ editor.inVirtualSelectionMode = false;
});
- } else if (alt && button === 0) {
+ } else if (selectionMode == "block") {
e.stop();
-
- if (isMultiSelect && !ctrl)
- selection.toSingleRange();
- else if (!isMultiSelect && ctrl)
- selection.addRange();
-
+ editor.inVirtualSelectionMode = true;
+ var initialRange;
var rectSel = [];
- if (shift) {
- screenAnchor = session.documentToScreenPosition(selection.lead);
- blockSelect();
- } else {
- selection.moveToPosition(pos);
- }
+ var blockSelect = function() {
+ var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
+ var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
+ if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))
+ return;
+ screenCursor = newCursor;
+
+ editor.selection.moveToPosition(cursor);
+ editor.renderer.scrollCursorIntoView();
+
+ editor.removeSelectionMarkers(rectSel);
+ rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
+ if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())
+ rectSel[0] = editor.$mouseHandler.$clickSelection.clone();
+ rectSel.forEach(editor.addSelectionMarker, editor);
+ editor.updateSelectionMarkers();
+ };
+
+ if (isMultiSelect && !accel) {
+ selection.toSingleRange();
+ } else if (!isMultiSelect && accel) {
+ initialRange = selection.toOrientedRange();
+ editor.addSelectionMarker(initialRange);
+ }
+
+ if (shift)
+ screenAnchor = session.documentToScreenPosition(selection.lead);
+ else
+ selection.moveToPosition(pos);
+
+ screenCursor = {row: -1, column: -1};
var onMouseSelectionEnd = function(e) {
clearInterval(timerId);
editor.removeSelectionMarkers(rectSel);
+ if (!rectSel.length)
+ rectSel = [selection.toOrientedRange()];
+ editor.$blockScrolling++;
+ if (initialRange) {
+ editor.removeSelectionMarker(initialRange);
+ selection.toSingleRange(initialRange);
+ }
for (var i = 0; i < rectSel.length; i++)
selection.addRange(rectSel[i]);
+ editor.inVirtualSelectionMode = false;
+ editor.$mouseHandler.$clickSelection = null;
+ editor.$blockScrolling--;
};
var onSelectionInterval = blockSelect;
diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js
index b079e387..ef0f7a2e 100644
--- a/lib/ace/multi_select.js
+++ b/lib/ace/multi_select.js
@@ -76,7 +76,7 @@ var EditSession = require("./edit_session").EditSession;
if (!range)
return;
- if (!this.inMultiSelectMode && this.rangeCount == 0) {
+ if (!this.inMultiSelectMode && this.rangeCount === 0) {
var oldRange = this.toOrientedRange();
this.rangeList.add(oldRange);
this.rangeList.add(range);
@@ -168,7 +168,7 @@ var EditSession = require("./edit_session").EditSession;
this._signal("removeRange", {ranges: removed});
- if (this.rangeCount == 0 && this.inMultiSelectMode) {
+ if (this.rangeCount === 0 && this.inMultiSelectMode) {
this.inMultiSelectMode = false;
this._signal("singleSelect");
this.session.$undoSelect = true;
@@ -543,6 +543,19 @@ var Editor = require("./editor").Editor;
}
return text;
};
+
+ this.$checkMultiselectChange = function(e, anchor) {
+ if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
+ var range = this.multiSelect.ranges[0];
+ if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)
+ return;
+ var pos = anchor == this.multiSelect.anchor
+ ? range.cursor == range.start ? range.end : range.start
+ : range.cursor;
+ if (!isSamePoint(pos, anchor))
+ this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());
+ }
+ };
// todo this should change when paste becomes a command
this.onPaste = function(text) {
@@ -742,8 +755,15 @@ var Editor = require("./editor").Editor;
var session = this.session;
var sel = session.multiSelect;
var ranges = sel.ranges;
-
- if (!ranges.length) {
+ // filter out ranges on same row
+ var row = -1;
+ var sameRowRanges = ranges.filter(function(r) {
+ if (r.cursor.row == row)
+ return true;
+ row = r.cursor.row;
+ });
+
+ if (!ranges.length || sameRowRanges.length == ranges.length - 1) {
var range = this.selection.getRange();
var fr = range.start.row, lr = range.end.row;
var guessRange = fr == lr;
@@ -769,14 +789,9 @@ var Editor = require("./editor").Editor;
}
this.selection.setRange(range);
} else {
- // filter out ranges on same row
- var row = -1;
- var sameRowRanges = ranges.filter(function(r) {
- if (r.cursor.row == row)
- return true;
- row = r.cursor.row;
+ sameRowRanges.forEach(function(r) {
+ sel.substractPoint(r.cursor);
});
- sel.$onRemoveRange(sameRowRanges);
var maxCol = 0;
var minSpace = Infinity;
@@ -851,19 +866,19 @@ var Editor = require("./editor").Editor;
function alignLeft(m) {
return !m[2] ? m[0] : spaces(startW) + m[2]
+ spaces(textW - m[2].length + endW)
- + m[4].replace(/^([=:])\s+/, "$1 ")
+ + m[4].replace(/^([=:])\s+/, "$1 ");
}
function alignRight(m) {
return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
+ spaces(endW, " ")
- + m[4].replace(/^([=:])\s+/, "$1 ")
+ + m[4].replace(/^([=:])\s+/, "$1 ");
}
function unAlign(m) {
return !m[2] ? m[0] : spaces(startW) + m[2]
+ spaces(endW)
- + m[4].replace(/^([=:])\s+/, "$1 ")
+ + m[4].replace(/^([=:])\s+/, "$1 ");
}
- }
+ };
}).call(Editor.prototype);
@@ -884,17 +899,21 @@ exports.onSessionChange = function(e) {
var oldSession = e.oldSession;
if (oldSession) {
- oldSession.multiSelect.removeEventListener("addRange", this.$onAddRange);
- oldSession.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
- oldSession.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
- oldSession.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
+ oldSession.multiSelect.off("addRange", this.$onAddRange);
+ oldSession.multiSelect.off("removeRange", this.$onRemoveRange);
+ oldSession.multiSelect.off("multiSelect", this.$onMultiSelect);
+ oldSession.multiSelect.off("singleSelect", this.$onSingleSelect);
+ oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange);
+ oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange);
}
session.multiSelect.on("addRange", this.$onAddRange);
session.multiSelect.on("removeRange", this.$onRemoveRange);
session.multiSelect.on("multiSelect", this.$onMultiSelect);
session.multiSelect.on("singleSelect", this.$onSingleSelect);
-
+ session.multiSelect.lead.on("change", this.$checkMultiselectChange);
+ session.multiSelect.anchor.on("change", this.$checkMultiselectChange);
+
// this.$onSelectionChange = this.onSelectionChange.bind(this);
if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
@@ -916,6 +935,7 @@ function MultiSelect(editor) {
editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
+ editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);
editor.$multiselectOnSessionChange(editor);
editor.on("changeSession", editor.$multiselectOnSessionChange);
@@ -969,7 +989,7 @@ require("./config").defineOptions(Editor.prototype, "editor", {
},
value: true
}
-})
+});
diff --git a/lib/ace/selection.js b/lib/ace/selection.js
index e113d8ad..63bc9668 100644
--- a/lib/ace/selection.js
+++ b/lib/ace/selection.js
@@ -37,7 +37,6 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
/**
- *
* Contains the cursor position and the text selection of an edit session.
*
* The row/columns used in the selection are in document coordinates representing ths coordinates as thez appear in the document before applying soft wrap and folding.
@@ -49,22 +48,16 @@ var Range = require("./range").Range;
* Emitted when the cursor position changes.
* @event changeCursor
*
- *
- *
**/
/**
* Emitted when the cursor selection changes.
+ *
* @event changeSelection
- *
- *
- *
**/
/**
* Creates a new `Selection` object.
* @param {EditSession} session The session to use
- *
- *
- *
+ *
* @constructor
**/
var Selection = function(session) {
diff --git a/lib/ace/snippets/gitignore.js b/lib/ace/snippets/gitignore.js
new file mode 100644
index 00000000..0a632c99
--- /dev/null
+++ b/lib/ace/snippets/gitignore.js
@@ -0,0 +1,7 @@
+define(function(require, exports, module) {
+"use strict";
+
+exports.snippetText = require("../requirejs/text!./gitignore.snippets");
+exports.scope = "gitignore";
+
+});
diff --git a/lib/ace/snippets/gitignore.snippets b/lib/ace/snippets/gitignore.snippets
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/ace/snippets/vala.js b/lib/ace/snippets/vala.js
new file mode 100644
index 00000000..6092d3c1
--- /dev/null
+++ b/lib/ace/snippets/vala.js
@@ -0,0 +1,195 @@
+define(function(require, exports, module) {
+"use strict";
+
+// exports.snippetText = require("../requirejs/text!./.snippets");
+exports.snippets = [
+ {
+ "content": "case ${1:condition}:\n\t$0\n\tbreak;\n",
+ "name": "case",
+ "scope": "vala",
+ "tabTrigger": "case"
+ },
+ {
+ "content": "/**\n * ${6}\n */\n${1:public} class ${2:MethodName}${3: : GLib.Object} {\n\n\t/**\n\t * ${7}\n\t */\n\tpublic ${2}(${4}) {\n\t\t${5}\n\t}\n\n\t$0\n}",
+ "name": "class",
+ "scope": "vala",
+ "tabTrigger": "class"
+ },
+ {
+ "content": "(${1}) => {\n\t${0}\n}\n",
+ "name": "closure",
+ "scope": "vala",
+ "tabTrigger": "=>"
+ },
+ {
+ "content": "/*\n * $0\n */",
+ "name": "Comment (multiline)",
+ "scope": "vala",
+ "tabTrigger": "/*"
+ },
+ {
+ "content": "Console.WriteLine($1);\n$0",
+ "name": "Console.WriteLine (writeline)",
+ "scope": "vala",
+ "tabTrigger": "writeline"
+ },
+ {
+ "content": "[DBus(name = \"$0\")]",
+ "name": "DBus annotation",
+ "scope": "vala",
+ "tabTrigger": "[DBus"
+ },
+ {
+ "content": "delegate ${1:void} ${2:DelegateName}($0);",
+ "name": "delegate",
+ "scope": "vala",
+ "tabTrigger": "delegate"
+ },
+ {
+ "content": "do {\n\t$0\n} while ($1);\n",
+ "name": "do while",
+ "scope": "vala",
+ "tabTrigger": "dowhile"
+ },
+ {
+ "content": "/**\n * $0\n */",
+ "name": "DocBlock",
+ "scope": "vala",
+ "tabTrigger": "/**"
+ },
+ {
+ "content": "else if ($1) {\n\t$0\n}\n",
+ "name": "else if (elseif)",
+ "scope": "vala",
+ "tabTrigger": "elseif"
+ },
+ {
+ "content": "else {\n\t$0\n}",
+ "name": "else",
+ "scope": "vala",
+ "tabTrigger": "else"
+ },
+ {
+ "content": "enum {$1:EnumName} {\n\t$0\n}",
+ "name": "enum",
+ "scope": "vala",
+ "tabTrigger": "enum"
+ },
+ {
+ "content": "public errordomain ${1:Error} {\n\t$0\n}",
+ "name": "error domain",
+ "scope": "vala",
+ "tabTrigger": "errordomain"
+ },
+ {
+ "content": "for ($1;$2;$3) {\n\t$0\n}",
+ "name": "for",
+ "scope": "vala",
+ "tabTrigger": "for"
+ },
+ {
+ "content": "foreach ($1 in $2) {\n\t$0\n}",
+ "name": "foreach",
+ "scope": "vala",
+ "tabTrigger": "foreach"
+ },
+ {
+ "content": "Gee.ArrayList<${1:G}>($0);",
+ "name": "Gee.ArrayList",
+ "scope": "vala",
+ "tabTrigger": "ArrayList"
+ },
+ {
+ "content": "Gee.HashMap<${1:K},${2:V}>($0);",
+ "name": "Gee.HashMap",
+ "scope": "vala",
+ "tabTrigger": "HashMap"
+ },
+ {
+ "content": "Gee.HashSet<${1:G}>($0);",
+ "name": "Gee.HashSet",
+ "scope": "vala",
+ "tabTrigger": "HashSet"
+ },
+ {
+ "content": "if ($1) {\n\t$0\n}",
+ "name": "if",
+ "scope": "vala",
+ "tabTrigger": "if"
+ },
+ {
+ "content": "interface ${1:InterfaceName}{$2: : SuperInterface} {\n\t$0\n}",
+ "name": "interface",
+ "scope": "vala",
+ "tabTrigger": "interface"
+ },
+ {
+ "content": "public static int main(string [] argv) {\n\t${0}\n\treturn 0;\n}",
+ "name": "Main function",
+ "scope": "vala",
+ "tabTrigger": "main"
+ },
+ {
+ "content": "namespace $1 {\n\t$0\n}\n",
+ "name": "namespace (ns)",
+ "scope": "vala",
+ "tabTrigger": "ns"
+ },
+ {
+ "content": "stdout.printf($0);",
+ "name": "printf",
+ "scope": "vala",
+ "tabTrigger": "printf"
+ },
+ {
+ "content": "${1:public} ${2:Type} ${3:Name} {\n\tset {\n\t\t$0\n\t}\n\tget {\n\n\t}\n}",
+ "name": "property (prop)",
+ "scope": "vala",
+ "tabTrigger": "prop"
+ },
+ {
+ "content": "${1:public} ${2:Type} ${3:Name} {\n\tget {\n\t\t$0\n\t}\n}",
+ "name": "read-only property (roprop)",
+ "scope": "vala",
+ "tabTrigger": "roprop"
+ },
+ {
+ "content": "@\"${1:\\$var}\"",
+ "name": "String template (@)",
+ "scope": "vala",
+ "tabTrigger": "@"
+ },
+ {
+ "content": "struct ${1:StructName} {\n\t$0\n}",
+ "name": "struct",
+ "scope": "vala",
+ "tabTrigger": "struct"
+ },
+ {
+ "content": "switch ($1) {\n\t$0\n}",
+ "name": "switch",
+ "scope": "vala",
+ "tabTrigger": "switch"
+ },
+ {
+ "content": "try {\n\t$2\n} catch (${1:Error} e) {\n\t$0\n}",
+ "name": "try/catch",
+ "scope": "vala",
+ "tabTrigger": "try"
+ },
+ {
+ "content": "\"\"\"$0\"\"\";",
+ "name": "Verbatim string (\"\"\")",
+ "scope": "vala",
+ "tabTrigger": "verbatim"
+ },
+ {
+ "content": "while ($1) {\n\t$0\n}",
+ "name": "while",
+ "scope": "vala",
+ "tabTrigger": "while"
+ }
+];
+exports.scope = "";
+
+});
diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js
index db56517c..3b7bf5d9 100644
--- a/lib/ace/test/all_browser.js
+++ b/lib/ace/test/all_browser.js
@@ -44,6 +44,7 @@ var testNames = [
"ace/mode/folding/xml_test",
"ace/mode/folding/coffee_test",
"ace/multi_select_test",
+ "ace/mouse/mouse_handler_test",
"ace/occur_test",
"ace/range_test",
"ace/range_list_test",
diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js
index 72989766..64bf59e8 100644
--- a/lib/ace/tokenizer.js
+++ b/lib/ace/tokenizer.js
@@ -116,6 +116,11 @@ var Tokenizer = function(rules) {
rule.onMatch = null;
}
+ if (!ruleRegExps.length) {
+ mapping[0] = 0;
+ ruleRegExps.push("$");
+ }
+
splitterRurles.forEach(function(rule) {
rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
}, this);
diff --git a/package.json b/package.json
index c48a9433..31a4dec9 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,8 @@
"asyncjs": "0.0.x",
"jsdom": "0.2.x",
"amd-loader": "~0.0.4",
- "dryice": "0.4.10"
+ "dryice": "0.4.11",
+ "architect-build": "https://github.com/c9/architect-build/tarball/42723e152bb"
},
"mappings": {
"ace": "."
@@ -30,6 +31,7 @@
"lib": "lib/ace"
},
"scripts": {
+ "start": "node static.js",
"test": "node lib/ace/test/all.js"
}
}
diff --git a/tool/update_deps.js b/tool/update_deps.js
index 99e2a9bd..249083c8 100644
--- a/tool/update_deps.js
+++ b/tool/update_deps.js
@@ -85,7 +85,7 @@ var deps = {
jshint: {
path: "mode/javascript/jshint.js",
browserify: {
- npmModule: "git+https://github.com/nightwing/jshint.git#master",
+ npmModule: "git+https://github.com/ajaxorg/jshint.git#master",
path: "jshint/src/jshint.js",
exports: "jshint"
},