commit
f4b5a13855
44 changed files with 2861 additions and 589 deletions
|
|
@ -43,7 +43,7 @@ var copy = require('dryice').copy;
|
||||||
var ACE_HOME = __dirname;
|
var ACE_HOME = __dirname;
|
||||||
|
|
||||||
function main(args) {
|
function main(args) {
|
||||||
var target;
|
var target = "minimal";
|
||||||
if (args.length == 3) {
|
if (args.length == 3) {
|
||||||
target = args[2];
|
target = args[2];
|
||||||
// Check if 'target' contains some allowed value.
|
// Check if 'target' contains some allowed value.
|
||||||
|
|
@ -52,12 +52,13 @@ function main(args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target) {
|
if (target == "help") {
|
||||||
console.log("--- Ace Dryice Build Tool ---");
|
console.log("--- Ace Dryice Build Tool ---");
|
||||||
console.log("");
|
console.log("");
|
||||||
console.log("Options:");
|
console.log("Options:");
|
||||||
|
console.log(" minimal Runs minimal build of Ace");
|
||||||
console.log(" normal Runs embedded build of Ace");
|
console.log(" normal Runs embedded build of Ace");
|
||||||
console.log(" demo Runs demo build of Ace");
|
console.log(" demo Runs demo build of Ace");
|
||||||
console.log(" bm Runs bookmarklet build of Ace");
|
console.log(" bm Runs bookmarklet build of Ace");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
@ -70,6 +71,15 @@ function main(args) {
|
||||||
textPluginPattern: /^ace\/requirejs\/text!/
|
textPluginPattern: /^ace\/requirejs\/text!/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (target == "minimal") {
|
||||||
|
buildAce(aceProject, {
|
||||||
|
compress: false,
|
||||||
|
noconflict: false,
|
||||||
|
suffix: "",
|
||||||
|
compat: true,
|
||||||
|
name: "ace"
|
||||||
|
});
|
||||||
|
}
|
||||||
if (target == "normal") {
|
if (target == "normal") {
|
||||||
ace(aceProject);
|
ace(aceProject);
|
||||||
}
|
}
|
||||||
|
|
@ -113,14 +123,14 @@ function ace(aceProject) {
|
||||||
buildAce(aceProject, {
|
buildAce(aceProject, {
|
||||||
compress: false,
|
compress: false,
|
||||||
noconflict: false,
|
noconflict: false,
|
||||||
suffix: "-uncompressed.js",
|
suffix: "-uncompressed",
|
||||||
compat: true,
|
compat: true,
|
||||||
name: "ace"
|
name: "ace"
|
||||||
});
|
});
|
||||||
buildAce(aceProject, {
|
buildAce(aceProject, {
|
||||||
compress: false,
|
compress: false,
|
||||||
noconflict: true,
|
noconflict: true,
|
||||||
suffix: "-uncompressed-noconflict.js",
|
suffix: "-uncompressed-noconflict",
|
||||||
compat: true,
|
compat: true,
|
||||||
name: "ace",
|
name: "ace",
|
||||||
workers: []
|
workers: []
|
||||||
|
|
@ -130,7 +140,7 @@ function ace(aceProject) {
|
||||||
buildAce(aceProject, {
|
buildAce(aceProject, {
|
||||||
compress: true,
|
compress: true,
|
||||||
noconflict: false,
|
noconflict: false,
|
||||||
suffix: ".js",
|
suffix: "",
|
||||||
compat: true,
|
compat: true,
|
||||||
name: "ace",
|
name: "ace",
|
||||||
workers: []
|
workers: []
|
||||||
|
|
@ -138,7 +148,7 @@ function ace(aceProject) {
|
||||||
buildAce(aceProject, {
|
buildAce(aceProject, {
|
||||||
compress: true,
|
compress: true,
|
||||||
noconflict: true,
|
noconflict: true,
|
||||||
suffix: "-noconflict.js",
|
suffix: "-noconflict",
|
||||||
compat: true,
|
compat: true,
|
||||||
name: "ace",
|
name: "ace",
|
||||||
workers: []
|
workers: []
|
||||||
|
|
@ -199,7 +209,7 @@ function demo(aceProject) {
|
||||||
noconflict: false,
|
noconflict: false,
|
||||||
compat: false,
|
compat: false,
|
||||||
name: "kitchen-sink",
|
name: "kitchen-sink",
|
||||||
suffix: "-uncompressed.js",
|
suffix: "",
|
||||||
keybindings: []
|
keybindings: []
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -213,14 +223,14 @@ function buildAce(aceProject, options) {
|
||||||
requires: null,
|
requires: null,
|
||||||
compress: false,
|
compress: false,
|
||||||
noconflict: false,
|
noconflict: false,
|
||||||
suffix: ".js",
|
suffix: "",
|
||||||
name: "ace",
|
name: "ace",
|
||||||
compat: true,
|
compat: true,
|
||||||
modes: [
|
modes: [
|
||||||
"css", "html", "javascript", "php", "coldfusion", "python", "lua", "xml", "ruby", "java", "c_cpp",
|
"css", "html", "javascript", "php", "coldfusion", "python", "lua", "xml", "ruby", "java", "c_cpp",
|
||||||
"coffee", "perl", "csharp", "haxe", "liquid", "svg", "clojure", "scss", "json", "groovy",
|
"coffee", "perl", "csharp", "haxe", "liquid", "svg", "clojure", "scss", "json", "groovy",
|
||||||
"ocaml", "scala", "textile", "scad", "markdown", "latex", "powershell", "sql",
|
"ocaml", "scala", "textile", "scad", "markdown", "latex", "powershell", "sql",
|
||||||
"text", "pgsql", "sh", "xquery", "less", "golang"
|
"text", "pgsql", "sh", "xquery", "less", "golang", "c9search"
|
||||||
],
|
],
|
||||||
themes: [
|
themes: [
|
||||||
"chrome", "clouds", "clouds_midnight", "cobalt", "crimson_editor", "dawn",
|
"chrome", "clouds", "clouds_midnight", "cobalt", "crimson_editor", "dawn",
|
||||||
|
|
@ -252,6 +262,15 @@ function buildAce(aceProject, options) {
|
||||||
var exportFilter = exportAce(options.ns, options.exportModule);
|
var exportFilter = exportAce(options.ns, options.exportModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove use strict
|
||||||
|
filters.push(function(text) {
|
||||||
|
return text.replace(/['"]use strict['"];/g, "");
|
||||||
|
})
|
||||||
|
// remove redundant comments
|
||||||
|
filters.push(function(text) {
|
||||||
|
return text.replace(/(;)\s*\/\*[\d\D]*?\*\//g, "$1");
|
||||||
|
})
|
||||||
|
|
||||||
if (options.compress)
|
if (options.compress)
|
||||||
filters.push(copy.filter.uglifyjs);
|
filters.push(copy.filter.uglifyjs);
|
||||||
|
|
||||||
|
|
@ -279,7 +298,7 @@ function buildAce(aceProject, options) {
|
||||||
copy({
|
copy({
|
||||||
source: ace,
|
source: ace,
|
||||||
filter: exportFilter ? filters.concat(exportFilter) : filters,
|
filter: exportFilter ? filters.concat(exportFilter) : filters,
|
||||||
dest: targetDir + '/' + name + suffix
|
dest: targetDir + suffix + '/' + name + ".js"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.compat) {
|
if (options.compat) {
|
||||||
|
|
@ -292,7 +311,7 @@ function buildAce(aceProject, options) {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filter: filters,
|
filter: filters,
|
||||||
dest: targetDir + "/" + name + "-compat" + suffix
|
dest: targetDir + suffix + "/" + name + "-compat.js"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,7 +328,7 @@ function buildAce(aceProject, options) {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filter: filters,
|
filter: filters,
|
||||||
dest: targetDir + "/mode-" + mode + suffix
|
dest: targetDir + suffix + "/mode-" + mode + ".js"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -324,7 +343,7 @@ function buildAce(aceProject, options) {
|
||||||
require: ["ace/theme/" + theme]
|
require: ["ace/theme/" + theme]
|
||||||
}],
|
}],
|
||||||
filter: filters,
|
filter: filters,
|
||||||
dest: targetDir + "/theme-" + theme + suffix
|
dest: targetDir + suffix + "/theme-" + theme + ".js"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -373,11 +392,11 @@ function buildAce(aceProject, options) {
|
||||||
source: [
|
source: [
|
||||||
{
|
{
|
||||||
project: cloneProject(project),
|
project: cloneProject(project),
|
||||||
require: [ 'ace/keyboard/keybinding/' + keybinding ]
|
require: [ 'ace/keyboard/' + keybinding ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filter: filters,
|
filter: filters,
|
||||||
dest: "build/src/keybinding-" + keybinding + suffix
|
dest: targetDir + suffix + "/keybinding-" + keybinding + ".js"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -423,6 +442,7 @@ function exportAce(ns, module, requireBase) {
|
||||||
var template = function() {
|
var template = function() {
|
||||||
(function() {
|
(function() {
|
||||||
REQUIRE_NS.require(["MODULE"], function(a) {
|
REQUIRE_NS.require(["MODULE"], function(a) {
|
||||||
|
a.config.init();
|
||||||
if (!window.NS)
|
if (!window.NS)
|
||||||
window.NS = {};
|
window.NS = {};
|
||||||
for (var key in a) if (a.hasOwnProperty(key))
|
for (var key in a) if (a.hasOwnProperty(key))
|
||||||
|
|
@ -443,3 +463,5 @@ function exportAce(ns, module, requireBase) {
|
||||||
|
|
||||||
if (!module.parent)
|
if (!module.parent)
|
||||||
main(process.argv);
|
main(process.argv);
|
||||||
|
else
|
||||||
|
exports.buildAce = buildAce;
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ var theme = require("ace/theme/textmate");
|
||||||
var EditSession = require("ace/edit_session").EditSession;
|
var EditSession = require("ace/edit_session").EditSession;
|
||||||
var UndoManager = require("ace/undomanager").UndoManager;
|
var UndoManager = require("ace/undomanager").UndoManager;
|
||||||
|
|
||||||
var vim = require("ace/keyboard/keybinding/vim").Vim;
|
var vim = require("ace/keyboard/vim").handler;
|
||||||
var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
|
var emacs = require("ace/keyboard/emacs").handler;
|
||||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||||
|
|
||||||
var modesByName;
|
var modesByName;
|
||||||
|
|
|
||||||
64
install.js
Normal file
64
install.js
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
* Julian Viereck <julian.viereck@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
var buildAce = require("./Makefile.dryice").buildAce;
|
||||||
|
|
||||||
|
|
||||||
|
var ACE_HOME = __dirname;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var aceProject = {
|
||||||
|
roots: [
|
||||||
|
ACE_HOME + '/lib',
|
||||||
|
ACE_HOME + '/demo'
|
||||||
|
],
|
||||||
|
textPluginPattern: /^ace\/requirejs\/text!/
|
||||||
|
};
|
||||||
|
buildAce(aceProject, {
|
||||||
|
compress: false,
|
||||||
|
noconflict: false,
|
||||||
|
suffix: "",
|
||||||
|
compat: true,
|
||||||
|
name: "ace"
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("--- Ace Build error ---");
|
||||||
|
console.log(e);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
@ -227,7 +227,7 @@
|
||||||
<!--DEVEL -->
|
<!--DEVEL -->
|
||||||
|
|
||||||
<!--PACKAGE
|
<!--PACKAGE
|
||||||
<script src="demo/kitchen-sink/kitchen-sink-uncompressed.js" data-ace-suffix="-uncompressed.js" data-ace-base="demo/kitchen-sink" type="text/javascript" charset="utf-8"></script>
|
<script src="demo/kitchen-sink/kitchen-sink.js" data-ace-base="demo/kitchen-sink" type="text/javascript" charset="utf-8"></script>
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
require("kitchen-sink/demo");
|
require("kitchen-sink/demo");
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,7 @@ require("./worker/worker_client");
|
||||||
require("./keyboard/hash_handler");
|
require("./keyboard/hash_handler");
|
||||||
require("./keyboard/state_handler");
|
require("./keyboard/state_handler");
|
||||||
require("./placeholder");
|
require("./placeholder");
|
||||||
require("./config").init();
|
exports.config = require("./config");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ace.edit(el) -> Editor
|
* Ace.edit(el) -> Editor
|
||||||
* - el (String | DOMElement): Either the id of an element, or the element itself
|
* - el (String | DOMElement): Either the id of an element, or the element itself
|
||||||
|
|
@ -76,6 +75,9 @@ exports.edit = function(el) {
|
||||||
el = document.getElementById(el);
|
el = document.getElementById(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (el.env && el.env.editor instanceof Editor)
|
||||||
|
return el.env.editor;
|
||||||
|
|
||||||
var doc = new EditSession(Dom.getInnerText(el));
|
var doc = new EditSession(Dom.getInnerText(el));
|
||||||
doc.setUndoManager(new UndoManager());
|
doc.setUndoManager(new UndoManager());
|
||||||
el.innerHTML = '';
|
el.innerHTML = '';
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ exports.init = function() {
|
||||||
|
|
||||||
var scriptOptions = {};
|
var scriptOptions = {};
|
||||||
var scriptUrl = "";
|
var scriptUrl = "";
|
||||||
var suffix;
|
|
||||||
|
|
||||||
var scripts = document.getElementsByTagName("script");
|
var scripts = document.getElementsByTagName("script");
|
||||||
for (var i=0; i<scripts.length; i++) {
|
for (var i=0; i<scripts.length; i++) {
|
||||||
|
|
@ -98,10 +97,9 @@ exports.init = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = src.match(/^(?:(.*\/)ace\.js|(.*\/)ace((-uncompressed)?(-noconflict)?\.js))(?:\?|$)/);
|
var m = src.match(/^(?:(.*\/)ace\.js)(?:\?|$)/);
|
||||||
if (m) {
|
if (m) {
|
||||||
scriptUrl = m[1] || m[2];
|
scriptUrl = m[1] || m[2];
|
||||||
suffix = m[3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +108,6 @@ exports.init = function() {
|
||||||
scriptOptions.packaged = true;
|
scriptOptions.packaged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptOptions.suffix = scriptOptions.suffix || suffix;
|
|
||||||
scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
|
scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
|
||||||
scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
|
scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
|
||||||
scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
|
scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@
|
||||||
|
|
||||||
.ace_scroller {
|
.ace_scroller {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow-x: scroll;
|
overflow: hidden;
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_content {
|
.ace_content {
|
||||||
|
|
@ -33,7 +32,7 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: auto;
|
width: auto;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
z-index: 1000;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_gutter_active_line {
|
.ace_gutter_active_line {
|
||||||
|
|
@ -42,8 +41,8 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_gutter.horscroll {
|
.ace_scroller.horscroll {
|
||||||
box-shadow: 0px 0px 20px rgba(0,0,0,0.4);
|
box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_gutter-cell {
|
.ace_gutter-cell {
|
||||||
|
|
@ -52,13 +51,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_gutter-cell.ace_error {
|
.ace_gutter-cell.ace_error {
|
||||||
background-image: url("data:image/gif,GIF89a%10%00%10%00%D5%00%00%F5or%F5%87%88%F5nr%F4ns%EBmq%F5z%7F%DDJT%DEKS%DFOW%F1Yc%F2ah%CE(7%CE)8%D18E%DD%40M%F2KZ%EBU%60%F4%60m%DCir%C8%16(%C8%19*%CE%255%F1%3FR%F1%3FS%E6%AB%B5%CA%5DI%CEn%5E%F7%A2%9A%C9G%3E%E0a%5B%F7%89%85%F5yy%F6%82%80%ED%82%80%FF%BF%BF%E3%C4%C4%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%25%00%2C%00%00%00%00%10%00%10%00%00%06p%C0%92pH%2C%1A%8F%C8%D2H%93%E1d4%23%E4%88%D3%09mB%1DN%B48%F5%90%40%60%92G%5B%94%20%3E%22%D2%87%24%FA%20%24%C5%06A%00%20%B1%07%02B%A38%89X.v%17%82%11%13q%10%0Fi%24%0F%8B%10%7BD%12%0Ei%09%92%09%0EpD%18%15%24%0A%9Ci%05%0C%18F%18%0B%07%04%01%04%06%A0H%18%12%0D%14%0D%12%A1I%B3%B4%B5IA%00%3B");
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTQ4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTU4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBMjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBMzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkgXxbAAAAJbSURBVHjapFNNaBNBFH4zs5vdZLP5sQmNpT82QY209heh1ioWisaDRcSKF0WKJ0GQnrzrxasHsR6EnlrwD0TagxJabaVEpFYxLWlLSS822tr87m66ccfd2GKyVhA6MMybgfe97/vmPUQphd0sZjto9XIn9OOsvlu2nkqRzVU+6vvlzPf8W6bk8dxQ0NPbxAALgCgg2JkaQuhzQau/El0zbmUA7U0Es8v2CiYmKQJHGO1QICCLoqilMhkmurDAyapKgqItezi/USRdJqEYY4D5jCy03ht2yMkkvL91jTTX10qzyyu2hruPRN7jgbH+EOsXcMLgYiThEgAMhABW85oqy1DXdRIdvP1AHJ2acQXvDIrVHcdQNrEKNYSVMSZGMjEzIIAwDXIo+6G/FxcGnzkC3T2oMhLjre49sBB+RRcHLqdafK6sYdE/GGBwU1VpFNj0aN8pJbe+BkZyevUrvLl6Xmm0W9IuTc0DxrDNAJd5oEvI/KRsNC3bQyNjPO9yQ1YHcfj2QvfQc/5TUhJTBc2iM0U7AWDQtc1nJHvD/cfO2s7jaGkiTEfa/Ep8coLu7zmNmh8+dc5lZDuUeFAGUNA/OY6JVaypQ0vjr7XYjUvJM37vt+j1vuTK5DgVfVUoTjVe+y3/LxMxY2GgU+CSLy4cpfsYorRXuXIOi0Vt40h67uZFTdIo6nLaZcwUJWAzwNS0tBnqqKzQDnjdG/iPyZxo46HaKUpbvYkj8qYRTZsBhge+JHhZyh0x9b95JqjVJkT084kZIPwu/mPWqPgfQ5jXh2+92Ay7HedfAgwA6KDWafb4w3cAAAAASUVORK5CYII=");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 2px center;
|
background-position: 2px center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_gutter-cell.ace_warning {
|
.ace_gutter-cell.ace_warning {
|
||||||
background-image: url("data:image/gif,GIF89a%10%00%10%00%D5%00%00%FF%DBr%FF%DE%81%FF%E2%8D%FF%E2%8F%FF%E4%96%FF%E3%97%FF%E5%9D%FF%E6%9E%FF%EE%C1%FF%C8Z%FF%CDk%FF%D0s%FF%D4%81%FF%D5%82%FF%D5%83%FF%DC%97%FF%DE%9D%FF%E7%B8%FF%CCl%7BQ%13%80U%15%82W%16%81U%16%89%5B%18%87%5B%18%8C%5E%1A%94d%1D%C5%83-%C9%87%2F%C6%84.%C6%85.%CD%8B2%C9%871%CB%8A3%CD%8B5%DC%98%3F%DF%9BB%E0%9CC%E1%A5U%CB%871%CF%8B5%D1%8D6%DB%97%40%DF%9AB%DD%99B%E3%B0p%E7%CC%AE%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%2F%00%2C%00%00%00%00%10%00%10%00%00%06a%C0%97pH%2C%1A%8FH%A1%ABTr%25%87%2B%04%82%F4%7C%B9X%91%08%CB%99%1C!%26%13%84*iJ9(%15G%CA%84%14%01%1A%97%0C%03%80%3A%9A%3E%81%84%3E%11%08%B1%8B%20%02%12%0F%18%1A%0F%0A%03'F%1C%04%0B%10%16%18%10%0B%05%1CF%1D-%06%07%9A%9A-%1EG%1B%A0%A1%A0U%A4%A5%A6BA%00%3B");
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTg4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTk4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBNjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBNzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pgd7PfIAAAGmSURBVHjaYvr//z8DJZiJgUIANoCRkREb9gLiSVAaQx4OQM7AAkwd7XU2/v++/rOttdYGEB9dASEvOMydGKfH8Gv/p4XTkvRBfLxeQAP+1cUhXopyvzhP7P/IoSj7g7Mw09cNKO6J1QQ0L4gICPIv/veg/8W+JdFvQNLHVsW9/nmn9zk7B+cCkDwhL7gt6knSZnx9/LuCEOcvkIAMP+cvto9nfqyZmmUAksfnBUtbM60gX/3/kgyv3/xSFOL5DZT+L8vP+Yfh5cvfPvp/xUHyQHXGyAYwgpwBjZYFT3Y1OEl/OfCH4ffv3wzc4iwMvNIsDJ+f/mH4+vIPAxsb631WW0Yln6ZpQLXdMK/DXGDflh+sIv37EivD5x//Gb7+YWT4y86sl7BCCkSD+Z++/1dkvsFRl+HnD1Rvje4F8whjMXmGj58YGf5zsDMwcnAwfPvKcml62DsQDeaDxN+/Y0qwlpEHqrdB94IRNIDUgfgfKJChGK4OikEW3gTiXUB950ASLFAF54AC94A0G9QAfOnmF9DCDzABFqS08IHYDIScdijOjQABBgC+/9awBH96jwAAAABJRU5ErkJggg==");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 2px center;
|
background-position: 2px center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -761,6 +761,9 @@ var EditSession = function(text, mode) {
|
||||||
|
|
||||||
this.$modes = {};
|
this.$modes = {};
|
||||||
this._loadMode = function(mode, callback) {
|
this._loadMode = function(mode, callback) {
|
||||||
|
if (!this.$modes["null"])
|
||||||
|
this.$modes["null"] = this.$modes["ace/mode/text"] = new TextMode();
|
||||||
|
|
||||||
if (this.$modes[mode])
|
if (this.$modes[mode])
|
||||||
return callback(this.$modes[mode]);
|
return callback(this.$modes[mode]);
|
||||||
|
|
||||||
|
|
@ -772,6 +775,10 @@ var EditSession = function(text, mode) {
|
||||||
if (module)
|
if (module)
|
||||||
return done(module);
|
return done(module);
|
||||||
|
|
||||||
|
// set mode to text until loading is finished
|
||||||
|
if (!this.$mode)
|
||||||
|
this.$setModePlaceholder();
|
||||||
|
|
||||||
fetch(function() {
|
fetch(function() {
|
||||||
require([mode], done);
|
require([mode], done);
|
||||||
});
|
});
|
||||||
|
|
@ -794,11 +801,30 @@ var EditSession = function(text, mode) {
|
||||||
return callback();
|
return callback();
|
||||||
|
|
||||||
var base = mode.split("/").pop();
|
var base = mode.split("/").pop();
|
||||||
var filename = config.get("modePath") + "/mode-" + base + config.get("suffix");
|
var filename = config.get("modePath") + "/mode-" + base + ".js";
|
||||||
net.loadScript(filename, callback);
|
net.loadScript(filename, callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$setModePlaceholder = function() {
|
||||||
|
this.$mode = this.$modes["null"];
|
||||||
|
var tokenizer = this.$mode.getTokenizer();
|
||||||
|
|
||||||
|
if (!this.bgTokenizer) {
|
||||||
|
this.bgTokenizer = new BackgroundTokenizer(tokenizer);
|
||||||
|
var _self = this;
|
||||||
|
this.bgTokenizer.addEventListener("update", function(e) {
|
||||||
|
_self._emit("tokenizerUpdate", e);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.bgTokenizer.setTokenizer(tokenizer);
|
||||||
|
}
|
||||||
|
this.bgTokenizer.setDocument(this.getDocument());
|
||||||
|
|
||||||
|
this.tokenRe = this.$mode.tokenRe;
|
||||||
|
this.nonTokenRe = this.$mode.nonTokenRe;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EditSession.setMode(mode)
|
* EditSession.setMode(mode)
|
||||||
* - mode (TextMode): Set a new text mode
|
* - mode (TextMode): Set a new text mode
|
||||||
|
|
@ -809,6 +835,7 @@ var EditSession = function(text, mode) {
|
||||||
this.$mode = null;
|
this.$mode = null;
|
||||||
this.$modeId = null;
|
this.$modeId = null;
|
||||||
this.setMode = function(mode) {
|
this.setMode = function(mode) {
|
||||||
|
mode = mode || "null";
|
||||||
// load on demand
|
// load on demand
|
||||||
if (typeof mode === "string") {
|
if (typeof mode === "string") {
|
||||||
if (this.$modeId == mode)
|
if (this.$modeId == mode)
|
||||||
|
|
@ -823,12 +850,6 @@ var EditSession = function(text, mode) {
|
||||||
_self.setMode(module);
|
_self.setMode(module);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else if (mode == null) {
|
|
||||||
mode = "ace/mode/text"
|
|
||||||
this.$modeId = mode;
|
|
||||||
this.$modes[mode] = this.$modes[mode] || (new TextMode());
|
|
||||||
this.setMode(this.$modes[mode]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$mode === mode) return;
|
if (this.$mode === mode) return;
|
||||||
|
|
|
||||||
|
|
@ -96,21 +96,24 @@ function BracketMatch() {
|
||||||
"}": "{"
|
"}": "{"
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$findOpeningBracket = function(bracket, position) {
|
this.$findOpeningBracket = function(bracket, position, typeRe) {
|
||||||
var openBracket = this.$brackets[bracket];
|
var openBracket = this.$brackets[bracket];
|
||||||
var depth = 1;
|
var depth = 1;
|
||||||
|
|
||||||
var iterator = new TokenIterator(this, position.row, position.column);
|
var iterator = new TokenIterator(this, position.row, position.column);
|
||||||
var token = iterator.getCurrentToken();
|
var token = iterator.getCurrentToken();
|
||||||
if (!token) return null;
|
if (!token)
|
||||||
|
token = iterator.stepForward();
|
||||||
|
if (!token)
|
||||||
|
return
|
||||||
|
|
||||||
// token.type contains a period-delimited list of token identifiers
|
if (!typeRe){
|
||||||
// (e.g.: "constant.numeric" or "paren.lparen"). Create a pattern that
|
typeRe = new RegExp(
|
||||||
// matches any token containing the same identifiers or a subset. In
|
"(\\.?" +
|
||||||
// addition, if token.type includes "rparen", then also match "lparen".
|
token.type.replace(".", "\\.").replace("rparen", ".paren")
|
||||||
// So if type.token is "paren.rparen", then typeRe will match "lparen.paren".
|
+ ")+"
|
||||||
var typeRe = new RegExp("(\\.?" +
|
);
|
||||||
token.type.replace(".", "|").replace("rparen", "lparen|rparen") + ")+");
|
}
|
||||||
|
|
||||||
// Start searching in token, just before the character at position.column
|
// Start searching in token, just before the character at position.column
|
||||||
var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
|
var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
|
||||||
|
|
@ -149,21 +152,24 @@ function BracketMatch() {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$findClosingBracket = function(bracket, position) {
|
this.$findClosingBracket = function(bracket, position, typeRe, allowBlankLine) {
|
||||||
var closingBracket = this.$brackets[bracket];
|
var closingBracket = this.$brackets[bracket];
|
||||||
var depth = 1;
|
var depth = 1;
|
||||||
|
|
||||||
var iterator = new TokenIterator(this, position.row, position.column);
|
var iterator = new TokenIterator(this, position.row, position.column);
|
||||||
var token = iterator.getCurrentToken();
|
var token = iterator.getCurrentToken();
|
||||||
if (!token) return null;
|
if (!token)
|
||||||
|
token = iterator.stepForward();
|
||||||
|
if (!token)
|
||||||
|
return
|
||||||
|
|
||||||
// token.type contains a period-delimited list of token identifiers
|
if (!typeRe){
|
||||||
// (e.g.: "constant.numeric" or "paren.lparen"). Create a pattern that
|
typeRe = new RegExp(
|
||||||
// matches any token containing the same identifiers or a subset. In
|
"(\\.?" +
|
||||||
// addition, if token.type includes "lparen", then also match "rparen".
|
token.type.replace(".", "\\.").replace("lparen", ".paren")
|
||||||
// So if type.token is "lparen.paren", then typeRe will match "paren.rparen".
|
+ ")+"
|
||||||
var typeRe = new RegExp("(\\.?" +
|
);
|
||||||
token.type.replace(".", "|").replace("lparen", "lparen|rparen") + ")+");
|
}
|
||||||
|
|
||||||
// Start searching in token, after the character at position.column
|
// Start searching in token, after the character at position.column
|
||||||
var valueIndex = position.column - iterator.getCurrentTokenColumn();
|
var valueIndex = position.column - iterator.getCurrentTokenColumn();
|
||||||
|
|
@ -191,6 +197,12 @@ function BracketMatch() {
|
||||||
// whose type matches typeRe
|
// whose type matches typeRe
|
||||||
do {
|
do {
|
||||||
token = iterator.stepForward();
|
token = iterator.stepForward();
|
||||||
|
if (allowBlankLine) {
|
||||||
|
// if you've reached the doc end, or, you match a new content line
|
||||||
|
if (token === null || token.type == "string") {
|
||||||
|
return {row: iterator.getCurrentTokenRow() + (token === null ? 1 : -1), column: 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
} while (token && !typeRe.test(token.type));
|
} while (token && !typeRe.test(token.type));
|
||||||
|
|
||||||
if (token == null)
|
if (token == null)
|
||||||
|
|
|
||||||
|
|
@ -509,8 +509,11 @@ var Editor = function(renderer, session) {
|
||||||
this.$updateHighlightActiveLine();
|
this.$updateHighlightActiveLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$highlightSelectedWord)
|
if (this.$highlightSelectedWord && !this.$wordHighlightTimer)
|
||||||
this.session.getMode().highlightSelection(this);
|
this.$wordHighlightTimer = setTimeout(function(self) {
|
||||||
|
self.session.$mode.highlightSelection(self);
|
||||||
|
self.$wordHighlightTimer = null;
|
||||||
|
}, 30, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -875,6 +878,7 @@ var Editor = function(renderer, session) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.renderer.setHighlightGutterLine(shouldHighlight);
|
this.renderer.setHighlightGutterLine(shouldHighlight);
|
||||||
|
this.$highlightGutterLine = shouldHighlight;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getHighlightGutterLine = function() {
|
this.getHighlightGutterLine = function() {
|
||||||
|
|
@ -893,10 +897,15 @@ var Editor = function(renderer, session) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.$highlightSelectedWord = shouldHighlight;
|
this.$highlightSelectedWord = shouldHighlight;
|
||||||
if (shouldHighlight)
|
if (shouldHighlight) {
|
||||||
this.session.getMode().highlightSelection(this);
|
this.session.getMode().highlightSelection(this);
|
||||||
else
|
} else {
|
||||||
this.session.getMode().clearSelectionHighlight(this);
|
this.session.getMode().clearSelectionHighlight(this);
|
||||||
|
if (this.$wordHighlightTimer) {
|
||||||
|
clearTimeout(this.$wordHighlightTimer);
|
||||||
|
this.$wordHighlightTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1956,7 +1965,7 @@ var Editor = function(renderer, session) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.needle = needle;
|
options.needle = needle;
|
||||||
this.$search.set(options);
|
this.$search.set(options);
|
||||||
this.$find(false, animate);
|
this.$find(options.backwards, animate);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** related to: Editor.find
|
/** related to: Editor.find
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,9 @@ module.exports = {
|
||||||
this.editor.moveCursorTo(0, 9);
|
this.editor.moveCursorTo(0, 9);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
|
|
||||||
|
assert.ok(this.editor.$wordHighlightTimer != null);
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "ipsum");
|
assert.equal(this.session.getTextRange(range), "ipsum");
|
||||||
assert.equal(this.session.$selectionOccurrences.length, 1);
|
assert.equal(this.session.$selectionOccurrences.length, 1);
|
||||||
|
|
@ -95,6 +98,7 @@ module.exports = {
|
||||||
"test: highlight a word and clear highlight": function() {
|
"test: highlight a word and clear highlight": function() {
|
||||||
this.editor.moveCursorTo(0, 8);
|
this.editor.moveCursorTo(0, 8);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "ipsum");
|
assert.equal(this.session.getTextRange(range), "ipsum");
|
||||||
|
|
@ -107,6 +111,7 @@ module.exports = {
|
||||||
"test: highlight another word": function() {
|
"test: highlight another word": function() {
|
||||||
this.selection.moveCursorTo(0, 14);
|
this.selection.moveCursorTo(0, 14);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "dolor");
|
assert.equal(this.session.getTextRange(range), "dolor");
|
||||||
|
|
@ -115,13 +120,18 @@ module.exports = {
|
||||||
|
|
||||||
"test: no selection, no highlight": function() {
|
"test: no selection, no highlight": function() {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
assert.equal(this.session.$selectionOccurrences.length, 0);
|
assert.equal(this.session.$selectionOccurrences.length, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: select a word, no highlight": function() {
|
"test: select a word, no highlight": function() {
|
||||||
this.editor.setHighlightSelectedWord(false);
|
|
||||||
this.selection.moveCursorTo(0, 14);
|
this.selection.moveCursorTo(0, 14);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
|
this.editor.setHighlightSelectedWord(false);
|
||||||
|
|
||||||
|
assert.ok(this.editor.$wordHighlightTimer == null);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "dolor");
|
assert.equal(this.session.getTextRange(range), "dolor");
|
||||||
|
|
@ -146,6 +156,7 @@ module.exports = {
|
||||||
this.search.set(currentOptions);
|
this.search.set(currentOptions);
|
||||||
|
|
||||||
this.selection.setSelectionRange(match);
|
this.selection.setSelectionRange(match);
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
assert.equal(this.session.getTextRange(match), "Mauris");
|
assert.equal(this.session.getTextRange(match), "Mauris");
|
||||||
assert.equal(this.session.$selectionOccurrences.length, 0);
|
assert.equal(this.session.$selectionOccurrences.length, 0);
|
||||||
|
|
@ -155,6 +166,7 @@ module.exports = {
|
||||||
this.selection.moveCursorTo(0, 14);
|
this.selection.moveCursorTo(0, 14);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
this.selection.selectLeft();
|
this.selection.selectLeft();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "dolo");
|
assert.equal(this.session.getTextRange(range), "dolo");
|
||||||
|
|
@ -165,6 +177,7 @@ module.exports = {
|
||||||
this.selection.moveCursorTo(0, 13);
|
this.selection.moveCursorTo(0, 13);
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
this.selection.selectRight();
|
this.selection.selectRight();
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "dolor ");
|
assert.equal(this.session.getTextRange(range), "dolor ");
|
||||||
|
|
@ -176,6 +189,7 @@ module.exports = {
|
||||||
this.selection.selectWord();
|
this.selection.selectWord();
|
||||||
this.selection.selectLeft();
|
this.selection.selectLeft();
|
||||||
this.selection.shiftSelection(1);
|
this.selection.shiftSelection(1);
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
var range = this.selection.getRange();
|
var range = this.selection.getRange();
|
||||||
assert.equal(this.session.getTextRange(range), "olor");
|
assert.equal(this.session.getTextRange(range), "olor");
|
||||||
|
|
@ -202,6 +216,7 @@ module.exports = {
|
||||||
this.search.set(currentOptions);
|
this.search.set(currentOptions);
|
||||||
|
|
||||||
this.selection.setSelectionRange(match);
|
this.selection.setSelectionRange(match);
|
||||||
|
this.session.$mode.highlightSelection(this.editor);
|
||||||
|
|
||||||
assert.equal(this.session.getTextRange(match), "consectetur");
|
assert.equal(this.session.getTextRange(match), "consectetur");
|
||||||
assert.equal(this.session.$selectionOccurrences.length, 2);
|
assert.equal(this.session.$selectionOccurrences.length, 2);
|
||||||
|
|
|
||||||
367
lib/ace/keyboard/emacs.js
Normal file
367
lib/ace/keyboard/emacs.js
Normal file
|
|
@ -0,0 +1,367 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Skywriter.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Julian Viereck (julian.viereck@gmail.com)
|
||||||
|
* Harutyun Amirjanyan (harutyun@c9.io)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var dom = require("../lib/dom");
|
||||||
|
|
||||||
|
var screenToTextBlockCoordinates = function(pageX, pageY) {
|
||||||
|
var canvasPos = this.scroller.getBoundingClientRect();
|
||||||
|
|
||||||
|
var col = Math.floor(
|
||||||
|
(pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
|
||||||
|
);
|
||||||
|
var row = Math.floor(
|
||||||
|
(pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.session.screenToDocumentPosition(row, col);
|
||||||
|
};
|
||||||
|
|
||||||
|
var HashHandler = require("./hash_handler").HashHandler;
|
||||||
|
exports.handler = new HashHandler();
|
||||||
|
|
||||||
|
var initialized = false;
|
||||||
|
exports.handler.attach = function(editor) {
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = true;
|
||||||
|
dom.importCssString('\
|
||||||
|
.emacs-mode .ace_cursor{\
|
||||||
|
border: 2px rgba(50,250,50,0.8) solid!important;\
|
||||||
|
-moz-box-sizing: border-box!important;\
|
||||||
|
box-sizing: border-box!important;\
|
||||||
|
background-color: rgba(0,250,0,0.9);\
|
||||||
|
opacity: 0.5;\
|
||||||
|
}\
|
||||||
|
.emacs-mode .ace_cursor.ace_hidden{\
|
||||||
|
opacity: 1;\
|
||||||
|
background-color: transparent;\
|
||||||
|
}\
|
||||||
|
.emacs-mode .ace_cursor.ace_overwrite {\
|
||||||
|
opacity: 1;\
|
||||||
|
background-color: transparent;\
|
||||||
|
border-width: 0 0 2px 2px !important;\
|
||||||
|
}\
|
||||||
|
.emacs-mode .ace_text-layer {\
|
||||||
|
z-index: 4\
|
||||||
|
}\
|
||||||
|
.emacs-mode .ace_cursor-layer {\
|
||||||
|
z-index: 2\
|
||||||
|
}', 'emacsMode'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.renderer.screenToTextCoordinates = screenToTextBlockCoordinates;
|
||||||
|
editor.setStyle("emacs-mode");
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.handler.detach = function(editor) {
|
||||||
|
delete editor.renderer.screenToTextCoordinates;
|
||||||
|
editor.unsetStyle("emacs-mode");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var keys = require("../lib/keys").KEY_MODS;
|
||||||
|
var eMods = {
|
||||||
|
C: "ctrl", S: "shift", M: "alt"
|
||||||
|
};
|
||||||
|
["S-C-M", "S-C", "S-M", "C-M", "S", "C", "M"].forEach(function(c) {
|
||||||
|
var hashId = 0;
|
||||||
|
c.split("-").forEach(function(c){
|
||||||
|
hashId = hashId | keys[eMods[c]];
|
||||||
|
});
|
||||||
|
eMods[hashId] = c.toLowerCase() + "-";
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.handler.bindKey = function(key, command) {
|
||||||
|
if (!key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ckb = this.commmandKeyBinding;
|
||||||
|
key.split("|").forEach(function(keyPart) {
|
||||||
|
keyPart = keyPart.toLowerCase();
|
||||||
|
ckb[keyPart] = command;
|
||||||
|
keyPart = keyPart.split(" ")[0];
|
||||||
|
if (!ckb[keyPart])
|
||||||
|
ckb[keyPart] = "null";
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
|
||||||
|
if (hashId == -1) {
|
||||||
|
if (data.count) {
|
||||||
|
var str = Array(data.count + 1).join(key);
|
||||||
|
data.count = null;
|
||||||
|
return {command: "insertstring", args: str};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == "\x00")
|
||||||
|
return;
|
||||||
|
|
||||||
|
var modifier = eMods[hashId];
|
||||||
|
if (modifier == "c-" || data.universalArgument) {
|
||||||
|
var count = parseInt(key[key.length - 1]);
|
||||||
|
if (count) {
|
||||||
|
data.count = count;
|
||||||
|
return {command: "null"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.universalArgument = false;
|
||||||
|
|
||||||
|
if (modifier)
|
||||||
|
key = modifier + key;
|
||||||
|
|
||||||
|
if (data.keyChain)
|
||||||
|
key = data.keyChain += " " + key;
|
||||||
|
|
||||||
|
var command = this.commmandKeyBinding[key];
|
||||||
|
data.keyChain = command == "null" ? key : "";
|
||||||
|
|
||||||
|
if (!command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (command == "null")
|
||||||
|
return {command: "null"};
|
||||||
|
|
||||||
|
if (command == "universalArgument") {
|
||||||
|
data.universalArgument = true;
|
||||||
|
return {command: "null"};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof command != "string") {
|
||||||
|
var args = command.args;
|
||||||
|
command = command.command;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof command == "string") {
|
||||||
|
command = this.commands[command] || data.editor.commands.commands[command];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!command.readonly && !command.isYank)
|
||||||
|
data.lastCommand = null;
|
||||||
|
|
||||||
|
if (data.count) {
|
||||||
|
var count = data.count;
|
||||||
|
data.count = 0;
|
||||||
|
return {
|
||||||
|
args: args,
|
||||||
|
command: {
|
||||||
|
exec: function(editor, args) {
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
command.exec(editor, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {command: command, args: args};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.emacsKeys = {
|
||||||
|
// movement
|
||||||
|
"Up|C-p" : "golineup",
|
||||||
|
"Down|C-n" : "golinedown",
|
||||||
|
"Left|C-b" : "gotoleft",
|
||||||
|
"Right|C-f" : "gotoright",
|
||||||
|
"C-Left|M-b" : "gotowordleft",
|
||||||
|
"C-Right|M-f" : "gotowordright",
|
||||||
|
"Home|C-a" : "gotolinestart",
|
||||||
|
"End|C-e" : "gotolineend",
|
||||||
|
"C-Home|S-M-,": "gotostart",
|
||||||
|
"C-End|S-M-." : "gotoend",
|
||||||
|
|
||||||
|
// selection
|
||||||
|
"S-Up|S-C-p" : "selectup",
|
||||||
|
"S-Down|S-C-n" : "selectdown",
|
||||||
|
"S-Left|S-C-b" : "selectleft",
|
||||||
|
"S-Right|S-C-f" : "selectright",
|
||||||
|
"S-C-Left|S-M-b" : "selectwordleft",
|
||||||
|
"S-C-Right|S-M-f" : "selectwordright",
|
||||||
|
"S-Home|S-C-a" : "selecttolinestart",
|
||||||
|
"S-End|S-C-e" : "selecttolineend",
|
||||||
|
"S-C-Home" : "selecttostart",
|
||||||
|
"S-C-End" : "selecttoend",
|
||||||
|
|
||||||
|
"C-l|M-s" : "centerselection",
|
||||||
|
"M-g": "gotoline",
|
||||||
|
"C-x C-p": "selectall",
|
||||||
|
|
||||||
|
// todo fix these
|
||||||
|
"C-Down": "gotopagedown",
|
||||||
|
"C-Up": "gotopageup",
|
||||||
|
"PageDown|C-v": "gotopagedown",
|
||||||
|
"PageUp|M-v": "gotopageup",
|
||||||
|
"S-C-Down": "selectpagedown",
|
||||||
|
"S-C-Up": "selectpageup",
|
||||||
|
"C-s": "findnext",
|
||||||
|
"C-r": "findprevious",
|
||||||
|
"M-C-s": "findnext",
|
||||||
|
"M-C-r": "findprevious",
|
||||||
|
"S-M-5": "replace",
|
||||||
|
|
||||||
|
// basic editing
|
||||||
|
"Backspace": "backspace",
|
||||||
|
"Delete|C-d": "del",
|
||||||
|
"Return|C-m": {command: "insertstring", args: "\n"}, // "newline"
|
||||||
|
"C-o": "splitline",
|
||||||
|
|
||||||
|
"M-d|C-Delete": {command: "killWord", args: "right"},
|
||||||
|
"C-Backspace|M-Backspace|M-Delete": {command: "killWord", args: "left"},
|
||||||
|
"C-k": "killLine",
|
||||||
|
|
||||||
|
"C-y|S-Delete": "yank",
|
||||||
|
"M-y": "yankRotate",
|
||||||
|
"C-g": "keyboardQuit",
|
||||||
|
|
||||||
|
"C-w": "killRegion",
|
||||||
|
"M-w": "killRingSave",
|
||||||
|
|
||||||
|
"C-Space": "setMark",
|
||||||
|
"C-x C-x": "exchangePointAndMark",
|
||||||
|
|
||||||
|
"C-t": "transposeletters",
|
||||||
|
|
||||||
|
"M-u": "touppercase",
|
||||||
|
"M-l": "tolowercase",
|
||||||
|
"M-/": "autocomplete",
|
||||||
|
"C-u": "universalArgument",
|
||||||
|
"M-;": "togglecomment",
|
||||||
|
|
||||||
|
"C-/|C-x u|S-C--|C-z": "undo",
|
||||||
|
"S-C-/|S-C-x u|C--|S-C-z": "redo", //infinite undo?
|
||||||
|
// vertical editing
|
||||||
|
"C-x r": "selectRectangularRegion"
|
||||||
|
|
||||||
|
// todo
|
||||||
|
// "M-x" "C-x C-t" "M-t" "M-c" "F11" "C-M- "M-q"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.handler.bindKeys(exports.emacsKeys);
|
||||||
|
|
||||||
|
exports.handler.addCommands({
|
||||||
|
selectRectangularRegion: function(editor) {
|
||||||
|
editor.multiSelect.toggleBlockSelection();
|
||||||
|
},
|
||||||
|
setMark: function() {
|
||||||
|
},
|
||||||
|
exchangePointAndMark: {
|
||||||
|
exec: function(editor) {
|
||||||
|
var range = editor.selection.getRange();
|
||||||
|
editor.selection.setSelectionRange(range, !editor.selection.isBackwards());
|
||||||
|
},
|
||||||
|
readonly: true,
|
||||||
|
multiselectAction: "forEach"
|
||||||
|
},
|
||||||
|
killWord: {
|
||||||
|
exec: function(editor, dir) {
|
||||||
|
editor.clearSelection();
|
||||||
|
if (dir == "left")
|
||||||
|
editor.selection.selectWordLeft();
|
||||||
|
else
|
||||||
|
editor.selection.selectWordRight();
|
||||||
|
|
||||||
|
var range = editor.getSelectionRange();
|
||||||
|
var text = editor.session.getTextRange(range);
|
||||||
|
exports.killRing.add(text);
|
||||||
|
|
||||||
|
editor.session.remove(range);
|
||||||
|
editor.clearSelection();
|
||||||
|
},
|
||||||
|
multiselectAction: "forEach"
|
||||||
|
},
|
||||||
|
killLine: function(editor) {
|
||||||
|
editor.selection.selectLine();
|
||||||
|
var range = editor.getSelectionRange();
|
||||||
|
var text = editor.session.getTextRange(range);
|
||||||
|
exports.killRing.add(text);
|
||||||
|
|
||||||
|
editor.session.remove(range);
|
||||||
|
editor.clearSelection();
|
||||||
|
},
|
||||||
|
yank: function(editor) {
|
||||||
|
editor.onPaste(exports.killRing.get());
|
||||||
|
editor.keyBinding.$data.lastCommand = "yank";
|
||||||
|
},
|
||||||
|
yankRotate: function(editor) {
|
||||||
|
if (editor.keyBinding.$data.lastCommand != "yank")
|
||||||
|
return;
|
||||||
|
|
||||||
|
editor.undo();
|
||||||
|
editor.onPaste(exports.killRing.rotate());
|
||||||
|
editor.keyBinding.$data.lastCommand = "yank";
|
||||||
|
},
|
||||||
|
killRegion: function(editor) {
|
||||||
|
exports.killRing.add(editor.getCopyText());
|
||||||
|
editor.cut();
|
||||||
|
},
|
||||||
|
killRingSave: function(editor) {
|
||||||
|
exports.killRing.add(editor.getCopyText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var commands = exports.handler.commands;
|
||||||
|
commands.yank.isYank = true;
|
||||||
|
commands.yankRotate.isYank = true;
|
||||||
|
|
||||||
|
exports.killRing = {
|
||||||
|
$data: [],
|
||||||
|
add: function(str) {
|
||||||
|
str && this.$data.push(str);
|
||||||
|
if (this.$data.length > 30)
|
||||||
|
this.$data.shift();
|
||||||
|
},
|
||||||
|
get: function() {
|
||||||
|
return this.$data[this.$data.length - 1] || "";
|
||||||
|
},
|
||||||
|
pop: function() {
|
||||||
|
if (this.$data.length > 1)
|
||||||
|
this.$data.pop();
|
||||||
|
return this.get();
|
||||||
|
},
|
||||||
|
rotate: function() {
|
||||||
|
this.$data.unshift(this.$data.pop());
|
||||||
|
return this.get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -127,7 +127,7 @@ function HashHandler(config, platform) {
|
||||||
this.bindKey(key, command);
|
this.bindKey(key, command);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.parseKeys = function(keys, val) {
|
this.parseKeys = function(keys) {
|
||||||
var key;
|
var key;
|
||||||
var hashId = 0;
|
var hashId = 0;
|
||||||
var parts = keys.toLowerCase().trim().split(/\s*\-\s*/);
|
var parts = keys.toLowerCase().trim().split(/\s*\-\s*/);
|
||||||
|
|
@ -139,6 +139,11 @@ function HashHandler(config, platform) {
|
||||||
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
|
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parts[0] == "text" && parts.length == 2) {
|
||||||
|
hashId = -1;
|
||||||
|
key = parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: key,
|
key: key,
|
||||||
hashId: hashId
|
hashId: hashId
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
var keyUtil = require("../lib/keys");
|
var keyUtil = require("../lib/keys");
|
||||||
var event = require("../lib/event");
|
var event = require("../lib/event");
|
||||||
require("../commands/default_commands");
|
|
||||||
|
|
||||||
var KeyBinding = function(editor) {
|
var KeyBinding = function(editor) {
|
||||||
this.$editor = editor;
|
this.$editor = editor;
|
||||||
|
|
@ -52,34 +51,45 @@ var KeyBinding = function(editor) {
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
this.setDefaultHandler = function(keyboardHandler) {
|
this.setDefaultHandler = function(kb) {
|
||||||
this.removeKeyboardHandler(this.$defaultHandler);
|
this.removeKeyboardHandler(this.$defaultHandler);
|
||||||
this.$defaultHandler = keyboardHandler;
|
this.$defaultHandler = kb;
|
||||||
if (keyboardHandler)
|
this.addKeyboardHandler(kb, 0);
|
||||||
this.$handlers.unshift(keyboardHandler);
|
this.$data = {editor: this.$editor};
|
||||||
this.$data = { };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setKeyboardHandler = function(keyboardHandler) {
|
this.setKeyboardHandler = function(kb) {
|
||||||
if (this.$handlers[this.$handlers.length - 1] == keyboardHandler)
|
if (this.$handlers[this.$handlers.length - 1] == kb)
|
||||||
return;
|
return;
|
||||||
this.$data = { };
|
|
||||||
this.$handlers = [];
|
while (this.$handlers[1])
|
||||||
this.setDefaultHandler(this.$defaultHandler);
|
this.removeKeyboardHandler(this.$handlers[1]);
|
||||||
if (keyboardHandler)
|
|
||||||
this.$handlers.push(keyboardHandler);
|
this.addKeyboardHandler(kb, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addKeyboardHandler = function(keyboardHandler) {
|
this.addKeyboardHandler = function(kb, pos) {
|
||||||
this.removeKeyboardHandler(keyboardHandler);
|
if (!kb)
|
||||||
this.$handlers.push(keyboardHandler);
|
return;
|
||||||
|
var i = this.$handlers.indexOf(kb);
|
||||||
|
if (i != -1)
|
||||||
|
this.$handlers.splice(i, 1);
|
||||||
|
|
||||||
|
if (pos == undefined)
|
||||||
|
this.$handlers.push(kb);
|
||||||
|
else
|
||||||
|
this.$handlers.splice(pos, 0, kb);
|
||||||
|
|
||||||
|
if (i == -1 && kb.attach)
|
||||||
|
kb.attach(this.$editor);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.removeKeyboardHandler = function(keyboardHandler) {
|
this.removeKeyboardHandler = function(kb) {
|
||||||
var i = this.$handlers.indexOf(keyboardHandler);
|
var i = this.$handlers.indexOf(kb);
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
return false;
|
return false;
|
||||||
this.$handlers.splice(i, 1);
|
this.$handlers.splice(i, 1);
|
||||||
|
kb.detach && kb.detach(this.$editor);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -107,7 +117,7 @@ var KeyBinding = function(editor) {
|
||||||
if (toExecute.command != "null")
|
if (toExecute.command != "null")
|
||||||
success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
|
success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
|
||||||
else
|
else
|
||||||
success = true;
|
success = toExecute.passEvent != true;
|
||||||
|
|
||||||
if (success && e)
|
if (success && e)
|
||||||
event.stopEvent(e);
|
event.stopEvent(e);
|
||||||
|
|
@ -121,9 +131,7 @@ var KeyBinding = function(editor) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onTextInput = function(text) {
|
this.onTextInput = function(text) {
|
||||||
var success = false;
|
var success = this.$callKeyboardHandlers(-1, text);
|
||||||
if (text.length == 1)
|
|
||||||
success = this.$callKeyboardHandlers(0, text);
|
|
||||||
if (!success)
|
if (!success)
|
||||||
this.$editor.commands.exec("insertstring", this.$editor, text);
|
this.$editor.commands.exec("insertstring", this.$editor, text);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Mozilla Skywriter.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Mozilla.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Julian Viereck (julian.viereck@gmail.com)
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var StateHandler = require("../state_handler").StateHandler;
|
|
||||||
var matchCharacterOnly = require("../state_handler").matchCharacterOnly;
|
|
||||||
|
|
||||||
var emacsState = {
|
|
||||||
start: [
|
|
||||||
{
|
|
||||||
key: "ctrl-x",
|
|
||||||
then: "c-x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: [ "(?:command-([0-9]*))*", "(down|ctrl-n)" ],
|
|
||||||
exec: "golinedown",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: [ "(?:command-([0-9]*))*", "(right|ctrl-f)" ],
|
|
||||||
exec: "gotoright",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: [ "(?:command-([0-9]*))*", "(up|ctrl-p)" ],
|
|
||||||
exec: "golineup",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: [ "(?:command-([0-9]*))*", "(left|ctrl-b)" ],
|
|
||||||
exec: "gotoleft",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
comment: "This binding matches all printable characters except numbers as long as they are no numbers and print them n times.",
|
|
||||||
regex: [ "(?:command-([0-9]*))", "([^0-9]+)*" ],
|
|
||||||
match: matchCharacterOnly,
|
|
||||||
exec: "inserttext",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "text",
|
|
||||||
match: 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
comment: "This binding matches numbers as long as there is no meta_number in the buffer.",
|
|
||||||
regex: [ "(command-[0-9]*)*", "([0-9]+)" ],
|
|
||||||
match: matchCharacterOnly,
|
|
||||||
disallowMatches: [ 1 ],
|
|
||||||
exec: "inserttext",
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "text",
|
|
||||||
match: 2,
|
|
||||||
type: "text"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: [ "command-([0-9]*)", "(command-[0-9]|[0-9])" ],
|
|
||||||
comment: "Stops execution if the regex /meta_[0-9]+/ matches to avoid resetting the buffer."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"c-x": [
|
|
||||||
{
|
|
||||||
key: "ctrl-g",
|
|
||||||
then: "start"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ctrl-s",
|
|
||||||
exec: "save",
|
|
||||||
then: "start"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.Emacs = new StateHandler(emacsState);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Mozilla Skywriter.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Mozilla.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Julian Viereck (julian.viereck@gmail.com)
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var StateHandler = require("../state_handler").StateHandler;
|
|
||||||
var matchCharacterOnly = require("../state_handler").matchCharacterOnly;
|
|
||||||
|
|
||||||
var vimcommand = function(key, exec, then) {
|
|
||||||
return {
|
|
||||||
regex: [ "([0-9]*)", key ],
|
|
||||||
exec: exec,
|
|
||||||
params: [
|
|
||||||
{
|
|
||||||
name: "times",
|
|
||||||
match: 1,
|
|
||||||
type: "number",
|
|
||||||
defaultValue: 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
then: then
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var vimStates = {
|
|
||||||
start: [
|
|
||||||
{
|
|
||||||
key: "i",
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "d",
|
|
||||||
then: "deleteMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "a",
|
|
||||||
exec: "gotoright",
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "shift-i",
|
|
||||||
exec: "gotolinestart",
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "shift-a",
|
|
||||||
exec: "gotolineend",
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "shift-c",
|
|
||||||
exec: "removetolineend",
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "shift-r",
|
|
||||||
exec: "overwrite",
|
|
||||||
then: "replaceMode"
|
|
||||||
},
|
|
||||||
vimcommand("(k|up)", "golineup"),
|
|
||||||
vimcommand("(j|down)", "golinedown"),
|
|
||||||
vimcommand("(l|right)", "gotoright"),
|
|
||||||
vimcommand("(h|left)", "gotoleft"),
|
|
||||||
{
|
|
||||||
key: "shift-g",
|
|
||||||
exec: "gotoend"
|
|
||||||
},
|
|
||||||
vimcommand("b", "gotowordleft"),
|
|
||||||
vimcommand("e", "gotowordright"),
|
|
||||||
vimcommand("x", "del"),
|
|
||||||
vimcommand("shift-x", "backspace"),
|
|
||||||
vimcommand("shift-d", "removetolineend"),
|
|
||||||
vimcommand("u", "undo"), // [count] on this may/may not work, depending on browser implementation...
|
|
||||||
{
|
|
||||||
comment: "Catch some keyboard input to stop it here",
|
|
||||||
match: matchCharacterOnly
|
|
||||||
}
|
|
||||||
],
|
|
||||||
insertMode: [
|
|
||||||
{
|
|
||||||
key: "esc",
|
|
||||||
then: "start"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
replaceMode: [
|
|
||||||
{
|
|
||||||
key: "esc",
|
|
||||||
exec: "overwrite",
|
|
||||||
then: "start"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
deleteMode: [
|
|
||||||
{
|
|
||||||
key: "d",
|
|
||||||
exec: "removeline",
|
|
||||||
then: "start"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.Vim = new StateHandler(vimStates);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
@ -202,6 +202,8 @@ StateHandler.prototype = {
|
||||||
* This function is called by keyBinding.
|
* This function is called by keyBinding.
|
||||||
*/
|
*/
|
||||||
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
||||||
|
if (hashId == -1)
|
||||||
|
hashId = 0
|
||||||
// If we pressed any command key but no other key, then ignore the input.
|
// If we pressed any command key but no other key, then ignore the input.
|
||||||
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
||||||
// which results in "shift-shift-g" which doesn't make sense.
|
// which results in "shift-shift-g" which doesn't make sense.
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,22 @@ var TextInput = function(parentNode, host) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (useragent.isOpera) {
|
||||||
|
event.addListener(parentNode, "keydown", function(e) {
|
||||||
|
if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((e.keyCode == 88 || e.keyCode == 67)) {
|
||||||
|
var copyText = host.getCopyText();
|
||||||
|
if (copyText) {
|
||||||
|
text.value = copyText;
|
||||||
|
text.select();
|
||||||
|
if (e.keyCode == 88)
|
||||||
|
host.onCut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
event.addListener(text, "copy", onCopy);
|
event.addListener(text, "copy", onCopy);
|
||||||
event.addListener(text, "cut", onCut);
|
event.addListener(text, "cut", onCut);
|
||||||
|
|
@ -265,7 +281,6 @@ var TextInput = function(parentNode, host) {
|
||||||
text.style.cssText =
|
text.style.cssText =
|
||||||
'position:fixed; z-index:1000;' +
|
'position:fixed; z-index:1000;' +
|
||||||
'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;';
|
'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;';
|
||||||
|
|
||||||
}
|
}
|
||||||
if (isEmpty)
|
if (isEmpty)
|
||||||
text.value='';
|
text.value='';
|
||||||
|
|
|
||||||
120
lib/ace/keyboard/vim.js
Normal file
120
lib/ace/keyboard/vim.js
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
* Harutyun Amirjanyan <harutyun AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var keyUtil = require("../lib/keys");
|
||||||
|
var cmds = require("./vim/commands");
|
||||||
|
var coreCommands = cmds.coreCommands;
|
||||||
|
var util = require("./vim/maps/util");
|
||||||
|
|
||||||
|
var startCommands = {
|
||||||
|
"i": {
|
||||||
|
command: coreCommands.start
|
||||||
|
},
|
||||||
|
"I": {
|
||||||
|
command: coreCommands.startBeginning
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
command: coreCommands.append
|
||||||
|
},
|
||||||
|
"A": {
|
||||||
|
command: coreCommands.appendEnd
|
||||||
|
},
|
||||||
|
"ctrl-f": {
|
||||||
|
command: "gotopagedown"
|
||||||
|
},
|
||||||
|
"ctrl-b": {
|
||||||
|
command: "gotopageup"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.handler = {
|
||||||
|
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
||||||
|
// ignore command keys (shift, ctrl etc.)
|
||||||
|
if (hashId != 0 && (key == "" || key == "\x00"))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (hashId == 1)
|
||||||
|
key = "ctrl-" + key;
|
||||||
|
|
||||||
|
if (data.state == "start") {
|
||||||
|
if (hashId == -1 || hashId == 1) {
|
||||||
|
if (cmds.inputBuffer.idle && startCommands[key])
|
||||||
|
return startCommands[key];
|
||||||
|
|
||||||
|
return { command: {
|
||||||
|
exec: function(editor) {cmds.inputBuffer.push(editor, key);}
|
||||||
|
} };
|
||||||
|
} // wait for input
|
||||||
|
else if (key.length == 1 && (hashId == 0 || hashId == 4)) { //no modifier || shift
|
||||||
|
return {command: "null", passEvent: true};
|
||||||
|
} else if (key == "esc") {
|
||||||
|
return {command: coreCommands.stop};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (key == "esc" || key == "ctrl-[") {
|
||||||
|
data.state = "start";
|
||||||
|
return {command: coreCommands.stop};
|
||||||
|
} else if (key == "ctrl-w") {
|
||||||
|
return {command: "removewordleft"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
attach: function(editor) {
|
||||||
|
editor.on("click", exports.onCursorMove);
|
||||||
|
if (util.currentMode !== "insert")
|
||||||
|
cmds.coreCommands.stop.exec(editor);
|
||||||
|
},
|
||||||
|
|
||||||
|
detach: function(editor) {
|
||||||
|
editor.removeListener("click", exports.onCursorMove);
|
||||||
|
util.noMode(editor);
|
||||||
|
util.currentMode = "normal";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.onCursorMove = function(e) {
|
||||||
|
cmds.onCursorMove(e.editor, e);
|
||||||
|
exports.onCursorMove.scheduled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
567
lib/ace/keyboard/vim/commands.js
Normal file
567
lib/ace/keyboard/vim/commands.js
Normal file
|
|
@ -0,0 +1,567 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
* Harutyun Amirjanyan <harutyun AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
"never use strict";
|
||||||
|
|
||||||
|
var util = require("./maps/util");
|
||||||
|
var motions = require("./maps/motions");
|
||||||
|
var operators = require("./maps/operators");
|
||||||
|
var alias = require("./maps/aliases");
|
||||||
|
var registers = require("./registers");
|
||||||
|
|
||||||
|
var NUMBER = 1;
|
||||||
|
var OPERATOR = 2;
|
||||||
|
var MOTION = 3;
|
||||||
|
var ACTION = 4;
|
||||||
|
var HMARGIN = 8; // Minimum amount of line separation between margins;
|
||||||
|
|
||||||
|
exports.searchStore = {
|
||||||
|
current: "",
|
||||||
|
options: {
|
||||||
|
needle: "",
|
||||||
|
backwards: false,
|
||||||
|
wrap: true,
|
||||||
|
caseSensitive: false,
|
||||||
|
wholeWord: false,
|
||||||
|
regExp: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var repeat = function repeat(fn, count, args) {
|
||||||
|
while (0 < count--)
|
||||||
|
fn.apply(this, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
var ensureScrollMargin = function(editor) {
|
||||||
|
var renderer = editor.renderer;
|
||||||
|
var pos = renderer.$cursorLayer.getPixelPosition();
|
||||||
|
|
||||||
|
var top = pos.top;
|
||||||
|
|
||||||
|
var margin = HMARGIN * renderer.layerConfig.lineHeight;
|
||||||
|
if (2 * margin > renderer.$size.scrollerHeight)
|
||||||
|
margin = renderer.$size.scrollerHeight / 2;
|
||||||
|
|
||||||
|
if (renderer.scrollTop > top - margin) {
|
||||||
|
renderer.session.setScrollTop(top - margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer.scrollTop + renderer.$size.scrollerHeight < top + margin + renderer.lineHeight) {
|
||||||
|
renderer.session.setScrollTop(top + margin + renderer.lineHeight - renderer.$size.scrollerHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var actions = {
|
||||||
|
"z": {
|
||||||
|
param: true,
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
switch (param) {
|
||||||
|
case "z":
|
||||||
|
editor.alignCursor(null, 0.5);
|
||||||
|
break;
|
||||||
|
case "t":
|
||||||
|
editor.alignCursor(null, 0);
|
||||||
|
break;
|
||||||
|
case "b":
|
||||||
|
editor.alignCursor(null, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"r": {
|
||||||
|
param: true,
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
if (param && param.length) {
|
||||||
|
repeat(function() { editor.insert(param); }, count || 1);
|
||||||
|
editor.navigateLeft();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"R": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
util.insertMode(editor);
|
||||||
|
editor.setOverwrite(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"~": {
|
||||||
|
fn: function(editor, range, count) {
|
||||||
|
repeat(function() {
|
||||||
|
var range = editor.selection.getRange();
|
||||||
|
if (range.isEmpty())
|
||||||
|
range.end.column++;
|
||||||
|
var text = editor.session.getTextRange(range);
|
||||||
|
var toggled = text.toUpperCase();
|
||||||
|
if (toggled == text)
|
||||||
|
editor.navigateRight();
|
||||||
|
else
|
||||||
|
editor.session.replace(range, toggled);
|
||||||
|
}, count || 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"*": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
editor.selection.selectWord();
|
||||||
|
editor.findNext();
|
||||||
|
ensureScrollMargin(editor);
|
||||||
|
var r = editor.selection.getRange();
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"#": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
editor.selection.selectWord();
|
||||||
|
editor.findPrevious();
|
||||||
|
ensureScrollMargin(editor);
|
||||||
|
var r = editor.selection.getRange();
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"n": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
var options = editor.getLastSearchOptions();
|
||||||
|
options.backwards = false;
|
||||||
|
|
||||||
|
editor.selection.moveCursorRight();
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.findNext(options);
|
||||||
|
|
||||||
|
ensureScrollMargin(editor);
|
||||||
|
var r = editor.selection.getRange();
|
||||||
|
r.end.row = r.start.row;
|
||||||
|
r.end.column = r.start.column;
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
var options = editor.getLastSearchOptions();
|
||||||
|
options.backwards = true;
|
||||||
|
|
||||||
|
editor.findPrevious(options);
|
||||||
|
ensureScrollMargin(editor);
|
||||||
|
var r = editor.selection.getRange();
|
||||||
|
r.end.row = r.start.row;
|
||||||
|
r.end.column = r.start.column;
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"v": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
editor.selection.selectRight();
|
||||||
|
util.visualMode(editor, false);
|
||||||
|
},
|
||||||
|
acceptsMotion: true
|
||||||
|
},
|
||||||
|
"V": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
//editor.selection.selectLine();
|
||||||
|
//editor.selection.selectLeft();
|
||||||
|
var row = editor.getCursorPosition().row;
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.selection.moveCursorTo(row, 0);
|
||||||
|
editor.selection.selectLineEnd();
|
||||||
|
editor.selection.visualLineStart = row;
|
||||||
|
|
||||||
|
util.visualMode(editor, true);
|
||||||
|
},
|
||||||
|
acceptsMotion: true
|
||||||
|
},
|
||||||
|
"Y": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
util.copyLine(editor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
var defaultReg = registers._default;
|
||||||
|
|
||||||
|
editor.setOverwrite(false);
|
||||||
|
if (defaultReg.isLine) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
var lines = defaultReg.text.split("\n");
|
||||||
|
editor.session.getDocument().insertLines(pos.row + 1, lines);
|
||||||
|
editor.moveCursorTo(pos.row + 1, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.navigateRight();
|
||||||
|
editor.insert(defaultReg.text);
|
||||||
|
editor.navigateLeft();
|
||||||
|
}
|
||||||
|
editor.setOverwrite(true);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"P": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
var defaultReg = registers._default;
|
||||||
|
editor.setOverwrite(false);
|
||||||
|
|
||||||
|
if (defaultReg.isLine) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
var lines = defaultReg.text.split("\n");
|
||||||
|
editor.session.getDocument().insertLines(pos.row, lines);
|
||||||
|
editor.moveCursorTo(pos.row, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.insert(defaultReg.text);
|
||||||
|
}
|
||||||
|
editor.setOverwrite(true);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"J": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
var session = editor.session;
|
||||||
|
range = editor.getSelectionRange();
|
||||||
|
var pos = {row: range.start.row, column: range.start.column};
|
||||||
|
count = count || range.end.row - range.start.row;
|
||||||
|
var maxRow = Math.min(pos.row + (count || 1), session.getLength() - 1);
|
||||||
|
|
||||||
|
range.start.column = session.getLine(pos.row).length;
|
||||||
|
range.end.column = session.getLine(maxRow).length;
|
||||||
|
range.end.row = maxRow;
|
||||||
|
|
||||||
|
var text = "";
|
||||||
|
for (var i = pos.row; i < maxRow; i++) {
|
||||||
|
var nextLine = session.getLine(i + 1);
|
||||||
|
text += " " + /^\s*(.*)$/.exec(nextLine)[1] || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
session.replace(range, text);
|
||||||
|
editor.moveCursorTo(pos.row, pos.column);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"u": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = parseInt(count || 1, 10);
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.undo();
|
||||||
|
}
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ctrl-r": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = parseInt(count || 1, 10);
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.redo();
|
||||||
|
}
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
":": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
editor.blur();
|
||||||
|
txtConsoleInput.focus();
|
||||||
|
txtConsoleInput.setValue(":");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
editor.blur();
|
||||||
|
txtConsoleInput.focus();
|
||||||
|
txtConsoleInput.setValue("/");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
".": {
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
util.onInsertReplaySequence = inputBuffer.lastInsertCommands;
|
||||||
|
var previous = inputBuffer.previous;
|
||||||
|
if (previous) // If there is a previous action
|
||||||
|
inputBuffer.exec(editor, previous.action, previous.param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var inputBuffer = exports.inputBuffer = {
|
||||||
|
accepting: [NUMBER, OPERATOR, MOTION, ACTION],
|
||||||
|
currentCmd: null,
|
||||||
|
//currentMode: 0,
|
||||||
|
currentCount: "",
|
||||||
|
|
||||||
|
// Types
|
||||||
|
operator: null,
|
||||||
|
motion: null,
|
||||||
|
|
||||||
|
lastInsertCommands: [],
|
||||||
|
|
||||||
|
push: function(editor, char, keyId) {
|
||||||
|
this.idle = false;
|
||||||
|
var wObj = this.waitingForParam;
|
||||||
|
if (wObj) {
|
||||||
|
this.exec(editor, wObj, char);
|
||||||
|
}
|
||||||
|
// If input is a number (that doesn't start with 0)
|
||||||
|
else if (!(char === "0" && !this.currentCount.length) &&
|
||||||
|
(char.match(/^\d+$/) && this.isAccepting(NUMBER))) {
|
||||||
|
// Assuming that char is always of type String, and not Number
|
||||||
|
this.currentCount += char;
|
||||||
|
this.currentCmd = NUMBER;
|
||||||
|
this.accepting = [NUMBER, OPERATOR, MOTION, ACTION];
|
||||||
|
}
|
||||||
|
else if (!this.operator && this.isAccepting(OPERATOR) && operators[char]) {
|
||||||
|
this.operator = {
|
||||||
|
char: char,
|
||||||
|
count: this.getCount()
|
||||||
|
};
|
||||||
|
this.currentCmd = OPERATOR;
|
||||||
|
this.accepting = [NUMBER, MOTION, ACTION];
|
||||||
|
this.exec(editor, { operator: this.operator });
|
||||||
|
}
|
||||||
|
else if (motions[char] && this.isAccepting(MOTION)) {
|
||||||
|
this.currentCmd = MOTION;
|
||||||
|
|
||||||
|
var ctx = {
|
||||||
|
operator: this.operator,
|
||||||
|
motion: {
|
||||||
|
char: char,
|
||||||
|
count: this.getCount()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (motions[char].param)
|
||||||
|
this.waitForParam(ctx);
|
||||||
|
else
|
||||||
|
this.exec(editor, ctx);
|
||||||
|
}
|
||||||
|
else if (alias[char] && this.isAccepting(MOTION)) {
|
||||||
|
alias[char].operator.count = this.getCount();
|
||||||
|
this.exec(editor, alias[char]);
|
||||||
|
}
|
||||||
|
else if (actions[char] && this.isAccepting(ACTION)) {
|
||||||
|
var actionObj = {
|
||||||
|
action: {
|
||||||
|
fn: actions[char].fn,
|
||||||
|
count: this.getCount()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (actions[char].param) {
|
||||||
|
this.waitForParam(actionObj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.exec(editor, actionObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions[char].acceptsMotion)
|
||||||
|
this.idle = false;
|
||||||
|
}
|
||||||
|
else if (this.operator) {
|
||||||
|
this.exec(editor, { operator: this.operator }, char);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
waitForParam: function(cmd) {
|
||||||
|
this.waitingForParam = cmd;
|
||||||
|
},
|
||||||
|
|
||||||
|
getCount: function() {
|
||||||
|
var count = this.currentCount;
|
||||||
|
this.currentCount = "";
|
||||||
|
return count && parseInt(count, 10);
|
||||||
|
},
|
||||||
|
|
||||||
|
exec: function(editor, action, param) {
|
||||||
|
var m = action.motion;
|
||||||
|
var o = action.operator;
|
||||||
|
var a = action.action;
|
||||||
|
|
||||||
|
if (!param)
|
||||||
|
param = action.param;
|
||||||
|
|
||||||
|
if (o) {
|
||||||
|
this.previous = {
|
||||||
|
action: action,
|
||||||
|
param: param
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o && !editor.selection.isEmpty()) {
|
||||||
|
if (operators[o.char].selFn) {
|
||||||
|
operators[o.char].selFn(editor, editor.getSelectionRange(), o.count, param);
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is an operator, but no motion or action. We try to pass the
|
||||||
|
// current char to the operator to see if it responds to it (an example
|
||||||
|
// of this is the 'dd' operator).
|
||||||
|
else if (!m && !a && o && param) {
|
||||||
|
operators[o.char].fn(editor, null, o.count, param);
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
else if (m) {
|
||||||
|
var run = function(fn) {
|
||||||
|
if (fn && typeof fn === "function") { // There should always be a motion
|
||||||
|
if (m.count && !motionObj.handlesCount)
|
||||||
|
repeat(fn, m.count, [editor, null, m.count, param]);
|
||||||
|
else
|
||||||
|
fn(editor, null, m.count, param);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var motionObj = motions[m.char];
|
||||||
|
var selectable = motionObj.sel;
|
||||||
|
|
||||||
|
if (!o) {
|
||||||
|
if ((util.onVisualMode || util.onVisualLineMode) && selectable)
|
||||||
|
run(motionObj.sel);
|
||||||
|
else
|
||||||
|
run(motionObj.nav);
|
||||||
|
}
|
||||||
|
else if (selectable) {
|
||||||
|
repeat(function() {
|
||||||
|
run(motionObj.sel);
|
||||||
|
operators[o.char].fn(editor, editor.getSelectionRange(), o.count, param);
|
||||||
|
}, o.count || 1);
|
||||||
|
}
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
else if (a) {
|
||||||
|
a.fn(editor, editor.getSelectionRange(), a.count, param);
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
handleCursorMove(editor);
|
||||||
|
},
|
||||||
|
|
||||||
|
isAccepting: function(type) {
|
||||||
|
return this.accepting.indexOf(type) !== -1;
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function() {
|
||||||
|
this.operator = null;
|
||||||
|
this.motion = null;
|
||||||
|
this.currentCount = "";
|
||||||
|
this.accepting = [NUMBER, OPERATOR, MOTION, ACTION];
|
||||||
|
this.idle = true;
|
||||||
|
this.waitingForParam = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setPreviousCommand(fn) {
|
||||||
|
inputBuffer.previous = { action: { action: { fn: fn } } };
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.coreCommands = {
|
||||||
|
start: {
|
||||||
|
exec: function start(editor) {
|
||||||
|
util.insertMode(editor);
|
||||||
|
setPreviousCommand(start);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startBeginning: {
|
||||||
|
exec: function startBeginning(editor) {
|
||||||
|
editor.navigateLineStart();
|
||||||
|
util.insertMode(editor);
|
||||||
|
setPreviousCommand(startBeginning);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Stop Insert mode as soon as possible. Works like typing <Esc> in
|
||||||
|
// insert mode.
|
||||||
|
stop: {
|
||||||
|
exec: function stop(editor) {
|
||||||
|
inputBuffer.reset();
|
||||||
|
util.onVisualMode = false;
|
||||||
|
util.onVisualLineMode = false;
|
||||||
|
inputBuffer.lastInsertCommands = util.normalMode(editor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
append: {
|
||||||
|
exec: function append(editor) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
var lineLen = editor.session.getLine(pos.row).length;
|
||||||
|
if (lineLen)
|
||||||
|
editor.navigateRight();
|
||||||
|
util.insertMode(editor);
|
||||||
|
setPreviousCommand(append);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
appendEnd: {
|
||||||
|
exec: function appendEnd(editor) {
|
||||||
|
editor.navigateLineEnd();
|
||||||
|
util.insertMode(editor);
|
||||||
|
setPreviousCommand(appendEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleCursorMove = exports.onCursorMove = function(editor, e) {
|
||||||
|
if (util.currentMode === 'insert' || handleCursorMove.running)
|
||||||
|
return;
|
||||||
|
else if(!editor.selection.isEmpty()) {
|
||||||
|
handleCursorMove.running = true;
|
||||||
|
if (util.onVisualLineMode) {
|
||||||
|
var originRow = editor.selection.visualLineStart;
|
||||||
|
var cursorRow = editor.getCursorPosition().row;
|
||||||
|
if(originRow <= cursorRow) {
|
||||||
|
var endLine = editor.session.getLine(cursorRow);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.selection.moveCursorTo(originRow, 0);
|
||||||
|
editor.selection.selectTo(cursorRow, endLine.length);
|
||||||
|
} else {
|
||||||
|
var endLine = editor.session.getLine(originRow);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.selection.moveCursorTo(originRow, endLine.length);
|
||||||
|
editor.selection.selectTo(cursorRow, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleCursorMove.running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e && (util.onVisualLineMode || util.onVisualMode)) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
util.normalMode(editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCursorMove.running = true;
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
var lineLen = editor.session.getLine(pos.row).length;
|
||||||
|
|
||||||
|
if (lineLen && pos.column === lineLen)
|
||||||
|
editor.navigateLeft();
|
||||||
|
handleCursorMove.running = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
101
lib/ace/keyboard/vim/maps/aliases.js
Normal file
101
lib/ace/keyboard/vim/maps/aliases.js
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
module.exports = {
|
||||||
|
"x": {
|
||||||
|
operator: {
|
||||||
|
char: "d",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
char: "l",
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"X": {
|
||||||
|
operator: {
|
||||||
|
char: "d",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
char: "h",
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"D": {
|
||||||
|
operator: {
|
||||||
|
char: "d",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
char: "$",
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"C": {
|
||||||
|
operator: {
|
||||||
|
char: "c",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
char: "$",
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"s": {
|
||||||
|
operator: {
|
||||||
|
char: "c",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
motion: {
|
||||||
|
char: "l",
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
operator: {
|
||||||
|
char: "c",
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
param: "c"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
611
lib/ace/keyboard/vim/maps/motions.js
Normal file
611
lib/ace/keyboard/vim/maps/motions.js
Normal file
|
|
@ -0,0 +1,611 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
* Harutyun Amirjanyan <harutyun AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
var util = require("./util");
|
||||||
|
|
||||||
|
var keepScrollPosition = function(editor, fn) {
|
||||||
|
var scrollTopRow = editor.renderer.getScrollTopRow();
|
||||||
|
var initialRow = editor.getCursorPosition().row;
|
||||||
|
var diff = initialRow - scrollTopRow;
|
||||||
|
fn && fn.call(editor);
|
||||||
|
editor.renderer.scrollToRow(editor.getCursorPosition().row - diff);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Motion(getRange, type){
|
||||||
|
if (type == 'extend')
|
||||||
|
var extend = true;
|
||||||
|
else
|
||||||
|
var reverse = type;
|
||||||
|
|
||||||
|
this.nav = function(editor) {
|
||||||
|
var r = getRange(editor);
|
||||||
|
if (!r)
|
||||||
|
return;
|
||||||
|
if (!r.end)
|
||||||
|
var a = r;
|
||||||
|
else if (reverse)
|
||||||
|
var a = r.start;
|
||||||
|
else
|
||||||
|
var a = r.end;
|
||||||
|
|
||||||
|
editor.clearSelection();
|
||||||
|
editor.moveCursorTo(a.row, a.column);
|
||||||
|
}
|
||||||
|
this.sel = function(editor){
|
||||||
|
var r = getRange(editor);
|
||||||
|
if (!r)
|
||||||
|
return;
|
||||||
|
if (extend)
|
||||||
|
return editor.selection.setSelectionRange(r);
|
||||||
|
|
||||||
|
if (!r.end)
|
||||||
|
var a = r;
|
||||||
|
else if (reverse)
|
||||||
|
var a = r.start;
|
||||||
|
else
|
||||||
|
var a = r.end;
|
||||||
|
|
||||||
|
editor.selection.selectTo(a.row, a.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonWordRe = /[\s.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
|
||||||
|
var wordSeparatorRe = /[.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
|
||||||
|
var whiteRe = /\s/;
|
||||||
|
var StringStream = function(editor, cursor) {
|
||||||
|
var sel = editor.selection;
|
||||||
|
this.range = sel.getRange();
|
||||||
|
cursor = cursor || sel.selectionLead;
|
||||||
|
this.row = cursor.row;
|
||||||
|
this.col = cursor.column;
|
||||||
|
var line = editor.session.getLine(this.row);
|
||||||
|
var maxRow = editor.session.getLength()
|
||||||
|
this.ch = line[this.col] || '\n'
|
||||||
|
this.skippedLines = 0;
|
||||||
|
|
||||||
|
this.next = function() {
|
||||||
|
this.ch = line[++this.col] || this.handleNewLine(1);
|
||||||
|
//this.debug()
|
||||||
|
return this.ch;
|
||||||
|
}
|
||||||
|
this.prev = function() {
|
||||||
|
this.ch = line[--this.col] || this.handleNewLine(-1);
|
||||||
|
//this.debug()
|
||||||
|
return this.ch;
|
||||||
|
}
|
||||||
|
this.peek = function(dir) {
|
||||||
|
var ch = line[this.col + dir];
|
||||||
|
if (ch)
|
||||||
|
return ch;
|
||||||
|
if (dir == -1)
|
||||||
|
return '\n';
|
||||||
|
if (this.col == line.length - 1)
|
||||||
|
return '\n';
|
||||||
|
return editor.session.getLine(this.row + 1)[0] || '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleNewLine = function(dir) {
|
||||||
|
if (dir == 1){
|
||||||
|
if (this.col == line.length)
|
||||||
|
return '\n';
|
||||||
|
if (this.row == maxRow - 1)
|
||||||
|
return '';
|
||||||
|
this.col = 0;
|
||||||
|
this.row ++;
|
||||||
|
line = editor.session.getLine(this.row);
|
||||||
|
this.skippedLines++;
|
||||||
|
return line[0] || '\n';
|
||||||
|
}
|
||||||
|
if (dir == -1) {
|
||||||
|
if (this.row == 0)
|
||||||
|
return '';
|
||||||
|
this.row --;
|
||||||
|
line = editor.session.getLine(this.row);
|
||||||
|
this.col = line.length;
|
||||||
|
this.skippedLines--;
|
||||||
|
return '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.debug = function() {
|
||||||
|
console.log(line.substring(0, this.col)+'|'+this.ch+'\''+this.col+'\''+line.substr(this.col+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Search = require("ace/search").Search;
|
||||||
|
var search = new Search();
|
||||||
|
|
||||||
|
function find(editor, needle, dir) {
|
||||||
|
search.$options.needle = needle;
|
||||||
|
search.$options.backwards = dir == -1;
|
||||||
|
return search.find(editor.session);
|
||||||
|
}
|
||||||
|
|
||||||
|
var Range = require("ace/range").Range;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"w": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor);
|
||||||
|
|
||||||
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
|
str.next();
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.next();
|
||||||
|
}
|
||||||
|
while (str.ch && whiteRe.test(str.ch) && str.skippedLines < 2)
|
||||||
|
str.next();
|
||||||
|
|
||||||
|
str.skippedLines == 2 && str.prev();
|
||||||
|
return {column: str.col, row: str.row};
|
||||||
|
}),
|
||||||
|
"W": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor);
|
||||||
|
while(str.ch && !(whiteRe.test(str.ch) && !whiteRe.test(str.peek(1))) && str.skippedLines < 2)
|
||||||
|
str.next();
|
||||||
|
if (str.skippedLines == 2)
|
||||||
|
str.prev();
|
||||||
|
else
|
||||||
|
str.next();
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}),
|
||||||
|
"b": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor);
|
||||||
|
|
||||||
|
str.prev();
|
||||||
|
while (str.ch && whiteRe.test(str.ch) && str.skippedLines > -2)
|
||||||
|
str.prev();
|
||||||
|
|
||||||
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
|
str.prev();
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.prev();
|
||||||
|
}
|
||||||
|
str.ch && str.next();
|
||||||
|
return {column: str.col, row: str.row};
|
||||||
|
}),
|
||||||
|
"B": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
str.prev();
|
||||||
|
while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(-1))) && str.skippedLines > -2)
|
||||||
|
str.prev();
|
||||||
|
|
||||||
|
if (str.skippedLines == -2)
|
||||||
|
str.next();
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row};
|
||||||
|
}, true),
|
||||||
|
"e": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor);
|
||||||
|
|
||||||
|
str.next();
|
||||||
|
while (str.ch && whiteRe.test(str.ch))
|
||||||
|
str.next();
|
||||||
|
|
||||||
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
|
str.next();
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.next();
|
||||||
|
}
|
||||||
|
str.ch && str.prev();
|
||||||
|
return {column: str.col, row: str.row};
|
||||||
|
}),
|
||||||
|
"E": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor);
|
||||||
|
str.next();
|
||||||
|
while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(1))))
|
||||||
|
str.next();
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row};
|
||||||
|
}),
|
||||||
|
|
||||||
|
"l": {
|
||||||
|
nav: function(editor) {
|
||||||
|
editor.navigateRight();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
var col = pos.column;
|
||||||
|
var lineLen = editor.session.getLine(pos.row).length;
|
||||||
|
|
||||||
|
// Solving the behavior at the end of the line due to the
|
||||||
|
// different 0 index-based colum positions in ACE.
|
||||||
|
if (lineLen && col !== lineLen) //In selection mode you can select the newline
|
||||||
|
editor.selection.selectRight();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"h": {
|
||||||
|
nav: function(editor) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
if (pos.column > 0)
|
||||||
|
editor.navigateLeft();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
if (pos.column > 0)
|
||||||
|
editor.selection.selectLeft();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"k": {
|
||||||
|
nav: function(editor) {
|
||||||
|
editor.navigateUp();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
editor.selection.selectUp();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"j": {
|
||||||
|
nav: function(editor) {
|
||||||
|
editor.navigateDown();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
editor.selection.selectDown();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"i": {
|
||||||
|
param: true,
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
switch (param) {
|
||||||
|
case "w":
|
||||||
|
editor.selection.selectWord();
|
||||||
|
break;
|
||||||
|
case "W":
|
||||||
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "(":
|
||||||
|
case "{":
|
||||||
|
case "[":
|
||||||
|
var cursor = editor.getCursorPosition()
|
||||||
|
var end = editor.session.$findClosingBracket(param, cursor, /paren/)
|
||||||
|
if (!end)
|
||||||
|
return;
|
||||||
|
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/)
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
start.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start, end))
|
||||||
|
break
|
||||||
|
case "'":
|
||||||
|
case "\"":
|
||||||
|
case "/":
|
||||||
|
var end = find(editor, param, 1)
|
||||||
|
if (!end)
|
||||||
|
return;
|
||||||
|
var start = find(editor, param, -1)
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
param: true,
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
switch (param) {
|
||||||
|
case "w":
|
||||||
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "W":
|
||||||
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "(":
|
||||||
|
case "{":
|
||||||
|
case "[":
|
||||||
|
var cursor = editor.getCursorPosition();
|
||||||
|
var end = editor.session.$findClosingBracket(param, cursor, /paren/);
|
||||||
|
if (!end)
|
||||||
|
return;
|
||||||
|
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
end.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start, end));
|
||||||
|
break;
|
||||||
|
case "'":
|
||||||
|
case "\"":
|
||||||
|
case "/":
|
||||||
|
var end = find(editor, param, 1);
|
||||||
|
if (!end)
|
||||||
|
return;
|
||||||
|
var start = find(editor, param, -1);
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
end.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start.start, end.end));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"f": {
|
||||||
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
ed.moveCursorTo(cursor.row, column + cursor.column + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.moveCursorTo(cursor.row, column + cursor.column + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"F": {
|
||||||
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
count = parseInt(count, 10) || 1;
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
ed.moveCursorTo(cursor.row, cursor.column - column - 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.moveCursorTo(cursor.row, cursor.column - column - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"t": {
|
||||||
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
ed.moveCursorTo(cursor.row, column + cursor.column);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.moveCursorTo(cursor.row, column + cursor.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"T": {
|
||||||
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
ed.moveCursorTo(cursor.row, -column + cursor.column);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.moveCursorTo(cursor.row, -column + cursor.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"^": {
|
||||||
|
nav: function(editor) {
|
||||||
|
editor.navigateLineStart();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
editor.selection.selectLineStart();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$": {
|
||||||
|
nav: function(editor) {
|
||||||
|
editor.navigateLineEnd();
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
editor.selection.selectLineEnd();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
nav: function(editor) {
|
||||||
|
var ed = editor;
|
||||||
|
ed.navigateTo(ed.selection.selectionLead.row, 0);
|
||||||
|
},
|
||||||
|
sel: function(editor) {
|
||||||
|
var ed = editor;
|
||||||
|
ed.selectTo(ed.selection.selectionLead.row, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"G": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
if (!count && count !== 0) { // Stupid JS
|
||||||
|
count = editor.session.getLength();
|
||||||
|
}
|
||||||
|
editor.gotoLine(count);
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
if (!count && count !== 0) { // Stupid JS
|
||||||
|
count = editor.session.getLength();
|
||||||
|
}
|
||||||
|
editor.selection.selectTo(count, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"g": {
|
||||||
|
param: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
switch(param) {
|
||||||
|
case "m":
|
||||||
|
console.log("Middle line");
|
||||||
|
break;
|
||||||
|
case "e":
|
||||||
|
console.log("End of prev word");
|
||||||
|
break;
|
||||||
|
case "g":
|
||||||
|
editor.gotoLine(count || 0);
|
||||||
|
case "u":
|
||||||
|
editor.gotoLine(count || 0);
|
||||||
|
case "U":
|
||||||
|
editor.gotoLine(count || 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
switch(param) {
|
||||||
|
case "m":
|
||||||
|
console.log("Middle line");
|
||||||
|
break;
|
||||||
|
case "e":
|
||||||
|
console.log("End of prev word");
|
||||||
|
break;
|
||||||
|
case "g":
|
||||||
|
editor.selection.selectTo(count || 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"o": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
var content = "";
|
||||||
|
while (0 < count--)
|
||||||
|
content += "\n";
|
||||||
|
|
||||||
|
if (content.length) {
|
||||||
|
editor.navigateLineEnd()
|
||||||
|
editor.insert(content);
|
||||||
|
util.insertMode(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"O": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
var row = editor.getCursorPosition().row;
|
||||||
|
count = count || 1;
|
||||||
|
var content = "";
|
||||||
|
while (0 < count--)
|
||||||
|
content += "\n";
|
||||||
|
|
||||||
|
if (content.length) {
|
||||||
|
if(row > 0) {
|
||||||
|
editor.navigateUp();
|
||||||
|
editor.navigateLineEnd()
|
||||||
|
editor.insert(content);
|
||||||
|
} else {
|
||||||
|
editor.session.insert({row: 0, column: 0}, content);
|
||||||
|
editor.navigateUp();
|
||||||
|
}
|
||||||
|
util.insertMode(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"%": new Motion(function(editor){
|
||||||
|
var brRe = /[\[\]{}()]/g;
|
||||||
|
var cursor = editor.getCursorPosition();
|
||||||
|
var ch = editor.session.getLine(cursor.row)[cursor.column];
|
||||||
|
if (!brRe.test(ch)) {
|
||||||
|
var range = find(editor, brRe);
|
||||||
|
if (!range)
|
||||||
|
return;
|
||||||
|
cursor = range.start;
|
||||||
|
}
|
||||||
|
var match = editor.session.findMatchingBracket({
|
||||||
|
row: cursor.row,
|
||||||
|
column: cursor.column + 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}),
|
||||||
|
"ctrl-d": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
keepScrollPosition(editor, editor.gotoPageDown);
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
keepScrollPosition(editor, editor.selectPageDown);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ctrl-u": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
keepScrollPosition(editor, editor.gotoPageUp);
|
||||||
|
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
keepScrollPosition(editor, editor.selectPageUp);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.backspace = module.exports.left = module.exports.h;
|
||||||
|
module.exports.right = module.exports.l;
|
||||||
|
module.exports.up = module.exports.k;
|
||||||
|
module.exports.down = module.exports.j;
|
||||||
|
module.exports.pagedown = module.exports["ctrl-d"];
|
||||||
|
module.exports.pageup = module.exports["ctrl-u"];
|
||||||
|
|
||||||
|
});
|
||||||
193
lib/ace/keyboard/vim/maps/operators.js
Normal file
193
lib/ace/keyboard/vim/maps/operators.js
Normal file
|
|
@ -0,0 +1,193 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
"never use strict";
|
||||||
|
|
||||||
|
var util = require("./util");
|
||||||
|
var registers = require("../registers");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"d": {
|
||||||
|
selFn: function(editor, range, count, param) {
|
||||||
|
registers._default.text = editor.getCopyText();
|
||||||
|
registers._default.isLine = util.onVisualLineMode;
|
||||||
|
if(util.onVisualLineMode)
|
||||||
|
editor.removeLines();
|
||||||
|
else
|
||||||
|
editor.session.remove(range);
|
||||||
|
util.normalMode(editor);
|
||||||
|
},
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
switch (param) {
|
||||||
|
case "d":
|
||||||
|
registers._default.text = "";
|
||||||
|
registers._default.isLine = true;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.selection.selectLine();
|
||||||
|
registers._default.text += editor.getCopyText();
|
||||||
|
var selRange = editor.getSelectionRange();
|
||||||
|
editor.session.remove(selRange);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
registers._default.text = registers._default.text.replace(/\n$/, "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (range) {
|
||||||
|
editor.selection.setSelectionRange(range);
|
||||||
|
registers._default.text = editor.getCopyText();
|
||||||
|
registers._default.isLine = false;
|
||||||
|
editor.session.remove(range);
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
selFn: function(editor, range, count, param) {
|
||||||
|
editor.session.remove(range);
|
||||||
|
util.insertMode(editor);
|
||||||
|
},
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
switch (param) {
|
||||||
|
case "c":
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.removeLines();
|
||||||
|
util.insertMode(editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (range) {
|
||||||
|
|
||||||
|
// range.end.column ++;
|
||||||
|
editor.session.remove(range);
|
||||||
|
util.insertMode(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
selFn: function(editor, range, count, param) {
|
||||||
|
registers._default.text = editor.getCopyText();
|
||||||
|
registers._default.isLine = util.onVisualLineMode;
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
util.normalMode(editor);
|
||||||
|
},
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
switch (param) {
|
||||||
|
case "y":
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
editor.selection.selectLine();
|
||||||
|
for (var i = 0; i < count - 1; i++) {
|
||||||
|
editor.selection.moveCursorDown();
|
||||||
|
}
|
||||||
|
registers._default.text = editor.getCopyText().replace(/\n$/, "");
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
registers._default.isLine = true;
|
||||||
|
editor.moveCursorToPosition(pos);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (range) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
editor.selection.setSelectionRange(range);
|
||||||
|
registers._default.text = editor.getCopyText();
|
||||||
|
registers._default.isLine = false;
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.moveCursorTo(pos.row, pos.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
">": {
|
||||||
|
selFn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.indent();
|
||||||
|
}
|
||||||
|
util.normalMode(editor);
|
||||||
|
},
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = parseInt(count || 1, 10);
|
||||||
|
switch (param) {
|
||||||
|
case ">":
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
editor.selection.selectLine();
|
||||||
|
for (var i = 0; i < count - 1; i++) {
|
||||||
|
editor.selection.moveCursorDown();
|
||||||
|
}
|
||||||
|
editor.indent();
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.moveCursorToPosition(pos);
|
||||||
|
editor.navigateLineEnd();
|
||||||
|
editor.navigateLineStart();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"<": {
|
||||||
|
selFn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
editor.blockOutdent();
|
||||||
|
}
|
||||||
|
util.normalMode(editor);
|
||||||
|
},
|
||||||
|
fn: function(editor, range, count, param) {
|
||||||
|
count = count || 1;
|
||||||
|
switch (param) {
|
||||||
|
case "<":
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
editor.selection.selectLine();
|
||||||
|
for (var i = 0; i < count - 1; i++) {
|
||||||
|
editor.selection.moveCursorDown();
|
||||||
|
}
|
||||||
|
editor.blockOutdent();
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.moveCursorToPosition(pos);
|
||||||
|
editor.navigateLineEnd();
|
||||||
|
editor.navigateLineStart();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
134
lib/ace/keyboard/vim/maps/util.js
Normal file
134
lib/ace/keyboard/vim/maps/util.js
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
var registers = require("../registers");
|
||||||
|
|
||||||
|
var dom = require("../../../lib/dom");
|
||||||
|
dom.importCssString('.insert-mode. ace_cursor{\
|
||||||
|
border-left: 2px solid #333333;\
|
||||||
|
}\
|
||||||
|
.ace_dark.insert-mode .ace_cursor{\
|
||||||
|
border-left: 2px solid #eeeeee;\
|
||||||
|
}\
|
||||||
|
.normal-mode .ace_cursor{\
|
||||||
|
border: 0!important;\
|
||||||
|
background-color: red;\
|
||||||
|
opacity: 0.5;\
|
||||||
|
}', 'vimMode');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
onVisualMode: false,
|
||||||
|
onVisualLineMode: false,
|
||||||
|
currentMode: 'normal',
|
||||||
|
noMode: function(editor) {
|
||||||
|
editor.unsetStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
if (editor.commands.recording)
|
||||||
|
editor.commands.toggleRecording();
|
||||||
|
editor.setOverwrite(false);
|
||||||
|
},
|
||||||
|
insertMode: function(editor) {
|
||||||
|
this.currentMode = 'insert';
|
||||||
|
// Switch editor to insert mode
|
||||||
|
editor.setStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
|
||||||
|
editor.setOverwrite(false);
|
||||||
|
editor.keyBinding.$data.buffer = "";
|
||||||
|
editor.keyBinding.$data.state = "insertMode";
|
||||||
|
this.onVisualMode = false;
|
||||||
|
this.onVisualLineMode = false;
|
||||||
|
if(this.onInsertReplaySequence) {
|
||||||
|
// Ok, we're apparently replaying ("."), so let's do it
|
||||||
|
editor.commands.macro = this.onInsertReplaySequence;
|
||||||
|
editor.commands.replay(editor);
|
||||||
|
this.onInsertReplaySequence = null;
|
||||||
|
this.normalMode(editor);
|
||||||
|
} else {
|
||||||
|
editor._emit("vimMode", "insert");
|
||||||
|
// Record any movements, insertions in insert mode
|
||||||
|
if(!editor.commands.recording)
|
||||||
|
editor.commands.toggleRecording();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalMode: function(editor) {
|
||||||
|
// Switch editor to normal mode
|
||||||
|
this.currentMode = 'normal';
|
||||||
|
|
||||||
|
editor.unsetStyle('insert-mode');
|
||||||
|
editor.setStyle('normal-mode');
|
||||||
|
editor.clearSelection();
|
||||||
|
|
||||||
|
var pos;
|
||||||
|
if (!editor.getOverwrite()) {
|
||||||
|
pos = editor.getCursorPosition();
|
||||||
|
if (pos.column > 0)
|
||||||
|
editor.navigateLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.setOverwrite(true);
|
||||||
|
editor.keyBinding.$data.buffer = "";
|
||||||
|
editor.keyBinding.$data.state = "start";
|
||||||
|
this.onVisualMode = false;
|
||||||
|
this.onVisualLineMode = false;
|
||||||
|
editor._emit("changeVimMode", "normal");
|
||||||
|
// Save recorded keystrokes
|
||||||
|
if (editor.commands.recording) {
|
||||||
|
editor.commands.toggleRecording();
|
||||||
|
return editor.commands.macro;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
visualMode: function(editor, lineMode) {
|
||||||
|
if (
|
||||||
|
(this.onVisualLineMode && lineMode)
|
||||||
|
|| (this.onVisualMode && !lineMode)
|
||||||
|
) {
|
||||||
|
this.normalMode(editor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.setStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
|
||||||
|
editor._emit("changeVimMode", "visual");
|
||||||
|
if (lineMode) {
|
||||||
|
this.onVisualLineMode = true;
|
||||||
|
} else {
|
||||||
|
this.onVisualMode = true;
|
||||||
|
this.onVisualLineMode = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getRightNthChar: function(editor, cursor, char, n) {
|
||||||
|
var line = editor.getSession().getLine(cursor.row);
|
||||||
|
var matches = line.substr(cursor.column + 1).split(char);
|
||||||
|
|
||||||
|
return n < matches.length ? matches.slice(0, n).join(char).length : null;
|
||||||
|
},
|
||||||
|
getLeftNthChar: function(editor, cursor, char, n) {
|
||||||
|
var line = editor.getSession().getLine(cursor.row);
|
||||||
|
var matches = line.substr(0, cursor.column).split(char);
|
||||||
|
|
||||||
|
return n < matches.length ? matches.slice(-1 * n).join(char).length : null;
|
||||||
|
},
|
||||||
|
toRealChar: function(char) {
|
||||||
|
if (char.length === 1)
|
||||||
|
return char;
|
||||||
|
|
||||||
|
if (/^shift-./.test(char))
|
||||||
|
return char[char.length - 1].toUpperCase();
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
copyLine: function(editor) {
|
||||||
|
var pos = editor.getCursorPosition();
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.moveCursorTo(pos.row, pos.column);
|
||||||
|
editor.selection.selectLine();
|
||||||
|
registers._default.isLine = true;
|
||||||
|
registers._default.text = editor.getCopyText().replace(/\n$/, "");
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
editor.moveCursorTo(pos.row, pos.column);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
49
lib/ace/keyboard/vim/registers.js
Normal file
49
lib/ace/keyboard/vim/registers.js
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sergi Mansilla <sergi AT c9 DOT io>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
"never use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
_default: {
|
||||||
|
text: "",
|
||||||
|
isLine: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -63,7 +63,7 @@ var Text = function(parentEl) {
|
||||||
|
|
||||||
this.EOF_CHAR = "\xB6"; //"¶";
|
this.EOF_CHAR = "\xB6"; //"¶";
|
||||||
this.EOL_CHAR = "\xAC"; //"¬";
|
this.EOL_CHAR = "\xAC"; //"¬";
|
||||||
this.TAB_CHAR = "\u2192"; //"→";
|
this.TAB_CHAR = "\u2192"; //"→" "\u21E5";
|
||||||
this.SPACE_CHAR = "\xB7"; //"·";
|
this.SPACE_CHAR = "\xB7"; //"·";
|
||||||
this.$padding = 0;
|
this.$padding = 0;
|
||||||
|
|
||||||
|
|
@ -390,7 +390,7 @@ var Text = function(parentEl) {
|
||||||
|
|
||||||
this.$renderToken = function(stringBuilder, screenColumn, token, value) {
|
this.$renderToken = function(stringBuilder, screenColumn, token, value) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var replaceReg = /\t|&|<|( +)|([\u0000-\u0019\u00a0\u2000-\u200b\u2028\u2029\u3000])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
|
var replaceReg = /\t|&|<|( +)|([\u0000-\u0019\u00a0\u1680\u180E\u2000-\u200b\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
|
||||||
var replaceFunc = function(c, a, b, tabIdx, idx4) {
|
var replaceFunc = function(c, a, b, tabIdx, idx4) {
|
||||||
if (a) {
|
if (a) {
|
||||||
return new Array(c.length+1).join(" ");
|
return new Array(c.length+1).join(" ");
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ var Keys = (function() {
|
||||||
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
|
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
|
||||||
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
|
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
|
||||||
188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
|
188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
|
||||||
221: ']', 222: '\"'
|
221: ']', 222: '\''
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ define(function(require, exports, module) {
|
||||||
return !x.lastIndex;
|
return !x.lastIndex;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
if (compliantLastIndexIncrement && compliantExecNpcg)
|
||||||
|
return;
|
||||||
|
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
// Overriden native methods
|
// Overriden native methods
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var oop = require("../../lib/oop");
|
var oop = require("../../lib/oop");
|
||||||
var Behaviour = require('../behaviour').Behaviour;
|
var Behaviour = require("../behaviour").Behaviour;
|
||||||
|
|
||||||
var CstyleBehaviour = function () {
|
var CstyleBehaviour = function () {
|
||||||
|
|
||||||
|
|
|
||||||
86
lib/ace/mode/c9search.js
Normal file
86
lib/ace/mode/c9search.js
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Garen J. Torikian <gjtorikian AT gmail DOT com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../lib/oop");
|
||||||
|
var TextMode = require("./text").Mode;
|
||||||
|
var Tokenizer = require("../tokenizer").Tokenizer;
|
||||||
|
var C9SearchHighlightRules = require("./c9search_highlight_rules").C9SearchHighlightRules;
|
||||||
|
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
|
||||||
|
var C9StyleFoldMode = require("./folding/c9search").FoldMode;
|
||||||
|
|
||||||
|
var Mode = function() {
|
||||||
|
this.$tokenizer = new Tokenizer(new C9SearchHighlightRules().getRules(), "i");
|
||||||
|
this.$outdent = new MatchingBraceOutdent();
|
||||||
|
this.foldingRules = new C9StyleFoldMode();
|
||||||
|
};
|
||||||
|
oop.inherits(Mode, TextMode);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
this.getNextLineIndent = function(state, line, tab) {
|
||||||
|
var indent = this.$getIndent(line);
|
||||||
|
|
||||||
|
// ignore braces in comments
|
||||||
|
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
|
||||||
|
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||||
|
return indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = line.match(/^.*\{\s*$/);
|
||||||
|
if (match) {
|
||||||
|
indent += tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
return indent;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.checkOutdent = function(state, line, input) {
|
||||||
|
return this.$outdent.checkOutdent(line, input);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.autoOutdent = function(state, doc, row) {
|
||||||
|
this.$outdent.autoOutdent(doc, row);
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(Mode.prototype);
|
||||||
|
|
||||||
|
exports.Mode = Mode;
|
||||||
|
|
||||||
|
});
|
||||||
66
lib/ace/mode/c9search_highlight_rules.js
Normal file
66
lib/ace/mode/c9search_highlight_rules.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Garen J. Torikian <gjtorikian AT gmail DOT com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../lib/oop");
|
||||||
|
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
|
||||||
|
|
||||||
|
var C9SearchHighlightRules = function() {
|
||||||
|
|
||||||
|
// regexp must not have capturing parentheses. Use (?:) instead.
|
||||||
|
// regexps are ordered -> the first match is used
|
||||||
|
this.$rules = {
|
||||||
|
"start" : [
|
||||||
|
{
|
||||||
|
token : ["string", "text"], // single line
|
||||||
|
regex : "(.+)(:$)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : ["constant.numeric", "text"],
|
||||||
|
regex : "(^\\s*[0-9]+)(:\\s*)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
oop.inherits(C9SearchHighlightRules, TextHighlightRules);
|
||||||
|
|
||||||
|
exports.C9SearchHighlightRules = C9SearchHighlightRules;
|
||||||
|
|
||||||
|
});
|
||||||
97
lib/ace/mode/folding/c9search.js
Normal file
97
lib/ace/mode/folding/c9search.js
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Ajax.org Code Editor (ACE).
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Ajax.org B.V.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../../lib/oop");
|
||||||
|
var Range = require("../../range").Range;
|
||||||
|
var BaseFoldMode = require("./fold_mode").FoldMode;
|
||||||
|
|
||||||
|
var FoldMode = exports.FoldMode = function() {};
|
||||||
|
oop.inherits(FoldMode, BaseFoldMode);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
this.foldingStartMarker = /[a-zA-Z](:)\s*$/;
|
||||||
|
this.foldingStopMarker = /^(\s*)$/;
|
||||||
|
|
||||||
|
this.getFoldWidgetRange = function(session, foldStyle, row) {
|
||||||
|
var line = session.getLine(row);
|
||||||
|
var match = line.match(this.foldingStartMarker);
|
||||||
|
if (match) {
|
||||||
|
var i = match.index;
|
||||||
|
|
||||||
|
if (match[1])
|
||||||
|
return this.openingBracketBlock(session, match[1], row, i, false, true);
|
||||||
|
|
||||||
|
var range = session.getCommentFoldRange(row, i + match[0].length);
|
||||||
|
range.end.column -= 2;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foldStyle !== "markbeginend")
|
||||||
|
return;
|
||||||
|
|
||||||
|
var match = line.match(this.foldingStopMarker);
|
||||||
|
if (match) {
|
||||||
|
var i = match.index + match[0].length;
|
||||||
|
|
||||||
|
if (match[2]) {
|
||||||
|
var range = session.getCommentFoldRange(row, i);
|
||||||
|
range.end.column -= 2;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
var end = {row: row, column: i};
|
||||||
|
var start = session.$findOpeningBracket(match[1], end);
|
||||||
|
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
|
||||||
|
start.column++;
|
||||||
|
end.column--;
|
||||||
|
|
||||||
|
return Range.fromPoints(start, end);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(FoldMode.prototype);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -91,9 +91,9 @@ var FoldMode = exports.FoldMode = function() {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.openingBracketBlock = function(session, bracket, row, column) {
|
this.openingBracketBlock = function(session, bracket, row, column, typeRe, allowBlankLine) {
|
||||||
var start = {row: row, column: column + 1};
|
var start = {row: row, column: column + 1};
|
||||||
var end = session.$findClosingBracket(bracket, start);
|
var end = session.$findClosingBracket(bracket, start, typeRe, allowBlankLine);
|
||||||
if (!end)
|
if (!end)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ var PgsqlHighlightRules = function() {
|
||||||
"\\?\\||\\?\\|\\||@|@\\-@|@>|@@|@@@|\\^|\\||\\|\\&>|\\|/|\\|>>|\\|\\||\\|\\|/|~|~\\*|~<=~|~<~|" +
|
"\\?\\||\\?\\|\\||@|@\\-@|@>|@@|@@@|\\^|\\||\\|\\&>|\\|/|\\|>>|\\|\\||\\|\\|/|~|~\\*|~<=~|~<~|" +
|
||||||
"~=|~>=~|~>~|~~|~~\\*"
|
"~=|~>=~|~>~|~~|~~\\*"
|
||||||
}, {
|
}, {
|
||||||
token : "lparen.paren",
|
token : "paren.lparen",
|
||||||
regex : "[\\(]"
|
regex : "[\\(]"
|
||||||
}, {
|
}, {
|
||||||
token : "paren.rparen",
|
token : "paren.rparen",
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ var PythonHighlightRules = function() {
|
||||||
token : "keyword.operator",
|
token : "keyword.operator",
|
||||||
regex : "\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="
|
regex : "\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="
|
||||||
}, {
|
}, {
|
||||||
token : "lparen.paren",
|
token : "paren.lparen",
|
||||||
regex : "[\\[\\(\\{]"
|
regex : "[\\[\\(\\{]"
|
||||||
}, {
|
}, {
|
||||||
token : "paren.rparen",
|
token : "paren.rparen",
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ var ShHighlightRules = function() {
|
||||||
token : "keyword.operator",
|
token : "keyword.operator",
|
||||||
regex : "\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="
|
regex : "\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="
|
||||||
}, {
|
}, {
|
||||||
token : "lparen.paren",
|
token : "paren.lparen",
|
||||||
regex : "[\\[\\(\\{]"
|
regex : "[\\[\\(\\{]"
|
||||||
}, {
|
}, {
|
||||||
token : "paren.rparen",
|
token : "paren.rparen",
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ var SqlHighlightRules = function() {
|
||||||
token : "keyword.operator",
|
token : "keyword.operator",
|
||||||
regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="
|
regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="
|
||||||
}, {
|
}, {
|
||||||
token : "lparen.paren",
|
token : "paren.lparen",
|
||||||
regex : "[\\(]"
|
regex : "[\\(]"
|
||||||
}, {
|
}, {
|
||||||
token : "paren.rparen",
|
token : "paren.rparen",
|
||||||
|
|
|
||||||
|
|
@ -38,24 +38,34 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
var dom = require("../lib/dom");
|
||||||
|
|
||||||
function GutterHandler(mouseHandler) {
|
function GutterHandler(mouseHandler) {
|
||||||
var editor = mouseHandler.editor;
|
var editor = mouseHandler.editor;
|
||||||
|
|
||||||
mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
|
mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
|
||||||
if (e.domEvent.target.className.indexOf("ace_gutter-cell") == -1)
|
var target = e.domEvent.target;
|
||||||
|
if (target.className.indexOf("ace_gutter-cell") == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!editor.isFocused())
|
if (!editor.isFocused())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var padding = parseInt(dom.computedStyle(target).paddingLeft);
|
||||||
|
if (e.x < padding + target.getBoundingClientRect().left + 1)
|
||||||
|
return;
|
||||||
|
|
||||||
var row = e.getDocumentPosition().row;
|
var row = e.getDocumentPosition().row;
|
||||||
var selection = editor.session.selection;
|
var selection = editor.session.selection;
|
||||||
|
|
||||||
selection.moveCursorTo(row, 0);
|
if (e.getShiftKey()) {
|
||||||
selection.selectLine();
|
selection.selectTo(row, 0);
|
||||||
|
} else {
|
||||||
|
selection.moveCursorTo(row, 0);
|
||||||
|
selection.selectLine();
|
||||||
|
mouseHandler.$clickSelection = selection.getRange();
|
||||||
|
}
|
||||||
|
|
||||||
mouseHandler.$clickSelection = selection.getRange();
|
|
||||||
mouseHandler.captureMouse(e, "selectByLines");
|
mouseHandler.captureMouse(e, "selectByLines");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ function DefaultHandlers(mouseHandler) {
|
||||||
|
|
||||||
editor.selectAll();
|
editor.selectAll();
|
||||||
this.$clickSelection = editor.getSelectionRange();
|
this.$clickSelection = editor.getSelectionRange();
|
||||||
this.setState("select");
|
this.setState("null");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onScroll = function(ev) {
|
this.onScroll = function(ev) {
|
||||||
|
|
|
||||||
|
|
@ -504,13 +504,11 @@ var Editor = require("./editor").Editor;
|
||||||
if (!this.inMultiSelectMode)
|
if (!this.inMultiSelectMode)
|
||||||
return this.insert(text);
|
return this.insert(text);
|
||||||
|
|
||||||
var lines = text.split(this.session.getDocument().getNewLineCharacter());
|
var lines = text.split(/\r\n|\r|\n/);
|
||||||
var ranges = this.selection.rangeList.ranges;
|
var ranges = this.selection.rangeList.ranges;
|
||||||
|
|
||||||
if (lines.length > ranges.length) {
|
if (lines.length > ranges.length || (lines.length <= 2 || !lines[1]))
|
||||||
this.commands.exec("insertstring", this, text);
|
return this.commands.exec("insertstring", this, text);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = ranges.length; i--; ) {
|
for (var i = ranges.length; i--; ) {
|
||||||
var range = ranges[i];
|
var range = ranges[i];
|
||||||
|
|
|
||||||
|
|
@ -116,11 +116,10 @@ Search.SELECTION = 2;
|
||||||
if (!this.$options.needle)
|
if (!this.$options.needle)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (this.$options.backwards) {
|
var iterator = this.$matchIterator(session);
|
||||||
var iterator = this.$backwardMatchIterator(session);
|
|
||||||
} else {
|
if (!iterator)
|
||||||
iterator = this.$forwardMatchIterator(session);
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
var firstRange = null;
|
var firstRange = null;
|
||||||
iterator.forEach(function(range) {
|
iterator.forEach(function(range) {
|
||||||
|
|
@ -143,11 +142,10 @@ Search.SELECTION = 2;
|
||||||
if (!options.needle)
|
if (!options.needle)
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
if (options.backwards) {
|
var iterator = this.$matchIterator(session);
|
||||||
var iterator = this.$backwardMatchIterator(session);
|
|
||||||
} else {
|
if (!iterator)
|
||||||
iterator = this.$forwardMatchIterator(session);
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
var ignoreCursor = !options.start && options.wrap && options.scope == Search.ALL;
|
var ignoreCursor = !options.start && options.wrap && options.scope == Search.ALL;
|
||||||
if (ignoreCursor)
|
if (ignoreCursor)
|
||||||
|
|
@ -173,101 +171,116 @@ Search.SELECTION = 2;
|
||||||
*
|
*
|
||||||
* Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.
|
* Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.replace = function(input, replacement) {
|
this.replace = function(input, replacement) {
|
||||||
|
if (!this.$options.regExp)
|
||||||
|
return input == this.$options.needle ? replacement : null;
|
||||||
|
|
||||||
var re = this.$assembleRegExp();
|
var re = this.$assembleRegExp();
|
||||||
|
if (!re)
|
||||||
|
return;
|
||||||
|
|
||||||
var match = re.exec(input);
|
var match = re.exec(input);
|
||||||
if (match && match[0].length == input.length) {
|
if (match && match[0].length == input.length) {
|
||||||
if (this.$options.regExp) {
|
return input.replace(re, replacement);
|
||||||
return input.replace(re, replacement);
|
}
|
||||||
} else {
|
else {
|
||||||
return replacement;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** internal, hide
|
/** internal, hide
|
||||||
* Search.$forwardMatchIterator(session) -> String | Boolean
|
* Search.$matchIterator(session) -> String | Boolean
|
||||||
* - session (EditSession): The session to search with
|
* - session (EditSession): The session to search with
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.$forwardMatchIterator = function(session) {
|
this.$matchIterator = function(session) {
|
||||||
var re = this.$assembleRegExp();
|
var re = this.$assembleRegExp();
|
||||||
var self = this;
|
if (!re)
|
||||||
|
return false;
|
||||||
|
|
||||||
return {
|
var self = this, callback, backwards = this.$options.backwards;
|
||||||
forEach: function(callback) {
|
|
||||||
self.$forwardLineIterator(session).forEach(function(line, startIndex, row) {
|
|
||||||
if (startIndex) {
|
|
||||||
line = line.substring(startIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
var matches = [];
|
if (this.$options.$isMultiLine) {
|
||||||
|
var matchIterator = function(line, startIndex, row) {
|
||||||
|
var startLine = line;
|
||||||
|
if (startIndex)
|
||||||
|
line = line.substring(startIndex);
|
||||||
|
|
||||||
line.replace(re, function(str) {
|
var len = re.length;
|
||||||
var offset = arguments[arguments.length-2];
|
var part = re[0];
|
||||||
matches.push({
|
if (line.slice(-part.length) != part)
|
||||||
str: str,
|
return;
|
||||||
offset: startIndex + offset
|
|
||||||
});
|
|
||||||
return str;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var i=0; i<matches.length; i++) {
|
for (var i = 1; i < len - 1; i++)
|
||||||
var match = matches[i];
|
if (re[i] != session.getLine(row + i))
|
||||||
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
return;
|
||||||
if (callback(range))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
part = re[len - 1];
|
||||||
|
if (session.getLine(row + len - 1).slice(0, part.length) != part)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var range = new Range(
|
||||||
|
row, startLine.length - re[0].length,
|
||||||
|
row + len - 1, re[len - 1].length
|
||||||
|
);
|
||||||
|
if (callback(range))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
} else if (backwards) {
|
||||||
};
|
var matchIterator = function(line, startIndex, row) {
|
||||||
|
if (startIndex)
|
||||||
|
line = line.substring(startIndex);
|
||||||
|
|
||||||
/** internal, hide
|
var matches = [];
|
||||||
* Search.$backwardMatchIterator(session) -> String
|
|
||||||
* - session (EditSession): The session to search with
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
this.$backwardMatchIterator = function(session) {
|
|
||||||
var re = this.$assembleRegExp();
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
return {
|
line.replace(re, function(str) {
|
||||||
forEach: function(callback) {
|
var offset = arguments[arguments.length-2];
|
||||||
self.$backwardLineIterator(session).forEach(function(line, startIndex, row) {
|
matches.push({
|
||||||
if (startIndex) {
|
str: str,
|
||||||
line = line.substring(startIndex);
|
offset: startIndex + offset
|
||||||
}
|
|
||||||
|
|
||||||
var matches = [];
|
|
||||||
|
|
||||||
line.replace(re, function(str, offset) {
|
|
||||||
matches.push({
|
|
||||||
str: str,
|
|
||||||
offset: startIndex + offset
|
|
||||||
});
|
|
||||||
return str;
|
|
||||||
});
|
});
|
||||||
|
return str;
|
||||||
for (var i=matches.length-1; i>= 0; i--) {
|
|
||||||
var match = matches[i];
|
|
||||||
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
|
||||||
if (callback(range))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (var i=matches.length-1; i>= 0; i--) {
|
||||||
|
var match = matches[i];
|
||||||
|
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
||||||
|
if (callback(range))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
|
var matchIterator = function(line, startIndex, row) {
|
||||||
|
if (startIndex)
|
||||||
|
line = line.substring(startIndex);
|
||||||
|
|
||||||
|
var matches = [];
|
||||||
|
|
||||||
|
line.replace(re, function(str) {
|
||||||
|
var offset = arguments[arguments.length-2];
|
||||||
|
matches.push({
|
||||||
|
str: str,
|
||||||
|
offset: startIndex + offset
|
||||||
|
});
|
||||||
|
return str;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var i=0; i<matches.length; i++) {
|
||||||
|
var match = matches[i];
|
||||||
|
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
||||||
|
if (callback(range))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {forEach: function(_callback) {
|
||||||
|
callback = _callback;
|
||||||
|
self.$lineIterator(session).forEach(matchIterator);
|
||||||
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$rangeFromMatch = function(row, column, length) {
|
this.$rangeFromMatch = function(row, column, length) {
|
||||||
|
|
@ -275,12 +288,21 @@ Search.SELECTION = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$assembleRegExp = function() {
|
this.$assembleRegExp = function() {
|
||||||
if (this.$options.regExp) {
|
if (typeof this.$options.needle != 'string')
|
||||||
var needle = this.$options.needle;
|
return this.$options.needle;
|
||||||
} else {
|
|
||||||
needle = lang.escapeRegExp(this.$options.needle);
|
var needle = this.$options.needle;
|
||||||
|
|
||||||
|
if (!this.$options.regExp) {
|
||||||
|
if (/[\n\r]/.test(needle)){
|
||||||
|
this.$options.$isMultiLine = true;
|
||||||
|
return needle.split(/\r\n|\r|\n/)
|
||||||
|
}
|
||||||
|
needle = lang.escapeRegExp(needle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$options.$isMultiLine = false;
|
||||||
|
|
||||||
if (this.$options.wholeWord) {
|
if (this.$options.wholeWord) {
|
||||||
needle = "\\b" + needle + "\\b";
|
needle = "\\b" + needle + "\\b";
|
||||||
}
|
}
|
||||||
|
|
@ -290,15 +312,22 @@ Search.SELECTION = 2;
|
||||||
modifier += "i";
|
modifier += "i";
|
||||||
}
|
}
|
||||||
|
|
||||||
var re = new RegExp(needle, modifier);
|
try {
|
||||||
|
var re = new RegExp(needle, modifier);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return re;
|
return re;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$forwardLineIterator = function(session) {
|
this.$lineIterator = function(session) {
|
||||||
var searchSelection = this.$options.scope == Search.SELECTION;
|
var searchSelection = this.$options.scope == Search.SELECTION;
|
||||||
|
var backwards = this.$options.backwards;
|
||||||
|
|
||||||
var range = this.$options.range || session.getSelection().getRange();
|
var range = this.$options.range || session.getSelection().getRange();
|
||||||
var start = this.$options.start || range[searchSelection ? "start" : "end"];
|
var start = this.$options.start || range[searchSelection != backwards ? "start" : "end"];
|
||||||
|
|
||||||
var firstRow = searchSelection ? range.start.row : 0;
|
var firstRow = searchSelection ? range.start.row : 0;
|
||||||
var firstColumn = searchSelection ? range.start.column : 0;
|
var firstColumn = searchSelection ? range.start.column : 0;
|
||||||
|
|
@ -318,8 +347,8 @@ Search.SELECTION = 2;
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
if (!backwards) {
|
||||||
forEach: function(callback) {
|
var forEach = function(callback) {
|
||||||
var row = start.row;
|
var row = start.row;
|
||||||
|
|
||||||
var line = getLine(row);
|
var line = getLine(row);
|
||||||
|
|
@ -329,10 +358,8 @@ Search.SELECTION = 2;
|
||||||
inWrap = false;
|
inWrap = false;
|
||||||
|
|
||||||
while (!callback(line, startIndex, row)) {
|
while (!callback(line, startIndex, row)) {
|
||||||
|
if (stop)
|
||||||
if (stop) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
row++;
|
row++;
|
||||||
startIndex = 0;
|
startIndex = 0;
|
||||||
|
|
@ -353,23 +380,8 @@ Search.SELECTION = 2;
|
||||||
line = getLine(row);
|
line = getLine(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
};
|
var forEach = function(callback) {
|
||||||
|
|
||||||
this.$backwardLineIterator = function(session) {
|
|
||||||
var searchSelection = this.$options.scope == Search.SELECTION;
|
|
||||||
|
|
||||||
var range = this.$options.range || session.getSelection().getRange();
|
|
||||||
var start = this.$options.start || range[searchSelection ? "end" : "start"];
|
|
||||||
|
|
||||||
var firstRow = searchSelection ? range.start.row : 0;
|
|
||||||
var firstColumn = searchSelection ? range.start.column : 0;
|
|
||||||
var lastRow = searchSelection ? range.end.row : session.getLength() - 1;
|
|
||||||
|
|
||||||
var wrap = this.$options.wrap;
|
|
||||||
|
|
||||||
return {
|
|
||||||
forEach : function(callback) {
|
|
||||||
var row = start.row;
|
var row = start.row;
|
||||||
|
|
||||||
var line = session.getLine(row).substring(0, start.column);
|
var line = session.getLine(row).substring(0, start.column);
|
||||||
|
|
@ -378,7 +390,6 @@ Search.SELECTION = 2;
|
||||||
var inWrap = false;
|
var inWrap = false;
|
||||||
|
|
||||||
while (!callback(line, startIndex, row)) {
|
while (!callback(line, startIndex, row)) {
|
||||||
|
|
||||||
if (stop)
|
if (stop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -409,7 +420,9 @@ Search.SELECTION = 2;
|
||||||
startIndex = start.column;
|
startIndex = start.column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
return {forEach: forEach};
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(Search.prototype);
|
}).call(Search.prototype);
|
||||||
|
|
|
||||||
|
|
@ -139,10 +139,6 @@ var VirtualRenderer = function(container, theme) {
|
||||||
var scrollLeft = _self.scroller.scrollLeft;
|
var scrollLeft = _self.scroller.scrollLeft;
|
||||||
_self.scrollLeft = scrollLeft;
|
_self.scrollLeft = scrollLeft;
|
||||||
_self.session.setScrollLeft(scrollLeft);
|
_self.session.setScrollLeft(scrollLeft);
|
||||||
|
|
||||||
_self.scroller.className = scrollLeft == 0
|
|
||||||
? "ace_scroller"
|
|
||||||
: "ace_scroller horscroll";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.cursorPos = {
|
this.cursorPos = {
|
||||||
|
|
@ -455,6 +451,10 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
this.$highlightGutterLine = false;
|
this.$highlightGutterLine = false;
|
||||||
this.setHighlightGutterLine = function(shouldHighlight) {
|
this.setHighlightGutterLine = function(shouldHighlight) {
|
||||||
|
// adding this element to gutter causes strange behavior on ie
|
||||||
|
if (useragent.isIE)
|
||||||
|
return;
|
||||||
|
|
||||||
if (this.$highlightGutterLine == shouldHighlight)
|
if (this.$highlightGutterLine == shouldHighlight)
|
||||||
return;
|
return;
|
||||||
this.$highlightGutterLine = shouldHighlight;
|
this.$highlightGutterLine = shouldHighlight;
|
||||||
|
|
@ -476,7 +476,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$updateGutterLineHighlight = function() {
|
this.$updateGutterLineHighlight = function() {
|
||||||
this.$gutterLineHighlight.style.top = this.$cursorLayer.$pixelPos.top + "px";
|
this.$gutterLineHighlight.style.top = this.$cursorLayer.$pixelPos.top - this.layerConfig.offset + "px";
|
||||||
this.$gutterLineHighlight.style.height = this.layerConfig.lineHeight + "px";
|
this.$gutterLineHighlight.style.height = this.layerConfig.lineHeight + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -651,6 +651,8 @@ var VirtualRenderer = function(container, theme) {
|
||||||
var scrollLeft = this.scroller.scrollLeft;
|
var scrollLeft = this.scroller.scrollLeft;
|
||||||
this.scrollLeft = scrollLeft;
|
this.scrollLeft = scrollLeft;
|
||||||
this.session.setScrollLeft(scrollLeft);
|
this.session.setScrollLeft(scrollLeft);
|
||||||
|
|
||||||
|
this.scroller.className = this.scrollLeft == 0 ? "ace_scroller" : "ace_scroller horscroll";
|
||||||
}
|
}
|
||||||
|
|
||||||
// full
|
// full
|
||||||
|
|
@ -784,7 +786,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
// For debugging.
|
// For debugging.
|
||||||
// console.log(JSON.stringify(this.layerConfig));
|
// console.log(JSON.stringify(this.layerConfig));
|
||||||
|
|
||||||
this.$gutter.style.marginTop = (-offset) + "px";
|
this.$gutterLayer.element.style.marginTop = (-offset) + "px";
|
||||||
this.content.style.marginTop = (-offset) + "px";
|
this.content.style.marginTop = (-offset) + "px";
|
||||||
this.content.style.width = longestLine + 2 * this.$padding + "px";
|
this.content.style.width = longestLine + 2 * this.$padding + "px";
|
||||||
this.content.style.height = minHeight + "px";
|
this.content.style.height = minHeight + "px";
|
||||||
|
|
@ -1011,6 +1013,16 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.session.setScrollTop(row * this.lineHeight);
|
this.session.setScrollTop(row * this.lineHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.alignCursor = function(cursor, alignment) {
|
||||||
|
if (typeof cursor == "number")
|
||||||
|
cursor = {row: cursor, column: 0};
|
||||||
|
|
||||||
|
var pos = this.$cursorLayer.getPixelPosition(cursor);
|
||||||
|
var offset = pos.top - this.$size.scrollerHeight * (alignment || 0);
|
||||||
|
|
||||||
|
this.session.setScrollTop(offset);
|
||||||
|
};
|
||||||
|
|
||||||
this.STEPS = 8;
|
this.STEPS = 8;
|
||||||
this.$calcSteps = function(fromValue, toValue){
|
this.$calcSteps = function(fromValue, toValue){
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
@ -1064,12 +1076,12 @@ var VirtualRenderer = function(container, theme) {
|
||||||
// trick session to think it's already scrolled to not loose toValue
|
// trick session to think it's already scrolled to not loose toValue
|
||||||
_self.session.$scrollTop = toValue;
|
_self.session.$scrollTop = toValue;
|
||||||
} else {
|
} else {
|
||||||
this.$inScrollAnimation = false;
|
_self.$inScrollAnimation = false;
|
||||||
clearInterval(_self.$timer);
|
clearInterval(_self.$timer);
|
||||||
|
|
||||||
_self.session.$scrollTop = -1;
|
_self.session.$scrollTop = -1;
|
||||||
_self.session.setScrollTop(toValue);
|
_self.session.setScrollTop(toValue);
|
||||||
callback && callback();
|
callback && callback();
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
|
|
@ -1099,7 +1111,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.scrollToX = function(scrollLeft) {
|
this.scrollToX = function(scrollLeft) {
|
||||||
if (scrollLeft <= this.$padding)
|
if (scrollLeft < 0)
|
||||||
scrollLeft = 0;
|
scrollLeft = 0;
|
||||||
|
|
||||||
if (this.scrollLeft !== scrollLeft)
|
if (this.scrollLeft !== scrollLeft)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"asyncjs": "0.0.x",
|
"asyncjs": "0.0.x",
|
||||||
"jsdom": "0.2.x",
|
"jsdom": "0.2.x",
|
||||||
"amd-loader": "~0.0.4",
|
"amd-loader": "~0.0.4",
|
||||||
"libxml": "0.0.x",
|
"plist": "",
|
||||||
"dryice": "0.4.2",
|
"dryice": "0.4.2",
|
||||||
"panino" : "~1.0.15"
|
"panino" : "~1.0.15"
|
||||||
},
|
},
|
||||||
|
|
@ -41,7 +41,8 @@
|
||||||
"lib": "lib/ace"
|
"lib": "lib/ace"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node lib/ace/test/all.js"
|
"test": "node lib/ace/test/all.js",
|
||||||
|
"postinstall": "node ./install.js"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"github.com/sourcemint/bundler-js/0/-meta/config/0": {
|
"github.com/sourcemint/bundler-js/0/-meta/config/0": {
|
||||||
|
|
@ -62,7 +63,7 @@
|
||||||
"dynamicLinks": [
|
"dynamicLinks": [
|
||||||
"/lib/ace/mode/*_worker.js"
|
"/lib/ace/mode/*_worker.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,14 @@
|
||||||
var xml = require("libxml");
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
|
||||||
function plistToJson(el) {
|
var parseString = require("plist").parseString;
|
||||||
if (el.tagName != "plist")
|
function parseTheme(themeXml, callback) {
|
||||||
throw new Error("not a plist!");
|
parseString(themeXml, function(_, theme) {
|
||||||
|
console.log(theme)
|
||||||
return $plistParse(el.selectSingleNode("dict"));
|
callback(theme[0])
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function $plistParse(el) {
|
|
||||||
if (el.tagName == "dict") {
|
|
||||||
var dict = {};
|
|
||||||
var key;
|
|
||||||
var childNodes = el.childNodes;
|
|
||||||
for (var i=0, l=childNodes.length; i<l; i++) {
|
|
||||||
var child = childNodes[i];
|
|
||||||
if (child.nodeType !== 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (child.tagName == "key") {
|
|
||||||
key = child.nodeValue;
|
|
||||||
} else {
|
|
||||||
if (!key)
|
|
||||||
throw new Error("missing key");
|
|
||||||
dict[key] = $plistParse(child);
|
|
||||||
key = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
else if (el.tagName == "array") {
|
|
||||||
var arr = [];
|
|
||||||
var childNodes = el.childNodes;
|
|
||||||
for (var i=0, l=childNodes.length; i<l; i++) {
|
|
||||||
var child = childNodes[i];
|
|
||||||
if (child.nodeType !== 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
arr.push($plistParse(child));
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
else if (el.tagName == "string") {
|
|
||||||
return el.nodeValue;
|
|
||||||
} else {
|
|
||||||
throw new Error("unsupported node type " + el.tagName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseTheme(themeXml) {
|
|
||||||
try {
|
|
||||||
return plistToJson(xml.parseFromString(themeXml).documentElement);
|
|
||||||
} catch(e) { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
var supportedScopes = {
|
var supportedScopes = {
|
||||||
"keyword": "keyword",
|
"keyword": "keyword",
|
||||||
|
|
@ -253,10 +209,15 @@ var themes = {
|
||||||
"vibrant_ink": "Vibrant Ink"
|
"vibrant_ink": "Vibrant Ink"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var name in themes) {
|
function convertTheme(name) {
|
||||||
console.log("Converting " + name);
|
console.log("Converting " + name);
|
||||||
var tmTheme = fs.readFileSync(__dirname + "/tmthemes/" + themes[name] + ".tmTheme", "utf8");
|
var tmTheme = fs.readFileSync(__dirname + "/tmthemes/" + themes[name] + ".tmTheme", "utf8");
|
||||||
|
parseTheme(tmTheme, function(theme) {
|
||||||
var styles = extractStyles(parseTheme(tmTheme));
|
var styles = extractStyles(theme);
|
||||||
fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".js", createTheme(name, styles, cssTemplate, jsTemplate));
|
theme = createTheme(name, styles, cssTemplate, jsTemplate)
|
||||||
|
fs.writeFileSync(__dirname + "/../lib/ace/theme/" + name + ".js", theme);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var name in themes)
|
||||||
|
convertTheme(name);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue