include all plugins in c9/core

pull/402/head
nightwing 2017-01-06 10:47:08 +00:00
rodzic 0e6c7b6642
commit 30a497b8f6
1560 zmienionych plików z 288086 dodań i 55 usunięć

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.automate

Wyświetl plik

@ -0,0 +1,289 @@
define(function(require, exports, module) {
main.consumes = ["Plugin", "c9"];
main.provides = ["automate"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var c9 = imports.c9;
var async = require("async");
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var namespaces = {};
/***** Methods *****/
function addCommand(ns, name, implementation) {
if (!namespaces[ns]) namespaces[ns] = { commands: {}, alias: {}};
namespaces[ns].commands[name] = implementation;
}
function removeCommand(ns, name) {
if (!namespaces[ns]) namespaces[ns] = { commands: {}, alias: {}};
delete namespaces[ns].commands[name];
}
function addCommandAlias(ns, name) {
if (!namespaces[ns]) namespaces[ns] = { commands: {}, alias: {}};
for (var i = 1; i < arguments.length; i++) {
namespaces[ns].alias[arguments[i]] = name;
}
}
function getCommand(ns, name) {
if (!namespaces[ns]) throw new Error("Unknown namespace: " + ns);
var cmd = namespaces[ns].commands;
return cmd[name] || cmd[namespaces[ns].alias[name]];
}
function createSession(ns) {
var session = new Plugin("Ajax.org", main.consumes);
var emit = session.getEmitter();
var tasks = [];
var output = "";
var lastProcess;
var lastTask;
var executing = false;
var aborting = false;
function task(task, options, validate) {
if (executing) throw new Error("Adding tasks while executing");
if (typeof options == "function" || options === undefined) {
if (!validate) validate = options;
options = {};
}
Object.defineProperty(task, "$options", {
enumerable: false,
configurable: false,
writable: false,
value: options
});
tasks.push(task);
}
function execute(tasks, callback, options) {
if (tasks.$options)
options = tasks.$options;
// Loop over all tasks or sub-tasks when called recursively
async.eachSeries(tasks, function(task, next) {
options = task.$options || options || {};
if (options.ignore)
return next();
// The task consists of multiple tasks
if (Array.isArray(task))
return execute(task, next, options);
// Loop over all competing tasks
async.eachSeries(Object.keys(task), function(type, next) {
var s = type.split(":");
if (s.length > 1)
s = { ns: s[0], type: s[1] };
if (type == "install") {
return execute(task[type], function(err) {
next(err || 1);
}, options);
}
var command = getCommand(s.ns || ns, s.type || type);
command.isAvailable(function(available) {
if (!available) return next();
var items = Array.isArray(task[type])
? task[type] : [task[type]];
// Loop over each of the tasks for this command
async.eachSeries(items, function(item, next) {
if (aborting)
return next(new Error("Aborted"));
emit("each", {
session: session,
task: task,
options: options,
type: type,
item: item
});
lastTask = task;
var onData = function(chunk, process) {
if (aborting) return process && process.end();
output += chunk;
lastProcess = process;
emit("data", { data: chunk, process: process });
};
var onFinish = function(err) {
if (err && err.code == "EDISCONNECT") {
c9.once("connect", function() {
command.execute(item, options, onData, onFinish);
});
return;
}
next(err);
};
command.execute(item, options, onData, onFinish);
}, function(err) {
next(err || 1);
});
});
}, function(err) {
// Success
if (err === 1) return next();
// Failure
if (err) return next(err);
// No command avialable
err = new Error("None of the available commands are available: "
+ JSON.stringify(task, 4, " "));
err.code = "ENOTAVAILABLE";
return next(err);
});
}, function(err) {
callback(err);
});
}
function run(callback) {
if (executing) return;
emit("run");
aborting = false;
executing = true;
execute(tasks, function(err) {
executing = false;
lastProcess = null;
callback && callback.apply(this, arguments);
session.unload();
emit("stop", err);
});
}
function abort(callback) {
aborting = true;
if (!executing) {
lastProcess = null;
emit("stop", new Error("Aborted"));
}
callback && callback();
}
// Make session a baseclass to allow others to extend
session.baseclass();
/**
*
**/
session.freezePublicAPI({
/**
*
*/
get tasks() { return tasks; },
/**
*
*/
get executing() { return executing; },
/**
*
*/
get output() { return output; },
/**
*
*/
get process() { return lastProcess || null; },
/**
*
*/
get lastTask() { return lastTask || null; },
/**
*
*/
task: task,
/**
*
*/
run: run,
/**
*
*/
abort: abort
});
return session;
}
/***** Lifecycle *****/
plugin.on("load", function() {
});
plugin.on("unload", function() {
});
/***** Register and define API *****/
/**
*
**/
plugin.freezePublicAPI({
/**
*
*/
createSession: createSession,
/**
*
*/
addCommand: addCommand,
/**
*
*/
removeCommand: removeCommand,
/**
*
*/
addCommandAlias: addCommandAlias
});
register(null, {
automate: plugin
});
}
});

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.automate",
"description": "The repository for c9.automate",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.automate.git"
},
"plugins": {
"automate": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.emmet

Wyświetl plik

@ -0,0 +1,127 @@
define(function(require, exports, module) {
"use strict";
main.consumes = [
"Plugin", "commands", "menus", "ace"
];
main.provides = ["emmet"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var commands = imports.commands;
var menus = imports.menus;
var emmetExt = require("ace/ext/emmet");
emmetExt.setCore("lib/emmet/emmet");
emmetExt.updateCommands = function() {};
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
var keymap = {
expand_abbreviation: { mac: "ctrl+alt+e", win: "ctrl+alt+e" },
match_pair_outward: {}, // {mac: "ctrl+d", win: "ctrl+,"},
match_pair_inward: {}, // {mac: "ctrl+j", win: "ctrl+shift+0"},
matching_pair: {}, // {mac: "ctrl+alt+j", win: "alt+j"},
next_edit_point: {}, // "alt+right",
prev_edit_point: {}, // "alt+left",
toggle_comment: {}, // {mac: "command+/", win: "ctrl+/"},
split_join_tag: {}, // {mac: "shift+command+'", win: "shift+ctrl+`"},
remove_tag: {}, // {mac: "command+'", win: "shift+ctrl+;"},
evaluate_math_expression: { mac: "shift+command+y", win: "shift+ctrl+y" },
increment_number_by_1: {}, // "ctrl+up",
decrement_number_by_1: {}, // "ctrl+down",
increment_number_by_01: {}, // "alt+up",
decrement_number_by_01: {}, // "alt+down",
increment_number_by_10: {}, // {mac: "alt+command+up", win: "shift+alt+up"},
decrement_number_by_10: {}, // {mac: "alt+command+down", win: "shift+alt+down"},
select_next_item: { mac: "shift+command+.", win: "shift+ctrl+." },
select_previous_item: { mac: "shift+command+,", win: "shift+ctrl+," },
reflect_css_value: {}, // {mac: "shift+command+r", win: "shift+ctrl+r"},
// encode_decode_data_url: {}, // {mac: "shift+ctrl+d", win: "ctrl+'"},
// update_image_size: {mac: "shift+ctrl+i", win: "ctrl+u"},
// expand_as_you_type: "ctrl+alt+enter",
// wrap_as_you_type: {mac: "shift+ctrl+g", win: "shift+ctrl+g"},
expand_abbreviation_with_tab: { mac: "Tab", win: "Tab" },
wrap_with_abbreviation: { mac: "shift+ctrl+a", win: "shift+ctrl+a" }
};
for (var i in keymap) {
commands.addCommand({
name: "emmet_" + i,
action: i,
group: "emmet",
bindKey: keymap[i],
exec: emmetExt.runEmmetCommand,
isAvailable: isAvailable,
findEditor: findEditor
}, plugin);
}
}
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
// TODO add menu items?
emit("draw");
}
/***** Methods *****/
function isAvailable(editor, args, event) {
if (!editor || !editor.ace) return false;
// using this instead of editor.type == "ace" to make
// commands avaliable in editors inheriting from ace
if (event instanceof KeyboardEvent && (!editor.ace.isFocused()))
return false;
return emmetExt.isAvailable(editor.ace, this.name);
}
function findEditor(editor) {
if (editor && editor.ace)
return editor.ace;
return editor;
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
drawn = false;
});
/***** Register and define API *****/
/**
*
**/
plugin.freezePublicAPI({
});
register(null, {
emmet: plugin
});
}
});

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.emmet",
"description": "The repository for c9.ide.ace.emmet, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.emmet.git"
},
"plugins": {
"emmet": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.gotoline

Wyświetl plik

@ -0,0 +1,403 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "c9", "settings", "ui",
"anims", "menus", "commands", "util", "tabManager"
];
main.provides = ["ace.gotoline"];
return main;
// @todo add commands for list navigation and bookmarking
// @todo fix pasting of line numbers
function main(options, imports, register) {
var c9 = imports.c9;
var Plugin = imports.Plugin;
var settings = imports.settings;
var ui = imports.ui;
var anims = imports.anims;
var util = imports.util;
var menus = imports.menus;
var commands = imports.commands;
var tabs = imports.tabManager;
var skin = require("text!./skin.xml");
var markup = require("text!./gotoline.xml");
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var originalLine, originalColumn, control, lastLine, lineControl;
var nohide, originalPath;
var win, input, list, model; // ui elements
var loaded = false, changed = false;
function load() {
if (loaded) return false;
loaded = true;
model = new ui.model();
menus.addItemByPath("Goto/Goto Line...", new apf.item({
caption: "Goto Line...",
hint: "enter a line number and jump to it in the active document",
command: "gotoline"
}), 200, plugin);
commands.addCommand({
name: "gotoline",
bindKey: { mac: "Command-L", win: "Ctrl-G" },
isAvailable: function(editor) {
return editor && editor.type == "ace";
},
exec: function() {
gotoline();
}
}, plugin);
commands.addCommand({
name: "hideGotoLine",
group: "ignore",
bindKey: { mac: "ESC", win: "ESC" },
isAvailable: function(editor) { return win && win.visible; },
exec: function() {
hide();
var tab = tabs.focussedTab;
tab && tabs.focusTab(tab);
if (originalLine) {
execGotoLine(originalLine, originalColumn, true);
originalPath = originalColumn = originalLine = undefined;
}
}
}, plugin);
settings.on("read", function() {
var lines = settings.getJson("state/gotoline") || [];
var xml = "";
for (var i = 0, l = lines.length; i < l; i += 2) {
xml += "<line nr='" + lines[i] + "' />";
}
model.load("<lines>" + xml + "</lines>");
}, plugin);
settings.on("write", function() {
if (changed) {
var nodes = model.data.childNodes;
var lines = [];
for (var i = 0, l = Math.min(20, nodes.length); i < l; i++) {
lines.push(nodes[i].getAttribute("nr"));
}
settings.setJson("state/gotoline", lines);
}
}, plugin);
}
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
// Import Skin
ui.insertSkin({
name: "gotoline",
data: skin,
"media-path": options.staticPrefix + "/images/"
}, plugin);
// Create UI elements
ui.insertMarkup(null, markup, plugin);
win = plugin.getElement("window");
input = plugin.getElement("input");
list = plugin.getElement("list");
list.setAttribute("model", model);
list.addEventListener("afterchoose", function() {
if (list.selected) {
execGotoLine(parseInt(list.selected.getAttribute("nr"), 10));
}
else {
execGotoLine();
}
});
list.addEventListener("afterselect", function() {
if (!list.selected)
return;
var line = list.selected.getAttribute("nr");
input.setValue(line);
// Focus the list
list.focus();
// Go to the right line
execGotoLine(null, null, true);
});
var restricted = [38, 40, 36, 35];
list.addEventListener("keydown", function(e) {
if (e.keyCode == 13 && list.selected) {
return false;
}
else if (e.keyCode == 38) {
if (list.selected == list.getFirstTraverseNode()) {
input.focus();
list.clearSelection();
}
}
else if (restricted.indexOf(e.keyCode) == -1)
input.focus();
}, true);
input.addEventListener("keydown", function(e) {
var NotANumber = (e.keyCode > 57 || e.keyCode == 32)
&& (e.keyCode < 96 || e.keyCode > 105);
if (e.keyCode == 13) {
execGotoLine();
return false;
}
else if (e.keyCode == 40) {
var first = list.getFirstTraverseNode();
if (first) {
list.select(first);
list.$container.scrollTop = 0;
list.focus();
}
}
else if (NotANumber && !e.metaKey && !e.ctrlKey && !e.altKey) {
return false;
}
// Numbers & Cmd-V / Cmd-C
if (!NotANumber || (e.metaKey || e.ctrlKey)
&& (e.keyCode == 86 || e.keyCode == 88)) {
setTimeout(function() {
execGotoLine(null, null, true);
}, 10);
}
});
win.addEventListener("blur", function(e) {
if (!ui.isChildOf(win, e.toElement))
hide();
});
input.addEventListener("blur", function(e) {
if (!ui.isChildOf(win, e.toElement))
hide();
});
emit("draw");
}
/***** Methods *****/
function show(noanim) {
var tab = tabs.focussedTab;
var editor = tab && tab.editor;
if (!editor || editor.type != "ace") return;
var ace = editor.ace;
var aceHtml = ace.container;
var cursor = ace.getCursorPosition();
originalLine = cursor.row + 1;
originalColumn = cursor.column;
originalPath = tab.path;
//Set the current line
input.setValue(input.getValue() || cursor.row + 1);
//Determine the position of the window
var pos = ace.renderer.textToScreenCoordinates(cursor.row, cursor.column);
var epos = ui.getAbsolutePosition(aceHtml.parentNode);
var maxTop = aceHtml.offsetHeight - 100;
var top = Math.max(0, Math.min(maxTop, pos.pageY - epos[1] - 5));
var left = 0;
ace.container.parentNode.appendChild(win.$ext);
win.show();
win.$ext.style.top = top + "px";
//Animate
if (!noanim && settings.getBool('user/general/@animateui')) {
win.setWidth(0);
anims.animate(win, {
width: "60px",
duration: 0.15,
timingFunction: "cubic-bezier(.11, .93, .84, 1)"
}, function() {
win.$ext.style.left = left + "px";
});
}
else {
win.setWidth(60);
}
input.focus();
}
function hide() {
if (nohide) return;
if (settings.getBool('user/general/@animateui')) {
anims.animate(win, {
width: "0px",
duration: 0.15,
timingFunction: "cubic-bezier(.10, .10, .25, .90)"
}, function() {
win.hide();
});
}
else {
win.hide();
}
}
function gotoline(force) {
draw();
if (control && control.stop)
control.stop();
var tab = tabs.focussedTab;
var editor = tab && tab.editor;
if (!editor || editor.type != "ace")
return;
if (force != 2 && !win.visible || force == 1)
show();
else
hide();
return false;
}
function execGotoLine(line, column, preview) {
var tab = tabs.focussedTab && tabs.focussedTab;
var editor = tab && tab.editor;
if (!editor || editor.type != "ace") return;
var ace = editor.ace;
var aceHtml = ace.container;
if (typeof line != "number")
line = parseInt(input.getValue(), 10) || 0;
// I don't know why this if was here. It caused a bug where if the
// line target was already in view, it wouldn't jump to it.
// if (!lastLine || lastLine != line || !ace.isRowFullyVisible(line)) {
ace.gotoLine(line, column);
lastLine = line;
// }
if (typeof preview != "undefined") {
var animate = settings.getBool("user/ace/@animatedScroll");
if (!animate)
return;
var cursor = ace.getCursorPosition();
var renderer = ace.renderer;
var pos = renderer.textToScreenCoordinates(cursor.row, cursor.column);
var maxTop = renderer.$size.height - win.getHeight() - 10;
var epos = ui.getAbsolutePosition(aceHtml);
var sm = renderer.scrollMargin;
var scrollTop = ace.session.getScrollTop();
scrollTop = Math.max(-sm.top, Math.min(scrollTop,
renderer.layerConfig.maxHeight - renderer.$size.scrollerHeight + sm.v));
var top = Math.min(pos.pageY - epos[1] - 2
+ renderer.scrollTop - scrollTop, maxTop);
if (lineControl)
lineControl.stop();
//Animate
anims.animate(win, {
top: top + "px",
duration: 0.25,
timingFunction: "cubic-bezier(.11, .93, .84, 1)"
}, function() {
win.$ext.style.left = "0px";
});
}
else {
//win.hide();
hide();
var lineNode = model.queryNode("line[@nr='" + line + "']");
if (!lineNode) {
lineNode = ui.n("<line />")
.attr("nr", line)
.node();
}
var pNode = model.data;
if (lineNode != pNode.firstChild) {
apf.xmldb.appendChild(pNode, lineNode, pNode.firstChild);
changed = true;
settings.save();
}
tabs.focusTab(tab);
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
* The goto line dialog for ace editors. The goto line dialog allows
* users to jump to a line in a file. It has a history of all lines
* that were jumped to before. Users can navigate this list and press
* ESC to return to their original position.
*
* @singleton
**/
plugin.freezePublicAPI({
/**
* Jump to a line and column in the focussed tab.
* @param {Number} line The line to jump to.
* @param {Number} column The column to jump to.
* @param {Boolean} preview Whether to keep the original location in memory.
*/
gotoline: function(line, column, preview) {
gotoline(1);
return execGotoLine(line, column, preview);
},
/**
* Show the goto line dialog
*/
show: function() { gotoline(1); },
/**
* Hide the goto line dialog
*/
hide: function() { gotoline(2); }
});
register(null, {
"ace.gotoline": plugin
});
}
});

Wyświetl plik

@ -0,0 +1,22 @@
<?xml version='1.0'?>
<a:application xmlns:a="http://ajax.org/2005/aml">
<a:bar id="window"
skinset = "gotoline"
visible = "false"
width = "60"
height = "90"
left = "0"
zindex = "100000"
style = "overflow:hidden">
<a:vbox top="0" right="0" bottom="0" width="61" padding="0" edge="5">
<a:textbox id="input" focusselect="true" />
<a:list id="list"
flex = "1"
caption = "[@nr]"
each = "[line]"
autoselect = "false"
multiselect = "false"
empty-message = "empty" />
</a:vbox>
</a:bar>
</a:application>

Wyświetl plik

@ -0,0 +1,191 @@
/*global describe it before after apf bar */
"use client";
require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai) {
var expect = chai.expect;
expect.setupArchitectTest([
{
packagePath: "plugins/c9.core/c9",
workspaceId: "ubuntu/ip-10-35-77-180",
startdate: new Date(),
debug: true,
hosted: true,
local: false,
davPrefix: "/"
},
"plugins/c9.core/ext",
"plugins/c9.core/http-xhr",
"plugins/c9.core/util",
{
packagePath: "plugins/c9.core/settings",
settings: { user: { general: { animateui: true }}}
},
"plugins/c9.core/api.js",
"plugins/c9.ide.ui/lib_apf",
"plugins/c9.ide.ui/anims",
"plugins/c9.ide.ui/menus",
{
packagePath: "plugins/c9.ide.ui/ui",
staticPrefix: "plugins/c9.ide.ui"
},
"plugins/c9.ide.editors/document",
"plugins/c9.ide.editors/undomanager",
{
packagePath: "plugins/c9.ide.editors/editors",
defaultEditor: "ace"
},
"plugins/c9.ide.editors/editor",
"plugins/c9.ide.editors/tabmanager",
"plugins/c9.ide.ui/focus",
"plugins/c9.ide.editors/pane",
"plugins/c9.ide.editors/tab",
"plugins/c9.ide.ace/ace",
{
packagePath: "plugins/c9.ide.ace.gotoline/gotoline",
staticPrefix: "plugins/c9.ide.ace.gotoline"
},
"plugins/c9.ide.keys/commands",
"plugins/c9.fs/proc",
"plugins/c9.vfs.client/vfs_client",
"plugins/c9.vfs.client/endpoint",
"plugins/c9.ide.auth/auth",
"plugins/c9.fs/fs",
// Mock plugins
{
consumes: ["tabManager", "ace", "settings"],
provides: [],
setup: main
}
], architect);
function main(options, imports, register) {
var tabs = imports.tabManager;
var ace = imports.ace;
function getTabHtml(tab) {
return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
}
expect.html.setConstructor(function(tab) {
if (typeof tab == "object")
return tab.$ext;
});
describe('gotoline', function() {
before(function(done) {
apf.config.setProperty("allow-select", false);
apf.config.setProperty("allow-blur", false);
bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
bar.$ext.style.position = "fixed";
bar.$ext.style.left = "20px";
bar.$ext.style.right = "20px";
bar.$ext.style.bottom = "20px";
bar.$ext.style.height = "33%";
imports.settings.set("user/ace/@animatedscroll", "true");
document.body.style.marginBottom = "33%";
tabs.once("ready", function() {
tabs.getPanes()[0].focus();
done();
});
});
describe("open", function() {
this.timeout(10000);
it('should open a pane with just an editor', function(done) {
tabs.openFile("/file.js", function(err, tab) {
setTimeout(function() {
expect(tabs.getTabs()).length(1);
// var sb = tab.document.getSession().statusBar;
// var bar = sb.getElement("bar");
// expect.html(bar, "rowcol").text("1:1");
//
// tab.document.editor.ace.selectAll();
// setTimeout(function(){
// expect.html(bar, "rowcol sel").text("2:1");
// expect.html(bar, "sel").text("23 Bytes");
//
// done();
// }, 100);
done();
}, 50);
});
});
it('should handle multiple documents in the same pane', function(done) {
tabs.openFile("/listing.json", function(err, tab) {
setTimeout(function() {
expect(tabs.getTabs()).length(2);
tab.activate();
// setTimeout(function(){
// var sb = tab.document.getSession().statusBar;
// expect.html(sb.getElement("bar"), "caption").text("1:1");
done();
// }, 100);
});
});
});
});
describe("split(), pane.unload()", function() {
it('should split a pane horizontally, making the existing pane the left one', function(done) {
var pane = tabs.focussedTab.pane;
var righttab = pane.hsplit(true);
tabs.focussedTab.attachTo(righttab);
done();
// setTimeout(function(){
// expect.html(pane.aml, "pane").text("2:1");
// expect.html(righttab.aml, "righttab").text("1:1");
//done();
// }, 100);
});
// it('should remove the left pane from a horizontal split', function(done) {
// var pane = tabs.getPanes()[0];
// var tab = tabs.getPanes()[1].getTab();
// pane.unload();
// expect(tabs.getPanes()).length(1);
// expect(tabs.getTabs()).length(2);
// tabs.focusTab(tab);
// done();
// });
});
// describe("Change Theme", function(){
// this.timeout(10000);
//
// it('should change a theme', function(done) {
// var editor = tabs.focussedTab.editor;
// ace.on("themeInit", function setTheme(){
// ace.off("theme.init", setTheme);
// expect.html(getTabHtml(tabs.focussedTab).childNodes[1]).className("ace-monokai");
// editor.setOption("theme", "ace/theme/textmate");
// done();
// });
// editor.setOption("theme", "ace/theme/monokai");
// });
// });
// @todo test split api and menu
if (!onload.remain) {
after(function(done) {
tabs.unload();
document.body.style.marginBottom = "";
done();
});
}
});
onload && onload();
}
});

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 990 B

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.gotoline",
"description": "The repository for c9.ide.ace.gotoline, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.gotoline.git"
},
"plugins": {
"gotoline": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,186 @@
<?xml version='1.0'?>
<a:skin xmlns:a="http://ajax.org/2005/aml" xmlns="http://www.w3.org/1999/xhtml">
<a:list name="list">
<a:style><![CDATA[
.gotolinelist{
overflow: hidden;
position: relative;
border-style: solid;
.gradient(~"@{gotoline-list-background}");
color: @gotoline-list-color;
border-color: @gotoline-list-border-color;
border-width: @gotoline-list-border-width;
border-radius: @gotoline-list-border-radius;
margin: 0;
outline: none;
font-family: Tahoma;
font-size: 12px;
text-overflow: ellipsis;
cursor: default;
text-align: right;
}
.dark .gotolinelist{
.gradient(~"@{gotoline-list-background-dark}");
color: @gotoline-list-color-dark;
border-color: @gotoline-list-border-color-dark;
border-width: @gotoline-list-border-width-dark;
border-radius: @gotoline-list-border-radius-dark;
}
.gotolinelist>.selected{
background-color: @gotoline-list-selected-background;
color: #e7e7e7;
}
.dark .gotolinelist>.selected{
background-color: @gotoline-list-selected-background-dark;
}
.gotolinelistFocus>.selected{
color : #e7e7e7;
}
.gotolinelist .empty, .gotolinelist .offline, .gotolinelist .loading{
text-align: center;
padding: 8px 0 0 0;
color: #777;
font-size : 8pt;
font-weight : normal;
}
.gotolinelist>DIV{
padding: 2px 6px;
}
]]></a:style>
<a:presentation>
<a:main container=".">
<div class='gotolinelist'>
</div>
</a:main>
<a:item
class = "."
container = "."
caption = "."
select = "."
>
<div> </div>
</a:item>
<a:empty caption=".">
<div class="message">-</div>
</a:empty>
</a:presentation>
</a:list>
<a:bar name="bar">
<a:style><![CDATA[
.barGotoline{
position : absolute;
background-color: @gotoline-background;
border-radius: @gotoline-border-radius;
box-shadow: @gotoline-box-shadow;
border: @gotoline-border;
border-left: 0;
width : 20px;
left : -100px;
}
.dark .barGotoline{
background-color: @gotoline-background-dark;
box-shadow: @gotoline-box-shadow-dark;
border: @gotoline-border-dark;
border-left: 0;
}
.brGtlContent {
}
.barGotoline .brGtlTop {
background: url(images/barGotoLineCorners.png) no-repeat 0 0;
height: 3px;
width: 4px;
position: absolute;
top: -3px;
left:0;
}
.barGotoline .brGtlBottom {
background: url(images/barGotoLineCorners.png) no-repeat 0 -3px;
height: 3px;
width: 4px;
position: absolute;
bottom: -3px;
left:0;
}
]]></a:style>
<a:presentation>
<a:main container=".">
<div class="barGotoline">
<div class="brGtlTop"></div>
<div class="brGtlBottom"></div>
</div>
</a:main>
</a:presentation>
</a:bar>
<a:textbox name="textbox">
<a:style><![CDATA[
.tbGotoline {
position : relative;
height : 25px;
}
.tbGotoline .sbtb_middle {
height : 15px;
padding : 2px 5px 2px 5px;
background-color: #ffffff;
.gradient(~"linear-gradient(center bottom,rgb(255,255,255) 50%,rgb(235,235,235) 100%)");
color: #0471cf;
margin: 0;
outline: none;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;
font-size: 12px;
text-overflow: ellipsis;
border-style: solid;
border-color: @gotoline-input-border-color;
border-width: @gotoline-input-border-width;
border-radius: @gotoline-input-border-radius;
box-shadow: @gotoline-input-box-shadow;
}
.dark .tbGotoline .sbtb_middle{
border-color: @gotoline-input-border-color-dark;
border-width: @gotoline-input-border-width-dark;
border-radius: @gotoline-input-border-radius-dark;
box-shadow: @gotoline-input-box-shadow-dark;
}
.tbGotoline .sbtb_middle INPUT {
border : 0;
height : 14px;
font-size : 12px;
color : #0471cf;
font-family : 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;
outline : none;
background-color : transparent;
width: 100%;
text-align: center;
}
.tbGotolineInitial .sbtb_middle INPUT {
color : #0471cf;
}
.tbGotolineDisabled .sbtb_middle INPUT {
color : #0471cf;
}
.tbGotolineDisabled .sbtb_middle{
background: linear-gradient(center bottom,rgb(235,235,235) 0%,rgb(255,255,255) 40%);
cursor : default;
}
]]></a:style>
<a:presentation>
<a:main input="div[1]/input">
<div class="tbGotoline">
<div class="sbtb_middle">
<input type="text" />
</div>
</div>
</a:main>
</a:presentation>
</a:textbox>
</a:skin>

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.keymaps

Wyświetl plik

@ -0,0 +1,803 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "ui", "layout", "commands", "fs", "navigate", "save",
"tabbehavior", "ace", "commands", "tabManager"
];
main.provides = ["vim.cli"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var commands = imports.commands;
var layout = imports.layout;
var fs = imports.fs;
var navigate = imports.navigate;
var save = imports.save;
var tabbehavior = imports.tabbehavior;
var tabManager = imports.tabManager;
var ace = imports.ace;
var Editor = require("ace/editor").Editor;
var lang = require("ace/lib/lang");
var pathLib = require("path");
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var cmdLine;
var searchStore = {
current: "",
options: {
needle: "",
backwards: false,
wrap: true,
caseSensitive: false,
wholeWord: false,
regExp: false
}
};
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
}
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
cmdLine = new apf.codebox();
layout.findParent(plugin).appendChild(cmdLine);
cmdLine.setHeight(23);
cmdLine.$ext.className = "searchbox tb_console vimInput";
updateTheme();
initCmdLine(cmdLine.ace);
ace.on("themeChange", updateTheme, plugin);
emit("draw");
}
function updateTheme() {
if (!cmdLine)
return;
var activeTheme = ace.theme; // themes.getActiveTheme();
if (!activeTheme)
return;
cmdLine.ace.setTheme(activeTheme);
var htmlNode = cmdLine.ace.container.parentNode;
var style = htmlNode.style;
style.background = activeTheme.bg;
activeTheme.isDark
? ui.setStyleClass(htmlNode, "dark")
: ui.setStyleClass(htmlNode, "", ["dark"]);
}
function show() {
draw();
layout.setFindArea(cmdLine, { isDefault: true });
}
function hide() {
if (cmdLine) {
layout.setFindArea(null, { isDefault: true });
}
}
function toggle(force, a, b, callback) {
if (force == -1)
hide();
else
show();
callback && callback();
}
/***** Methods *****/
var cliCmds = {};
cliCmds.ascii = {
name: "ascii",
description: "",
exec: function(editor) {
var onSelectionChange = lang.delayedCall(function(e) {
var c = editor.getCursorPosition();
var ch = editor.session.getLine(c.row)[c.column - 1] || "\n";
var code = ch.charCodeAt(0);
var msg = JSON.stringify(ch).slice(1, -1) + "=" + " ";
var str = code.toString(16);
str = [, "\\x0", "\\x", "\\u0", "\\u"][str.length] + str;
msg += str + " ";
msg += "\\" + code.toString(8) + " ";
msg += "&#" + code + ";";
editor.cmdLine.setMessage(msg);
clear.delay(2000);
});
var clear = lang.delayedCall(function(e) {
editor.removeListener(editor.asciiMessageListener);
editor.asciiMessageListener = null;
editor.cmdLine.setMessage("");
});
if (editor.asciiMessageListener) {
return clear.call();
}
editor.on("changeSelection", editor.asciiMessageListener = function() {
onSelectionChange.schedule(200);
});
onSelectionChange.call();
}
};
cliCmds.set = {
name: "set",
description: "set editor option",
exec: function(editor, args) {
var cmd = args.text.split(" ");
var optName = cmd[1];
var optValue = parseOption(cmd[2]);
editor.setOption(optName, optValue);
},
getCompletions: function() {
return Object.keys(Editor.prototype.$options);
}
};
function parseOption(optValue) {
if (/^\d+$/.test(optValue))
optValue = parseInt(optValue, 10);
if (/^[\d.\^e]+$/.test(optValue))
optValue = parseFloat(optValue);
else if (/^(true|false)$/i.test(optValue))
optValue = optValue.length = 4;
return optValue;
}
cliCmds["/"] = {
name: "/",
history: [],
cliExec: function(ed, data) { }
};
cliCmds["?"] = {
name: "?",
history: cliCmds["/"].history,
cliExec: cliCmds["/"].cliExec
};
cliCmds[":"] = {
name: ":",
history: [],
getCompletions: function() {
return Object.keys(this.commands).concat(Object.keys(commands.commands));
}
};
cliCmds[":"].commands = {
w: function(editor, data, callback) {
var tab = tabManager.focussedTab;
if (!tab || !tab.path)
return;
var lines = editor.session.getLength();
if (data.argv.length === 2 && data.argv[1]) {
var path = pathLib.join(pathLib.dirname(tab.path), data.argv[1]);
save.save(tab, { path: path }, function(err) {
if (!err)
editor.cmdLine.setTimedMessage(path + " [New] " + lines + "L, ##C written to ");
callback && callback();
});
}
else {
save.save(tab, {}, function(err) {
if (!err)
editor.cmdLine.setTimedMessage(tab.path + " " + lines + "L, ##C written");
callback && callback();
});
}
},
e: function(editor, data) {
var path = data.argv[1];
if (!path) {
navigate.show();
return false;
}
else {
var currentPath = tabManager.focussedTab && tabManager.focussedTab.path || "/";
path = pathLib.join(pathLib.dirname(currentPath), data.argv[1]);
fs.exists(path, function(exists) {
if (exists) {
tabManager.openFile(path, { focus: true }, function() {});
}
else {
tabManager.open({
path: path,
focus: true,
document: {
meta: {
newfile: true,
cli: true
}
}
});
}
});
}
},
x: function(editor, data) {
var page = tabManager.focussedTab;
if (!page)
return;
if (page.document.changed) {
cliCmds[":"].commands.wq(editor, data);
return;
}
else {
cliCmds[":"].commands.q();
}
},
wq: function(editor, data) {
cliCmds[":"].commands.w(editor, data, function() {
cliCmds[":"].commands.q();
});
},
wa: function(editor, data) {
commands.exec("saveall");
},
q: function(editor, data) {
var page = tabManager.focussedTab;
if (!page) return;
if (data && data.force)
page.document.undoManager.bookmark();
page.close();
},
"q!": function() {
cliCmds[":"].commands.q(null, { force: true });
},
tabn: "gototabright",
tabp: "gototableft",
tabfirst: function() {
tabbehavior.cycleTab("first", { editorType: "ace" });
},
tablast: function() {
tabbehavior.cycleTab("last", { editorType: "ace" });
},
tabnew: function(editor, data) {
var path = data.argv[1];
if (!path) {
tabManager.open({
path: "",
document: {
meta: {
newfile: true
}
},
focus: true
});
}
else {
cliCmds[":"].commands.e(editor, data);
}
},
tabclose: "closetab",
tabmove: function(editor, data) {
// todo
},
ascii: cliCmds.ascii,
sort: function(editor, data) {
commands.exec("sortlines");
},
};
// aliases
cliCmds[":"].commands["tab drop"] = cliCmds[":"].commands.e;
cliCmds[":"].commands.write = cliCmds[":"].commands.w;
cliCmds[":"].commands.tabNext = cliCmds[":"].commands.tabn;
cliCmds[":"].commands.tabPrevious = cliCmds[":"].commands.tabp;
cliCmds[":"].commands.tabc = cliCmds[":"].commands.tabclose;
cliCmds[":"].commands.set = {
vimOpts: [
"cursorline", "cul", "nocursorline", "nocul", //, "highlightActiveLine",
"expandtab", "et", "noexpandtab", "noet", //"useSoftTabs",
"number", "nu", "nonumber", "nonu" // "showGutter"
// ["relativenumber", "rnu", "norelativenumber", "nornu"]
// 'softtabstop' 'sts' number
// 'tabstop' 'ts' number
],
exec: function(ed, args) {
var optName = args.argv[1];
var optval = optName.slice(0, 2) != "no";
if (optName[optName.length - 1] == "!") {
var toggle = true;
optName = optName.slice(0, -1);
}
var i = this.vimOpts.indexOf(optName);
if (i == -1) {
ed.cmdLine.setTimedMessage("Unrecognised option '" + optName + "'.", 1500);
return;
} else if (i < 4) {
optName = "highlightActiveLine";
} else if (i < 8) {
optName = "useSoftTabs";
} else if (i < 12) {
optName = "showGutter";
}
if (toggle)
optval = !ed.getOption(optName);
ed.setOption(optName, optval);
},
getCompletions: function(e) {
return this.vimOpts; //.concat(Object.keys(Editor.prototype.$options));
}
};
cliCmds[":"].commands.syntax = commands.commands.syntax;
cliCmds[":"].cliExec = function(ed, cmd, tokens) {
var last = tokens[tokens.length - 1];
if (last && last.type == "invisible")
cmd += last.value;
cmd = cmd.substr(1).trim();
var args = cmd.split(/\s+/);
cmd = args[0];
if (this.commands[cmd]) {
cmd = this.commands[cmd];
if (typeof cmd == "string")
return commands.exec(cmd, null, { argv: args });
else if (typeof cmd == "function")
return cmd(ed, { argv: args });
else if (cmd.exec)
return cmd.exec(ed, { argv: args });
}
else if (commands.commands[cmd]) {
commands.exec(cmd, null, { argv: args });
}
else if (/^\d+$/.test(cmd)) {
ed.gotoLine(cmd, 0, true);
}
else {
ed.cmdLine.setTimedMessage("Vim command '"
+ cmd + "' not implemented.", 1500);
}
};
var allCommands;
function getCompletions(command) {
if (command) {
if (command.getCompletions)
return command.getCompletions() || [];
if (command.commands)
return Object.keys(command.commands);
return [];
}
if (!allCommands) {
allCommands = Object.keys(commands.commands)
.concat(Object.keys(cliCmds));
}
return allCommands;
}
function getCommand(name, root) {
if (root && root.commands && root.commands[name])
return root.commands[name];
if (root)
return root;
return cliCmds[name] || commands.commands[name];
}
function getActiveEditor() {
var tab = tabManager.focussedTab;
if (tab && tab.editorType == "ace")
return tab.editor.ace;
}
function processCommandParts(ed, tokens, text) {
for (var i = 0; i < tokens.length; i++) {
var tok = tokens[i];
var cmd = tok.command;
if (!cmd)
continue;
if (cmd.name !== tok.value) {
var next = tokens[i + 1];
if (!next || next.type !== "invisible")
continue;
}
if (cmd.cliExec)
return cmd.cliExec(ed, text, tokens);
else if (cmd.exec)
return cmd.exec(ed, {
argv: text.split(/\s+/),
text: text,
tokens: tokens
});
}
}
function endCommandInput(cmdLine) {
cmdLine.addToHistory();
cmdLine.setValue("");
var editor = getActiveEditor();
if (editor) editor.focus();
}
function initCmdLine(cmdLine) {
cmdLine.commands.addCommands([{
bindKey: "Shift-Return|Ctrl-Return|Alt-Return",
name: "insertNewLine",
exec: function(cmdLine) {
cmdLine.insert("\n");
},
}, {
bindKey: "Esc|Shift-Esc|Ctrl-[",
name: "cancel",
exec: function(cmdLine) {
endCommandInput(cmdLine);
}
}, {
bindKey: "Return",
name: "run",
exec: function run(cmdLine) {
var editor = cmdLine.editor || getActiveEditor();
var tokens = cmdLine.session.getTokens(0);
if (editor) editor.cmdLine = cmdLine;
processCommandParts(editor, tokens, cmdLine.getValue());
endCommandInput(cmdLine);
},
}, {
bindKey: "Tab",
name: "tabNext",
exec: function tabNext(ed) { tabCycle(ed, 1); },
}, {
bindKey: "Shift-Tab",
name: "tabPrevious",
exec: function tabPrevious(ed) { tabCycle(ed, -1); },
}, {
bindKey: "Right",
name: "arrowCompleteRight",
exec: function arrowCompleteRight(ed) {
var session = ed.session;
var col = ed.selection.isEmpty() ? ed.selection.lead.column : -1;
ed.navigateRight();
var tok = session.getTokenAt(0, col + 1);
if (col == ed.selection.lead.column && tok && tok.type == "invisible")
session.doc.insertInLine({ row: 0, column: col }, tok.value);
},
}, {
bindKey: "Up",
name: "Up",
exec: function(cmdLine) {cmdLine.navigateHistory(-1);},
}, {
bindKey: "Down",
name: "Down",
exec: function(cmdLine) {cmdLine.navigateHistory(1);},
}, {
bindKey: "Ctrl-Home|PageUp",
name: "firstInHistory",
exec: function(cmdLine) {cmdLine.navigateHistory(0);},
}, {
bindKey: "Ctrl-End|PageDown",
name: "lastInHistory",
exec: function(cmdLine) {cmdLine.navigateHistory();}
}]);
function tabCycle(ed, dir) {
var session = ed.session;
var range = ed.getSelectionRange();
var line = session.getLine(0);
var len = line.length;
if (range.end.column != len || !range.isEmpty()) {
ed.navigateLineEnd();
return;
}
if (!ed.$tabCycle) {
var tok = session.getTokenAt(0, len) || { value: "", type: "" };
var matches = session.getState(0);
if (matches == "start")
matches = getCompletions();
if (!matches)
return;
if (matches.length == 1 && tok.value == matches[0]) {
if (tok.command) {
matches = getCompletions(tok.command);
tok = { value: "", type: "" };
}
if (!matches)
return;
}
ed.$tabCycle = {
matches: matches,
index: tok.value == matches[0] ? 0 : -1,
start: len - tok.value.length
};
ed.commands.on("exec", function onExec(e) {
var name = e.command && e.command.name;
if (name !== "tabNext" && name !== "tabPrevious") {
ed.$tabCycle = null;
ed.commands.removeListener("exec", onExec);
}
});
}
var matches = ed.$tabCycle.matches;
var index = ed.$tabCycle.index;
var start = ed.$tabCycle.start;
index += dir;
index %= matches.length;
if (index < 0)
index = matches.length + index;
ed.$tabCycle.index = index;
var match = matches[index];
if (!match)
return;
var i = 0;
while (match[i] && match[i] == line[start + i])
i++;
start += i;
match = match.substr(i);
if (i === 0 && (/\w/.test(match[0]) && /\w/.test(line[start - 1])))
match = " " + match;
if (/\w$/.test(match))
match += " ";
range.start.column = start;
range.end.column = len;
session.replace(range, match);
if (ed.$tabCycle.matches.length == 1)
ed.$tabCycle = null;
}
cmdLine.history = [];
cmdLine.navigateHistory = function(dir) {
var cliCmd = this.getCurrentCommandWithHistory() || {};
var history = cliCmd.history || this.history;
var index = history.index;
var cmd = history[index] || "";
if (dir === 0) {
index = 0;
} else if (dir === null) {
index = history.length;
} else if (typeof dir == "number") {
index += dir;
if (index < 0)
index = 0;
if (index > history.length)
index = history.length;
}
cmd = history[index] || "";
if (cliCmd.history && cliCmd.name)
cmd = cliCmd.name + cmd;
// TODO keep history.lastTyped
this.setValue(cmd, 1);
history.index = index;
};
cmdLine.addToHistory = function(val) {
var cliCmd = this.getCurrentCommandWithHistory() || {};
var history = cliCmd.history || this.history;
val = val || this.getValue();
if (cliCmd.name && cliCmd.history)
val = val.substr(cliCmd.name.length);
if (val && val != history[history.index]) {
history.push(val);
history.index = history.length;
}
};
cmdLine.getCurrentCommand = function() {
var tokens = this.session.getTokens(0);
var tok = tokens[tokens.length - 1];
return tok && tok.command;
};
cmdLine.getCurrentCommandWithHistory = function() {
var tokens = this.session.getTokens(0);
for (var i = tokens.length; i--;) {
var tok = tokens[i];
if (tok && tok.command && tok.command.history)
return tok.command;
}
};
cmdLine.on("blur", function() {
cmdLine.renderer.$cursorLayer.element.style.opacity = 0;
if (!cmdLine.getValue()) {
cmdLine.renderer.content.style.visibility = "hidden";
cmdLine.$messageNode.style.display = "";
cmdLine.$inMessageMode = true;
cmdLine.$messageNode.textContent = cmdLine.$message || "";
}
});
cmdLine.on("focus", function() {
cmdLine.renderer.$cursorLayer.element.style.opacity = "";
cmdLine.renderer.content.style.visibility = "";
cmdLine.$messageNode.style.display = "none";
cmdLine.$inMessageMode = false;
});
cmdLine.commands.on("exec", function(e) {
if (!e.command)
return;
if (e.command.name == "insertstring") {
}
cmdLine.commands.lastCommandName = e.command.name;
});
cmdLine.session.bgTokenizer.$tokenizeRow = function(row) {
var line = this.doc.getLine(row);
var command = null;
var tokens = [];
function add(type, value) {
tokens.push({ type: type, value: value, command: command });
}
while (line.length) {
var names = getCompletions(command);
var matches = matchCommand(line, names);
if (!matches.length) {
add("text", line);
break;
}
var cur = matches[0];
command = getCommand(cur, command);
if (cur.length >= line.length) {
add("keyword", line);
add("invisible", cur.substring(line.length));
} else {
add("keyword", cur);
}
line = line.substr(cur.length);
var i = line.search(/\S|$/);
if (i > 0) {
add("text", line.substring(0, i));
line = line.substr(i);
if (!line.length)
matches = getCompletions(command);
}
}
this.lines[row] = tokens;
this.states[row] = matches;
return tokens;
};
function matchCommand(line, names) {
var matches = [];
names.forEach(function(name) {
if (name.length < line.length) {
var isMatch = line.lastIndexOf(name, 0) === 0;
if (isMatch && /\w/.test(name[name.length - 1]))
isMatch = !/\w/.test(line[name.length]);
} else {
var isMatch = name.lastIndexOf(line, 0) === 0;
}
if (isMatch)
matches.push(name);
});
return matches;
}
cmdLine.$messageNode = document.createElement("div");
cmdLine.$messageNode.style.cssText = "position:absolute;"
+ "opacity:0.8;padding:0 5px;top:0;font-size:11px";
cmdLine.container.appendChild(cmdLine.$messageNode);
cmdLine.$clearMessageDelayed = lang.delayedCall(function() {
cmdLine.setMessage("");
});
cmdLine.setTimedMessage = function(text, timeout) {
this.setMessage(text);
this.once("setMessage", function() {
cmdLine.$clearMessageDelayed.cancel();
});
cmdLine.$clearMessageDelayed.schedule(timeout || 2000);
};
cmdLine.setMessage = function(text, from) {
this._signal("setMessage", text);
this.$message = text;
if (this.$inMessageMode)
this.$messageNode.textContent = text;
};
if (!cmdLine.isFocused())
cmdLine._emit("blur");
cmdLine.commands.removeCommands(
["find", "gotoline", "findall", "replace", "replaceall"]);
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
*
**/
plugin.freezePublicAPI({
/**
* @ignore
*/
searchStore: searchStore,
/**
*
*/
get aml() { return cmdLine; },
/**
*
*/
get ace() { return cmdLine.ace; },
/**
*
*/
show: show,
/**
*
*/
hide: hide,
/**
*
*/
toggle: toggle
});
register(null, {
"vim.cli": plugin
});
}
});

Wyświetl plik

@ -0,0 +1,33 @@
define(function(require, exports, module) {
exports.showCli = true;
exports.aceKeyboardHandler = require("ace/keyboard/emacs").handler;
var keys = [{
bindKey: "C-x C-f",
name: "navigate"
}, {
bindKey: "C-x C-s",
name: "save"
}, {
bindKey: "C-x s",
name: "saveall"
}, {
bindKey: "C-x C-w",
name: "saveas"
}];
keys.forEach(function(item) {
exports.aceKeyboardHandler.bindKey(item.bindKey, {
name: item.name,
exec: ideCommand
});
});
// todo find a way to integrate ide commands with vim and emacs modes
exports.execIdeCommand = null;
function ideCommand() {
exports.execIdeCommand(this.name);
}
});

Wyświetl plik

@ -0,0 +1,255 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "ui", "ace", "menus", "settings", "vim.cli", "tabManager",
"commands", "c9", "tree", "dialog.error"
];
main.provides = ["keymaps"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var ace = imports.ace;
var menus = imports.menus;
var commands = imports.commands;
var tabManager = imports.tabManager;
var settings = imports.settings;
var cli = imports["vim.cli"];
var c9 = imports.c9;
var tree = imports.tree; // TODO: find a way to make dependency on tree optional
var showError = imports["dialog.error"].show;
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var currentMode, activeMode;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
var mnuKbModes = new ui.menu({
"onprop.visible": function(e) {
if (e.value) {
var value = settings.get("user/ace/@keyboardmode");
mnuKbModes.select(null, value);
}
}
});
menus.addItemByPath("Edit/~", new ui.divider(), 650, plugin);
menus.addItemByPath("Edit/Keyboard Mode/", mnuKbModes, 660, plugin);
var c = 1000;
["Default", "Vim", "Emacs", "Sublime"].forEach(function(label) {
menus.addItemByPath("Edit/Keyboard Mode/" + label, new ui.item({
type: "radio",
value: label.toLowerCase(),
onclick: function(e) {
setMode(mnuKbModes.getValue());
}
}), c += 100, plugin);
});
settings.on("read", function() {
settings.setDefaults("user/ace", [
["keyboardmode", "default"]
]);
var mode = settings.get("user/ace/@keyboardmode");
if (mode && mode != "default")
setMode(mode);
}, plugin);
settings.on("user/ace", function() {
var mode = settings.get("user/ace/@keyboardmode");
if (currentMode != mode)
setMode(mode);
}, plugin);
ace.on("create", function(e) { setMode(null, e); }, plugin);
setTimeout(checkHostileExtensions, 1000);
}
/***** Methods *****/
function setMode(mode, tab) {
if (!settings.model.loaded)
return;
if (!mode)
mode = settings.get("user/ace/@keyboardmode");
else if (currentMode != mode) {
currentMode = mode;
settings.set("user/ace/@keyboardmode", mode);
}
if (mode == "emacs" || mode == "vim" || mode == "sublime") {
mode = "plugins/c9.ide.ace.keymaps/" + mode + "/keymap";
} else {
mode = null;
}
if (mode)
require([mode], setKeymap);
else
setKeymap({});
function setKeymap(keymap) {
if (keymap.showCli)
cli.show();
else
cli.hide();
(tab ? [tab] : tabManager.getTabs()).forEach(function(tab) {
if (tab.editor && tab.editor.type == "ace") {
var editor = tab.editor.ace;
// Set Mode
editor.setKeyboardHandler(keymap.aceKeyboardHandler);
editor.showCommandLine = showCommandLine;
}
});
if (activeMode == mode)
return;
updateIdeKeymap(mode);
activeMode = mode;
}
}
function updateIdeKeymap(path) {
tree.once("ready", function() {
var kb = path ? require(path) : {};
tree.tree.keyBinding.setKeyboardHandler(kb.treeKeyboardHandler);
});
c9.once("ready", function() {
var allCommands = commands.commands;
Object.keys(allCommands).forEach(function(name) {
var cmd = allCommands[name];
if (cmd && cmd.originalBindKey)
cmd.bindKey = cmd.originalBindKey;
});
var kb = path ? require(path) : {};
if ("execIdeCommand" in kb)
kb.execIdeCommand = commands.exec;
if (kb.ideCommands) {
kb.ideCommands.forEach(function(x) {
commands.addCommand(x, plugin);
});
}
if (kb.editorCommands) {
kb.editorCommands.forEach(function(x) {
x.findEditor = findEditor;
x.isAvailable = isAvailableAce;
commands.addCommand(x, plugin);
});
}
if (kb.ideKeymap)
kb.ideKeymap.forEach(bindKey);
if (kb.editorKeymap)
kb.editorKeymap.forEach(bindKey);
commands.reset();
function bindKey(x) {
var cmd = allCommands[x.name];
if (cmd && x.bindKey) {
x.bindKey.mac = normalize(x.bindKey.mac);
x.bindKey.win = normalize(x.bindKey.win);
cmd.bindKey = x.bindKey;
}
}
function normalize(str) {
return str && str.replace(/(^|-| )(\w)/g, function(_, a, b) {
return a + b.toUpperCase();
});
}
});
}
function showCommandLine(val, options) {
if (!options) options = {};
cli.show();
this.cmdLine = cli.ace;
this.cmdLine.editor = this;
if (options.focus !== false) {
cli.aml.focus();
}
if (options.message != null) {
if (options.timeout)
cli.ace.setTimedMessage(options.message, options.timeout);
else
cli.ace.setMessage(options.message);
}
if (typeof val == "string")
this.cmdLine.setValue(val, 1);
}
function isAvailableAce(editor, args, event) {
if (!editor || !editor.ace) return false;
// using this instead of editor.type == "ace" to make
// commands avaliable in editors inheriting from ace
if (event instanceof KeyboardEvent && (!editor.ace.isFocused()))
return false;
return true;
}
function findEditor(editor) {
return editor && editor.ace || editor;
}
function checkHostileExtensions() {
var messages = [];
try {
var d = document.body.nextSibling;
if (d && d.shadowRoot && d.shadowRoot.querySelector
&& d.shadowRoot.querySelector("[class*=vimium]")) {
messages.push("Vimium breaks cloud9 keyboard shortcuts, please disable it on this site.");
}
} catch (e) {
}
if (messages.length)
showError(messages.join("\n"));
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
currentMode = activeMode = null;
loaded = false;
});
/***** Register and define API *****/
plugin.freezePublicAPI({
});
register(null, {
keymaps: plugin
});
}
});

Wyświetl plik

@ -0,0 +1,21 @@
{
"name": "c9.ide.ace.keymaps",
"description": "The repository for c9.ide.ace.keymaps, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.keymaps.git"
},
"plugins": {
"cli": {},
"keymaps": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,132 @@
var fs = require("fs");
var base = __dirname;
var commands = {};
fs.readdirSync(base).map(function(p) {
if (/.sublime-keymap/.test(p)) {
var a = eval(fs.readFileSync(base + "/" + p, "utf8"));
a.name = /\((\w+)\)/.exec(p)[1].toLowerCase();
if (a.name == "osx") a.name = "mac";
if (a.name == "windows") a.name = "win";
return a;
}
}).filter(Boolean).map(function(keyMap) {
keyMap.forEach(function(sublKey) {
var name = sublKey.command;
var args = sublKey.args ? JSON.stringify(sublKey.args) : "";
var id = name + args;
var o = commands[id] || (commands[id] = {
bindKey: {},
id: id,
name: name
});
var oldKey = o.bindKey[keyMap.name];
var newKey = convertKeys(sublKey.keys);
if (oldKey) {
if (oldKey.split("|").indexOf(newKey) == -1)
newKey = oldKey + "|" + newKey;
else
newKey = oldKey;
}
o.bindKey[keyMap.name] = newKey;
if (sublKey.context)
o.context = sublKey.context;
if (sublKey.args)
o.args = sublKey.args;
});
});
commands = Object.keys(commands).map(function(id) {
var cmd = commands[id];
delete cmd.id;
if (cmd.bindKey.linux && cmd.bindKey.win == cmd.bindKey.linux)
delete cmd.bindKey.linux;
return cmd;
}).sort(function(a, b) {
if (a.context && !b.context) return 1;
if (!a.context && b.context) return -1;
if (a.context && b.context) {
var astr = JSON.stringify(a.context);
var bstr = JSON.stringify(b.context);
if (astr > bstr) return 1;
if (astr < bstr) return -1;
}
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
if (a.args && !b.args) return 1;
if (!a.args && b.args) return -1;
}).filter(function(x) {
// filter out brace pairing commands as they are handled elsewhere
return !/^(["'\[\]{}()\/](\|["'\[\]{}()\/])*|(escape))$/.test(x.bindKey.mac);
}).filter(function(x) {
// filter out completion commands
return !/(^|_)completion($|_)/.test(x.name);
});
void function group() {
function nameCore(cmd) {
if (/bookmark/.test(cmd.name))
return "bookmark";
if (/(^|_)mark($|_)/.test(cmd.name))
return "mark";
var name = cmd.name.replace(/(de|in)crease|prev|next|left|right|upper|lower|un|all/g, "");
name = name.replace(/(^_*|_*$)/g, "");
return name;
}
for (var i = 0; i < commands.length; i++) {
var name = nameCore(commands[i]);
var nameParts = name.split("_");
for (var j = i + 1; j < commands.length; j++) {
var o = commands[j];
if (nameCore(o) == name) {
commands.splice(j, 1);
i++;
commands.splice(i, 0, o);
}
}
}
}();
var cmdString = JSON.stringify(commands, null, 4)
.replace(/\n {8}( +|(?=[}\]]))/g, " ")
.replace(/"(\w+)":/g, "$1:")
.replace(/(\[|\{) |(\S) (\]|\})/g, "$1$2$3")
.replace(/"\\""/g, "'\"'")
.replace(/},\s*{/g, "}, {")
.replace(/\[\s*{/g, "[{")
.replace(/}\s*]/g, "}]")
.replace(/^ {4}/gm, "");
fs.writeFileSync("keymap", cmdString, "utf8");
function convertKeys(sublKeys) {
var sublimeToAceKey = {
keypad0: "numpad0",
keypad1: "numpad1",
keypad2: "numpad2",
keypad3: "numpad3",
keypad4: "numpad4",
keypad5: "numpad5",
keypad6: "numpad6",
keypad7: "numpad7",
keypad8: "numpad8",
keypad9: "numpad9",
keypad_period: ".",
keypad_divide: "/",
forward_slash: "/",
keypad_multiply: "*",
keypad_minus: "-",
keypad_plus: "+",
keypad_enter: "numpadEnter",
equals: "=",
plus: "+",
super: "cmd"
};
return sublKeys.map(function(combo) {
return combo.split("+").map(function(key) {
return sublimeToAceKey[key] || key;
}).join("-");
}).join(" ");
}

Wyświetl plik

@ -0,0 +1,870 @@
define(function(require, exports, module) {
/* ide commands */
exports.ideKeymap = [
// fallback to c9 defaults
// {
// bindKey: {mac: "cmd-w", win: "ctrl-w|ctrl-f4"},
// name: "close"
// }, {
// bindKey: {mac: "cmd-shift-w", win: "ctrl-shift-w"},
// name: "close_window"
// }, {
// bindKey: {linux: "ctrl-q", mac: "cmd-q"},
// name: "exit"
// }, {
// bindKey: {mac: "cmd-n", win: "ctrl-n"},
// name: "new_file"
// },
// {
// bindKey: {mac: "cmd-o", win: "ctrl-o"},
// name: "newfile"
// }, {
// bindKey: {mac: "cmd-shift-s", win: "ctrl-shift-s"},
// name: "saveas"
// }, {
// bindKey: {mac: "cmd-s", win: "ctrl-s"},
// name: "save"
// }, {
// bindKey: {mac: "cmd-alt-s"},
// name: "saveall"
// }, {
// bindKey: {mac: "cmd-shift-n", win: "ctrl-shift-n"},
// name: "newWindow"
// },
{
// todo
bindKey: { mac: "cmd-ctrl-p", win: "ctrl-alt-p" },
name: "prompt_select_workspace"
}, {
bindKey: { mac: "cmd-shift-t", win: "ctrl-shift-t" },
name: "reopenLastTab"
},
{
bindKey: { mac: "f7|cmd-b", win: "f7|ctrl-b" },
name: "build"
}, {
bindKey: { mac: "cmd-shift-b", win: "ctrl-shift-b" },
name: "run"
}, {
bindKey: { mac: "ctrl-break", win: "ctrl-break" },
name: "stopbuild"
},
{
bindKey: { mac: "cmd-t|cmd-p", win: "ctrl-p" },
name: "navigate"
}, {
bindKey: { mac: "cmd-r", win: "ctrl-r" },
name: "outline",
args: { overlay: "goto", text: "@" }
}, {
bindKey: { mac: "cmd-shift-r", win: "ctrl-shift-r" },
// todo: this should be project outline
name: "outline"
}, {
bindKey: { mac: "ctrl-g", win: "ctrl-g" },
name: "gotoline",
args: { overlay: "goto", text: ":" }
},
// todo what is this?
// {
// bindKey: {win: "ctrl-;"},
// name: "show_overlay",
// args: {overlay: "goto", text: "#"}
// },
{
bindKey: { mac: "cmd-shift-p", win: "ctrl-shift-p" },
name: "commands"
}, {
bindKey: { mac: "ctrl-`", win: "ctrl-`" },
name: "toggleconsole"
}, {
bindKey: { mac: "cmd-k cmd-b", win: "ctrl-k ctrl-b" },
name: "toggletree"
},
{
bindKey: { mac: "f12|cmd-alt-down", win: "f12" },
name: "jumptodef"
},
/* panels */
// {
// bindKey: {mac: "cmd-k cmd-down", win: "ctrl-k ctrl-down"},
// name: "mergeWithOtherPanels"
// },
// {
// bindKey: {mac: "ctrl-1", win: "ctrl-1"},
// name: "focus_group",
// args: {group: 0}
// }, {
// bindKey: {mac: "ctrl-9", win: "ctrl-9"},
// name: "focus_group",
// args: {group: 8}
// }, {
// bindKey: {mac: "ctrl-2", win: "ctrl-2"},
// name: "focus_group",
// args: {group: 1}
// }, {
// bindKey: {mac: "ctrl-3", win: "ctrl-3"},
// name: "focus_group",
// args: {group: 2}
// }, {
// bindKey: {mac: "ctrl-4", win: "ctrl-4"},
// name: "focus_group",
// args: {group: 3}
// }, {
// bindKey: {mac: "ctrl-5", win: "ctrl-5"},
// name: "focus_group",
// args: {group: 4}
// }, {
// bindKey: {mac: "ctrl-6", win: "ctrl-6"},
// name: "focus_group",
// args: {group: 5}
// }, {
// bindKey: {mac: "ctrl-8", win: "ctrl-8"},
// name: "focus_group",
// args: {group: 7}
// }, {
// bindKey: {mac: "ctrl-7", win: "ctrl-7"},
// name: "focus_group",
// args: {group: 6}
// }, {
// bindKey: {mac: "cmd-k cmd-right", win: "ctrl-k ctrl-right"},
// name: "focus_neighboring_group"
// }, {
// bindKey: {mac: "cmd-k cmd-left", win: "ctrl-k ctrl-left"},
// name: "focus_neighboring_group",
// args: {forward: false}
// }, {
// bindKey: {mac: "ctrl-0", win: "ctrl-0"},
// name: "focus_side_bar"
// }, {
// bindKey: {mac: "ctrl-shift-9", win: "ctrl-shift-9"},
// name: "move_to_group",
// args: {group: 8}
// }, {
// bindKey: {mac: "ctrl-shift-2", win: "ctrl-shift-2"},
// name: "move_to_group",
// args: {group: 1}
// }, {
// bindKey: {mac: "ctrl-shift-8", win: "ctrl-shift-8"},
// name: "move_to_group",
// args: {group: 7}
// }, {
// bindKey: {mac: "ctrl-shift-7", win: "ctrl-shift-7"},
// name: "move_to_group",
// args: {group: 6}
// }, {
// bindKey: {mac: "ctrl-shift-1", win: "ctrl-shift-1"},
// name: "move_to_group",
// args: {group: 0}
// }, {
// bindKey: {mac: "ctrl-shift-6", win: "ctrl-shift-6"},
// name: "move_to_group",
// args: {group: 5}
// }, {
// bindKey: {mac: "ctrl-shift-5", win: "ctrl-shift-5"},
// name: "move_to_group",
// args: {group: 4}
// }, {
// bindKey: {mac: "ctrl-shift-4", win: "ctrl-shift-4"},
// name: "move_to_group",
// args: {group: 3}
// }, {
// bindKey: {mac: "ctrl-shift-3", win: "ctrl-shift-3"},
// name: "move_to_group",
// args: {group: 2}
// }, {
// bindKey: {mac: "cmd-9", win: "alt-9"},
// name: "select_by_index",
// args: {index: 8}
// }, {
// bindKey: {mac: "cmd-1", win: "alt-1"},
// name: "select_by_index",
// args: {index: 0}
// }, {
// bindKey: {mac: "cmd-0", win: "alt-0"},
// name: "select_by_index",
// args: {index: 9}
// }, {
// bindKey: {mac: "cmd-8", win: "alt-8"},
// name: "select_by_index",
// args: {index: 7}
// }, {
// bindKey: {mac: "cmd-3", win: "alt-3"},
// name: "select_by_index",
// args: {index: 2}
// }, {
// bindKey: {mac: "cmd-7", win: "alt-7"},
// name: "select_by_index",
// args: {index: 6}
// }, {
// bindKey: {mac: "cmd-2", win: "alt-2"},
// name: "select_by_index",
// args: {index: 1}
// }, {
// bindKey: {mac: "cmd-6", win: "alt-6"},
// name: "select_by_index",
// args: {index: 5}
// }, {
// bindKey: {mac: "cmd-5", win: "alt-5"},
// name: "select_by_index",
// args: {index: 4}
// }, {
// bindKey: {mac: "cmd-4", win: "alt-4"},
// name: "select_by_index",
// args: {index: 3}
// }, {
// bindKey: {mac: "cmd-k cmd-shift-right", win: "ctrl-k ctrl-shift-right"},
// name: "move_to_neighboring_group"
// }, {
// bindKey: {mac: "cmd-k cmd-shift-left", win: "ctrl-k ctrl-shift-left"},
// name: "move_to_neighboring_group",
// args: {forward: false}
// }, {
// bindKey: {mac: "cmd-k cmd-up", win: "ctrl-k ctrl-up"},
// name: "new_pane"
// }, {
// bindKey: {mac: "cmd-k cmd-shift-up", win: "ctrl-k ctrl-shift-up"},
// name: "new_pane",
// args: {move: false}
// }, {
// bindKey: {mac: "cmd-alt-4", win: "alt-shift-4"},
// name: "set_layout",
// args: {cols: [0, 0.25, 0.5, 0.75, 1], rows: [0, 1], cells: [[0, 0, 1, 1], [1, 0, 2, 1], [2, 0, 3, 1], [3, 0, 4, 1] ]}
// }, {
// bindKey: {mac: "cmd-alt-shift-2", win: "alt-shift-8"},
// name: "set_layout",
// args: {cols: [0, 1], rows: [0, 0.5, 1], cells: [[0, 0, 1, 1], [0, 1, 1, 2] ]}
// }, {
// bindKey: {mac: "cmd-alt-shift-3", win: "alt-shift-9"},
// name: "set_layout",
// args: {cols: [0, 1], rows: [0, 0.33, 0.66, 1], cells: [[0, 0, 1, 1], [0, 1, 1, 2], [0, 2, 1, 3] ]}
// }, {
// bindKey: {mac: "cmd-alt-5", win: "alt-shift-5"},
// name: "set_layout",
// args: {cols: [0, 0.5, 1], rows: [0, 0.5, 1], cells: [[0, 0, 1, 1], [1, 0, 2, 1], [0, 1, 1, 2], [1, 1, 2, 2] ]}
// }, {
// bindKey: {mac: "cmd-alt-3", win: "alt-shift-3"},
// name: "set_layout",
// args: {cols: [0, 0.33, 0.66, 1], rows: [0, 1], cells: [[0, 0, 1, 1], [1, 0, 2, 1], [2, 0, 3, 1] ]}
// }, {
// bindKey: {mac: "cmd-alt-2", win: "alt-shift-2"},
// name: "set_layout",
// args: {cols: [0, 0.5, 1], rows: [0, 1], cells: [[0, 0, 1, 1], [1, 0, 2, 1] ]}
// }, {
// bindKey: {mac: "cmd-alt-1", win: "alt-shift-1"},
// name: "set_layout",
// args: {cols: [0, 1], rows: [0, 1], cells: [[0, 0, 1, 1] ]}
// },
// {
// bindKey: {mac: "cmd-ctrl-shift-f", win: "shift-f11"},
// name: "toggle_distraction_free"
// }, {
// bindKey: {mac: "cmd-ctrl-f", win: "f11"},
// name: "toggle_full_screen"
// },
{
bindKey: { mac: "cmd-shift-]|cmd-alt-right", win: "ctrl-pagedown" },
name: "gototabright"
}, {
bindKey: { mac: "cmd-shift-[|cmd-alt-left", win: "ctrl-pageup" },
name: "gototableft"
}, {
bindKey: { mac: "ctrl-tab", win: "ctrl-tab" },
name: "nexttab"
}, {
bindKey: { mac: "ctrl-shift-tab", win: "ctrl-shift-tab" },
name: "previoustab"
},
{
bindKey: {},
name: "nextpane"
},
{
bindKey: { mac: "ctrl+alt+f", win: "ctrl+alt+f" }, // shortcut from codeformatter plugin
name: "formatcode"
},
// {
// bindKey: {mac: "cmd-alt-up", win: "alt-o"},
// name: "switch_file",
// args: {extensions: ["cpp", "cxx", "cc", "c", "hpp", "hxx", "h", "ipp", "inl", "m", "mm"] }
// },
{
bindKey: { linux: "ctrl--", mac: "cmd--", win: "ctrl--|ctrl-shift-=|ctrl-shift-+" },
name: "smallerfont"
}, {
bindKey: { linux: "ctrl--|ctrl-=", mac: "cmd-=|cmd-+", win: "ctrl--|ctrl-=|ctrl-+" },
name: "largerfont"
},
/* bookmarks */
// {
// bindKey: {mac: "cmd-shift-f2", win: "ctrl-shift-f2"},
// name: "clear_bookmarks"
// }, {
// bindKey: {mac: "cmd-k cmd-g", win: "ctrl-k ctrl-g"},
// name: "clear_bookmarks",
// args: {name: "mark"}
// }, {
// bindKey: {mac: "f2", win: "f2"},
// name: "next_bookmark"
// }, {
// bindKey: {mac: "shift-f2", win: "shift-f2"},
// name: "prev_bookmark"
// }, {
// bindKey: {mac: "alt-f2", win: "alt-f2"},
// name: "select_all_bookmarks"
// }, {
// bindKey: {mac: "cmd-f2", win: "ctrl-f2"},
// name: "toggle_bookmark"
// },
{
bindKey: { mac: "cmd-e", win: "ctrl-e" },
name: "revealtab" // todo
},
/* find replace */
{
bindKey: { mac: "cmd-alt-f", win: "ctrl-h" },
name: "replace"
}, {
bindKey: { mac: "cmd-alt-e", win: "ctrl-shift-h" },
name: "replacenext"
}, {
bindKey: { mac: "cmd-e", win: "ctrl-e" },
name: "slurp_find_string" // todo
}, {
bindKey: { mac: "cmd-shift-e", win: "ctrl-shift-e" },
name: "slurp_replace_string"
}, {
bindKey: { mac: "ctrl-alt-enter", win: "ctrl-alt-enter" },
name: "replaceall"
}, {
bindKey: { mac: "cmd-f", win: "ctrl-f" },
name: "find"
}, {
bindKey: { mac: "cmd-shift-f", win: "ctrl-shift-f" },
name: "searchinfiles",
},
// {
// bindKey: {mac: "f4", win: "f4"},
// name: "next_result"
// }, {
// bindKey: {mac: "shift-f4", win: "shift-f4"},
// name: "prev_result"
// },
// todo incremental_find
// {
// bindKey: {mac: "cmd-alt-c", win: "alt-c"},
// name: "toggle_case_sensitive",
// }, {
// bindKey: {mac: "cmd-i", win: "ctrl-i"},
// name: "show_panel",
// args: {panel: "incremental_find", reverse: false}
// }, {
// bindKey: {mac: "cmd-shift-i", win: "ctrl-shift-i"},
// name: "show_panel",
// args: {panel: "incremental_find", reverse: true}
// },
// {
// bindKey: {mac: "cmd-alt-a", win: "alt-a"},
// name: "toggle_preserve_case",
// }, {
// bindKey: {mac: "cmd-alt-r", win: "alt-r"},
// name: "toggle_regex",
// }, {
// bindKey: {mac: "cmd-alt-w", win: "alt-w"},
// name: "toggle_whole_word",
// },
];
exports.editorCommands = [{
name: "find_all_under",
exec: function(editor) {
if (editor.selection.isEmpty())
editor.selection.selectWord();
editor.findAll();
},
readOnly: true
}, {
name: "find_under",
exec: function(editor) {
if (editor.selection.isEmpty())
editor.selection.selectWord();
editor.findNext();
},
readOnly: true
}, {
name: "find_under_prev",
exec: function(editor) {
if (editor.selection.isEmpty())
editor.selection.selectWord();
editor.findPrevious();
},
readOnly: true
}, {
name: "find_under_expand",
exec: function(editor) {
editor.selectMore(1, false, true);
},
scrollIntoView: "animate",
readOnly: true
}, {
name: "find_under_expand_skip",
exec: function(editor) {
editor.selectMore(1, true, true);
},
scrollIntoView: "animate",
readOnly: true
}, {
name: "delete_to_hard_bol",
exec: function(editor) {
var pos = editor.selection.getCursor();
editor.session.remove({
start: { row: pos.row, column: 0 },
end: pos
});
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
}, {
name: "delete_to_hard_eol",
exec: function(editor) {
var pos = editor.selection.getCursor();
editor.session.remove({
start: pos,
end: { row: pos.row, column: Infinity }
});
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
}, {
name: "moveToWordStartLeft",
exec: function(editor) {
editor.selection.moveCursorLongWordLeft();
editor.clearSelection();
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
}, {
name: "moveToWordEndRight",
exec: function(editor) {
editor.selection.moveCursorLongWordRight();
editor.clearSelection();
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
}, {
name: "selectToWordStartLeft",
exec: function(editor) {
var sel = editor.selection;
sel.$moveSelection(sel.moveCursorLongWordLeft);
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
}, {
name: "selectToWordEndRight",
exec: function(editor) {
var sel = editor.selection;
sel.$moveSelection(sel.moveCursorLongWordRight);
},
multiSelectAction: "forEach",
scrollIntoView: "cursor",
},
];
/* editor commands */
exports.editorKeymap = [{
bindKey: { linux: "alt-/|ctrl-space", mac: "ctrl-space", win: "ctrl-space" },
name: "complete"
},
// {
// bindKey: {mac: "cmd-c", win: "ctrl-insert|ctrl-c"},
// name: "copy"
// }, {
// bindKey: {mac: "cmd-x", win: "shift-delete|ctrl-x"},
// name: "cut"
// },
// {
// bindKey: {mac: "cmd-k cmd-w", win: "ctrl-k ctrl-w"},
// name: "delete_to_mark"
// }, {
// bindKey: {mac: "cmd-k cmd-a", win: "ctrl-k ctrl-a"},
// name: "select_to_mark"
// }, {
// bindKey: {mac: "cmd-k cmd-space", win: "ctrl-k ctrl-space"},
// name: "set_mark"
// }, {
// bindKey: {mac: "cmd-k cmd-x", win: "ctrl-k ctrl-x"},
// name: "swap_with_mark"
// }, {
// bindKey: {mac: "cmd-k cmd-y|ctrl-y", win: "ctrl-k ctrl-y"},
// name: "yank"
// },
// // TODO check if these are same as ace
// {
// bindKey: {win: "ctrl-delete"},
// name: "delete_word",
// args: {forward: true}
// }, {
// bindKey: {mac: "ctrl-backspace"},
// name: "delete_word",
// args: {forward: false, sub_words: true}
// }, {
// bindKey: {mac: "ctrl-delete"},
// name: "delete_word",
// args: {forward: true, sub_words: true}
// }, {
// bindKey: {win: "ctrl-backspace"},
// name: "delete_word",
// args: {forward: false}
// }, {
// bindKey: {win: "backspace|shift-backspace|ctrl-shift-backspace"},
// name: "left_delete"
// }, {
// bindKey: {win: "delete"},
// name: "right_delete"
// },
{
bindKey: { mac: "cmd-k cmd-backspace|cmd-backspace", win: "ctrl-shift-backspace|ctrl-k ctrl-backspace" },
name: "delete_to_hard_bol"
}, {
bindKey: { mac: "cmd-k cmd-k|cmd-delete|ctrl-k", win: "ctrl-shift-delete|ctrl-k ctrl-k" },
name: "delete_to_hard_eol"
},
{
bindKey: { mac: "cmd-shift-d", win: "ctrl-shift-d" },
name: "duplicateSelection"
}, {
bindKey: { mac: "cmd-l", win: "ctrl-l" },
name: "expandtoline",
},
// {
// bindKey: {mac: "cmd-shift-a", win: "ctrl-shift-a"},
// name: "expand_selection",
// args: {to: "tag"}
// }, {
// bindKey: {mac: "cmd-shift-j", win: "ctrl-shift-j"},
// name: "expand_selection",
// args: {to: "indentation"}
// }, {
// bindKey: {mac: "ctrl-shift-m", win: "ctrl-shift-m"},
// name: "expand_selection",
// args: {to: "brackets"}
// }, {
// bindKey: {mac: "cmd-shift-space", win: "ctrl-shift-space"},
// name: "expand_selection",
// args: {to: "scope"}
// },
{
bindKey: { mac: "ctrl-cmd-g", win: "alt-f3" },
name: "find_all_under"
}, {
bindKey: { mac: "alt-cmd-g", win: "ctrl-f3" },
name: "find_under"
}, {
bindKey: { mac: "shift-alt-cmd-g", win: "ctrl-shift-f3" },
name: "find_under_prev"
}, {
bindKey: { mac: "cmd-g", win: "f3" },
name: "findnext"
}, {
bindKey: { mac: "shift-cmd-g", win: "shift-f3" },
name: "findprevious"
}, {
bindKey: { mac: "cmd-d", win: "ctrl-d" },
name: "find_under_expand"
}, {
bindKey: { mac: "cmd-k cmd-d", win: "ctrl-k ctrl-d" },
name: "find_under_expand_skip"
},
/* fold */
{
bindKey: { mac: "cmd-alt-[", win: "ctrl-shift-[" },
name: "toggleFoldWidget"
}, {
bindKey: { mac: "cmd-alt-]", win: "ctrl-shift-]" },
name: "unfold"
}, {
bindKey: { mac: "cmd-k cmd-0|cmd-k cmd-j", win: "ctrl-k ctrl-0|ctrl-k ctrl-j" },
name: "unfoldall"
}, {
bindKey: { mac: "cmd-k cmd-1", win: "ctrl-k ctrl-1" },
name: "foldOther",
args: { level: 1 }
},
// {
// bindKey: {mac: "cmd-k cmd-2", win: "ctrl-k ctrl-2"},
// name: "fold_by_level",
// args: {level: 2}
// }, {
// bindKey: {mac: "cmd-k cmd-3", win: "ctrl-k ctrl-3"},
// name: "fold_by_level",
// args: {level: 3}
// }, {
// bindKey: {mac: "cmd-k cmd-4", win: "ctrl-k ctrl-4"},
// name: "fold_by_level",
// args: {level: 4}
// }, {
// bindKey: {mac: "cmd-k cmd-5", win: "ctrl-k ctrl-5"},
// name: "fold_by_level",
// args: {level: 5}
// }, {
// bindKey: {mac: "cmd-k cmd-6", win: "ctrl-k ctrl-6"},
// name: "fold_by_level",
// args: {level: 6}
// }, {
// bindKey: {mac: "cmd-k cmd-7", win: "ctrl-k ctrl-7"},
// name: "fold_by_level",
// args: {level: 7}
// }, {
// bindKey: {mac: "cmd-k cmd-8", win: "ctrl-k ctrl-8"},
// name: "fold_by_level",
// args: {level: 8}
// }, {
// bindKey: {mac: "cmd-k cmd-9", win: "ctrl-k ctrl-9"},
// name: "fold_by_level",
// args: {level: 9}
// }, {
// bindKey: {mac: "cmd-k cmd-t", win: "ctrl-k ctrl-t"},
// name: "fold_tag_attributes"
// },
/* move */
{
bindKey: { win: "ctrl-left", mac: "alt-left" },
name: "moveToWordStartLeft"
}, {
bindKey: { win: "ctrl-right", mac: "alt-right" },
name: "moveToWordEndRight"
}, {
bindKey: { win: "ctrl-shift-left", mac: "alt-shift-left" },
name: "selectToWordStartLeft",
}, {
bindKey: { win: "ctrl-shift-right", mac: "alt-shift-right" },
name: "selectToWordEndRight",
},
// todo implement move by subwords
// {
// bindKey: {mac: "ctrl-alt-shift-right|ctrl-shift-right", win: "alt-shift-right"},
// name: "move",
// args: {by: "subword_ends", forward: true, extend: true}
// }, {
// bindKey: {mac: "ctrl-alt-shift-left|ctrl-shift-left", win: "alt-shift-left"},
// name: "move",
// args: {by: "subwords", forward: false, extend: true}
// }, {
// bindKey: {mac: "ctrl-alt-right|ctrl-right", win: "alt-right"},
// name: "move",
// args: {by: "subword_ends", forward: true}
// }, {
// bindKey: {mac: "ctrl-alt-left|ctrl-left", win: "alt-left"},
// name: "move",
// args: {by: "subwords", forward: false}
// },
{
bindKey: { mac: "ctrl-m", win: "ctrl-m" },
name: "jumptomatching",
args: { to: "brackets" }
},
/* other */
{
bindKey: { mac: "ctrl-f6", win: "ctrl-f6" },
name: "goToNextError"
}, {
bindKey: { mac: "ctrl-shift-f6", win: "ctrl-shift-f6" },
name: "goToPreviousError"
},
{
bindKey: { mac: "ctrl-o" },
name: "splitline",
},
// {
// bindKey: {mac: "ctrl-shift-w", win: "alt-shift-w"},
// name: "surrowndWithTag",
// args: {name: "Packages/XML/long-tag.sublime-snippet"}
// },{
// bindKey: {mac: "cmd-alt-.", win: "alt-."},
// name: "close_tag"
// },
{
bindKey: { mac: "cmd-j", win: "ctrl-j" },
name: "joinlines"
},
// {
// bindKey: {mac: "ctrl--", win: "alt--"},
// name: "jump_back"
// }, {
// bindKey: {mac: "ctrl-shift--", win: "alt-shift--"},
// name: "jump_forward"
// },
{
bindKey: { mac: "cmd-k cmd-l", win: "ctrl-k ctrl-l" },
name: "tolowercase"
}, {
bindKey: { mac: "cmd-k cmd-u", win: "ctrl-k ctrl-u" },
name: "touppercase"
},
// {
// bindKey: {mac: "cmd-v", win: "shift-insert|ctrl-v"},
// name: "paste"
// }, {
// bindKey: {mac: "cmd-shift-v", win: "ctrl-shift-v"},
// name: "paste_and_indent"
// }, {
// bindKey: {mac: "cmd-k cmd-v|cmd-alt-v", win: "ctrl-k ctrl-v"},
// name: "paste_from_history"
// },
// {
// bindKey: {mac: "cmd-z", win: "ctrl-z"},
// name: "undo"
// }, {
// bindKey: {mac: "cmd-shift-z", win: "ctrl-shift-z"},
// name: "redo"
// }, {
// bindKey: {mac: "cmd-y", win: "ctrl-y"},
// name: "redo_or_repeat"
// }, {
// bindKey: {mac: "cmd-shift-u", win: "ctrl-shift-u"},
// name: "soft_redo"
// }, {
// bindKey: {mac: "cmd-u", win: "ctrl-u"},
// name: "soft_undo"
// },
{
bindKey: { mac: "cmd-shift-enter", win: "ctrl-shift-enter" },
name: "addLineBefore"
}, {
bindKey: { mac: "cmd-enter", win: "ctrl-enter" },
name: "addLineAfter"
}, {
bindKey: { mac: "ctrl-shift-k", win: "ctrl-shift-k" },
name: "removeline"
}, {
bindKey: { mac: "ctrl-alt-up", win: "ctrl-up" },
name: "scrollup",
}, {
bindKey: { mac: "ctrl-alt-down", win: "ctrl-down" },
name: "scrolldown",
}, {
bindKey: { mac: "cmd-a", win: "ctrl-a" },
name: "selectall"
}, {
bindKey: { linux: "alt-shift-down", mac: "ctrl-shift-down", win: "ctrl-alt-down" },
name: "addCursorBelow",
}, {
bindKey: { linux: "alt-shift-up", mac: "ctrl-shift-up", win: "ctrl-alt-up" },
name: "addCursorAbove",
},
{
bindKey: { mac: "cmd-k cmd-c|ctrl-l", win: "ctrl-k ctrl-c" },
name: "centerselection"
},
{
bindKey: { mac: "f5", win: "f9" },
name: "sortlines"
},
// {
// bindKey: {mac: "ctrl-f5", win: "ctrl-f9"},
// name: "sortlines",
// args: {case_sensitive: true}
// },
{
bindKey: { mac: "cmd-shift-l", win: "ctrl-shift-l" },
name: "splitIntoLines"
}, {
bindKey: { mac: "ctrl-cmd-down", win: "ctrl-shift-down" },
name: "movelinesdown"
}, {
bindKey: { mac: "ctrl-cmd-up", win: "ctrl-shift-up" },
name: "movelinesup"
}, {
bindKey: { mac: "alt-down", win: "alt-down" },
name: "modifyNumberDown"
}, {
bindKey: { mac: "alt-up", win: "alt-up" },
name: "modifyNumberUp"
}, {
bindKey: { mac: "cmd-/", win: "ctrl-/" },
name: "togglecomment"
}, {
bindKey: { mac: "cmd-alt-/", win: "ctrl-shift-/" },
name: "toggleBlockComment"
},
{
bindKey: { linux: "ctrl-alt-q", mac: "ctrl-q", win: "ctrl-q" },
// name: "toggle_record_macro"
name: "togglerecording"
}, {
bindKey: { linux: "ctrl-alt-shift-q", mac: "ctrl-shift-q", win: "ctrl-shift-q" },
// name: "run_macro"
name: "replaymacro"
},
{
bindKey: { mac: "ctrl-t", win: "ctrl-t" },
name: "transpose"
}
];
});
// won't implement
// {
// bindKey: {mac: "cmd-alt-q", win: "alt-q"},
// name: "wrap_lines"
// },
// {
// bindKey: {mac: "f6", win: "f6"},
// name: "toggle_setting",
// args: {setting: "spell_check"}
// }, {
// bindKey: {mac: "cmd-alt-p|ctrl-shift-p", win: "ctrl-alt-shift-p"},
// name: "show_scope_name"
// },
// {
// bindKey: {mac: "cmd-alt-o", win: "insert"},
// name: "toggle_overwrite"
// },
// {
// bindKey: {mac: "alt-f2", win: "context_menu"},
// name: "context_menu"
// },

Wyświetl plik

@ -0,0 +1,72 @@
define(function(require, exports, module) {
exports.showCli = true;
var Vim = require("ace/keyboard/vim").Vim;
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
exports.aceKeyboardHandler = require("ace/keyboard/vim").handler;
exports.aceKeyboardHandler.defaultKeymap.unshift(
{ keys: ':', type: 'action', action: 'aceCommand', actionArgs: { exec: function(ace) {
ace.showCommandLine(":");
} }}
);
exports.aceKeyboardHandler.defaultKeymap.push(
{ keys: 'gt', type: 'action', action: 'aceCommand', actionArgs: { exec: ideCommand, name: 'gototabright', args: { editorType: "ace" }}},
{ keys: 'gT', type: 'action', action: 'aceCommand', actionArgs: { exec: ideCommand, name: 'gototableft', args: { editorType: "ace" }}}
);
exports.execIdeCommand = null;
function ideCommand() {
exports.execIdeCommand(this.name, null, this.args);
}
/**
* require(["plugins/c9.ide.ace.keymaps/vim/keymap"], function(vim) {
* vim.map("J", "8j", "normal")
* vim.map("K", "8k", "normal")
* vim.map(",b", "c9:build", "normal")
* vim.map(",g", "c9:run", "normal")
* });
*/
exports.map = function(keys, action, context) {
if (!action)
return Vim.unmap(keys, context);
var mapping;
if (typeof action == "function") {
mapping = {
keys: keys,
type: 'action',
action: 'aceCommand',
actionArgs: { exec: ideCommand, name: 'gototableft' }
};
}
if (/^c9:/.test(action)) {
var commandName = action.substr(3);
mapping = {
keys: keys,
type: 'action',
action: 'aceCommand',
actionArgs: { exec: ideCommand, name: commandName }
};
}
if (mapping) {
if (context)
mapping.context = context;
mapping.user = true;
exports.aceKeyboardHandler.defaultKeymap.unshift(mapping);
} else {
Vim.map(keys, action, context);
}
};
exports.treeKeyboardHandler = new HashHandler();
exports.treeKeyboardHandler.bindKeys({
"k": "goUp",
"j": "goDown",
"h": "levelUp",
"l": "levelDown"
});
});

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.repl

Wyświetl plik

@ -0,0 +1,92 @@
define(function(require, exports, module) {
main.consumes = ["editors"];
main.provides = ["ace.repl"];
return main;
function main(options, imports, register) {
var editors = imports.editors;
var Repl = require("./repl").Repl;
/***** Initialization *****/
var extensions = [];
function ReplEditor() {
var Baseclass = editors.findEditor("ace");
var plugin = new Baseclass(true, []);
// var emit = plugin.getEmitter();
var currentSession;
var ace;
plugin.on("draw", function(e) {
ace = plugin.ace;
if (currentSession)
currentSession.repl.attach(ace);
});
/***** Method *****/
/***** Lifecycle *****/
plugin.on("load", function() {
});
plugin.on("documentLoad", function(e) {
var session = e.doc.getSession();
if (session.repl) return;
session.repl = new Repl(session.session, {
mode: e.state.mode,
evaluator: e.state.evaluator,
message: e.state.message
});
});
plugin.on("documentActivate", function(e) {
currentSession = e.doc.getSession();
if (ace)
currentSession.repl.attach(ace);
});
plugin.on("documentUnload", function(e) {
var session = e.doc.getSession();
session.repl.detach();
delete session.repl;
});
plugin.on("getState", function(e) {
});
plugin.on("setState", function(e) {
});
plugin.on("clear", function() {
});
plugin.on("focus", function() {
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
});
/***** Register and define API *****/
/**
* Read Only Image Editor
**/
plugin.freezePublicAPI({
});
plugin.load(null, "ace.repl");
return plugin;
}
register(null, {
"ace.repl": editors.register("ace.repl", "Ace REPL",
ReplEditor, extensions)
});
}
});

Wyświetl plik

@ -0,0 +1,96 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
var Editor = require("ace/editor").Editor;
var Evaluator = function() {
};
(function() {
this.canEvaluate = function(str) {
return !!str.trim();
};
this.evaluate = function(str, cell, cb) {
if (/table|ace/.test(str)) {
cb("");
var editor = new Editor(new Renderer);
editor.setValue("command " + str);
editor.container.addEventListener("mousedown", function(e) {
e.stopPropagation();
});
cell.addWidget({ rowCount: 8, el: editor.container, editor: editor });
setTimeout(function() {
editor.resize(true);
}, 80);
} else if (/repl/.test(str)) {
cb("");
var editor = new Editor(new Renderer);
cell.session.repl.constructor.fromEditor(editor, {
mode: "repl_demo/logiql_command_mode",
evaluator: this,
message: "welcome to inner Repl!"
});
editor.container.addEventListener("mousedown", function(e) {
e.stopPropagation();
});
cell.addWidget({ rowCount: 12, el: editor.container, editor: editor });
setTimeout(function() {
editor.resize(true);
}, 80);
} else if (/logo/.test(str)) {
setTimeout(function() {
cb("");
cell.addWidget({ rowCount: 6, html: "<img src='http://martin.bravenboer.name/logo-trans-85.png'>" });
}, 300);
} else if (/lorem/.test(str)) {
var a = [];
for (var i = 0; i < 100; i++) {
a.push(i);
}
cb(a.join("\n"));
} else if (/\n|slow/.test(str)) {
setTimeout(function() {
cb("evaluated slow command:" + str);
}, 1000);
} else {
cb("evaluated command: " + str);
}
};
}).call(Evaluator.prototype);
exports.Evaluator = Evaluator;
});

Wyświetl plik

@ -0,0 +1,283 @@
define(function(require, exports, module) {
var oop = require("ace/lib/oop");
var TextMode = require("ace/mode/text").Mode;
var Range = require("ace/range").Range;
var dom = require("ace/lib/dom");
var FoldMode = require("ace/mode/folding/cstyle").FoldMode;
var foldMode = new FoldMode();
foldMode.foldingStartMarker = /(^#>>)|(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
foldMode.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]) {
var cell = session.$mode.getCellBounds(row);
var start = { row: row, column: session.$mode.dl };
var end = { row: cell.bodyEnd, column: session.getLine(cell.bodyEnd).length };
var placeholder = session.getLine(cell.headerStart).slice(0, 10) + "=====================";
range = Range.fromPoints(start, end);
range.placeholder = placeholder;
return range;
}
if (match[3]) {
var range = session.getCommentFoldRange(row, i + match[0].length);
range.end.column -= 2;
return range;
}
var start = { row: row, column: i + 1 };
var end = session.$findClosingBracket(match[2], start);
if (!end)
return;
var fw = session.foldWidgets[end.row];
if (fw == null)
fw = this.getFoldWidget(session, end.row);
if (fw == "start") {
end.row --;
end.column = session.getLine(end.row).length;
}
return Range.fromPoints(start, end);
}
};
dom.importCssString("\
\
.ace_cellHead{\
background:rgba(120,50,100,0.1);\
color: darkred;\
}\
.ace_filler{\
position: absolute;\
left: 0;\
display: inline-block;\
border-top: 1px solid gray;\
width: 100%;\
}");
var commands = [{
name: "newCell",
bindKey: { win: "Shift-Return", mac: "Shift-Return" },
exec: function(editor) {
var session = editor.session;
var c = editor.getCursorPosition();
var end = session.insert(c, c.column == 0 ? "#>>" : "\n#>>");
var addNewLine = (c.column != 0 || c.row == 0)
&& c.column != session.getLine(c.row).length;
if (addNewLine) {
session.insert(end, "\n");
editor.selection.setSelectionRange({ start: end, end: end });
}
}
}];
var JSMode = require("ace/mode/javascript").Mode;
var modes = {
js: new JSMode()
};
var jsMode = modes.js;
var tk = {};
var delimiter = '#>>';
var dl = delimiter.length;
function testLang(lang, fullName) {
lang = lang.toLowerCase();
fullName = fullName.toLowerCase();
var lastI = 0;
for (var j = 0, ftLen = lang.length; j < ftLen; j++) {
lastI = fullName.indexOf(lang[j], lastI);
if (lastI === -1)
return false; // doesn't match
lastI++;
}
return true;
}
var states = {};
var $getState = function(state, lang, isHeader) {
var g = lang + state + isHeader;
return states[g] || (states[g] = { state: state, lang: lang, isHeader: isHeader });
};
tk.getLineTokens = function(line, startState) {
var match, lang, isHeader = 0;
if (typeof startState == 'object') {
lang = startState.lang;
isHeader = startState.isHeader || 0;
startState = startState.state || "start";
} else {
lang = 'js';
}
if (line.substr(0, dl) == delimiter) {
var index = dl;
var type = !isHeader ? 'firstcell.' : '';
var tok = [{ type: type + 'cellHead', value: delimiter }];
if ((match = line.match(/lang\s*=\s*(\w+)\b/))) {
lang = testLang(match[1], 'coffeeScript') ? 'coffee' : 'js';
if (dl < match.index) {
tok.push({ type: type, value: line.substring(dl, match.index) });
}
tok.push({ type: type + 'comment.doc', value: match[0] });
index = match.index + match[0].length;
}
tok.push({ type: type, value: line.substr(index) });
if (!isHeader) {
tok.push({ type: 'filler', value: ' ' });
}
ans = {
tokens: tok,
state: $getState("start", lang, isHeader + 1)
};
}
else {
var ans = (modes[lang] || jsMode).getTokenizer().getLineTokens(line, startState);
ans.state = $getState(ans.state, lang);
}
return ans;
};
var Mode = function() {
this.$tokenizer = tk;
this.foldingRules = foldMode;
};
oop.inherits(Mode, TextMode);
(function() {
this.delimiter = delimiter;
this.dl = dl;
this.getCellBounds = function(row, editor) {
var lines = editor.session.doc.$lines;
var cur = row;
// go to header end if row is inside header
var line = lines[row];
while (line && line.substr(0, dl) == delimiter) {
line = lines[++row];
}
if (!line)
line = lines[--row];
// read up to header
var i = row;
while (line != null) {
if (line.substr(0, dl) == delimiter)
break;
line = lines[--i];
}
var minI = i + 1;
// read header
while (line != null) {
if (line.substr(0, dl) != delimiter)
break;
line = lines[--i];
}
var headerI = i + 1;
// read rest of the body
i = row + 1;
line = lines[i];
while (line != null) {
if (line.substr(0, dl) == delimiter)
break;
line = lines[++i];
}
var maxI = i - 1;
return {
headerStart: headerI,
headerEnd: minI - 1,
bodyStart: minI,
bodyEnd: maxI,
cursor: cur
};
};
this.getHeaderText = function(cell) {
if (cell) {
cell.headerText = cell.header.join('\n')
.replace(/lang\s*=\s*(\w+)\b/g, '')
.replace(delimiter, '', 'g')
.trim();
return cell;
}
};
this.getCurrentCell = function(editor) {
var cursor = editor.getCursorPosition();
var session = editor.session;
var cell = this.getCellBounds(cursor.row, editor);
cell.header = session.getLines(cell.headerStart, cell.headerEnd);
cell.body = session.getLines(cell.bodyStart, cell.bodyEnd);
cell.lang = session.getState(cell.headerStart).lang;
this.getHeaderText(cell);
return cell;
};
this.setCellText = function(text, editor) {
var cursor = editor.getCursorPosition();
var session = editor.session;
var cell = this.getCellBounds(cursor.row, editor);
var end = session.getLine(cell.bodyEnd).length;
if (cell.bodyStart > cell.bodyEnd) { // empty cell
var range = new Range(cell.bodyEnd, end, cell.bodyEnd, end);
text = '\n' + text;
} else
var range = new Range(cell.bodyStart, 0, cell.bodyEnd, end);
session.replace(range, text);
return text;
};
this.toggleCommentLines = function(state, doc, startRow, endRow) {
(modes[state.lang] || jsMode).toggleCommentLines(state.state, doc, startRow, endRow);
};
this.getNextLineIndent = function(state, line, tab, lineEnd) {
return (modes[state.lang] || jsMode).getNextLineIndent(state.state, line, tab, lineEnd);
};
this.checkOutdent = function(state, line, input) {
return (modes[state.lang] || jsMode).checkOutdent(state.state, line, input);
};
this.autoOutdent = function(state, doc, row) {
return (modes[state.lang] || jsMode).autoOutdent(state.state, doc, row);
};
this.createWorker = function(session) {
return null;
};
this.transformAction = function(state, action, editor, session, param) {
return (modes[state.lang] || jsMode).transformAction(state.state, action, editor, session, param);
};
}).call(Mode.prototype);
exports.Mode = Mode;
exports.commands = commands;
});

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.repl",
"description": "The repository for c9.ide.ace.repl, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.repl.git"
},
"plugins": {
"editor": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,920 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var dom = require("ace/lib/dom");
var Anchor = require("ace/anchor").Anchor;
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
var Range = require("ace/range").Range;
var comparePoints = Range.comparePoints;
var ReplCell = require("./repl_cell").ReplCell;
var css = require("ace/requirejs/text!./repl.css");
dom.importCssString(css, "ace_repl");
var replCommands = new HashHandler([{
name: "newLine",
bindKey: { win: "Shift-Return|Alt-Enter", mac: "Shift-Return|Alt-Enter" },
exec: function(editor) {editor.insert("\n");},
scrollIntoView: "cursor"
}, {
name: "eval",
bindKey: "Ctrl-Return|Cmd-Return",
exec: function(editor) {return editor.repl.eval(true);},
scrollIntoView: "cursor"
}, {
name: "evalOrNewLine",
bindKey: "Return",
exec: function(editor) {return editor.repl.eval();},
scrollIntoView: "cursor"
}, {
name: "down",
bindKey: "down",
exec: function(editor) {return editor.repl.navigateHistory(1);},
scrollIntoView: "center-animate"
}, {
name: "up",
bindKey: "up",
exec: function(editor) {return editor.repl.navigateHistory(-1);},
scrollIntoView: "center-animate"
}, {
name: "prevCell",
bindKey: { mac: "cmd-up", win: "ctrl-up" },
exec: function(editor) {return editor.repl.moveByCells(-1, null, "input");},
scrollIntoView: "center-animate"
}, {
name: "nextCell",
bindKey: { mac: "cmd-down", win: "ctrl-down" },
exec: function(editor) {return editor.repl.moveByCells(1, null, "input");},
scrollIntoView: "center-animate"
}, {
name: "firstCell",
bindKey: { mac: "alt-up|ctrl-home", win: "ctrl-home" },
exec: function(editor) {return editor.repl.moveByCells("first", null, "input");},
scrollIntoView: "center-animate"
}, {
name: "lastCell",
bindKey: { mac: "alt-down|ctrl-end", win: "ctrl-end" },
exec: function(editor) {return editor.repl.moveByCells("last", null, "input");},
scrollIntoView: "center-animate"
}, {
name: "clear",
bindKey: { mac: "cmd-k", win: "Alt-k" },
exec: function(editor) {return editor.repl.clear();},
scrollIntoView: "center-animate"
}, {
name: "removeOutputCell",
bindKey: { mac: "Shift-delete", win: "Shift-delete" },
exec: function(editor) {return editor.repl.removeOutputCell();},
scrollIntoView: "cursor"
}, {
name: "newInputCell",
bindKey: { mac: "ctrl-insert", win: "ctrl-insert" },
exec: function(editor) { editor.repl.insertCell();},
scrollIntoView: "center-animate"
}]);
for (var key in replCommands.commands) {
replCommands.commands[key].isRepl = true;
}
/******************************************************/
var Repl = function(session, options) {
options = options || {};
this.history = new History();
this.evaluator = options.evaluator || new Evaluator();
this.session = session;
this._replResize = this._replResize.bind(this);
this.updateCellsOnChange = this.updateCellsOnChange.bind(this);
this.updateWidgets = this.updateWidgets.bind(this);
this.measureWidgets = this.measureWidgets.bind(this);
this.session._changedWidgets = [];
this.detach = this.detach.bind(this);
this.session.on("change", this.updateCellsOnChange);
session.repl = this;
session.replCells = [];
var pos = { row: session.getLength(), column: 0 };
if (!session.getValue() && options.message)
pos = session.insert(pos, options.message);
if (session.getValue())
this.insertCell({ row: 0, column: 0 }, { type: "start" }, true);
var last = this.insertCell(pos, { type: "input" });
this.select(last.range.end);
this.session.on("changeMode", function() {
session.getFoldWidget = function(row) {
if (!session.replCells[row])
return;
if (session.replCells[row + 1])
return;
if (row == session.replCells.length - 1)
return;
if (session.replCells[row].lineWidget)
return;
return "start";
};
session.getFoldWidgetRange = function(row) {
return session.repl.getCellAt(row).range;
};
session.bgTokenizer.$tokenizeRow = session.repl.$tokenizeRow;
session.bgTokenizer.session = session;
});
session.getRowLength = function(row) {
if (this.lineWidgets)
var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
else
h = 0;
if (!this.$useWrapMode || !this.$wrapData[row]) {
return 1 + h;
} else {
return this.$wrapData[row].length + 1 + h;
}
};
session.$getWidgetScreenLength = function() {
var screenRows = 0;
this.lineWidgets.forEach(function(w) {
if (w && w.rowCount)
screenRows += w.rowCount;
});
return screenRows;
};
session.gutterRenderer = this.gutterRenderer;
this.session.setMode(options.mode);
this.$updateSession();
this._addCursorMonitor();
};
(function() {
this.message = "\nWelcome to ace repl!\n";
this.setEvaluator = function(evaluator) {
this.evaluator = evaluator;
};
this.getEvaluator = function() {
return this.evaluator;
};
this._replResize = function(oldSize, renderer) {
var session = renderer.session;
var size = renderer.$size;
var dh = size.scrollerHeight - oldSize.scrollerHeight;
if (dh > 0)
return;
var oldMaxScrollTop = renderer.layerConfig.maxHeight
- oldSize.scrollerHeight + renderer.scrollMargin.v;
var scrollTop = session.getScrollTop();
if (scrollTop > oldMaxScrollTop - renderer.layerConfig.lineHeight) {
session.setScrollTop(scrollTop - dh);
}
};
this.gutterRenderer = {
getText: function(session, row) {
var cell = session.replCells[row];
if (cell)
return cell.prompt || "";
return row + "";
},
getWidth: function(session, lastLineNumber, config) {
var chars = Math.max(lastLineNumber.toString().length, session.maxPromptLength || 0);
return chars * config.characterWidth;
}
};
// hide cursor in non editable cells
this._addCursorMonitor = function() {
this._updateCursorVisibility = this._updateCursorVisibility.bind(this);
this.$cursorChanged = false;
var markDirty = function() {
this.$cursorChanged = true;
}.bind(this);
this.session.selection.on("changeSelection", markDirty);
this.session.selection.on("changeCursor", markDirty);
};
this._updateCursorVisibility = function(e, renderer) {
if (!this.$cursorChanged) return;
this.$cursorChanged = false;
var cell = this.getCurrentCell();
var visible = cell && cell.type === "input";
if (visible != renderer.$cursorLayer.inEditableCell) {
renderer.$cursorLayer.inEditableCell = visible;
renderer.$cursorLayer.element.style.opacity = visible ? "" : "0";
}
};
this.onMouseUp = function(e) {
var editor = e.editor;
if (editor.repl.$mouseTimer)
clearTimeout(editor.repl.$mouseTimer);
editor.repl.$mouseTimer = setTimeout(function() {
var sel = editor.selection;
if (sel.isEmpty() && !sel.rangeCount) {
var cell = editor.repl.getCurrentCell();
if (cell.type != "input") {
var r = cell.getRange();
if (r && (sel.lead.row - r.start.row) / (r.end.row - r.start.row) < 0.1)
cell = editor.repl.getSiblingCell(-1, cell, "input");
if (!cell)
cell = editor.repl.getSiblingCell(1, cell, "input");
if (cell)
editor.repl.select(cell.range.end);
}
}
}, 250);
};
// commands
this.beforeCommand = function(e) {
var editor = e.editor;
var command = e.command;
var cell = editor.repl.getCurrentCell();
if (!editor.curReplOp)
editor.curReplOp = { command: command, cell: cell };
if (command.isRepl)
return;
if (cell && cell.lineWidget) {
editor.repl.moveByCells(-1, cell);
e.preventDefault();
}
if (cell && cell.type != "input") {
if (!command.readOnly)
e.preventDefault();
return;
}
if (!cell)
return;
var op = editor.curReplOp;
if (command.readOnly) {
op.clipSelection = "before";
if (editor.lastReplOp && editor.lastReplOp.command === command) {
// todo allow some commands to go outside of cell
op.clipSelection = "after";
}
} else if (command) {
op.clipSelection = "before";
}
if (op.clipSelection == "before") {
var range = cell.getRange();
editor.repl.$trackedRange = range;
setClipToRange(editor.selection.lead, range);
setClipToRange(editor.selection.anchor, range);
}
};
this.afterCommand = function(e) {
var editor = e.editor;
var op = editor.curReplOp;
editor.curReplOp = null;
editor.lastReplOp = op;
if (!op)
return;
var command = op.command;
if (op.clipSelection == "before") {
setClipToRange(editor.selection.lead, false);
setClipToRange(editor.selection.anchor, false);
} else if (op.clipSelection == "after") {
var range = editor.selection.toOrientedRange();
if (op.cell) {
range.clip(op.cell.getRange());
editor.selection.fromOrientedRange(range);
}
}
editor.repl.$trackedRange = null;
if (!command.readOnly && !command.isRepl)
editor.repl.ensureLastInputCell();
};
this.attach = function(editor) {
if (editor.repl && editor.repl != this)
editor.repl.detach();
if (this.editor == editor)
return;
this.detach();
this.editor = editor;
this.editor.on("changeSession", this.detach);
editor.keyBinding.addKeyboardHandler(replCommands);
editor.commands.on("exec", this.beforeCommand);
editor.commands.on("afterExec", this.afterCommand);
editor.on("mouseup", this.onMouseUp);
editor.repl = this;
// editor.setOption("enableLineWidgets", true);
editor.renderer.on("beforeRender", this.measureWidgets);
editor.renderer.on("afterRender", this.updateWidgets);
editor.renderer.on("afterRender", this._updateCursorVisibility);
editor.renderer.on("resize", this._replResize);
};
this.detach = function(e) {
console.log("detach", this.session.getLength(), e);
if (e && e.session == this.session)
return; // sometimes attach can be called before setSession
var editor = this.editor;
if (!editor)
return;
editor.keyBinding.removeKeyboardHandler(replCommands);
editor.commands.off("exec", this.beforeCommand);
editor.commands.off("afterExec", this.afterCommand);
editor.off("mouseup", this.onMouseUp);
editor.off("changeSession", this.detach);
delete editor.renderer.$gutterLayer.update;
this.editor = null;
editor.repl = null;
editor.renderer.off("beforeRender", this.measureWidgets);
editor.renderer.off("afterRender", this.updateWidgets);
this.session.lineWidgets.forEach(function(w) {
if (w && w.el && w.el.parentNode) {
w._inDocument = false;
w.el.parentNode.removeChild(w.el);
}
});
editor.renderer.off("afterRender", this._updateCursorVisibility);
editor.renderer.off("resize", this._replResize);
};
this.navigateHistory = function(dir) {
var cell = this.getCurrentCell();
if (!cell || cell.type != "input")
return false;
var row = this.editor.getCursorPosition().row;
if (dir == 1 && cell.range.end.row != row)
return false;
else if (dir == -1 && cell.range.start.row != row)
return false;
var val = cell.getValue();
val = this.history.navigateList(dir == -1 ? "prev" : "next", val);
if (typeof val == "string") {
dir = -dir;
if (dir == -1 && val.indexOf("\n") == -1)
dir = 1;
cell.setValue(val, dir);
}
};
this.getCurrentCell = function(returnAdjacent) {
var range = this.editor.getSelectionRange();
var cell = this.getCellAt(range.start);
if (returnAdjacent || cell && cell.range.contains(range.end.row, range.end.column)) {
return cell;
}
};
this.getCellAt = function(pos) {
if (pos == undefined)
pos = { row: this.session.getLength(), column: 0 };
else if (typeof pos == "number")
pos = { row: pos, column: 0 };
var cells = this.session.replCells;
for (var i = pos.row; i > 0; i--) {
if (cells[i])
break;
}
var cell = cells[i];
if (!cell)
return;
cell.row = i;
for (var i = pos.row + 1, l = this.session.getLength(); i < l; i++) {
if (cells[i])
break;
}
cell.endRow = Math.min(i - 1, l - 1);
cell.range = new Range(cell.row, 0, cell.endRow, Number.MAX_VALUE);
return cell;
};
this.getSiblingCell = function(dir, cell, type) {
if (dir == -1) {
var pos = cell.range.clone().start;
pos.row--;
} else {
var pos = cell.range.clone().end;
pos.row++;
}
cell = this.getCellAt(pos);
if (!cell)
return;
if (!type || cell.type == type)
return cell;
return this.getSiblingCell(dir, cell, type);
};
this.moveByCells = function(dir, cell, type) {
if (dir == "first")
cell = this.getFirstCell(type);
else if (dir == "last")
cell = this.getLastCell(type);
else
cell = this.getSiblingCell(dir, cell || this.getCurrentCell(), type);
if (cell)
return this.select(cell.range.end);
};
this.getFirstCell = function(type) {
var cell = this.getCellAt(0);
if (type && cell.type != type)
return this.getSiblingCell(1, cell, type);
return cell;
};
this.getLastCell = function(type) {
var cell = this.getCellAt(null);
if (type && cell.type != type)
return this.getSiblingCell(-1, cell, type);
return cell;
};
this.removeOutputCell = function(cell) {
cell = cell || this.getCurrentCell();
if (cell && cell.type == "input")
cell = cell.output;
if (cell)
this.removeCell(cell);
};
this.removeCell = function(cell) {
var range = cell.getRange().clone();
range.start.row--;
range.start.column = this.session.getLine(range.start.row).length;
this.session.replace(range, "");
};
this.clear = function() {
this.session.setValue("");
this.ensureLastInputCell();
};
this.ensureLastInputCell = function() {
var end = { row: this.session.getLength(), column: 0 };
var cell = this.getCellAt(end);
if (!cell || cell.type != "input") {
this.insertCell(end, { type: "input" }, true);
}
};
this.select = function(pos) {
var sel = this.session.selection;
if (typeof pos.row == "number" && typeof pos.column == "number") {
if (sel.rangeCount)
sel.toSingleRange();
sel.setRange(Range.fromPoints(pos, pos));
}
};
this.eval = function(force, cell) {
cell = cell || this.getCurrentCell();
if (!cell)
return;
if (!force && cell.type != "input")
cell = cell.input || this.getSiblingCell(1, cell) || this.getSiblingCell(-1, cell);
var str = cell.getValue();
if (force || this.evaluator.canEvaluate(str)) {
this.session.getUndoManager().reset();
if (!cell.output || !cell.output.session) {
cell.output = this.insertCell(cell.range.end, { type: "output" });
var newCell = this.getSiblingCell(1, cell.output);
}
this.history.add(str);
cell.output.waiting = true;
cell.output.input = cell;
var self = this;
var success = this.evaluator.evaluate(str, cell.output, function(result) {
cell.output.waiting = false;
if (result !== undefined)
cell.output.setValue(result);
var renderer = self.editor.renderer;
renderer.scrollSelectionIntoView(cell.range.end, cell.range.start);
renderer.scrollCursorIntoView();
});
if (success !== false && newCell && newCell.type != "input") {
newCell = this.insertCell(cell.output.range.end, { type: "input" });
this.session.selection.setRange(newCell.range);
}
if (cell.output.waiting) {
cell.output.setPlaceholder("...");
}
} else
this.editor.insert("\n");
if (this.evaluator.afterEvaluate)
this.evaluator.afterEvaluate(cell, newCell);
};
this.insertCell = function(pos, options, allowSplit) {
pos = pos || this.session.selection.getCursor();
if (!options)
options = { type: "input" };
var cell = !allowSplit && this.getCellAt(pos);
if (cell) {
pos = cell.range.end;
pos = this.session.insert(pos, "\n");
}
var newCell = new ReplCell(options, this.session);
pos.row = Math.max(0, Math.min(pos.row, this.session.getLength() - 1));
var range = Range.fromPoints(pos, pos);
range.end.column = Number.MAX_VALUE;
range.start.column = 0;
newCell.range = range;
newCell.row = range.end.row;
var oldCell = this.session.replCells[pos.row];
if (oldCell)
oldCell.destroy();
this.session.replCells[pos.row] = newCell;
this.$updateSession();
return newCell;
};
this.$updateSession = function() {
var session = this.session;
session.$decorations = [];
var lastType = "";
session.replCells.forEach(function(c, row) {
if (!c) {
if (lastType)
session.$decorations[row] = lastType;
return;
}
var dec = "";
if (c.type == "input") {
dec = "repl_prompt ";
lastType = "repl_dots ";
} else if (c.type == "output") {
dec = "repl_output ";
lastType = "repl_nonum ";
}
if (c && c.waiting)
dec += "waiting ";
session.$decorations[row] = dec;
});
session.addGutterDecoration(0, session.$decorations[0]);
session.lineWidgets = session.replCells.map(function(c) {
return c && c.lineWidget;
});
};
this.updateCellsOnChange = function(delta) {
var startRow = delta.start.row;
var len = delta.end.row - startRow;
var range = this.$trackedRange;
var cells = this.session.replCells;
if (len === 0) {
} else if (delta.action == "remove") {
var removed = cells.splice(startRow + 1, len);
removed.forEach(function(cell) {
if (cell) {
cell.destroy();
}
});
if (range && range.start.row <= startRow && range.end.row >= startRow) {
this.$trackedRange.end.row = Math.max(this.$trackedRange.end.row - len, this.$trackedRange.start.row);
}
if (cells.length <= 1)
this.ensureLastInputCell();
} else {
var args = Array(len);
args.unshift(startRow + 1, 0);
cells.splice.apply(cells, args);
if (range && range.start.row <= startRow && range.end.row >= startRow) {
this.$trackedRange.end.row += len;
}
}
this.$updateSession();
this.session._signal("updateCells");
};
this.$tokenizeRow = function(row) {
var line = this.doc.getLine(row);
var state = this.states[row - 1];
var cell = this.session.replCells[row];
if (!cell && !state) {
cell = this.session.repl.getCellAt(row);
}
if (cell) {
state = cell.tokenizerState || cell.type;
if (!this.tokenizer.regExps[state])
state = "start";
}
var data = this.tokenizer.getLineTokens(line, state, row);
if (this.states[row] + "" !== data.state + "") {
if (!this.states[row] || !this.states[row].cellData)
this.states[row] = data.state;
this.lines[row + 1] = null;
if (this.currentLine > row + 1)
this.currentLine = row + 1;
} else if (this.currentLine == row) {
this.currentLine = row + 1;
}
if (this.session.repl.onTokenizeRow)
data.tokens = this.session.repl.onTokenizeRow(row, data.tokens) || data.tokens;
return this.lines[row] = data.tokens;
};
this.addLineWidget = function(w) {
var renderer = this.editor.renderer;
if (w.html && !w.el) {
w.el = dom.createElement("div");
w.el.innerHTML = w.html;
}
if (w.el) {
dom.addCssClass(w.el, "ace_lineWidgetContainer");
renderer.container.appendChild(w.el);
w._inDocument = true;
}
if (!w.coverGutter) {
w.el.style.zIndex = 3;
}
if (!w.pixelHeight) {
w.pixelHeight = w.el.offsetHeight;
}
if (w.rowCount == null)
w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
this.session._emit("changeFold", { data: { start: { row: w.row }}});
this.$updateSession();
this.updateWidgets(null, renderer);
return w;
};
this.removeLineWidget = function(w) {
w._inDocument = false;
if (w.el && w.el.parentNode)
w.el.parentNode.removeChild(w.el);
if (w.editor && w.editor.destroy) try {
w.editor.destroy();
} catch (e) {}
this.session._emit("changeFold", { data: { start: { row: w.row }}});
this.$updateSession();
};
this.onWidgetChanged = function(w) {
this.session._changedWidgets.push(w);
this.editor && this.editor.renderer.updateFull();
};
this.measureWidgets = function(e, renderer) {
var ws = this.session._changedWidgets;
var config = renderer.layerConfig;
if (!ws || !ws.length) return;
var min = Infinity;
for (var i = 0; i < ws.length; i++) {
var w = ws[i].lineWidget;
if (!w._inDocument) {
w._inDocument = true;
renderer.container.appendChild(w.el);
}
w.h = w.el.offsetHeight;
if (!w.fixedWidth) {
w.w = w.el.offsetWidth;
w.screenWidth = Math.ceil(w.w / config.characterWidth);
}
var rowCount = w.h / config.lineHeight;
if (w.coverLine)
rowCount -= this.session.getRowLineCount(w.row);
if (w.rowCount != rowCount) {
w.rowCount = rowCount;
if (w.row < min)
min = w.row;
}
}
if (min != Infinity) {
this.session._emit("changeFold", { data: { start: { row: min }}});
this.session.lineWidgetWidth = null;
}
this.session._changedWidgets = [];
};
this.updateWidgets = function(e, renderer) {
var config = renderer.layerConfig;
var cells = this.session.replCells;
if (!cells)
return;
var first = Math.min(this.firstRow, config.firstRow);
var last = Math.max(this.lastRow, config.lastRow, cells.length);
while (first > 0 && !cells[first])
first--;
this.firstRow = config.firstRow;
this.lastRow = config.lastRow;
renderer.$cursorLayer.config = config;
for (var i = first; i <= last; i++) {
var c = cells[i];
var w = c && c.lineWidget;
if (!w || !w.el) continue;
if (!w._inDocument) {
w._inDocument = true;
renderer.container.appendChild(w.el);
}
var top = renderer.$cursorLayer.getPixelPosition({ row: i, column: 0 }, true).top;
if (!w.coverLine)
top += config.lineHeight * this.session.getRowLineCount(w.row);
w.el.style.top = top - config.offset + "px";
var left = w.coverGutter ? 0 : renderer.gutterWidth;
if (!w.fixedWidth)
left -= renderer.scrollLeft;
w.el.style.left = left + "px";
if (w.fixedWidth) {
w.el.style.right = renderer.scrollBar.getWidth() + "px";
} else {
w.el.style.right = "";
}
}
};
}).call(Repl.prototype);
var History = function() {
this._data = [];
this._tempData = Object.create(null);
this.position = 0;
};
History.prototype = {
add: function(text) {
if (text && this._data[0] !== text) {
this._data.unshift(text);
}
delete this._tempData[this.position];
this.position = -1;
this._tempData[-1] = "";
return this._data;
},
navigateList: function(type, value) {
var lines = this._data;
if (value && (lines[this.position] != value)) {
this._tempData[this.position] = value;
}
if (type == "next") {
if (this.position <= 0) {
this.position = -1;
return this._tempData[this.position] || "";
}
var next = Math.max(0, this.position - 1);
}
else if (type == "prev")
next = Math.min(lines.length - 1, this.position + 1);
else if (type == "last")
next = Math.max(lines.length - 1, 0);
else if (type == "first")
next = 0;
if (lines[next] && next != this.position) {
this.position = next;
return this._tempData[next] || lines[next];
}
}
};
function clonePos(pos) {
return { row: pos.row, column: pos.column };
}
function setPos(pos, newPos) {
pos.row = newPos.row;
pos.column = newPos.column;
}
function clipPos(pos, range) {
if (comparePoints(pos, range.start) < 0) {
setPos(pos, range.start);
} else if (comparePoints(pos, range.end) > 0) {
setPos(pos, range.end);
}
}
Range.prototype.clip = function(range) {
clipPos(this.start, range);
clipPos(this.end, range);
};
function setClipToRange(anchor, range) {
anchor.$clip_default = Anchor.prototype.$clipPositionToDocument;
if (!range) {
anchor.$clipPositionToDocument = anchor.$clip_default;
return;
}
anchor.$clipPositionToDocument = function(row, column) {
var pos = this.$clip_default(row, column);
clipPos(pos, range);
return pos;
};
}
// dummy example
var Evaluator = function() {
};
(function() {
this.canEvaluate = function(str) {
return !!str.trim();
};
this.evaluate = function(str, cell, cb) {
cb("evaluator is missing!");
};
}).call(Evaluator.prototype);
Repl.fromEditor = function(editor, options) {
// todo different modes for input and output
var repl = new Repl(editor.session, options);
// this should happen on session.changeEditor event
repl.attach(editor);
editor.setOption("showPrintMargin", false);
return repl;
};
exports.Repl = Repl;
});

Wyświetl plik

@ -0,0 +1,154 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var Anchor = require("ace/anchor").Anchor;
var Range = require("ace/range").Range;
var comparePoints = Range.comparePoints;
var lang = require("ace/lib/lang");
var ReplCell = function(options, session) {
this.session = session;
this.type = options.type;
};
(function() {
this.insert = function(pos, text) {
if (typeof pos == "string") {
text = pos;
pos = this.getRange().end;
}
this.session.insert(pos, text);
};
this.setPlaceholder = function(str) {
this.placeholder = str;
};
this.setMode = function() {
};
this.setWaiting = function(val) {
this.waiting = val;
this.session.repl.$updateSession();
};
this.prompt = "";
this.promptType = null;
this.setPrompt = function(str, type) {
if (this.prompt == str)
return;
this.promptType = type;
this.prompt = (str || "") + " ";
this.session.maxPromptLength = Math.max(this.session.maxPromptLength || 0, this.prompt.length);
};
this.setValue = function(val, selection) {
if (!this.session)
return;
if (val == null)
return this.remove();
if (this.lineWidget && val.trim())
this.removeWidget();
this.$updateRange();
var pos = this.session.doc.replace(this.range, val);
this.range.setEnd(pos);
if (selection == 1)
this.session.selection.setRange({ start: this.range.end, end: this.range.end });
else if (selection == -1)
this.session.selection.setRange({ start: this.range.start, end: this.range.start });
};
this.getValue = function() {
if (!this.session)
return "";
return this.session.doc.getTextRange(this.range);
};
this.getRange = function() {
this.$updateRange();
return this.range;
};
this.$updateRange = function(row) {
var cells = this.session.replCells;
if (row == null)
row = cells.indexOf(this);
for (i = row; i > 0; i--) {
if (cells[i])
break;
}
var cell = cells[i];
if (!cell)
return;
cell.row = i;
for (var i = row + 1; i < this.session.getLength(); i++) {
if (cells[i])
break;
}
cell.endRow = i - 1;
cell.range = new Range(cell.row, 0, cell.endRow, Number.MAX_VALUE);
return this.range;
};
this.removeWidget = function() {
if (this.lineWidget) {
var w = this.lineWidget;
this.lineWidget = null;
this.session.repl.removeLineWidget(w);
}
};
this.addWidget = function(options) {
if (this.lineWidget)
this.removeWidget();
this.setValue("");
options.row = this.range.end.row;
this.lineWidget = options;
this.session.repl.addLineWidget(this.lineWidget);
};
this.destroy = function() {
this.removeWidget();
this.session = null;
};
this.remove = function() {
if (this.session)
this.session.repl.removeCell(this);
};
}).call(ReplCell.prototype);
exports.ReplCell = ReplCell;
});

Wyświetl plik

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>ReplAce</title>
<style>
#editor {
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
}
</style>
</head>
<body>
<div id="editor"></div>
<script src="/static/mini_require.js"></script>
<script src="/configs/require_config.js"></script>
<script src="/static/test.js"></script>
<script>
require(["ace/ace", "plugins/c9.ide.ace.repl/repl", "plugins/c9.ide.ace.repl/notebook"], function(ace, repl, nb) {
editor = ace.edit("editor")
editor.session.setMode(new nb.Mode)
editor.commands.addCommands(nb.commands)
});
</script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,95 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
require("ace/lib/fixoldbrowsers");
require("ace/config").set("packaged", false);
require("ace/line_widgets");
var dom = require("ace/lib/dom");
var net = require("ace/lib/net");
var lang = require("ace/lib/lang");
var useragent = require("ace/lib/useragent");
var event = require("ace/lib/event");
var theme = require("ace/theme/textmate");
var EditSession = require("ace/edit_session").EditSession;
var UndoManager = require("ace/undomanager").UndoManager;
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
var Editor = require("ace/editor").Editor;
var MultiSelect = require("ace/multi_select").MultiSelect;
/*********** create editor ***************************/
var container = document.getElementById("editor");
var editor = new Editor(new Renderer(container));
require("ace/multi_select").MultiSelect(editor);
editor.session.setUndoManager(new UndoManager);
editor.on("click", function(e) {
if (e.domEvent.target.className == "ace_repl_button") {
var pos = e.getDocumentPosition();
var input = document.forms[0].upfile;
input.onchange = function() {
editor.session.insert(pos, "\x01" + input.value + "\x02");
};
input.click();
}
});
window.editor = editor;
require("./repl").Repl.fromEditor(editor, {
mode: "logiql_command_mode",
evaluator: new (require("./evaluator").Evaluator)
});
/*********** manage layout ***************************/
var consoleHeight = 20;
function onResize() {
editor.resize();
}
window.onresize = onResize;
onResize();
});

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.split

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.split",
"description": "The repository for c9.ide.ace.split, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.split.git"
},
"plugins": {
"split": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,372 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "ui", "ace", "tabbehavior", "menus", "tabManager"
];
main.provides = ["ace.split"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var ace = imports.ace;
var event = require("ace/lib/event");
var Editor = require("ace/editor").Editor;
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var editors = [], splits = {};
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
ace.on("create", function(e) {
if (e.editor.type != "ace")
return;
draw();
var editor = e.editor;
var grabber;
editor.once("draw", function() {
grabber = createGrabber(editor);
}, plugin);
editor.on("documentActivate", function(e) {
var doc = e.doc;
var session = doc.getSession();
var split = session.split;
var splitInfo = splits[doc.editor.name];
// If we are not in split mode and the editor is not split
// lets do nothing.
if (!split && !splitInfo)
return;
if (split) {
// Make sure we have a split inited for this editor
if (!splitInfo)
splitInfo = initSplit(editor, split.height);
var editor2 = splitInfo.editor2;
// Set Session
editor2.setSession(split.session2);
// Set Height
splitInfo.topPane.setHeight(split.height);
// Show bottom pane
splitInfo.topPane.show();
// Hide Grabber
grabber.style.display = "none";
}
else {
// Hide bottom pane
splitInfo.topPane.hide();
// Show Grabber
grabber.style.display = "block";
}
});
editor.on("getState", function(e) {
var session = e.doc.getSession();
var state = e.state;
if (e.filter || !session.split)
return;
var session2 = session.split.session2;
state.split = {
height: session.split.height,
// Scroll state
scrolltop: session2.getScrollTop(),
scrollleft: session2.getScrollLeft(),
// Selection
selection: session2.selection.toJSON()
};
});
editor.on("setState", function(e) {
var state = e.state.split;
var session = e.doc.getSession();
if (!state)
return;
var splitInfo = initSplit(editor, state.height);
var session2 = ace.cloneSession(session.session);
session.split = {
height: state.height,
session2: session2
};
// Set 2nd Session
splitInfo.editor2.setSession(session2);
// Set selection
if (state.selection)
session2.selection.fromJSON(state.selection);
// Set scroll state
if (state.scrolltop)
session2.setScrollTop(state.scrolltop);
if (state.scrollleft)
session2.setScrollLeft(state.scrollleft);
if (state.options)
session2.setOptions(state.options);
var grabber = editor.aml.$int.querySelector(".splitgrabber");
grabber.style.display = "none";
});
editor.on("resize", function(e) {
var splitInfo = splits[editor.name];
if (!splitInfo || !splitInfo.topPane.visible) return;
splitInfo.editor2.resize(true); // @Harutyun
});
editor.on("unload", function(e) {
delete splits[editor.name];
});
});
}
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
// Insert CSS
ui.insertCss(require("text!./style.css"), plugin);
emit("draw");
}
function createGrabber(editor) {
var htmlNode = editor.ace.container.parentNode;
var grabber = document.createElement("div");
htmlNode.appendChild(grabber);
grabber.className = "splitgrabber";
grabber.innerHTML = "=";
grabber.addEventListener("mousedown", function(e) {
startSplit(e, grabber, editor);
});
plugin.addOther(function() {
grabber.parentNode.removeChild(grabber);
});
return grabber;
}
/***** Methods *****/
function startSplit(e, grabber, editor) {
var container = grabber;
var drag = grabber;
// Set Top
drag.style.zIndex = 1000000;
var offsetY = e.clientY - (parseInt(container.style.top, 10) || 0);
var moved = false;
var startY = e.clientY - offsetY;
var offset = e.offsetY;
var session = editor.activeDocument.getSession();
event.capture(container, function(e) {
var y = e.clientY - offsetY;
if (!moved) {
if (Math.abs(y - startY) > 3) {
moved = true;
var percentage = ((y - startY) / grabber.parentNode.offsetHeight) * 100;
session.split = {
height: percentage + "%",
session2: ace.cloneSession(session.session)
};
var splitInfo = initSplit(editor, percentage);
// Set 2nd Session
splitInfo.editor2.setSession(session.split.session2);
// Start splitter
splitInfo.splitbox.$handle.$ext.onmousedown({
clientY: e.clientY,
offsetY: -7 + offset
});
// Hide Grabber
grabber.style.display = "none";
}
else return;
}
}, function() {
if (moved)
setFinalState(editor, session);
});
event.stopEvent(e);
}
function initSplit(editor, percentage) {
if (splits[editor.name]) {
var splitInfo = splits[editor.name];
splitInfo.topPane.show();
return splitInfo;
}
var container = editor.aml.$int;
var amlNode = container.host;
// @todo detect if this already happened
var splitbox = amlNode.appendChild(new ui.vsplitbox({
"class": "ace_split",
padding: 7,
edge: "7 0 0 0",
splitter: true
}));
var topPane = splitbox.appendChild(new ui.bar({
height: percentage + "%"
}));
var bottomPane = splitbox.appendChild(new ui.bar());
// Original Editor
bottomPane.$int.appendChild(editor.ace.container);
editor.ace.container.style.top = "0px";
// New Editor
var editor2 = new Editor(new Renderer(topPane.$int, ace.theme));
editors.push(editor2);
splitbox.$handle.on("dragmove", function() {
editor.resize();
editor2.resize();
});
splitbox.$handle.on("dragdrop", function() {
editor.resize();
editor2.resize();
var session = editor.activeDocument.getSession();
setFinalState(editor, session);
});
ace.on("settingsUpdate", function(e) {
editor2.setOptions(e.options);
}, editor);
function setTheme() {
var theme = ace.theme;
editor2.setTheme(theme.path);
var node = splitbox.$ext.parentNode;
if (theme.isDark)
ui.setStyleClass(node, "dark");
else
ui.setStyleClass(node, "", ["dark"]);
}
ace.on("themeChange", setTheme, editor);
setTheme();
var lastFocused = editor2;
editor2.on("focus", function() {
lastFocused = editor2;
});
editor.ace.on("focus", function() {
lastFocused = null;
});
editor.on("getAce", function() {
if (lastFocused)
return editor2;
});
editor.addEditor(editor2);
splits[editor.name] = {
splitbox: splitbox,
topPane: topPane,
bottomPane: bottomPane,
editor: editor,
editor2: editor2
};
return splits[editor.name];
}
function setFinalState(editor, session) {
var splitInfo = splits[editor.name];
var pixelHeight = splitInfo.topPane.getHeight();
var grabber = editor.aml.$int.querySelector(".splitgrabber");
if (pixelHeight < 3) {
// Remove the split
splitInfo.topPane.hide();
delete session.split;
// Show Grabber
grabber.style.display = "block";
}
else {
// Record the height
session.split.height = splitInfo.topPane.height;
// Hide Grabber
grabber.style.display = "none";
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
drawn = false;
});
/***** Register and define API *****/
/**
*
**/
plugin.freezePublicAPI({
_events: [
/**
* @event draw
*/
"draw"
]
});
register(null, {
"ace.split": plugin
});
}
});

Wyświetl plik

@ -0,0 +1,61 @@
.splitgrabber {
display: block;
width: 16px;
height: 7px;
position: absolute;
right: 0;
top: 0;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
vertical-align: top;
line-height: 9px;
font-family: Courier New;
font-size: 15px;
cursor: ns-resize;
pointer-events: all;
text-align: right;
padding-right: 3px;
z-index: 100;
color: rgba(0, 0, 0, 0.4);
text-shadow: 0 1px white;
}
.dark .splitgrabber {
color: rgba(255, 255, 255, 0.2);
text-shadow: 0 1px rgba(0, 0, 0, 0.34);
}
.splitgrabber:hover{
}
.ace_split{
height : 100%;
}
.ace_split .splitter.horizontal:after {
content: "=";
text-align: center;
width: 100%;
/*background: rgba(255, 255, 255, 0.105);*/
position: absolute;
height: 7px;
line-height: 8px;
font-size: 15px;
font-family: Courier New;
box-sizing: border-box;
color: rgba(0, 0, 0, 0.3);
border-top: 1px solid rgba(255, 255, 255, 0.6);
box-shadow: 0 -1px rgb(211, 211, 211);
text-shadow: 0 1px white;
}
.dark .ace_split .splitter.horizontal:after {
color: rgba(255, 255, 255, 0.23);
border-top: 1px solid rgba(255, 255, 255, 0.06);
box-shadow: 0 -1px rgba(0, 0, 0, 0.29);
text-shadow: none;
}
.ace_split .splitter.horizontal{
background: transparent !important;
}

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.statusbar

Wyświetl plik

@ -0,0 +1,37 @@
<a:application xmlns:a="http://ajax.org/2005/aml">
<a:menu id="menu"
class = "mnuSbPrefs"
sticky = "false"
render = "runtime">
<a:item type="check" caption="Show Invisibles" checked="user/ace/@showInvisibles" />
<a:item type="check" caption="Show Gutter" checked="user/ace/@showGutter" />
<a:item type="check" caption="Auto-pair Brackets, Quotes, etc." checked="user/ace/@behavioursEnabled" />
<a:item type="check" caption="Wrap Lines" id="itmSbWrap" />
<a:item type="check" style="margin-left:18px;position:relative" caption="&#8627; to Print Margin" id="itmSbWrapPM" />
<a:divider />
<a:hbox edge="0 5 2 23" align="center">
<a:label flex="1" style="padding: 2px 2px 2px 0">Font Size</a:label>
<a:spinner value="user/ace/@fontSize" realtime="true" min="1" max="72" width="50" />
</a:hbox>
</a:menu>
<a:menu id="menuTabs" render="runtime" class="mnuSbPrefs">
<a:item type="check" caption="Soft Tabs (spaces)" />
<a:divider />
<a:item disabled="true">Tab Size</a:item>
<a:item type="radio" caption="2" style="padding-left:35px" />
<a:item type="radio" caption="3" style="padding-left:35px" />
<a:item type="radio" caption="4" style="padding-left:35px" />
<a:item type="radio" caption="8" style="padding-left:35px" />
<a:divider />
<a:hbox edge="0 10 2 23" align="center">
<a:label style="padding: 2px 10px 2px 3px;flex:1 1 50px;">Other</a:label>
<a:spinner id="itmTabSize" realtime="true" min="1" max="64" width="50" />
</a:hbox>
<a:divider />
<a:item caption="Guess Tab Size" />
<a:divider />
<a:item caption="Convert to Spaces" />
<a:item caption="Convert to Tabs" />
</a:menu>
</a:application>

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.statusbar",
"description": "The repository for c9.ide.ace.statusbar, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.statusbar.git"
},
"plugins": {
"statusbar": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,113 @@
<?xml version='1.0'?>
<a:skin xmlns:a="http://ajax.org/2005/aml" xmlns="http://www.w3.org/1999/xhtml">
<a:bar name="bar-status">
<a:style><![CDATA[
.bar-status {
position : absolute;
color: rgba(0, 0, 0, 0.4);
border-radius: 4px;
white-space: nowrap;
}
.bar-status > *{
display : inline-block;
vertical-align : middle;
}
.bar-status .lbl_row_col {
text-align: center;
color: rgba(0, 0, 0, 0.4);
}
.bar-status .label {
color: @ace-status-color;
padding: @ace-status-padding;
overflow: visible;
text-shadow: 0px 1px 0px rgba(255,255,255,0.5);
.font-smoothing(true);
font-weight: @ace-status-font-weight;
font-size: @ace-status-font-size;
}
.bar-status.ace_dark .label {
color: rgba(255,255,255,0.5);
text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.57);
}
.mnuSbPrefs{
margin-top : -8px;
margin-left : 1px;
}
.mnuSbPrefs .label {
color : @menu-color;
}
.bar-status .label:hover{
text-decoration : @ace-status-label-hover-decoration;
color : @ace-status-label-hover-color;
}
.bar-status .label.labelDown{
color : @ace-status-label-active-color;
}
.bar-status .nounderline:hover{
text-decoration : none;
}
]]></a:style>
<a:presentation>
<a:main container=".">
<div class="bar-status">
</div>
</a:main>
</a:presentation>
</a:bar>
<a:button name="btn-statusbar-icon">
<a:style><![CDATA[
.btn-statusbar-icon {
height : 23px;
width : 22px;
overflow : hidden;
cursor : pointer;
position : relative;
cursor : default;
-moz-user-select : none;
-khtml-user-select : none;
user-select : none;
background-position : 0 0;
background-repeat : no-repeat;
margin: @ace-status-icon-margin !important;
.image-2x(@ace-status-icon-image, @ace-status-icon-image-width, @ace-status-icon-image-height, no-repeat, true);
}
.btn-statusbar-iconOver {
background-position : 0 -23px;
}
.btn-statusbar-iconDown {
background-position : 0 -46px;
}
.ace_dark .btn-statusbar-icon {
background-position : -22px 0;
}
.ace_dark .btn-statusbar-iconOver {
background-position : -22px -23px;
}
.ace_dark .btn-statusbar-iconDown {
background-position : -22px -46px;
}
]]></a:style>
<a:presentation>
<a:main
caption = "text()"
background = "."
icon = ".">
<div class="btn-statusbar-icon"> </div>
</a:main>
</a:presentation>
</a:button>
</a:skin>

Wyświetl plik

@ -0,0 +1,485 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "c9", "settings", "ui", "menus", "ace",
"ace.gotoline", "tabManager"
];
main.provides = ["ace.status"];
return main;
function main(options, imports, register) {
var c9 = imports.c9;
var Plugin = imports.Plugin;
var settings = imports.settings;
var ui = imports.ui;
var tabs = imports.tabManager;
var menus = imports.menus;
var gotoline = imports["ace.gotoline"];
var aceHandle = imports.ace;
var skin = require("text!./skin.xml");
var markup = require("text!./statusbar.xml");
var menuAml = require("text!./menu.xml");
var aceWhitespace = require("ace/ext/whitespace");
var lang = require("ace/lib/lang");
/***** Generic Load *****/
// Set up the generic handle
var handle = new Plugin("Ajax.org", main.consumes);
var statusbars = {};
var menuItem, menu, menuTabs;
handle.on("load", function() {
settings.on("read", function(e) {
settings.setDefaults("user/ace/statusbar", [["show", "true"]]);
}, handle);
menuItem = new ui.item({
test: "1",
type: "check",
checked: "user/ace/statusbar/@show"
// -> if you're looking for disabled, check the init function :-)
// the moment that someone clicks this thing well call preinit
// (its already called if the user has it checked on IDE load)
});
menus.addItemByPath("View/Status Bar", menuItem, 600, handle);
aceHandle.on("create", function(e) {
if (e.editor.type != "ace")
return;
var editor = e.editor;
var statusbar;
editor.once("draw", function() {
statusbar = new Statusbar(editor);
}, editor);
editor.once("unload", function h2() {
if (statusbar) statusbar.unload();
}, editor);
});
ui.insertMarkup(null, menuAml, handle);
menu = handle.getElement("menu");
menuTabs = handle.getElement("menuTabs");
var currentSession;
function setCurrentSession(menu) {
var node = menu.opener;
while (node && node.localName != "tab")
node = node.parentNode;
if (!node) return;
var tab = node.cloud9pane.getTab();
currentSession = tab.document.getSession();
}
function setOption(name, value) {
if (currentSession) {
if (currentSession.setOption)
currentSession.setOption(name, value);
currentSession.statusBar.update();
}
}
function getOption(name) {
return currentSession && currentSession.session.getOption(name);
}
// Checkboxes
menu.on("afterrender", function(e) {
var itmSbWrap = window.itmSbWrap;
var itmSbWrapPM = window.itmSbWrapPM;
itmSbWrap.on("click", function() {
setOption("wrap", itmSbWrap.checked
? itmSbWrapPM.checked ? "printMargin" : true
: false);
});
itmSbWrapPM.on("click", function() {
setOption("wrap", itmSbWrapPM.checked
? "printMargin"
: itmSbWrap.checked);
});
function update(e) {
if (!e || e.value) {
setCurrentSession(menu);
var wrap = getOption("wrap");
itmSbWrap.setAttribute("checked", !ui.isFalse(wrap));
itmSbWrapPM.setAttribute("checked", wrap == "printMargin");
}
}
menu.on("prop.visible", update);
update();
});
// Menu Tab functionality
var handlers = [
function() { setOption("useSoftTabs", this.checked); },
function() {},
function() { setOption("tabSize", 2); },
function() { setOption("tabSize", 3); },
function() { setOption("tabSize", 4); },
function() { setOption("tabSize", 8); },
function() {
if (!currentSession) return;
aceWhitespace.detectIndentation(currentSession.session);
currentSession.setOption("guessTabSize", true);
currentSession.statusBar.update();
},
// Tabs to Spaces
function() {
if (!currentSession) return;
aceWhitespace.convertIndentation(currentSession.session, " ");
currentSession.statusBar.update();
},
// Spaces to Tabs
function() {
if (!currentSession) return;
aceWhitespace.convertIndentation(currentSession.session, "\t");
currentSession.statusBar.update();
}
];
menuTabs.on("afterrender", function(e) {
var items = menuTabs.selectNodes("a:item");
items.forEach(function(node, idx) {
node.on("click", handlers[idx]);
});
var itmTabSize = window.itmTabSize;
itmTabSize.on("afterchange", function() {
setOption("tabSize", this.value);
update();
});
var lut = [0, 0, 2, 3, 4, 0, 0, 0, 5];
function update(e) {
if (e && !e.value)
return;
setCurrentSession(menuTabs);
items[0].setAttribute("checked", getOption("useSoftTabs"));
var tabSize = getOption("tabSize") || 1;
items.forEach(function(node, idx) {
node.setAttribute("selected", "false");
});
if (lut[tabSize])
items[lut[tabSize]].setAttribute("selected", "true");
itmTabSize.setAttribute("value", getOption("tabSize"));
}
menuTabs.on("prop.visible", update);
update();
});
});
handle.on("unload", function() {
drawn = false;
Object.keys(statusbars).forEach(function(name) {
statusbars[name].unload();
});
statusbars = {};
menuItem = null;
menu = null;
menuTabs = null;
});
/***** Methods *****/
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
// Import Skin
ui.insertSkin({
name: "c9statusbar",
data: skin,
"media-path": options.staticPrefix + "/images/",
"icon-path": options.staticPrefix + "/icons/"
}, handle);
}
function getStatusbar(editor) {
return statusbars[editor.name];
}
function show() {
settings.set("user/ace/statusbar/@show", "true");
}
function hide() {
settings.set("user/ace/statusbar/@show", "false");
}
/***** Register and define API *****/
/**
* Manages the status bar instances for ace.
* @singleton
**/
handle.freezePublicAPI({
/**
* Show all the status bars.
*/
show: show,
/**
* Hide all the status bars.
*/
hide: hide,
/**
* Retrieve the status bar that belongs to an ace editor.
* @param {Editor} ace The ace editor the status bar belongs to.
* @return {ace.status.Statusbar}
*/
getStatusbar: getStatusbar,
/**
* Inserts CSS for the statusbar.
* @private
*/
draw: draw
});
/***** Initialization *****/
function Statusbar(editor) {
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var showRange;
var bar, lblSelection, lblStatus, lblRowCol, lblTabs, lblSyntax; // ui elements
statusbars[editor.name] = plugin;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
function updateBarVisible() {
if (!settings.getBool("user/ace/statusbar/@show")) {
bar && bar.hide();
menuItem.enable();
}
else {
draw();
bar.show();
menuItem.enable();
}
}
settings.on("user/ace/statusbar", updateBarVisible, plugin);
if (settings.getBool("user/ace/statusbar/@show"))
draw();
editor.on("documentLoad", function(e) {
var doc = e.doc;
var session = doc.getSession();
session.statusBar = plugin;
session.session.on("changeMode", function(e) { statusUpdate.schedule(); });
if (!doc.hasValue())
doc.once("setValue", function() {
statusUpdate.schedule();
}, doc);
}, plugin);
editor.on("documentActivate", function(e) { statusUpdate.schedule(); }, plugin);
editor.on("documentUnload", function(e) {
delete e.doc.getSession().statusBar;
}, plugin);
}
var drawn = false;
function draw() {
if (drawn) return;
drawn = true;
handle.draw();
// Create UI elements
var htmlNode = editor.aml; //ace.container.parentNode.host;
ui.insertMarkup(htmlNode, markup, plugin);
function setTheme(e) {
var theme = e.theme;
if (!theme) return;
var cssClass = theme.cssClass;
var isDark = theme.isDark;
var bg = ui.getStyleRule("." + cssClass, "backgroundColor");
bar.setAttribute("class", isDark ? "ace_dark" : "");
if (bg) {
// bg = bg.replace(/rgb\((.*)\)/, "rgba($1, 0.9)");
bar.$ext.style.backgroundColor = bg;
}
}
editor.on("themeChange", setTheme);
bar = plugin.getElement("bar");
lblSelection = plugin.getElement("lblSelectionLength");
lblStatus = plugin.getElement("lblEditorStatus");
lblRowCol = plugin.getElement("lblRowCol");
lblTabs = plugin.getElement("lblTabs");
lblSyntax = plugin.getElement("lblSyntax");
// For editor search of submenus
bar.editor = editor;
// Set sub menus
var button = plugin.getElement("btnSbPrefs");
button.setAttribute("submenu", menu);
lblTabs.setAttribute("submenu", menuTabs);
var mnuSyntax = menus.get("View/Syntax").menu;
lblSyntax.setAttribute("submenu", mnuSyntax);
lblSyntax.on("mousedown", function() {
if (editor.activeDocument)
tabs.focusTab(editor.activeDocument.tab);
});
// Click behavior for the labels
lblSelection.on("click", function() {
showRange = !showRange;
updateStatus();
});
lblRowCol.on("click", function() {
gotoline.gotoline(null, null, true);
});
// Hook into ace
var ace = editor.ace;
if (!ace.$hasStatusBar) {
// Throttle UI updates
ace.on("changeSelection", function() { selStatusUpdate.schedule(); });
ace.on("changeStatus", function() { statusUpdate.schedule(); });
ace.on("keyboardActivity", function() { statusUpdate.schedule(); });
ace.renderer.on("scrollbarVisibilityChanged", function(e, renderer) {
bar.$ext.style.right = renderer.scrollBarV.getWidth() + 5 + "px";
bar.$ext.style.bottom = renderer.scrollBarH.getHeight() + 3 + "px";
})(null, ace.renderer);
ace.$hasStatusBar = true;
var theme = editor.theme;
setTheme({ theme: theme });
}
// Update status information
updateStatus();
emit("draw");
}
var selStatusUpdate = lang.delayedCall(updateSelStatus, 10);
var statusUpdate = lang.delayedCall(updateStatus, 10);
/***** Helper Functions *****/
function updateSelStatus() {
var ace = editor.ace;
if (!ace || !drawn || !ace.selection) return;
if (!ace.selection.isEmpty()) {
var range = ace.getSelectionRange();
var selLen;
if (showRange) {
selLen = "(" +
(range.end.row - range.start.row) + ":" +
(range.end.column - range.start.column) + ")";
}
else {
selLen = "(" + ace.session.getTextRange(range).length + " Bytes)";
}
lblSelection.setAttribute("caption", selLen);
}
else {
lblSelection.setAttribute("caption", "");
}
var cursor = ace.selection.lead;
var columnText = (cursor.row + 1) + ":" + (cursor.column + 1);
if (ace.selection.rangeCount)
columnText += " &#91;" + ace.selection.rangeCount + "\u202f]";
lblRowCol.setAttribute("caption", columnText);
}
function updateStatus() {
var ace = editor.ace;
if (!ace || !drawn) return;
updateSelStatus();
lblTabs.setAttribute("caption",
(ace.getOption("useSoftTabs") ? "Spaces" : "Tabs") + ": "
+ ace.getOption("tabSize")); // "\\[" + + "\\]");
var status = ace.keyBinding.getStatusText() || "";
if (ace.commands.recording)
status = "REC";
lblStatus.setAttribute("caption", status);
var caption = aceHandle.getSyntaxCaption(ace.session.syntax);
lblSyntax && lblSyntax.setAttribute("caption", caption);
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
* The status bar for ace editors.
* @class ace.status.Statusbar
**/
plugin.freezePublicAPI({
/**
* Redraw the display of the statusbar
*/
update: updateStatus
});
plugin.load(null, "acestatus");
return plugin;
}
register(null, {
"ace.status": handle
});
}
});

Wyświetl plik

@ -0,0 +1,44 @@
<a:application xmlns:a="http://ajax.org/2005/aml">
<a:bar id="bar"
skin = "bar-status"
skinset = "c9statusbar"
class = ""
zindex = "10000"
style = "position:absolute;right:5px;bottom:3px;"
height = "23">
<a:label id="lblSelectionLength"
caption = ""
style = "cursor:pointer"
margin = "1 10 4 3"
visible = "{this.caption != ''}" />
<a:label id="lblRowCol"
class = "lbl_row_col"
style = "cursor:pointer"
margin = "1 10 4 3" />
<a:label id="lblEditorStatus"
caption = ""
class = "nounderline"
margin = "1 10 4 3"
visible = "{this.caption != ''}" />
<a:button id="lblSyntax"
skin = "label"
style = "cursor:pointer"
caption = ""
margin = "1 10 4 3"
visible = "{this.caption != ''}"
submenudir = "up" />
<a:button id="lblTabs"
skin = "label"
style = "cursor:pointer"
caption = ""
margin = "1 10 4 3"
visible = "{this.caption != ''}"
submenudir = "up" />
<a:button id="btnSbPrefs"
skin = "btn-statusbar-icon"
skinset = "c9statusbar"
height = "23"
icon = "pref-ico.png"
submenudir = "up" />
</a:bar>
</a:application>

Wyświetl plik

@ -0,0 +1,199 @@
/*global describe it before after apf bar = */
"use client";
require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai) {
var expect = chai.expect;
expect.setupArchitectTest([
{
packagePath: "plugins/c9.core/c9",
workspaceId: "ubuntu/ip-10-35-77-180",
startdate: new Date(),
debug: true,
hosted: true,
local: false,
davPrefix: "/"
},
"plugins/c9.core/ext",
"plugins/c9.core/http-xhr",
"plugins/c9.core/util",
"plugins/c9.ide.ui/lib_apf",
"plugins/c9.ide.ui/menus",
{
packagePath: "plugins/c9.core/settings",
testing: true
},
"plugins/c9.core/api.js",
{
packagePath: "plugins/c9.ide.ui/ui",
staticPrefix: "plugins/c9.ide.ui"
},
"plugins/c9.ide.editors/document",
"plugins/c9.ide.editors/undomanager",
{
packagePath: "plugins/c9.ide.editors/editors",
defaultEditor: "ace"
},
"plugins/c9.ide.editors/editor",
"plugins/c9.ide.editors/tabmanager",
"plugins/c9.ide.ui/focus",
"plugins/c9.ide.editors/pane",
"plugins/c9.ide.editors/tab",
"plugins/c9.ide.ace/ace",
{
packagePath: "plugins/c9.ide.ace.statusbar/statusbar",
staticPrefix: "plugins/c9.ide.layout.classic"
},
"plugins/c9.ide.keys/commands",
"plugins/c9.fs/proc",
"plugins/c9.vfs.client/vfs_client",
"plugins/c9.vfs.client/endpoint",
"plugins/c9.ide.auth/auth",
"plugins/c9.fs/fs",
// Mock plugins
{
consumes: ["apf", "ui", "Plugin"],
provides: [
"commands", "menus", "layout", "watcher",
"save", "preferences", "anims", "gotoline", "clipboard",
"dialog.alert", "auth.bootstrap", "info", "ace.gotoline",
"dialog.error"
],
setup: expect.html.mocked
},
{
consumes: ["tabManager", "ace"],
provides: [],
setup: main
}
], architect);
function main(options, imports, register) {
var tabs = imports.tabManager;
var ace = imports.ace;
function getTabHtml(tab) {
return tab.pane.aml.getPage("editor::" + tab.editorType).$ext;
}
expect.html.setConstructor(function(tab) {
if (typeof tab == "object")
return tab.$ext;
});
describe('statusbar', function() {
before(function(done) {
apf.config.setProperty("allow-select", false);
apf.config.setProperty("allow-blur", false);
bar.$ext.style.background = "rgba(220, 220, 220, 0.93)";
bar.$ext.style.position = "fixed";
bar.$ext.style.left = "20px";
bar.$ext.style.right = "20px";
bar.$ext.style.bottom = "20px";
bar.$ext.style.height = "33%";
document.body.style.marginBottom = "33%";
tabs.once("ready", function() {
tabs.getPanes()[0].focus();
done();
});
});
describe("open", function() {
this.timeout(10000);
it('should open a pane with just an editor', function(done) {
tabs.openFile("/file.txt", function(err, tab) {
expect(!err);
expect(tabs.getTabs()).length(1);
// statusbar is added only after editor draw event
// TODO make this api easier to use
setTimeout(function() {
var sb = tab.document.getSession().statusBar;
var bar = sb.getElement("bar");
expect.html(bar, "rowcol").text("1:1");
tab.document.editor.ace.selectAll();
setTimeout(function() {
expect.html(bar, "rowcol sel").text("2:1");
expect.html(bar, "sel").text("23 Bytes");
done();
}, 10);
});
});
});
it('should handle multiple documents in the same pane', function(done) {
tabs.openFile("/listing.json", function(err, tab) {
expect(!err);
expect(tabs.getTabs()).length(2);
tab.activate();
setTimeout(function() {
var sb = tab.document.getSession().statusBar;
expect.html(sb.getElement("bar"), "caption").text("1:1");
done();
}, 10);
});
});
});
describe("split(), pane.unload()", function() {
it('should split a pane horizontally, making the existing pane the left one', function(done) {
var pane = tabs.focussedTab.pane;
var righttab = pane.hsplit(true);
tabs.focussedTab.attachTo(righttab);
setTimeout(function() {
expect.html(pane.aml, "pane").text("2:1");
expect.html(righttab.aml, "righttab").text("1:1");
done();
}, 100);
});
// it('should remove the left pane from a horizontal split', function(done) {
// var pane = tabs.getPanes()[0];
// var tab = tabs.getPanes()[1].getTab();
// pane.unload();
// expect(tabs.getPanes()).length(1);
// expect(tabs.getTabs()).length(2);
// tabs.focusTab(tab);
// done();
// });
});
// describe("Change Theme", function(){
// this.timeout(10000);
//
// it('should change a theme', function(done) {
// var editor = tabs.focussedTab.editor;
// ace.on("themeInit", function setTheme(){
// ace.off("theme.init", setTheme);
// expect.html(getTabHtml(tabs.focussedTab).childNodes[1]).className("ace-monokai");
// editor.setOption("theme", "ace/theme/textmate");
// done();
// });
// editor.setOption("theme", "ace/theme/monokai");
// });
// });
// @todo test split api and menu
if (!onload.remain) {
after(function(done) {
tabs.unload();
document.body.style.marginBottom = "";
done();
});
}
});
onload && onload();
}
});

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.ace.stripws

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.ace.stripws",
"description": "The repository for c9.ide.ace.stripws, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.ace.stripws.git"
},
"plugins": {
"stripws": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,130 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "menus", "commands", "tabManager", "settings",
"preferences", "save", "ui"
];
main.provides = ["ace.stripws"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var menus = imports.menus;
var commands = imports.commands;
var tabs = imports.tabManager;
var settings = imports.settings;
var prefs = imports.preferences;
var save = imports.save;
var ui = imports.ui;
var whitespaceUtil = require("ace/ext/whitespace");
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var disabled = false;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
commands.addCommand({
name: "stripws",
hint: "strip whitespace at the end of each line",
exec: function() {
stripws();
},
isAvailable: function (editor) {
return editor && tabs.focussedTab &&
typeof tabs.focussedTab.path == "string";
}
}, plugin);
menus.addItemByPath("Tools/Strip Trailing Space", new ui.item({
command: "stripws"
}), 100, plugin);
menus.addItemByPath("Tools/~", new ui.divider(), 200, plugin);
save.on("beforeSave", function (e) {
var shouldStrip = settings.getBool("project/general/@stripws");
if (!shouldStrip || e.options.silentsave)
return;
var keepCursorPosition = settings.getBool("user/general/@stripwsKeepCursorPosition");
stripws(e.document.tab, {
keepCursorPosition: keepCursorPosition
});
}, plugin);
settings.on("read", function(e) {
settings.setDefaults("project/general", [
["stripws", !!settings.getBool("user/general/@stripws")]
]);
}, plugin);
prefs.add({
"Project": {
position: 150,
"Code Editor (Ace)": {
"On Save, Strip Whitespace": {
type: "checkbox",
position: 900,
path: "project/general/@stripws"
}
}
}
}, plugin);
}
/***** Methods *****/
function stripws(tab, options) {
tab = tab || tabs.focussedTab;
if (!tab || !tab.path || disabled)
return;
options = options || {};
options.trimEmpty = true;
var session = tab.document.getSession().session;
whitespaceUtil.trimTrailingSpace(session, options);
session.$syncInformUndoManager();
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
disabled = false;
});
plugin.on("disable", function() {
disabled = true;
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
* Strips trailing whitespace from lines just before a file is saved.
* @singleton
**/
plugin.freezePublicAPI({
/*
* Strips whitespace at the end of each line in the given page
* @param {Tab} tab The tab to strip the whitespace from
* If not provided, the currently focussed tab will be used instead
*/
strpws: stripws
});
register(null, {
"ace.stripws": plugin
});
}
});

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.behaviors

Wyświetl plik

@ -0,0 +1,291 @@
define(function(require, exports, module) {
main.consumes = ["Plugin", "ui", "dashboard"];
main.provides = ["dashboardbehavior"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var dashboard = imports.dashboard;
/***** Initialization *****/
var handle = new Plugin("Ajax.org", main.consumes);
// var emit = handle.getEmitter();
var divSplit;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
// @todo how to make sure this happens only once?
var css = require("text!./style.css");
ui.insertCss(css, options.staticPrefix, handle);
dashboard.on("widgetCreate", function(e) {
if (e.widget.dashboard.configurable)
addInteraction(e.widget);
}, handle);
dashboard.on("widgetAfterClose", function(e) {
//@todo keep total tree small
}, handle);
}
function addInteraction(plugin) {
var widget = plugin.aml;
var titlebar = widget.oCaption && widget.oCaption.parentNode;
if (!titlebar) return;
var container = widget.$ext;
var offsetX, offsetY, startX, startY, dragWidth, dragHeight;
var originalBox, box, started, start;
var originalPosition, splitDirection, splitBox, originalSize;
function finish() {
divSplit.style.display = "none";
apf.removeListener(document, "mousemove", mouseMoveSplit);
apf.removeListener(document, "mouseup", mouseUpSplit);
container.style.zIndex =
container.style.opacity =
container.style.pointerEvents = "";
plugin.dashboard.widgets.forEach(function(widget) {
widget.aml.$int.style.pointerEvents = "";
});
widget.$dragging = false;
}
titlebar.addEventListener("mousedown", function(e) {
// APF stuff
widget.$dragging = true;
// Calculate where on the titlebar was clicked
var rect = container.getBoundingClientRect();
startX = e.clientX;
startY = e.clientY;
offsetX = startX - rect.left;
offsetY = startY - rect.top;
// Use mine
started = false;
// Set current box
box = widget.parentNode;
// Store original info
originalBox = box;
originalPosition = container.nextSibling;
originalSize = [container.style.left, container.style.top,
container.style.width, container.style.height,
ui.getStyle(container, "margin")];
dragWidth = container.offsetWidth;
dragHeight = container.offsetHeight;
// Div that shows where to insert split
if (!divSplit) {
divSplit = document.createElement("div");
divSplit.className = "split-area dark";
document.body.appendChild(divSplit);
}
// Fixate current position and width
start = function() {
rect = container.getBoundingClientRect();
container.style.width = (dragWidth - ui.getWidthDiff(container)) + "px";
container.style.height = (dragHeight - ui.getHeightDiff(container)) + "px";
// Prepare titlebar for dragging
container.style.zIndex = 100000;
container.style.opacity = 0.7;
container.style.margin = 0;
container.style.pointerEvents = "none";
plugin.dashboard.widgets.forEach(function(widget) {
widget.aml.$int.style.pointerEvents = "none";
});
document.body.appendChild(container);
};
apf.addListener(document, "mousemove", mouseMoveSplit);
apf.addListener(document, "mouseup", mouseUpSplit);
});
function showSplitPosition(e) {
var el = document.elementFromPoint(e.clientX, e.clientY);
var aml = apf.findHost(el);
while (aml && aml.localName != "frame")
aml = aml.parentNode;
// If aml is not the box we seek, lets abort
if (!aml) {
divSplit.style.display = "none";
splitBox = null;
splitDirection = null;
return;
}
// Find the rotated quarter that we're in
var rect = aml.$ext.getBoundingClientRect();
var left = (e.clientX - rect.left) / rect.width;
var right = 1 - left;
var top = (e.clientY - rect.top) / rect.height;
var bottom = 1 - top;
// Cannot split box that would be removed later
//@todo this needs to be a check against self
// if (aml.getWidgets().length === 0) { // && aml == originalBox
// divSplit.style.display = "none";
// splitBox = null;
// splitDirection = null;
// return;
// }
splitBox = aml;
// Anchor to closes side
var min = Math.min(left, top, right, bottom);
// Get titlebars height
var bHeight = aml.oCaption.parentNode.offsetHeight;
// Left
if (min == left) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = (rect.width / 2) + "px";
divSplit.style.height = (rect.height - bHeight) + "px";
splitDirection = "w";
}
// Right
else if (min == right) {
divSplit.style.left = rect.left + (rect.width / 2) + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = (rect.width / 2) + "px";
divSplit.style.height = (rect.height - bHeight) + "px";
splitDirection = "e";
}
// Top
else if (min == top) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = rect.width + "px";
divSplit.style.height = ((rect.height / 2) - bHeight) + "px";
splitDirection = "n";
}
// Bottom
else if (min == bottom) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (rect.top + (rect.height / 2)) + "px";
divSplit.style.width = rect.width + "px";
divSplit.style.height = (rect.height / 2) + "px";
splitDirection = "s";
}
divSplit.style.cursor = splitDirection + "-resize";
divSplit.style.display = "block";
}
function mouseMoveSplit(e) {
if (!started) {
if (Math.abs(startX - e.clientX) < 4
&& Math.abs(startY - e.clientY) < 4)
return;
started = true;
start();
}
container.style.left = (e.clientX - offsetX) + "px";
container.style.top = (e.clientY - offsetY) + "px";
return showSplitPosition(e);
}
function mouseUpSplit(e) {
apf.removeListener(document, "mousemove", mouseMoveSplit);
apf.removeListener(document, "mouseup", mouseUpSplit);
if (!started) return finish();
container.style.left = (e.clientX - offsetX) + "px";
container.style.top = (e.clientY - offsetY) + "px";
showSplitPosition(e);
if (splitBox) {
if (splitDirection == "n")
plugin.vsplit(splitBox, widget, false);
else if (splitDirection == "s")
plugin.vsplit(splitBox, widget, true);
else if (splitDirection == "w")
plugin.hsplit(splitBox, widget, false);
else if (splitDirection == "e")
plugin.hsplit(splitBox, widget, true);
var child = box.childNodes[0];
if (child.localName == "splitter")
child = box.childNodes[1];
var pNode = box.parentNode;
var next = box.nextSibling;
pNode.removeChild(box);
pNode.insertBefore(child, next);
if (box.edge) {
child.setAttribute("edge", box.edge);
child.$ext.style.margin = "";
}
child.setAttribute("width", box.width || "");
child.setAttribute("height", box.height || "");
box.destroy(true, true);
}
else {
originalBox.insertBefore(widget, originalPosition);
container.style.left = originalSize[0];
container.style.top = originalSize[1];
container.style.width = originalSize[2];
container.style.height = originalSize[3];
container.style.margin = originalSize[4];
}
// Remove box if empty
// if (originalBox && originalBox.getWidgets().length === 0)
// originalBox.cloud9box.unload();
finish();
}
}
/***** Methods *****/
/***** Lifecycle *****/
handle.on("load", function() {
load();
});
handle.on("enable", function() {
});
handle.on("disable", function() {
});
handle.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
**/
handle.freezePublicAPI({});
register(null, {
dashboardbehavior: handle
});
}
});

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 3.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 3.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 658 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.3 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 647 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.3 KiB

Wyświetl plik

@ -0,0 +1,22 @@
{
"name": "c9.ide.behaviors",
"description": "The repository for c9.ide.behaviors, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.behaviors.git"
},
"plugins": {
"dashboard": {},
"page": {},
"tabs": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,704 @@
define(function(require, exports, module) {
main.consumes = [
"Plugin", "ui", "tabManager", "ace", "anims", "settings", "preferences"
];
main.provides = ["tabinteraction"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var anims = imports.anims;
var settings = imports.settings;
var prefs = imports.preferences;
var tabs = imports.tabManager;
var aceHandle = imports.ace;
var css = require("text!./style.css");
/***** Initialization *****/
var handle = new Plugin("Ajax.org", main.consumes);
// var emit = handle.getEmitter();
var divSplit, divButton, plusMargin = 11;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
// Insert CSS
ui.insertCss(css, options.staticPrefix, handle);
settings.on("read", function() {
settings.setDefaults("user/tabs", [["autoclosepanes", true]]);
}, handle);
tabs.on("tabCreate", function(e) {
var tab = e.tab;
addInteraction(tab);
// Make sure that events are put on the button when the skin changes
tab.aml.on("$skinchange", function() {
addInteraction(tab);
});
}, handle);
tabs.on("tabDestroy", function(e) {
if (e.tab.meta.$skipAnimation)
setTimeout(function() { e.tab.pane.unload(); }, 0);
}, handle);
tabs.on("tabAfterClose", function(e) {
if (e.last && canTabBeRemoved(e.tab.pane, 1)
&& settings.getBool("user/tabs/@autoclosepanes")) {
e.tab.meta.$skipAnimation = true;
}
}, handle);
prefs.add({
"General": {
"User Interface": {
position: 20,
"Automatically Close Empty Panes": {
type: "checkbox",
path: "user/tabs/@autoclosepanes",
position: 1150
}
}
}
}, handle);
ui.insertCss("* { }", false, handle);
}
function canTabBeRemoved(pane, min) {
if (!pane || pane.getTabs().length > (min || 0))
return false;
var containers = tabs.containers;
for (var i = 0; i < containers.length; i++) {
if (ui.isChildOf(containers[i], pane.aml)) {
return containers[i]
.getElementsByTagNameNS(apf.ns.aml, "tab").length > 1;
}
}
return false;
}
function addInteraction(plugin) {
var tab = plugin.aml;
var button = tab.$button;
if (!button) return;
var offsetX, offsetY, startX, startY, dragWidth;
var mode, rightPadding, originalTab, btnPlus, pane;
var started, tabWidth, leftPadding, leftPos, start, initMouse;
var pages, clean, originalPosition, splitDirection, splitTab;
function setOrderMode(toTab, e) {
if (toTab.isOrderCleaned === false) {
return setTimeout(function() {
setOrderMode(toTab, e);
}, 10);
}
mode = "order";
clean && clean();
var lastPane = pane;
// Set new pane
pane = toTab;
// Plus Button
btnPlus = pane.$ext.querySelector(".plus_tab_button");
// Attach tab to pane
if (e) {
var curpage = pane.getPage();
if (curpage) {
var curbtn = curpage.$button;
ui.setStyleClass(curbtn, "", ["curbtn"]);
}
ui.setStyleClass(tab.$button, "curbtn");
}
var container = pane.$buttons;
var nodes = container.childNodes;
var rect = container.getBoundingClientRect();
var btn = (pane.getPage() || { $button: button }).$button;
var diff = ui.getWidthDiff(btn);
var leftMargin = parseInt(ui.getStyle(btn, "marginLeft"), 10) || 0;
var rightMargin = parseInt(ui.getStyle(btn, "marginRight"), 10) || 0;
var maxWidth = parseInt(ui.getStyle(btn, "maxWidth"), 10) || 150;
if (maxWidth > 500) maxWidth = 150;
leftPos = rect.left;
pages = pane.getPages();
leftPadding = parseInt(ui.getStyle(container, "paddingLeft"), 10) || 0;
rightPadding = (parseInt(ui.getStyle(container, "paddingRight"), 10) || 0) + 24;
var addOne = pages.indexOf(tab) == -1;
var maxTabWidth = Math.min(maxWidth + diff,
((rect.width - leftPadding - rightPadding + rightMargin)
/ (pages.length + (addOne ? 1 : 0))) - rightMargin);
var newTabWidth = maxTabWidth - diff;
tabWidth = maxTabWidth + leftMargin + rightMargin;
// Get the positions info of the tab buttons
var info = [];
for (var i = nodes.length - 1; i >= 0; i--) {
if ((btn = nodes[i]).nodeType != 1) continue;
info.push([btn, btn.offsetLeft, btn.offsetTop, btn.offsetWidth]);
}
// Append the button to the button container
if (e || addOne) {
pane.$buttons.appendChild(button);
info.push([button, 0, button.offsetTop, dragWidth]);
}
// Set the info
var iter;
while ((iter = info.pop())) {
btn = iter[0];
btn.style.left = (iter[1]) + "px";
btn.style.top = (iter[2]) + "px";
btn.style.width = (iter[3] - ui.getWidthDiff(btn)) + "px";
btn.style.margin = 0;
btn.style.position = "absolute";
}
start = function() {
// Remove from childNodes of old pane
var lastIndex = pane.childNodes.indexOf(tab);
pane.childNodes.remove(tab);
};
if (started)
start();
// Set initial position
if (e || addOne)
mouseMoveOrder(e, newTabWidth); //, lastPane == pane);
apf.addListener(document, "mousemove", mouseMoveOrder);
apf.addListener(document, "mouseup", mouseUpOrder);
clean = function(change, toTab) {
if (!toTab)
toTab = pane;
toTab.isOrderCleaned = false;
if (change !== false) {
apf.removeListener(document, "mousemove", mouseMoveOrder);
apf.removeListener(document, "mouseup", mouseUpOrder);
}
if (change === true) {
var maxTabWidth = Math.min(maxWidth + diff,
((rect.width - leftPadding - rightPadding + rightMargin + 3)
/ pane.getPages().length) - rightMargin);
tabWidth = maxTabWidth + leftMargin + rightMargin;
var cb = clean.bind(this, false, toTab);
return animateTabs(cb, null, maxTabWidth - diff);
}
if (curbtn && curpage.parentNode && curpage == curpage.parentNode.getPage()) {
ui.setStyleClass(curbtn, "curbtn");
curbtn = null;
}
for (var i = nodes.length - 1; i >= 0; i--) {
if ((btn = nodes[i]).nodeType != 1) continue;
btn.style.left =
btn.style.top =
btn.style.width =
btn.style.margin =
btn.style.position = "";
}
toTab.isOrderCleaned = true;
};
}
function setSplitMode(e) {
mode = "split";
// Div that shows where to insert split
if (!divSplit) {
divSplit = document.createElement("div");
divSplit.className = "split-area";
document.body.appendChild(divSplit);
}
// Remove all pointer events from iframes
var frames = document.getElementsByTagName("iframe");
for (var i = 0; i < frames.length; i++)
frames[i].style.pointerEvents = "none";
start = function() {
// Fixate current position and width
var rect = button.getBoundingClientRect();
button.style.left = (rect.left) + "px";
button.style.top = (rect.top) + "px";
button.style.width = (dragWidth - ui.getWidthDiff(button)) + "px";
button.style.position = "absolute";
// Attach tab to body
if (!divButton) {
divButton = document.createElement("div");
document.body.appendChild(divButton);
}
var theme = aceHandle.theme || {};
divButton.className =
(theme.isDark ? "dark " : "") + (theme.cssClass || "");
divButton.appendChild(button);
// Remove from parent childNodes
pane.childNodes.remove(tab);
ui.setStyleRule("*", "cursor", "default!important");
};
apf.addListener(document, "mousemove", mouseMoveSplit);
apf.addListener(document, "mouseup", mouseUpSplit);
if (started)
start();
clean && clean(true);
clean = function() {
button.style.left =
button.style.top =
button.style.width =
button.style.margin =
button.style.position = "";
divSplit.style.display = "none";
ui.setStyleRule("*", "cursor", "");
apf.removeListener(document, "mousemove", mouseMoveSplit);
apf.removeListener(document, "mouseup", mouseUpSplit);
};
if (started) {
// Set initial position and detect immediate snap
if (mouseMoveSplit(e) === false)
return;
}
}
function finish() {
if (!initMouse) {
clean(null, null, true);
button.style.zIndex =
button.style.pointerEvents = "";
// Return all pointer events to iframes
var frames = document.getElementsByTagName("iframe");
for (var i = 0; i < frames.length; i++)
frames[i].style.pointerEvents = "";
}
tab.$dragging = false;
}
button.addEventListener("mousedown", function(e) {
// Tab needs to support ordering
if (!tab.parentNode.$order || tab.$dragging || e.button)
return;
// APF stuff
tab.$dragging = true;
startX = e.clientX;
startY = e.clientY;
initMouse = function() {
// Calculate where on the button was clicked
var rect = button.getBoundingClientRect();
offsetX = startX - rect.left;
offsetY = startY - rect.top;
// Prepare button for dragging
button.style.zIndex = 100000;
button.style.pointerEvents = "none";
// Initialize with order mode
setOrderMode(tab.parentNode, e);
initMouse = null;
};
// Use mine
started = false;
// Set current pane
pane = plugin.pane.aml;
// Store original info
originalTab = pane;
originalPosition = button.nextSibling;
dragWidth = button.offsetWidth;
apf.addListener(document, "mousemove", mouseMoveOrder);
apf.addListener(document, "mouseup", mouseUpOrder);
}, true);
function isNotSnapped(e, container) {
if (!container)
container = pane.$buttons;
var rect = container.getBoundingClientRect();
var x = e.clientX;
var y = e.clientY;
var diff = 10;
return (
x < rect.left - diff ||
x > rect.left + rect.width + diff ||
y < rect.top - 5 ||
y > rect.top + rect.height + diff
);
}
function showOrderPosition(idx, toWidth, finalize, finish) {
if (idx < 0) idx = 0;
var orderTab = (pages[idx - 1] == tab
? pages[idx + 1]
: pages[idx]) || null;
// Remove tab from childNodes
pane.childNodes.remove(tab);
if (finalize) {
// Get new pages with new order
pages = pane.getPages();
// Reparent for real
var insert = pages[idx] && pages[idx].cloud9tab;
plugin.attachTo(pane.cloud9pane, insert, true);
}
else {
// If we're already at this position do nothing
if (orderTab == tab)
return;
// Move tab to new position
idx = pane.childNodes.indexOf(orderTab);
if (idx > -1) pane.childNodes.splice(idx, 0, tab);
else pane.childNodes.push(tab);
pane.$buttons.insertBefore(tab.$button,
orderTab && orderTab.$button || btnPlus);
}
// Patch + button which is changed to "" again
// btnPlus.style.position = "absolute";
// btnPlus.style.top = "6px";
animateTabs(finish, finalize, toWidth);
}
function animateTabs(finish, includeTab, toWidth) {
// Get new pages array (with new order)
pages = pane.getPages();
pages.push({ $button: btnPlus });
// Animate all pages to their right position
var p, tweens = [], offset = 0;
for (var i = 0, l = pages.length; i < l; i++) {
p = pages[i];
// Ignore the tab we are dragging
if (!includeTab && tab === p) {
if (p.$button.parentNode == document.body)
offset = 1;
if (toWidth)
p.$button.style.width = toWidth + "px";
continue;
}
var curLeft = p.$button.offsetLeft;
var toLeft = leftPadding + ((i - offset) * tabWidth)
+ (!p.localName ? plusMargin : 0);
if (toWidth || toLeft != curLeft) {
var tween = {
node: p.$button,
duration: tab === p ? 0.20 : 0.15,
timingFunction: tab === p
? "cubic-bezier(.30, .08, 0, 1)"
: "linear"
};
if (includeTab || tab !== p)
tween.left = toLeft + "px";
if (toWidth && p.localName)
tween.width = toWidth + "px";
tweens.push(tween);
}
}
anims.animateMultiple(tweens, function() {
finish && finish();
});
}
function mouseMoveOrder(e, toWidth, finalize) {
if (!e) e = event;
if (!started) {
if (Math.abs(startX - e.clientX) < 4
&& Math.abs(startY - e.clientY) < 4)
return;
started = true;
initMouse();
start();
}
if (isNotSnapped(e))
return setSplitMode(e);
button.style.left = (e.clientX - leftPos - offsetX) + "px";
var x = button.offsetLeft - leftPadding + (tabWidth / 2);
var idx = Math.floor(x / tabWidth);
showOrderPosition(idx, toWidth, finalize);
}
function mouseUpOrder(e) {
apf.removeListener(document, "mousemove", mouseMoveOrder);
apf.removeListener(document, "mouseup", mouseUpOrder);
if (!started)
return finish();
button.style.left = (e.clientX - leftPos - offsetX) + "px";
var x = button.offsetLeft - leftPadding + (tabWidth / 2);
var idx = Math.floor(x / tabWidth);
// Show final order
var orderTab = showOrderPosition(idx, null, true, finish);
// Activate tab
plugin.activate();
// Remove pane if empty
if (originalTab && canTabBeRemoved(originalTab.cloud9pane)
&& settings.getBool("user/tabs/@autoclosepanes"))
originalTab.cloud9pane.unload();
}
function showSplitPosition(e) {
var el = document.elementFromPoint(e.clientX, e.clientY);
var aml = apf.findHost(el);
while (aml && aml.localName != "tab")
aml = aml.parentNode;
// If aml is not the pane we seek, lets abort
if (!aml) {
divSplit.style.display = "none";
splitTab = null;
splitDirection = null;
return;
}
var tab = (aml.getPage() || {}).cloud9tab;
var dark = !tab || tab.classList.names.indexOf("dark") > -1;
divSplit.className = "split-area" + (dark ? " dark" : "");
// Find the rotated quarter that we're in
var rect = aml.$ext.getBoundingClientRect();
var left = (e.clientX - rect.left) / rect.width;
var right = 1 - left;
var top = (e.clientY - rect.top) / rect.height;
var bottom = 1 - top;
// Check whether we're going to dock
if (!isNotSnapped(e, aml.$buttons)) {
setOrderMode(aml, e);
return false;
}
// Cannot split pane that would be removed later
if (aml.getPages().length === 0) { // && aml == originalTab
divSplit.style.display = "none";
splitTab = null;
splitDirection = null;
return;
}
splitTab = aml;
// Anchor to closes side
var min = Math.min(left, top, right, bottom);
// Get buttons height
var bHeight = pane.$buttons.offsetHeight - 1;
// Left
if (min == left) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = (rect.width / 2) + "px";
divSplit.style.height = (rect.height - bHeight) + "px";
splitDirection = "w";
}
// Right
else if (min == right) {
divSplit.style.left = rect.left + (rect.width / 2) + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = (rect.width / 2) + "px";
divSplit.style.height = (rect.height - bHeight) + "px";
splitDirection = "e";
}
// Top
else if (min == top) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (bHeight + rect.top) + "px";
divSplit.style.width = rect.width + "px";
divSplit.style.height = ((rect.height / 2) - bHeight) + "px";
splitDirection = "n";
}
// Bottom
else if (min == bottom) {
divSplit.style.left = rect.left + "px";
divSplit.style.top = (rect.top + (rect.height / 2)) + "px";
divSplit.style.width = rect.width + "px";
divSplit.style.height = (rect.height / 2) + "px";
splitDirection = "s";
}
divSplit.style.cursor = splitDirection + "-resize";
divSplit.style.display = "block";
}
function mouseMoveSplit(e) {
if (!started) {
if (Math.abs(startX - e.clientX) < 4
&& Math.abs(startY - e.clientY) < 4)
return;
started = true;
initMouse();
start();
}
button.style.left = (e.clientX - offsetX) + "px";
button.style.top = (e.clientY - offsetY) + "px";
return showSplitPosition(e);
}
// var waiting;
// function schedule(e){
// if (waiting) {
// waiting = e;
// return;
// }
// waiting = e;
// setTimeout(function(){
// showSplitPosition(waiting);
// waiting = false;
// }, 1000);
// }
function mouseUpSplit(e) {
button.style.left = (e.clientX - offsetX) + "px";
button.style.top = (e.clientY - offsetY) + "px";
apf.removeListener(document, "mousemove", mouseMoveSplit);
apf.removeListener(document, "mouseup", mouseUpSplit);
showSplitPosition(e);
if (splitTab) {
splitTab = splitTab.cloud9pane;
var newTab;
if (splitDirection == "n")
newTab = splitTab.vsplit();
else if (splitDirection == "s")
newTab = splitTab.vsplit(true);
else if (splitDirection == "w")
newTab = splitTab.hsplit();
else if (splitDirection == "e")
newTab = splitTab.hsplit(true);
var oldTab = pane;
plugin.attachTo(newTab, null, true);
pane = newTab.aml;
if (oldTab && canTabBeRemoved(oldTab.cloud9pane)) {
oldTab.cloud9pane.unload();
originalTab = null;
}
}
else {
tab.parentNode.$buttons.insertBefore(button,
originalPosition);
if (originalTab == tab.parentNode) {
var idx = tab.parentNode.childNodes.indexOf(tab.nextSibling);
if (idx == -1)
tab.parentNode.childNodes.push(tab);
else
tab.parentNode.childNodes.splice(idx, 0, tab);
}
}
// Remove pane if empty
if (originalTab && originalTab != tab.parentNode
&& canTabBeRemoved(originalTab.cloud9pane))
originalTab.cloud9pane.unload();
finish();
}
}
/***** Methods *****/
/***** Lifecycle *****/
handle.on("load", function() {
load();
});
handle.on("enable", function() {
});
handle.on("disable", function() {
});
handle.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
**/
handle.freezePublicAPI({
get plusMargin() { return plusMargin; },
set plusMargin(v) { plusMargin = v; }
});
register(null, {
tabinteraction: handle
});
}
});

Wyświetl plik

@ -0,0 +1,50 @@
.splits{
padding : 6px 20px 3px 22px !important;
background: transparent;
}
.splits span{
.image-2x(@pane-menu-splits-image, @pane-menu-splits-image-width, @pane-menu-splits-image-height);
background-position: 0 0;
width : 23px;
height : 18px;
display : inline-block;
margin : 0 10px 0 0;
cursor : pointer;
}
.splits span.nosplit { background-position: 0 0; }
.splits span.nosplit:hover { background-position: 0 -18px; }
.splits span.nosplit:active { background-position: 0 -36px; }
.splits span.twovsplit { background-position: -23px 0; }
.splits span.twovsplit:hover { background-position: -23px -18px; }
.splits span.twovsplit:active { background-position: -23px -36px; }
.splits span.twohsplit { background-position: -46px 0; }
.splits span.twohsplit:hover { background-position: -46px -18px; }
.splits span.twohsplit:active { background-position: -46px -36px; }
.splits span.foursplit { background-position: -69px 0; }
.splits span.foursplit:hover { background-position: -69px -18px; }
.splits span.foursplit:active { background-position: -69px -36px; }
.splits span.threeleft { background-position: -92px 0; }
.splits span.threeleft:hover { background-position: -92px -18px; }
.splits span.threeleft:active { background-position: -92px -36px; }
.splits span.threeright { background-position: -115px 0; }
.splits span.threeright:hover { background-position: -115px -18px; }
.splits span.threeright:active { background-position: -115px -36px; }
.split-area {
position: absolute;
background: rgba(0,0,0,0.05);
border: 1px solid rgba(0, 0, 0, 0.2);
/*box-shadow: 0 0 200px rgba(0, 0, 0,0.2) inset;*/
display: none;
z-index: 100000;
pointer-events: none;
.box-sizing(border-box);
cursor : default;
}
.dark.split-area {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255, 0.3);
box-shadow: 0 0 200px rgba(255,255,255,0.15) inset;
outline: 1px solid black;
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,80 @@
define(function(require, exports, module) {
main.consumes = ["Plugin", "tabManager", "preferences", "settings"];
main.provides = ["zen"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var tabManager = imports.tabManager;
var prefs = imports.preferences;
var settings = imports.settings;
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
function load() {
prefs.add({
"Project": {
position: 10,
"Tabs and IDE Layout": {
position: 1500,
"Limit number of open tabs per pane (ZenTabs)": {
type: "checked-spinner",
checkboxPath: "user/zentabs/@useZenTabs",
path: "user/zentabs/@tabLimit",
min: 0,
max: 1000,
position: 100
}
}
}
}, plugin);
tabManager.on("open", runZenTabs, plugin);
}
/***** Methods *****/
function runZenTabs(event) {
var tab = event.tab;
var zentabsEnabled = settings.getBool("user/zentabs/@useZenTabs");
if (!zentabsEnabled) return;
var tabLimit = settings.get("user/zentabs/@tabLimit");
var openTabs = tab.pane.meta.accessList;
var tabsToRemove = openTabs.length - tabLimit;
// Try to close excess tabs, unless it's the one just opened
for (var i = openTabs.length - 1; i > 0; i--) {
if (tabsToRemove < 1) {
tab.pane.aml.$waitForMouseOut = false;
tab.pane.aml.$scaleinit(null, "sync");
return;
}
else if (!openTabs[i].document.changed) {
openTabs[i].close();
tabsToRemove--;
}
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("unload", function() {
});
/***** Register and define API *****/
plugin.freezePublicAPI({
});
register(null, {
"zen": plugin
});
}
});

Wyświetl plik

@ -0,0 +1,21 @@
Copyright (c) 2015, Ajax.org B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.closeconfirmation

Wyświetl plik

@ -0,0 +1,104 @@
define(function(require, exports, module) {
"use strict";
main.consumes = [
"Plugin", "tabManager", "settings", "preferences", "auth"
];
main.provides = ["closeconfirmation"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var tabs = imports.tabManager;
var settings = imports.settings;
var prefs = imports.preferences;
var auth = imports.auth;
var ideProviderName = options.ideProviderName || "Cloud9";
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var defaultValue = options.defaultValue;
var loaded = false;
function load(callback) {
if (loaded) return false;
loaded = true;
// when unloading the window
window.onbeforeunload = onBeforeUnloadHandler;
settings.on("read", function() {
settings.setDefaults("user/general", [
["confirmexit", defaultValue]
]);
}, plugin);
prefs.add({
"General": {
"General": {
"Warn Before Exiting": {
type: "checkbox",
position: 8000,
path: "user/general/@confirmexit"
}
}
}
}, plugin);
}
function unload() {
if (window.onbeforeunload === onBeforeUnloadHandler)
window.onbeforeunload = null;
}
/***** Methods *****/
function onBeforeUnloadHandler() {
var changed = tabs.getTabs().some(function(tab) {
return tab.document.value && tab.document.changed;
});
emit("exit", { changed: changed });
// see what's in the settings
var confirmExit = settings.getBool("user/general/@confirmexit") && auth.loggedIn;
if (confirmExit) {
if (changed)
return "You have unsaved changes. Your changes will be lost if you don't save them";
else
return "You're about to leave " + ideProviderName + ".";
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
unload();
loaded = false;
});
/***** Register and define API *****/
/**
* Shows a 'close confirmation' popup when closing the IDE
* @singleton
*/
plugin.freezePublicAPI({
});
register(null, {
closeconfirmation: plugin
});
}
});

Wyświetl plik

@ -0,0 +1,20 @@
{
"name": "c9.ide.closeconfirmation",
"description": "The repository for c9.ide.closeconfirmation, a Cloud9 core plugin",
"version": "3.0.0",
"author": "Cloud9",
"contributors": [],
"repository": {
"type": "git",
"url": "http://github.com/c9/c9.ide.closeconfirmation.git"
},
"plugins": {
"closeconfirmation": {}
},
"categories": [
"core"
],
"licenses": [
"MIT"
]
}

Wyświetl plik

@ -0,0 +1,3 @@
Copyright (C) 2015, Ajax.org B.V.
This software is available under the Cloud9 SDK License, available from https://github.com/c9/core/blob/master/LICENSE

Wyświetl plik

@ -0,0 +1 @@
# c9.ide.collab

Wyświetl plik

@ -0,0 +1,458 @@
define(function(require, module, exports) {
main.consumes = ["Plugin", "ace", "settings", "collab.workspace", "collab.util", "ui", "menus"];
main.provides = ["AuthorLayer"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var settings = imports.settings;
var ui = imports.ui;
var ace = imports.ace;
var util = imports["collab.util"];
var menus = imports.menus;
var workspace = imports["collab.workspace"];
var dom = require("ace/lib/dom");
var event = require("ace/lib/event");
var Range = require("ace/range").Range;
var AuthorAttributes = require("./ot/author_attributes")();
var showAuthorInfo = true;
var showAuthorInfoKey = "user/collab/@show-author-info";
settings.on("user/collab", function () {
showAuthorInfo = settings.getBool(showAuthorInfoKey);
}, workspace);
ace.on("create", function(e) {
showAuthorInfo = settings.getBool(showAuthorInfoKey);
initGutterLayer(e.editor.ace);
}, workspace);
menus.addItemByPath("context/ace-gutter/Gutter Options/Show Authorship Info", new ui.item({
type: "check",
checked: showAuthorInfoKey
}), 1000, workspace);
function AuthorLayer(session) {
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var marker = session.addDynamicMarker({ update: drawAuthInfos }, false);
function refresh() {
var doc = session.collabDoc.original;
var ace = doc.editor && doc.editor.ace;
var aceSession = ace && ace.session;
if (aceSession !== session)
return;
session._emit("changeBackMarker");
var gutter = ace.renderer.$gutterLayer;
gutter.update = updateGutter;
gutter.update(ace.renderer.layerConfig);
}
function drawAuthInfos(html, markerLayer, session, config) {
if (!showAuthorInfo || !util.isRealCollab(workspace))
return;
var doc = session.collabDoc;
var editorDoc = session.doc;
var colorPool = workspace.colorPool;
var reversedAuthorPool = workspace.reversedAuthorPool;
var firstRow = config.firstRow;
var lastRow = config.lastRow;
var range = new Range(firstRow, 0, lastRow, editorDoc.getLine(lastRow).length);
var cache = createAuthorKeyCache(editorDoc, doc.authAttribs, range);
var authKeyCache = cache.authorKeys;
var rowScores = cache.rowScores;
var fold = session.getNextFoldLine(firstRow);
var foldStart = fold ? fold.start.row : Infinity;
for (var i = firstRow; i < lastRow; i++) {
if (i > foldStart) {
i = fold.end.row + 1;
fold = session.getNextFoldLine(i, fold);
foldStart = fold ? fold.start.row : Infinity;
}
if (i > lastRow)
break;
if (!authKeyCache[i] || !rowScores[i])
continue;
var rowScore = rowScores[i];
for (var authVal in rowScore) {
if (authVal == authKeyCache[i])
continue;
var edits = rowScore[authVal].edits;
for (var j = 0; j < edits.length; j++) {
var edit = edits[j];
var uid = reversedAuthorPool[authVal];
var bgColor = colorPool[uid];
var extraStyle = "position:absolute;border-bottom:solid 2px " + util.formatColor(bgColor) + ";z-index: 2000";
var startPos = session.documentToScreenPosition(edit.pos);
markerLayer.drawSingleLineMarker(html,
new Range(startPos.row, startPos.column, startPos.row, startPos.column + edit.length),
"", config, 0, extraStyle);
}
}
}
}
function updateGutter(config) {
var session = this.session;
var firstRow = config.firstRow;
var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar
session.getLength() - 1);
var fold = session.getNextFoldLine(firstRow);
var foldStart = fold ? fold.start.row : Infinity;
var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
var breakpoints = session.$breakpoints;
var decorations = session.$decorations;
var firstLineNumber = session.$firstLineNumber;
var lastLineNumber = 0;
var gutterRenderer = session.gutterRenderer || this.$renderer;
var editorDoc = session.doc;
var doc = session.collabDoc;
var range = new Range(firstRow, 0, lastRow, editorDoc.getLine(lastRow).length);
var isCollabGutter = doc && showAuthorInfo && util.isRealCollab(workspace);
var authorKeysCache = isCollabGutter && createAuthorKeyCache(editorDoc, doc.authAttribs, range).authorKeys;
var colorPool = workspace.colorPool;
var reversedAuthorPool = workspace.reversedAuthorPool;
var cell = null;
var index = -1;
var row = firstRow;
while (true) {
if (row > foldStart) {
row = fold.end.row + 1;
fold = session.getNextFoldLine(row, fold);
foldStart = fold ? fold.start.row : Infinity;
}
if (row > lastRow) {
while (this.$cells.length > index + 1) {
cell = this.$cells.pop();
this.element.removeChild(cell.element);
}
break;
}
cell = this.$cells[++index];
if (!cell) {
cell = { element: null, textNode: null, foldWidget: null };
cell.element = dom.createElement("div");
cell.textNode = document.createTextNode('');
cell.element.appendChild(cell.textNode);
this.element.appendChild(cell.element);
this.$cells[index] = cell;
}
var className = "ace_gutter-cell ";
if (breakpoints[row])
className += breakpoints[row];
if (decorations[row])
className += decorations[row];
if (this.$annotations[row])
className += this.$annotations[row].className;
if (cell.element.className != className)
cell.element.className = className;
var height = session.getRowLength(row) * config.lineHeight + "px";
if (height != cell.element.style.height)
cell.element.style.height = height;
if (isCollabGutter) {
var authorKey = authorKeysCache[row];
var authorColor = "transparent";
var fullname = null;
if (authorKey) {
var uid = reversedAuthorPool[authorKey];
authorColor = util.formatColor(colorPool[uid]);
var user = workspace.users[uid];
fullname = user && user.fullname;
}
cell.element.style.borderLeft = "solid 5px " + authorColor;
cell.element.setAttribute("uid", fullname ? uid : "");
} else {
cell.element.style.borderLeft = "";
cell.element.setAttribute("uid", "");
}
if (foldWidgets) {
var c = foldWidgets[row];
// check if cached value is invalidated and we need to recompute
if (c == null)
c = foldWidgets[row] = session.getFoldWidget(row);
}
if (c) {
if (!cell.foldWidget) {
cell.foldWidget = dom.createElement("span");
cell.element.appendChild(cell.foldWidget);
}
var className = "ace_fold-widget ace_" + c;
if (c == "start" && row == foldStart && row < fold.end.row)
className += " ace_closed";
else
className += " ace_open";
if (cell.foldWidget.className != className)
cell.foldWidget.className = className;
var height = config.lineHeight + "px";
if (cell.foldWidget.style.height != height)
cell.foldWidget.style.height = height;
} else {
if (cell.foldWidget) {
cell.element.removeChild(cell.foldWidget);
cell.foldWidget = null;
}
}
var text = lastLineNumber = gutterRenderer
? gutterRenderer.getText(session, row)
: row + firstLineNumber;
if (text != cell.textNode.data)
cell.textNode.data = text;
row++;
}
this.element.style.height = config.minHeight + "px";
if (this.$fixedWidth || session.$useWrapMode)
lastLineNumber = session.getLength() + firstLineNumber;
var gutterWidth = gutterRenderer
? gutterRenderer.getWidth(session, lastLineNumber, config)
: lastLineNumber.toString().length * config.characterWidth;
var padding = this.$padding || this.$computePadding();
gutterWidth += padding.left + padding.right + (isCollabGutter ? 5 : 0);
if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {
this.gutterWidth = gutterWidth;
this.element.style.width = Math.ceil(this.gutterWidth) + "px";
this._emit("changeGutterWidth", gutterWidth);
}
}
function createAuthorKeyCache (editorDoc, authAttribs, range) {
var startI = editorDoc.positionToIndex(range.start);
var endI = editorDoc.positionToIndex(range.end);
var authKeyCache = {};
var rowScores = {};
var lastPos = range.start;
function processScore(index, length, value) {
var line = editorDoc.getLine(lastPos.row);
var rowScore = rowScores[lastPos.row] = rowScores[lastPos.row] || {};
var score = Math.min(line.length - lastPos.column, length);
var scoreObj = rowScore[value] = rowScore[value] || { edits: [], score: 0 };
scoreObj.edits.push({ pos: lastPos, length: score });
scoreObj.score += score;
var pos = editorDoc.indexToPosition(index + length);
if (lastPos.row !== pos.row) {
if (value) {
for (var i = lastPos.row + 1; i < pos.row; i++)
authKeyCache[i] = value;
}
line = editorDoc.getLine(pos.row);
rowScore = rowScores[pos.row] = rowScores[pos.row] || {};
score = pos.column;
scoreObj = rowScore[value] = rowScore[value] || { edits: [], score: 0 };
scoreObj.edits.push({ pos: pos, length: score });
scoreObj.score += score;
}
lastPos = pos;
}
AuthorAttributes.traverse(authAttribs, startI, endI, processScore);
for (var rowNum in rowScores) {
var rowScore = rowScores[rowNum];
delete rowScore[null];
delete rowScore[undefined];
delete rowScore[0];
var authorKeys = Object.keys(rowScore);
if (authorKeys.length === 0) {
delete rowScores[rowNum];
// authKeyCache[rowNum] = null;
}
else if (authorKeys.length === 1) {
authKeyCache[rowNum] = parseInt(authorKeys[0], 10);
}
else {
var biggestScore = 0;
var authKey;
for (var key in rowScore) {
if (rowScore[key].score > biggestScore) {
biggestScore = rowScore[key].score;
authKey = key;
}
}
authKeyCache[rowNum] = parseInt(authKey, 10);
}
}
return {
authorKeys: authKeyCache,
rowScores: rowScores
};
}
function dispose () {
session.removeMarker(marker.id);
}
plugin.freezePublicAPI({
get colorPool() { return workspace.colorPool; },
refresh: refresh,
dispose: dispose
});
return plugin;
}
function getLineAuthorKey(session, authAttribs, row) {
var editorDoc = session.doc;
var line = editorDoc.getLine(row);
var lineStart = editorDoc.positionToIndex({ row: row, column: 0 }) - 1;
var lineEnd = lineStart + line.length + 1;
var scores = {};
AuthorAttributes.traverse(authAttribs, lineStart, lineEnd, function (index, length, value) {
if (value)
scores[value] = (scores[value] || 0) + length;
});
var authorKeys = Object.keys(scores);
if (authorKeys.length === 0)
return null;
if (authorKeys.length === 1)
return parseInt(authorKeys[0], 10);
var biggestScore = 0;
var authorKey;
for (var key in scores) {
if (scores[key] > biggestScore) {
biggestScore = scores[key];
authorKey = key;
}
}
return parseInt(authorKey, 10);
}
function initGutterLayer(editor) {
if (!editor || editor.$authorGutterInited) return;
editor.$authorGutterInited = true;
var highlightedCell;
var tooltip = editor.tooltip = dom.createElement("div");
tooltip.className = "ace_gutter-tooltip";
tooltip.style.display = "none";
editor.container.appendChild(tooltip);
function onGutterMouseout(e) {
tooltip.style.display = "none";
highlightedCell = null;
}
var gutterEl = editor.renderer.$gutter;
// var gutterEl = editor.renderer.$gutterLayer.element;
// event.addListener(gutterEl, "mousemove", onMousemove);
event.addListener(gutterEl, "mouseout", onGutterMouseout);
gutterEl.addEventListener("mousemove", function(e) {
if (!showAuthorInfo || !util.isRealCollab(workspace))
return;
var target = e.target;
if (highlightedCell != target) {
var uid = target.getAttribute("uid");
if (uid) {
tooltip.style.display = "block";
highlightedCell = target;
var user = workspace.users[uid];
tooltip.textContent = user ? user.fullname : "";
}
}
if (highlightedCell) {
tooltip.style.top = e.clientY - 15 + "px";
tooltip.style.left = e.clientX + "px";
} else {
onGutterMouseout();
}
});
var mousePos;
editor.addEventListener("mousemove", function(e) {
if (!showAuthorInfo || !util.isRealCollab(workspace))
return;
mousePos = { x: e.x, y: e.y };
if (!editor.authorTooltipTimeout)
editor.authorTooltipTimeout = setTimeout(updateTooltip, tooltip.style.display === "block" ? 100 : 300);
});
editor.renderer.container.addEventListener("mouseout", function(e) {
tooltip.style.display = "none";
});
function updateTooltip() {
editor.authorTooltipTimeout = null;
var session = editor.session;
var otDoc = session.collabDoc;
if (!otDoc)
return;
var editorDoc = session.doc;
var authAttribs = otDoc.authAttribs;
var screenPos = editor.renderer.pixelToScreenCoordinates(mousePos.x, mousePos.y);
var docPos = session.screenToDocumentPosition(screenPos.row, screenPos.column);
var line = editorDoc.getLine(docPos.row);
var hoverIndex = editorDoc.positionToIndex({ row: docPos.row, column: docPos.column });
var authorKey = AuthorAttributes.valueAtIndex(authAttribs, hoverIndex);
// ignore newline tooltip and out of text hovering
if (!authorKey || line.length <= screenPos.column || editorDoc.$lines.length < screenPos.row)
return tooltip.style.display = "none";
var lineOwnerKey = getLineAuthorKey(session, authAttribs, docPos.row);
if (!lineOwnerKey || lineOwnerKey === authorKey)
return tooltip.style.display = "none";
var reversedAuthorPool = workspace.reversedAuthorPool;
var uid = reversedAuthorPool[authorKey];
var fullname = workspace.users[uid] && workspace.users[uid].fullname;
tooltip.style.display = "block";
tooltip.textContent = fullname;
tooltip.style.top = mousePos.y + 10 + "px";
tooltip.style.left = mousePos.x + 10 + "px";
}
editor.addEventListener("mousewheel", function documentScroll() {
clearTimeout(editor.authorTooltipTimeout);
delete editor.authorTooltipTimeout;
tooltip.style.display = "none";
});
}
/***** Register and define API *****/
register(null, {
AuthorLayer: AuthorLayer
});
}
});

Wyświetl plik

@ -0,0 +1,113 @@
#chatThrob {
display: none;
position: absolute;
bottom: 40px;
font-size: 12px;
width: 150px;
height: 40px;
right: 20px;
z-index: 1000;
color: rgb(39, 39, 39);
background-color: rgb(236, 236, 236);
background-color: rgba(236, 236, 236, 0.7);
padding: 10px;
border-radius: 6px;
opacity: .8;
}
.chatContainer{
.display-flex();
.flex-direction(column);
}
.chatText a {
color: #909090;
}
.chatText {
overflow: auto;
font-size: @collab-chat-font-size;
padding: 0 0 0 0;
.flex(1);
background: @collab-chat-background;
}
.chatText p {
padding: @collab-chat-item-padding;
word-wrap: break-word;
border-bottom : @collab-chat-item-border-bottom;
border-top : @collab-chat-item-border-top;
position : relative;
margin : 0;
}
.chatText p:first-child{
border-top: 0;
}
.chatText .chatBorder{
position : absolute;
left : 0;
top : 0;
bottom : 0;
width : 0;
border-left : @collab-chat-color-size solid white;
}
.chatText .emoji {
vertical-align: middle;
}
.chatText .authorName {
text-decoration: none;
color: @collab-chat-author-color;
display : block;
}
.chatText .chatmessage {
color : @collab-chat-message-color;
display : block;
padding: 3px 0 0 0;
}
.chatText .chattime {
position : absolute;
right: @collab-chat-time-right;
top: @collab-chat-time-top;
color: @collab-chat-time-color;
font-size: 10px;
font-weight: @collab-chat-time-font-weight;
text-shadow: @collab-chat-time-text-shadow;
}
.chatContainer .searchTxt.tb_console {
background: @collab-chat-input-background;
height:30px;
padding: 0;
cursor: text;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
.chatContainer .searchTxt.tb_console .sbtb_middle{
min-height : 37px;
border-color: @collab-chat-input-border-color;
border-radius: 0;
border-width: 1px 0 0 0;
box-shadow: @collab-chat-input-box-shadow;
background: @collab-chat-input-background;
padding: 4px 4px 3px 4px;
}
.chatContainer .tb_textboxInitialMsg {
color: #B9B9B9 !important;
text-indent: 3px;
text-shadow: none;
}
.chatContainer .searchbox .sbtb_middle .input{
color: @collab-chat-input-color;
.font-smoothing(@collab-chat-input-font-smoothing);
}
.chatContainer .ace-tm .ace_marker-layer .ace_selection {
background: @collab-chat-input-selection-color;
}
.chatContainer .ace-tm .ace_cursor {
color : @collab-chat-input-cursor-color;
}
#chatCounter {
color: #777;
font-size: 10px;
vertical-align: middle;
}

Wyświetl plik

@ -0,0 +1,3 @@
<audio style="display: none;" id="chatNotif" preload="true" src="/static/plugins/c9.ide.collab/chat/sounds/chat_notif.mp3"></audio>
<div id="chatThrob"></div>
<div id="chatCounter"></div>

Wyświetl plik

@ -0,0 +1,404 @@
define(function(require, exports, module) {
"use strict";
main.consumes = [
"CollabPanel", "ui", "panels", "collab.util", "collab.workspace",
"collab", "Menu", "MenuItem"
];
main.provides = ["chat"];
return main;
function main(options, imports, register) {
var CollabPanel = imports.CollabPanel;
var ui = imports.ui;
var panels = imports.panels;
var util = imports["collab.util"];
var workspace = imports["collab.workspace"];
var collab = imports.collab;
var Menu = imports.Menu;
var MenuItem = imports.MenuItem;
var html = require("text!./chat.html");
var css = require("text!./chat.css");
var timeago = require("timeago");
var staticPrefix = options.staticPrefix;
var toDeleteMessage;
var ROLE_NONE = "n";
var ROLE_VISITOR = "v";
var ROLE_COLLABORATOR = "c";
var ROLE_ADMIN = "a";
var plugin = new CollabPanel("Ajax.org", main.consumes, {
name: "chat",
index: 200,
caption: "Group Chat",
textselect: true,
style: "flex:1;-webkit-flex:1"
});
// var emit = plugin.getEmitter();
var emoji = require("./my_emoji");
// panel-relared UI elements
var chatInput, chatText, mnuCtxTreeEl, parent;
// non-panel related UI elements
var chatThrob, chatCounter, chatNotif;
function $(id) {
return document.getElementById(id);
}
var loaded = false;
function load() {
if (loaded) return;
loaded = true;
collab.on("chatMessage", onChatMessage);
collab.on("chatClear", onChatClear);
}
var drawn = false;
function draw(options) {
if (drawn) return;
drawn = true;
drawNonPanelElements();
parent = options.aml;
var parentExt = parent.$int;
parentExt.className += " chatContainer";
chatText = parentExt.appendChild(document.createElement("div"));
chatText.setAttribute("class", "chatText");
chatInput = new apf.codebox({
htmlNode: parentExt,
skin: "codebox",
"initial-message": "Enter your message here",
// clearbutton : "true",
focusselect: "true"
});
chatInput.$ext.classList.remove("ace_searchbox");
chatInput.ace.setOptions({
wrap: "free",
indentedSoftWrap: false,
maxLines: 5,
minLines: 2,
fontFamily: "inherit"
});
chatInput.ace.session.$setFontMetrics(chatInput.ace.renderer.$fontMetrics);
plugin.addElement(chatInput);
function onWorkspaceSync() {
var accessInfo = workspace.accessInfo;
if (accessInfo.private && (!accessInfo.member || accessInfo.pending))
return console.warn("Don't have read access - You can't use chat");
var chatHistory = workspace.chatHistory || [];
chatHistory.forEach(function(msg) {
addMessage(msg, msg.increment);
});
scrollDown();
chatCounter.innerHTML = chatHistory.length;
}
chatInput.ace.commands.addCommands([
{
bindKey: "ESC",
exec: function() {
if (chatInput.getValue())
chatInput.setValue("");
else
collab.hide();
}
}, {
bindKey: "Enter",
exec: send
}
]);
function listenWorkspaceSync() {
workspace.off("sync", onWorkspaceSync);
workspace.on("sync", onWorkspaceSync);
}
if (panels.isActive("collab"))
listenWorkspaceSync();
collab.on("show", function() {
chatInput.focus();
listenWorkspaceSync();
});
collab.on("hide", function() {
workspace.off("sync", onWorkspaceSync);
});
var deleteMsgItem = new MenuItem({
caption: "Delete Message",
match: "rw",
onclick: clearChatMessage,
disabled: true
});
var clearHistoryItem = new MenuItem({
caption: "Clear history",
match: "rw",
onclick: clearChatHistory,
disabled: true
});
var mnuCtxTree = new Menu({
id: "mnuChat",
items: [
deleteMsgItem,
clearHistoryItem
]
}, plugin);
mnuCtxTreeEl = mnuCtxTree.aml;
parent.setAttribute("contextmenu", mnuCtxTreeEl);
mnuCtxTree.on("show", function() {
setTimeout(function() {
var hasReadWrite = workspace.fs === "rw";
var collabConnected = collab.connected;
clearHistoryItem.disabled = !hasReadWrite || !collabConnected || !chatText.firstChild;
toDeleteMessage = findMessageToDelete(hasReadWrite);
deleteMsgItem.disabled = !toDeleteMessage || !collabConnected;
}, 10);
});
parent.on("resize", function() {
if (isOpen()) {
pending.forEach(addMessage);
pending = [];
updateCaption();
}
});
}
function findMessageToDelete(hasReadWrite) {
var menuRect = mnuCtxTreeEl.$int.getBoundingClientRect();
var msg;
[].slice.apply(chatText.getElementsByTagName("p")).forEach(function(msgP) {
var rect = msgP.getBoundingClientRect();
if (rect.left < menuRect.left && (rect.left + rect.width) > menuRect.left
&& rect.top < menuRect.top && (rect.top + rect.height) > menuRect.top
&& (hasReadWrite || msgP.userId == workspace.myUserId))
msg = msgP;
});
return msg;
}
function clearChatMessage() {
if (!toDeleteMessage || !toDeleteMessage.id)
return console.error("[OT] Chat: no message found to delete!");
var msgId = toDeleteMessage.id.match(/ot_chat_(\d+)/)[1];
collab.send("CLEAR_CHAT", { id: msgId });
}
function clearChatHistory() {
collab.send("CLEAR_CHAT", { clear: true });
}
var seenMsgs = {};
var pending = [];
var throbTimeout;
function scrollDown() {
chatText.scrollTop = chatText.scrollHeight;
}
function isOpen() {
return panels.isActive("collab") && parent.state[0] != "m";
}
function send() {
var text = chatInput.getValue().trim();
if (!text)
return;
text = emoji.toEmojiUnicode(text);
collab.send("CHAT_MESSAGE", { text: text });
chatInput.setValue("");
}
function getAuthorName(userId) {
if (userId == workspace.myUserId)
return "You";
var user = workspace.users[userId];
return util.escapeHTML(user.fullname);
}
function getAuthorColor(userId) {
var color = workspace.colorPool[userId];
return util.formatColor(color);
}
function formatMessageText(text) {
text = util.escapeHtmlWithClickableLinks(text.trim(), "_blank");
text = text.replace(/\n/g, "<br/>");
text = emoji.emoji(text, staticPrefix);
return text;
}
function onChatMessage(msg) {
drawNonPanelElements();
workspace.addChatMessage(msg);
if (isOpen()) {
addMessage(msg);
}
else {
pending.push(msg);
updateCaption();
var throbText = "<b>" + getAuthorName(msg.userId) + "</b> ";
var text = formatMessageText(msg.text);
var notif = msg.notification;
if (notif) {
throbText += text + " " + notif.linkText;
} else {
throbText += ": " + text;
}
chatThrob.innerHTML = throbText;
chatThrob.style.display = "block";
clearTimeout(throbTimeout);
throbTimeout = setTimeout(function () {
chatThrob.style.display = "none";
}, 5000);
}
if (msg.increment) {
var count = Number(chatCounter.innerHTML);
chatCounter.innerHTML = count + 1;
}
var inputFocussed = chatInput && chatInput.ace.isFocused();
if (!inputFocussed)
chatNotif.play();
}
function onChatClear(data) {
if (data.clear) {
// fast way to delete all children - not innerHtml = ''
while (chatText.firstChild)
chatText.removeChild(chatText.firstChild);
seenMsgs = {}; // sql truncate table would lead to same msg ids
workspace.chatHistory = [];
}
else if (data.id) {
var msgHtml = $("ot_chat_" + data.id);
msgHtml && msgHtml.parentNode.removeChild(msgHtml);
}
}
function addMessage(msg) {
if (seenMsgs[msg.id])
return;
seenMsgs[msg.id] = true;
// correct the time
// msg.timestamp += clientTimeOffset;
var msgDate = new Date(msg.timestamp);
// create the time string
var text = formatMessageText(msg.text);
var authorName = getAuthorName(msg.userId);
var authorColor = getAuthorColor(msg.userId);
var authorNameEl = document.createElement("a");
authorNameEl.href = "javascript:void(0)";
authorNameEl.className = "authorName";
authorNameEl.innerHTML = "<b>" + authorName + "</b>";
// authorNameEl.addEventListener("click", function () {
// });
var html = document.createElement("p");
html.id = "ot_chat_" + msg.id;
html.userId = msg.userId;
var borderEl = document.createElement("span");
html.appendChild(borderEl);
borderEl.className = "chatBorder";
borderEl.style.borderLeftColor = authorColor;
html.appendChild(authorNameEl);
var textEl = document.createElement("span");
textEl.className = "chatmessage";
textEl.innerHTML = text + "<br/>";
html.appendChild(textEl);
var timeEl = document.createElement("span");
timeEl.className = "chattime";
timeEl.title = msgDate.toISOString();
timeEl.innerHTML = msgDate;
timeago(timeEl);
html.appendChild(timeEl);
chatText.appendChild(html);
scrollDown();
}
function updateCaption() {
var caption = "Group Chat";
if (pending.length)
caption += "(" + pending.length + ")";
if (parent)
parent.setAttribute("caption", caption);
}
var nonPanelDrawn = false;
function drawNonPanelElements () {
if (nonPanelDrawn) return;
nonPanelDrawn = true;
ui.insertHtml(null, html, plugin);
ui.insertCss(css, staticPrefix, plugin);
chatThrob = $("chatThrob");
chatCounter = $("chatCounter");
chatNotif = $("chatNotif");
chatThrob.addEventListener("click", function () {
chatThrob.style.display = "none";
plugin.show();
});
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
plugin.once("draw", draw);
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
drawn = false;
});
/***** Register and define API *****/
/**
* Adds File->New File and File->New Folder menu items as well as the
* commands for opening a new file as well as an API.
* @singleton
**/
plugin.freezePublicAPI({
});
register(null, {
chat: plugin
});
}
});

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.0 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 572 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1016 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 934 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 863 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 875 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1009 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 790 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 878 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 604 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 961 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 939 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 686 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.0 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 884 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 822 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 849 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1017 B

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.1 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More