c9-core/plugins/c9.ide.terminal.monitor/monitor.js

178 wiersze
5.8 KiB
JavaScript

define(function(require, exports, module) {
main.consumes = [
"c9", "Plugin", "editors", "dialog.error",
"terminal.monitor.message_view", "tabManager",
"proc", "commands"
];
main.provides = ["terminal.monitor"];
return main;
function main(options, imports, register) {
var BASHBIN = options.bashBin || "/bin/bash";
var c9 = imports.c9;
var Plugin = imports.Plugin;
var editors = imports.editors;
var messageView = imports["terminal.monitor.message_view"];
var tabManager = imports.tabManager;
var commands = imports.commands;
var proc = imports.proc;
var messageMatchers = require("./message_matchers")(c9).matchers;
var plugin = new Plugin("Ajax.org", main.consumes);
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
messageView.on("action", function(cmd, message) {
proc.execFile(BASHBIN, {
args: ["--login", "-c", cmd]
}, function() {
messageView.hide(message);
});
}, plugin);
editors.on("create", function(e) {
if (!e.editor || e.editor.type !== "terminal" && e.editor.type !== "output")
return;
e.editor.on("documentLoad", onDocumentLoad);
}, plugin);
function onDocumentLoad(e) {
var session = e.doc.getSession();
session.once("terminalReady", setupTerminalMessageHandler);
}
}
function setupTerminalMessageHandler(session) {
var terminal = session.terminal;
var seenUpTo = 0;
var lastNewLine = 0;
var hasResizeCompleted = false;
var timer = null;
terminal.on("discardOldScrollback", function(e) {
seenUpTo = Math.max(seenUpTo - e, 0);
if (lastNewLine)
lastNewLine -= e;
});
terminal.on("newline", function(e) {
lastNewLine = e.y + e.ybase - 1;
if (!timer)
timer = setTimeout(checkNewText);
});
function checkNewText() {
timer = null;
if (!hasResizeCompleted)
return;
var lines = terminal.lines;
if (lastNewLine >= lines.length) lastNewLine = lines.length - 1;
var lineContents = "";
for (var i = Math.min(seenUpTo, lastNewLine); i <= lastNewLine; i++) {
var line = lines[i];
if (!line)
continue;
lineContents += lineToString(line);
if (line.wrapped)
continue;
seenUpTo = i + 1;
handleMessage(lineContents, session.tab);
lineContents = "";
}
}
var resizeTimeout;
terminal.on("resizeStart", function() {
hasResizeCompleted = false;
if (resizeTimeout) {
clearTimeout(resizeTimeout);
}
messageView.repositionMessages(session.tab);
resizeTimeout = setTimeout(function() {
resizeTimeout = null;
hasResizeCompleted = true;
}, 1000);
});
}
function lineToString(line) {
return line.map(function(character) {
return character && character[1];
}).join("");
}
function handleMessage(data, tab) {
messageMatchers.forEach(function(trigger) {
var matches = trigger.pattern.exec(data);
if (matches !== null) {
var message = trigger.message;
message = message && message.replace(/{(\d)}/g, function(_, num) {
return matches[num] || _;
});
if (!trigger.onMatch)
messageView.show(message, trigger.action, tab);
else if (typeof trigger.onMatch == "function")
trigger.onMatch(matches, tab);
else if (trigger.onMatch == "reloadPreview")
reloadPreview();
}
});
}
function reloadPreview() {
commands.exec("reloadpreview");
}
function addMessageMatcher(matcher) {
messageMatchers.pushUnique(matcher);
}
function removeMessageMatcher(matcher) {
messageMatchers.remove(matcher);
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("unload", function() {
loaded = false;
});
plugin.freezePublicAPI({
/**
* @ignore
*/
addMessageMatcher: addMessageMatcher,
/**
* @ignore
*/
removeMessageMatcher: removeMessageMatcher,
/**
* for testing
* @ignore
*/
get messageMatchers() { return messageMatchers; },
/**
* for testing
* @ignore
*/
handleMessage: handleMessage,
});
/***** Register and define API *****/
register(null, {
"terminal.monitor": plugin
});
}
});