kopia lustrzana https://github.com/c9/core
Added terminal widget
rodzic
d464139b75
commit
68fa6d861b
|
@ -83,7 +83,7 @@
|
|||
"c9.ide.help.support": "#60e88f5680",
|
||||
"c9.ide.imgeditor": "#08bbc53578",
|
||||
"c9.ide.immediate": "#6845a93705",
|
||||
"c9.ide.installer": "#4c31717a97",
|
||||
"c9.ide.installer": "#7a354bbd17",
|
||||
"c9.ide.mount": "#cb45b621f1",
|
||||
"c9.ide.navigate": "#64156c7f4a",
|
||||
"c9.ide.newresource": "#f1f0624768",
|
||||
|
|
|
@ -509,6 +509,12 @@ define(function(require, exports, module) {
|
|||
focus: function(){
|
||||
return acetree.focus();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
blur: function(){
|
||||
return acetree.blur();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,401 @@
|
|||
define(function(require, exports, module) {
|
||||
main.consumes = ["Plugin", "ui", "util", "commands"];
|
||||
main.provides = ["Terminal"];
|
||||
return main;
|
||||
|
||||
function main(options, imports, register) {
|
||||
var Plugin = imports.Plugin;
|
||||
var ui = imports.ui;
|
||||
var util = imports.util;
|
||||
var commands = imports.commands;
|
||||
|
||||
var Aceterm = require("../c9.ide.terminal/aceterm/aceterm");
|
||||
var libterm = require("../c9.ide.terminal/aceterm/libterm");
|
||||
|
||||
/***** Constructors *****/
|
||||
|
||||
/*
|
||||
plugin.on("copy", function(e) {
|
||||
if (e.native) return; // Ace handles this herself
|
||||
|
||||
var data = aceterm.getCopyText();
|
||||
e.clipboardData.setData("text/plain", data);
|
||||
});
|
||||
plugin.on("paste", function(e) {
|
||||
if (e.native) return; // Ace handles this herself
|
||||
|
||||
var data = e.clipboardData.getData("text/plain");
|
||||
if (data !== false)
|
||||
aceterm.onPaste(data);
|
||||
});
|
||||
*/
|
||||
|
||||
function Terminal(options, forPlugin, baseclass) {
|
||||
if (!options) throw new Error("options are required");
|
||||
|
||||
var plugin = new Plugin("Ajax.org", main.consumes);
|
||||
var emit = plugin.getEmitter();
|
||||
if (baseclass) plugin.baseclass();
|
||||
|
||||
var rows = options.rows || 0;
|
||||
var cols = options.cols || 0;
|
||||
|
||||
var aceterm, terminal;
|
||||
var redirectEvents;
|
||||
var meta = {};
|
||||
|
||||
var excludedEvents = {
|
||||
"draw": 1, "load":1, "unload":1, "resize":1,
|
||||
"addListener":1, "removeListener":1
|
||||
};
|
||||
var renameEvents = {
|
||||
"select": "changeSelection",
|
||||
"scroll": "changeScrollTop"
|
||||
};
|
||||
|
||||
/***** Methods *****/
|
||||
|
||||
function send(data) {
|
||||
emit("input", { data: data });
|
||||
}
|
||||
|
||||
function _resize(force){
|
||||
var ace = terminal.aceSession.ace;
|
||||
|
||||
var size = ace.renderer.$size;
|
||||
var config = ace.renderer.layerConfig;
|
||||
|
||||
var h = size.scrollerHeight;
|
||||
var w = size.scrollerWidth - 2 * config.padding;
|
||||
|
||||
if (!h || config.lineHeight <= 1)
|
||||
return false;
|
||||
|
||||
// top 1px is for cursor outline
|
||||
var _rows = Math.floor((h - 1) / config.lineHeight);
|
||||
if (_rows <= 2 && !ace.renderer.scrollBarV.isVisible)
|
||||
w -= ace.renderer.scrollBarV.width;
|
||||
var _cols = Math.floor(w / config.characterWidth);
|
||||
|
||||
if (!_cols || !_rows)
|
||||
return;
|
||||
|
||||
// Don't do anything if the size remains the same
|
||||
if (!force && _cols == terminal.cols && _rows == terminal.rows)
|
||||
return;
|
||||
|
||||
if (_cols > 1000 || _rows > 1000) {
|
||||
console.error("invalid terminal size");
|
||||
return;
|
||||
}
|
||||
|
||||
// do not resize terminal to very small heights during initialization
|
||||
rows = Math.max(_rows, 2);
|
||||
cols = Math.max(_cols, 2);
|
||||
|
||||
terminal.resize(_cols, _rows);
|
||||
|
||||
emit("resize", { cols: cols, rows: rows });
|
||||
}
|
||||
|
||||
/***** Life Cycle *****/
|
||||
|
||||
var drawn = false;
|
||||
function draw(htmlNode) {
|
||||
if (drawn) return;
|
||||
drawn = true;
|
||||
|
||||
aceterm = Aceterm.createEditor(null, "ace/theme/idle_fingers");
|
||||
aceterm.container.style.position = "absolute";
|
||||
aceterm.container.style.left = "0px";
|
||||
aceterm.container.style.right = "0px";
|
||||
aceterm.container.style.top = "0px";
|
||||
aceterm.container.style.bottom = "0px";
|
||||
|
||||
htmlNode.appendChild(aceterm.container);
|
||||
|
||||
terminal = new Aceterm(cols, rows, send);
|
||||
aceterm.setSession(terminal.aceSession);
|
||||
|
||||
aceterm.renderer.on("resize", function(){
|
||||
_resize();
|
||||
});
|
||||
|
||||
var cm = commands;
|
||||
// TODO find better way for terminal and ace commands to coexist
|
||||
aceterm.commands.addCommands(cm.getExceptionList());
|
||||
cm.on("update", function() {
|
||||
aceterm.commands.addCommands(cm.getExceptionList());
|
||||
}, plugin);
|
||||
|
||||
aceterm.commands.exec = function(command) {
|
||||
return cm.exec(command);
|
||||
};
|
||||
|
||||
// Set Default Theme
|
||||
// if (!options.theme)
|
||||
// options.theme = "custom-tree ace-tree-" + (options.baseName || "list");
|
||||
|
||||
// Set properties
|
||||
for (var prop in options) {
|
||||
if (prop == "container") continue;
|
||||
if (plugin.hasOwnProperty(prop))
|
||||
plugin[prop] = options[prop];
|
||||
}
|
||||
|
||||
// Configure redirected events
|
||||
redirectEvents = {
|
||||
afterRender: aceterm.renderer,
|
||||
title: terminal,
|
||||
afterWrite: terminal
|
||||
};
|
||||
|
||||
emit.sticky("draw");
|
||||
}
|
||||
|
||||
plugin.on("load", function(){
|
||||
if (options.container)
|
||||
plugin.attachTo(options.container);
|
||||
|
||||
forPlugin.once("unload", function(){
|
||||
plugin.unload();
|
||||
});
|
||||
});
|
||||
plugin.on("unload", function(){
|
||||
if (aceterm) {
|
||||
var container = aceterm.container;
|
||||
aceterm.destroy();
|
||||
|
||||
container.innerHTML = "";
|
||||
container.parentNode.removeChild(container);
|
||||
}
|
||||
|
||||
aceterm = null;
|
||||
container = null;
|
||||
meta = {};
|
||||
});
|
||||
plugin.on("newListener", function(type, fn){
|
||||
if (excludedEvents[type]) return;
|
||||
|
||||
if (renameEvents[type])
|
||||
type = renameEvents[type];
|
||||
|
||||
if (redirectEvents[type])
|
||||
redirectEvents[type].on(type, fn);
|
||||
else
|
||||
aceterm.on(type, fn);
|
||||
});
|
||||
plugin.on("removeListener", function(type, fn){
|
||||
if (excludedEvents[type]) return;
|
||||
|
||||
if (renameEvents[type])
|
||||
type = renameEvents[type];
|
||||
|
||||
if (redirectEvents[type])
|
||||
redirectEvents[type].removeListener(type, fn);
|
||||
else
|
||||
aceterm.removeListener(type, fn);
|
||||
});
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* Creates a new List instance.
|
||||
* @param {Object} options
|
||||
* @param {Plugin} plugin The plugin responsible for creating this list.
|
||||
*/
|
||||
plugin.freezePublicAPI({
|
||||
// Getter Properties
|
||||
/**
|
||||
* @ignore
|
||||
* @readonly
|
||||
*/
|
||||
get aceterm(){ return aceterm; },
|
||||
/**
|
||||
* A meta data object that allows you to store whatever you want
|
||||
* in relation to this menu.
|
||||
* @property {Object} meta
|
||||
* @readonly
|
||||
*/
|
||||
get meta(){ return meta; },
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// get scrollTop(){ return model.getScrollTop(); },
|
||||
// set scrollTop(value){ return model.setScrollTop(value); },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get focussed(){ return aceterm.isFocussed(); },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get container(){ return aceterm.container; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get renderer(){ return aceterm.renderer; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get selection(){ return aceterm.selection; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get commands(){ return aceterm.commands; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get cols(){ return cols; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get rows(){ return rows; },
|
||||
|
||||
// Getters and Setters for Properties
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get textInput(){ return aceterm.textInput; },
|
||||
set textInput(value){ return aceterm.textInput = value; },
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get scrollMargin(){ return aceterm.renderer.scrollMargin; },
|
||||
set scrollMargin(value){
|
||||
aceterm.renderer.setScrollMargin(value[0], value[1]);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
get theme(){ return aceterm.renderer.theme.cssClass; },
|
||||
set theme(value){ aceterm.renderer.setTheme({cssClass: value}); },
|
||||
|
||||
// Events
|
||||
_events: [
|
||||
/**
|
||||
* @event draw Fires
|
||||
*/
|
||||
"draw",
|
||||
/**
|
||||
* @event click Fires
|
||||
*/
|
||||
"click",
|
||||
/**
|
||||
* @event userSelect Fires
|
||||
*/
|
||||
"userSelect",
|
||||
/**
|
||||
* @event focus Fires
|
||||
*/
|
||||
"focus",
|
||||
/**
|
||||
* @event blur Fires
|
||||
*/
|
||||
"blur",
|
||||
/**
|
||||
* @event select Fires
|
||||
*/
|
||||
"select",
|
||||
/**
|
||||
* @event scroll Fires
|
||||
*/
|
||||
"scroll",
|
||||
/**
|
||||
* @event scrollbarVisibilityChanged Fires
|
||||
*/
|
||||
"scrollbarVisibilityChanged",
|
||||
/**
|
||||
* @event resize Fires
|
||||
*/
|
||||
"resize",
|
||||
/**
|
||||
* @event afterRender Fires
|
||||
*/
|
||||
"afterRender",
|
||||
/**
|
||||
* @event title Fires
|
||||
*/
|
||||
"title",
|
||||
/**
|
||||
* @event afterWrite Fires
|
||||
*/
|
||||
"afterWrite"
|
||||
],
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
resize: function(){
|
||||
return aceterm.resize(true);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
focus: function(){
|
||||
return aceterm.focus();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
blur: function(){
|
||||
return aceterm.blur();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
execCommand: function(cmd){
|
||||
return aceterm.execCommand(cmd);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
scrollIntoView: function(anchor, lead, offset){
|
||||
return aceterm.renderer.scrollCaretIntoView(anchor, lead, offset);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
enable: function(){
|
||||
return aceterm.enable();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
disable: function(){
|
||||
return aceterm.enable();
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
write: function(data){
|
||||
return terminal.write(data);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
attachTo: function(htmlNode, beforeNode){
|
||||
var container;
|
||||
if (drawn)
|
||||
container = aceterm.container;
|
||||
else {
|
||||
container = document.createElement("div");
|
||||
container.style.height = "100%";
|
||||
}
|
||||
|
||||
htmlNode.insertBefore(container, beforeNode);
|
||||
|
||||
if (!drawn)
|
||||
draw(container);
|
||||
}
|
||||
});
|
||||
|
||||
plugin.load(null, options.baseName || "list");
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
register(null, {
|
||||
Terminal: Terminal
|
||||
});
|
||||
}
|
||||
});
|
Ładowanie…
Reference in New Issue