Create Your First Package

This guide will walk you through the creation of a plugin that formats a selected block of json in an editor with proper indentation.

We'll use the built-in JSON.stringify() to format the json string. If you would like to try out the package simply run:

c9 install c9.example.formatjson

Enabling debug mode

To start creating Cloud9 plugins, first enable "debug mode" via Cloud9/Preferences/Experimental/SDK and enable the Plugin Manager. After this, you will have to re-load Cloud9 by pressing the reload button in you browser, or by clicking Cloud9/Restart Workspace.

Create from a template

Start your package from a template via the File/New Plugin/Empty Plugin menu. (Note this menu option is only available when running the workspace in debug mode). This will create a new plugin in the ~/.c9/plugins folder. You will find the directory of your package selected in the tree on the left.


The first step is to change the name of the plugin to something that works for you. Rename the directory via the context menu, or select the item and press the F2 key (in combination with Fn on a mac) to rename the folder. Choose a name that does not start with c9.. In this case formatjson would be a good name. You can check if the name does not already exist by doing c9 list | grep formatjson on the command line.

It is good practice to give your plugin.js and plugin_test.js file a descriptive name. I suggest to rename them to formatjson.js and formatjson_test.json. You'll also want to edit your package.json file to reference formatjson rather than plugin.


Now let's edit our plugin to make it do what we want.

Start by replacing myplugin in 2 locations in the file by the name of your plugin. In this case formatjson would be an appropriate name. Other plugins will be able to get a reference to your plugin using this name and can call any of the methods that you expose in the public API.


Let's start by adding all the dependencies we are going to need to the main.consumes array. This will add these dependencies to the imports object.

These are the dependencies that we'll use in this guide:

PluginThe constructor for our plugin
tabManagerProvides functions that can open and manipulate tabs
commandsProvides functions to create commands

Add these dependencies to the main.consumes array like this:

main.consumes = ["Plugin", "commands", "tabManager"];

Then add these local variables so you can easily use these dependencies in your plugin:

function main(options, imports, register) {
    var Plugin = imports.Plugin;
    var commands = imports.commands;
    var tabs = imports.tabManager;

Create a Command

Lets create a command that triggers the format() function that we'll write later on. It's good practice to use the plugin name as a prefix to the command names to avoid conflicts with other plugins. So lets call our command formatjson_format.

    name: "formatjson_format",
    bindKey: { 
        mac: "Command-Shift-J", 
        win: "Ctrl-Shift-J" 
    exec: function(){ 
}, plugin);

The exec method is called when the command is triggered, for instance by hitting Cmd-Shift-J on a mac.

The command is now almost ready. You do want to set the scope of the event to prevent it from being used when there is no editor active or when the editor has no selection. Lets add an isAvailable() method to the command:

isAvailable: function(editor) {
    if (editor && editor.ace)
        return !editor.ace.selection.isEmpty();
    return false;

This looks up the ace reference of an editor and then checks if the selection is empty. If the selection is not empty the function returns true, indicating the command can be executed. Otherwise it will return false.

Load the Package

Using Tools/Developer/Start in Debug Mode menu open Cloud9 in debug mode, You'll see a header bar with a quick link to open plugin explorer.


From plugin explorer you can enable the plugins on which you want to work for the duration of the browser session by clicking on the checkbox next to plugin name.
The header bar also provides a button to quickly reload the last enabled plugin.

Load the package in normal mode

To load package in normal mode use your init script (Cloud9 > Open Your Init Script menu.
And use pluginManager service to load the plugin

// check that this is the workspace you want to use
if (services.c9.workspaceId.match("{username}/{workspacename}")) {
    // call plugin manager with a list of plugins you want to load
    // this takes either url, or a path on your vm
        "https://cdn.url/pluginName1/package.pluginName1.js",  // packed from cdn
        "~/.c9/plugins/pluginName2/c9build/package.pluginName2.js", // packed from file
        "~/.c9/plugins/pluginName3/package.json"  // unpacked from file 

Trigger the Command

Simply hit Cmd-Shift-J on a mac or Ctrl-Shift-J on windows to see the alert!

Add the format() implementation


Updating package.json


Next steps