{"__v":10,"_id":"54d5635732d98b0d00384b18","category":{"__v":5,"_id":"54d5635632d98b0d00384afc","pages":["54d5635732d98b0d00384b18","54d5635732d98b0d00384b19","54d5635732d98b0d00384b1a","54d5635732d98b0d00384b1b","54d5635732d98b0d00384b1c","54d5635732d98b0d00384b1d","54d5635732d98b0d00384b1e","54d5635732d98b0d00384b1f","54d5689d7e05890d006f14ea","54d8243a0100e20d00ddd57b","5516e49f5a2a4f1700d4f5f8","552d5437d048dd0d00f36e68"],"project":"54d53c7b23010a0d001aca0c","version":"54d5635532d98b0d00384afb","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-02-06T23:43:10.191Z","from_sync":false,"order":0,"slug":"getting-started","title":"Getting Started"},"parentDoc":null,"project":"54d53c7b23010a0d001aca0c","user":"54cfa8e1a8a4fd0d00b7fd1d","version":{"__v":10,"_id":"54d5635532d98b0d00384afb","forked_from":"54d53c7c23010a0d001aca0f","project":"54d53c7b23010a0d001aca0c","createdAt":"2015-02-07T00:59:01.934Z","releaseDate":"2015-02-07T00:59:01.934Z","categories":["54d5635632d98b0d00384afc","54d5635632d98b0d00384afd","54d5635632d98b0d00384afe","54d5635632d98b0d00384aff","54d5635632d98b0d00384b00","54d5635632d98b0d00384b01","54d5635632d98b0d00384b02","54d652097e05890d006f153e","54dd1315ca1e5219007e9daa","54e21e2b22de1c230094b147","54e68e62a43fe13500db3879","54fa1d3fe7a0ba2f00306309","551c453a23a1ee190034d19a","551df586e52a0b23000c62b6","551f39be6886f8230055f02a","55a6720751457325000e4d97"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.1.0","version":"0.1"},"updates":["5500005778d5870d00ae87ce","556e4cfed02e0b190042f1f9","566f5571e61c1917005aa46b","57365775be10a92000307348","575efbe541c8ba0e00259bce","57ba69017c57e10e00cdadcf"],"next":{"pages":[],"description":""},"createdAt":"2015-02-06T23:47:19.242Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":3,"body":"This guide will walk you through the creation of a plugin that formats a selected block of json in an editor with proper indentation.\n\nWe'll use the built-in `JSON.stringify()` to format the json string. If you would like to try out the package simply run:\n\n```\nc9 install c9.example.formatjson\n```\n# Enabling debug mode\n\nTo 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`.\n\n# Create from a template\n\nStart 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. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/n1J8fGrCQpqRALoAVAHI_new_plugin.png\",\n        \"new_plugin.png\",\n        \"668\",\n        \"274\",\n        \"#ec1714\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nThe 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.\n\nIt 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`.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/O12JW6hTWi1YvZd3xWwo_plugin.png\",\n        \"plugin.png\",\n        \"808\",\n        \"344\",\n        \"#3c615c\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nNow let's edit our plugin to make it do what we want. \n\nStart 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.\n\n# Dependencies\n\nLet'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.\n\nThese are the dependencies that we'll use in this guide:\n[block:html]\n{\n  \"html\": \"<table>\\n    <tr><th>Plugin</th><td>The constructor for our plugin</td></tr>\\n    <tr><th>tabManager</th><td>Provides functions that can open and manipulate tabs</td></tr>\\n    <tr><th>commands</th><td>Provides functions to create commands</td></tr>\\n</table>\"\n}\n[/block]\nAdd these dependencies to the main.consumes array like this:\n\n```javascript\nmain.consumes = [\"Plugin\", \"commands\", \"tabManager\"];\n```\n\nThen add these local variables so you can easily use these dependencies in your plugin:\n\n```\nfunction main(options, imports, register) {\n    var Plugin = imports.Plugin;\n    var commands = imports.commands;\n    var tabs = imports.tabManager;\n```\n\n# Create a Command\n\nLets 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`.\n\n```\ncommands.addCommand({\n    name: \"formatjson_format\",\n    bindKey: { \n        mac: \"Command-Shift-J\", \n        win: \"Ctrl-Shift-J\" \n    },\n    exec: function(){ \n        alert(\"Success!\");\n    }\n}, plugin);\n```\n\nThe `exec` method is called when the command is triggered, for instance by hitting Cmd-Shift-J on a mac. \n\nThe 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:\n\n```\nisAvailable: function(editor) {\n    if (editor && editor.ace)\n        return !editor.ace.selection.isEmpty();\n    return false;\n}\n```\n\nThis looks up the [ace](http://ace.c9.io) 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`.\n\n# Load the Package\n\nUsing `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. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ddee47b-debugmode.PNG\",\n        \"debugmode.PNG\",\n        1040,\n        598,\n        \"#343532\"\n      ],\n      \"caption\": \"\"\n    }\n  ]\n}\n[/block]\nFrom 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.\nThe header bar also provides a button to quickly reload the last enabled plugin.\n\n# Load the package in normal mode\n\nTo load package in normal mode use your init script (`Cloud9 > Open Your Init Script` menu.\nAnd use `pluginManager` service to load the plugin\n\n```\n// check that this is the workspace you want to use\nif (services.c9.workspaceId.match(\"{username}/{workspacename}\")) {\n    // call plugin manager with a list of plugins you want to load\n    // this takes either url, or a path on your vm\n    services.pluginManager.loadPackage([\n        \"https://cdn.url/pluginName1/package.pluginName1.js\",  // packed from cdn\n        \"~/.c9/plugins/pluginName2/c9build/package.pluginName2.js\", // packed from file\n        \"~/.c9/plugins/pluginName3/package.json\"  // unpacked from file \n    ])\n}\n```\n\n# Trigger the Command\n\nSimply hit `Cmd-Shift-J` on a mac or `Ctrl-Shift-J` on windows to see the alert!\n\n# Add the format() implementation\n\nTODO\n\n# Updating package.json\n\nTODO\n\n# Next steps\n\nTODO","excerpt":"","slug":"create-your-first-package","type":"basic","title":"Create Your First Package"}

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. [block:image] { "images": [ { "image": [ "https://files.readme.io/n1J8fGrCQpqRALoAVAHI_new_plugin.png", "new_plugin.png", "668", "274", "#ec1714", "" ] } ] } [/block] 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`. [block:image] { "images": [ { "image": [ "https://files.readme.io/O12JW6hTWi1YvZd3xWwo_plugin.png", "plugin.png", "808", "344", "#3c615c", "" ] } ] } [/block] 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. # Dependencies 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: [block:html] { "html": "<table>\n <tr><th>Plugin</th><td>The constructor for our plugin</td></tr>\n <tr><th>tabManager</th><td>Provides functions that can open and manipulate tabs</td></tr>\n <tr><th>commands</th><td>Provides functions to create commands</td></tr>\n</table>" } [/block] Add these dependencies to the main.consumes array like this: ```javascript 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`. ``` commands.addCommand({ name: "formatjson_format", bindKey: { mac: "Command-Shift-J", win: "Ctrl-Shift-J" }, exec: function(){ alert("Success!"); } }, 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](http://ace.c9.io) 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. [block:image] { "images": [ { "image": [ "https://files.readme.io/ddee47b-debugmode.PNG", "debugmode.PNG", 1040, 598, "#343532" ], "caption": "" } ] } [/block] 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 services.pluginManager.loadPackage([ "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 TODO # Updating package.json TODO # Next steps TODO