c9-core/plugins/c9.ide.run.build/gui.js

284 wiersze
10 KiB
JavaScript

define(function(require, module, exports) {
main.consumes = [
"Plugin", "build", "settings", "commands", "fs", "save",
"menus", "tabManager", "ui", "dialog.error"
];
main.provides = ["build.gui"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var settings = imports.settings;
var commands = imports.commands;
var menus = imports.menus;
var save = imports.save;
var build = imports.build;
var fs = imports.fs;
var ui = imports.ui;
var tabs = imports.tabManager;
var showError = imports["dialog.error"].show;
var uCaseFirst = require("c9/string").uCaseFirst;
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var process, currentBuilder;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
// Commands
commands.addCommand({
name: "build",
group: "Run & Debug",
hint: "builds the current file (focussed document)",
bindKey: { mac: "Command-B", win: "Ctrl-B" },
isAvailable: function() {
return getFocusTab() ? true : false;
},
exec: function() {
buildFocusTab();
}
}, plugin);
commands.addCommand({
name: "stopbuild",
group: "Run & Debug",
hint: "stop a running build",
bindKey: { mac: "Ctrl-Shift-C", win: "Ctrl-Shift-C" },
isAvailable: function() {
return process && process.running;
},
exec: function() {
process && process.stop();
}
}, plugin);
// Settings
settings.on("read", function() {
settings.setDefaults("project/build", [
["saveall", true],
["builder", "auto"]
]);
settings.setDefaults("user/build", [
["autobuild", "false"]
]);
var name = settings.get("project/build/@builder");
setCurrentBuilder(name, function() {});
});
// Menus
var c = 10000;
menus.addItemByPath("Run/~", new ui.divider(), c += 100, plugin);
var mnuBuildSystem = new ui.menu({
"onprop.visible": function(e) {
if (e.value) {
build.listBuilders(function(err, names) {
var nodes = mnuBuildSystem.childNodes;
for (var i = nodes.length - 3; i >= 2; i--) {
mnuBuildSystem.removeChild(nodes[i]);
}
var builder = settings.get("project/build/@builder");
if (builder == "auto")
nodes[0].select();
var c = 300;
names.sort().forEach(function(name) {
menus.addItemToMenu(mnuBuildSystem, new ui.item({
type: "radio",
caption: uCaseFirst(name),
value: name,
selected: builder == name
}), c++, plugin);
});
});
}
},
"onitemclick": function(e) {
if (e.value == "new-build-system") {
tabs.open({
path: settings.get("project/build/@path")
+ "/My Builder.build",
active: true,
value: '// Create a custom Cloud9 build system - similar to the Sublime build system\n'
+ '// For more information see https://docs.c9.io/custom_runners.html\n'
+ '{\n'
+ ' "cmd" : ["ls", "$file", "$args"],\n'
+ ' "env" : {},\n'
+ ' "info" : "Building $project_path/$file_name",\n'
+ ' "selector": "source.ext"\n'
+ '}',
document: {
meta: {
newfile: true
},
ace: {
customSyntax: "javascript"
}
}
}, function() {});
return;
}
setCurrentBuilder(e.value, function() {});
settings.set("project/build/@builder", e.value);
}
});
menus.addItemByPath("Run/Build", new ui.item({
command: "build"
}), c += 100, plugin);
menus.addItemByPath("Run/Cancel Build", new ui.item({
command: "stopbuild"
}), c += 100, plugin);
menus.addItemByPath("Run/Build System/", mnuBuildSystem,
c += 100, plugin);
menus.addItemByPath("Run/Show Build Result", new ui.item({
onclick: function() {
commands.exec("showoutput", null, { id: "build" });
}
}), c += 100, plugin);
menus.addItemByPath("Run/~", new ui.divider(), c += 100, plugin);
menus.addItemByPath("Run/Automatically Build Supported Files", new ui.item({
type: "check",
checked: "user/build/@autobuild"
}), c += 100, plugin);
menus.addItemByPath("Run/Save All on Build", new ui.item({
type: "check",
checked: "project/build/@saveall"
}), c += 100, plugin);
c = 0;
menus.addItemByPath("Run/Build System/Automatic", new ui.item({
type: "radio",
value: "auto"
}), c += 100, plugin);
menus.addItemByPath("Run/Build System/~", new ui.divider(), c += 100, plugin);
menus.addItemByPath("Run/Build System/~", new ui.divider(), c += 1000, plugin);
menus.addItemByPath("Run/Build System/New Build System", new ui.item({
value: "new-build-system"
}), c += 100, plugin);
// Hook into FS and build file when writeFile is triggered
save.on("afterSave", function(e) {
if (!settings.getBool("user/build/@autobuild"))
return;
var ext = fs.getExtension(e.path);
if (!ext)
return;
// @todo consider making this a hash map
if (currentBuilder == "auto") {
if (Object.keys(build.builders).every(function(name) {
return build.builders[name].selector != "source." + ext;
})) return;
}
else if (currentBuilder.selector != "source." + ext)
return;
buildFocusTab(true, e.path);
});
}
/***** Methods *****/
function setCurrentBuilder(name, callback) {
currentBuilder = name;
if (currentBuilder != "auto") {
build.getBuilder(currentBuilder, true, function(err, builder) {
if (err)
currentBuilder = "auto";
else
currentBuilder = builder;
callback(err, builder);
});
}
}
function getFocusTab() {
var tab = tabs.focussedTab;
if (!tab) return false;
if (tab.path) return tab;
if (tab.editor.type != "output") return false;
var splits = tab.pane.aml
.parentNode.parentNode.getElementsByTagName("tab");
if (splits.length > 1) {
var idx = splits[0].cloud9pane == tab.pane ? 1 : 0;
tab = splits[idx].cloud9pane.getTab();
return tab;
}
return false;
}
function buildFocusTab(onlyBuild, path) {
if (!path) {
var tab = getFocusTab();
if (!tab) return;
path = tab.path;
}
if (!onlyBuild)
commands.exec("showoutput", null, { id: "build" });
if (settings.get("project/build/@saveall"))
save.saveAll(done);
else
done();
function done() {
process = build.build(currentBuilder,
{ path: path.substr(1) }, "build", function(err, pid) {
if (err && err.code != "EBUILDERNOTFOUND")
return showError(err);
});
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
* UI for the {@link build} plugin. This plugin is responsible for the Run
* menu in the main menu bar, as well as the settings and the
* preferences UI for the run plugin.
* @singleton
*/
/**
* @command build Builds the currently focussed tab.
*/
/**
* @command stopbuild Stops the running build.
*/
plugin.freezePublicAPI({
});
register(null, {
"build.gui": plugin
});
}
});