{"_id":"54dbce210e553a0d00dc1d09","parentDoc":null,"version":{"_id":"54d5635532d98b0d00384afb","project":"54d53c7b23010a0d001aca0c","__v":10,"forked_from":"54d53c7c23010a0d001aca0f","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"},"__v":115,"project":"54d53c7b23010a0d001aca0c","user":"54cfa8e1a8a4fd0d00b7fd1d","category":{"_id":"54e68e62a43fe13500db3879","__v":0,"project":"54d53c7b23010a0d001aca0c","pages":[],"version":"54d5635532d98b0d00384afb","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-02-20T01:31:13.999Z","from_sync":false,"order":5,"slug":"editor-plugins","title":"Editor Plugins"},"updates":["574e9fb8134895190017f304"],"next":{"pages":[],"description":""},"createdAt":"2015-02-11T21:48:17.919Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"Tabs are an important part of the Cloud9 UI. Tabs house documents which are displayed by editors. Tabs themselves live in panes and by default Cloud9 starts up with a single pane. Users can divide the UI into multiple panes and open / move tabs between panes. Tabs are controlled by the `tabManager` plugin, which offers an API to control the tabs and panes in Cloud9.\n\n# The Tab Manager\n\nUse the `tabManager` plugin to open tabs, look for already opened tabs and to listen for tabs being opened by other plugins. The focussed and active state of tabs is also handled by the `tabManager`. In addition the tabManager works closely together with other areas that house tabs such as the `console` plugin which is responsible for the console in the bottom of the screen.\n\n## Object structure\n\nBesides tabs and panes there are several other objects involved in displaying content and making it editable. The following hierarchy describes the relationships between those objects.\n\n- [Pane](https://docs.c9.io/api/#!/api/Pane) - Represent a single pane, housing multiple tabs\n  - [Editor](https://docs.c9.io/api/#!/api/Editor) - The editor responsible for displaying the document in the tab\n  - [Tab](https://docs.c9.io/api/#!/api/Tab) - A single tab (button) in a pane\n    - [Document](https://docs.c9.io/api/#!/api/Document) - The representation of a file in the tab\n      - [Session](https://docs.c9.io/api/#!/api/Session) - The session information of the editor\n      - [UndoManager](https://docs.c9.io/api/#!/api/UndoManager) - The object that manages the undo stack for this document\n\nIt is important to note that the `Editor` plugin(s) are related to the pane, not the tab. There's only one instance of a certain editor for each pane. The editor is responsible for displaying the content of a document based on the tab that is active. There can be a maximum of one tab active per pane.\n\n## Opening tabs\n\nThe most basic way to open a tab is based on a file. Simply specify the filename to open a tab.\n\n```\ntabManager.openFile(\"file.js\", function(err, tab){\n    if (err) return console.error(err);\n    \n    console.log(\"file.js was opened with content\", tab.document.value);\n});\n```\n\nThe default editor for the extension (in this case `.js`) is chosen from the installed editors and used to display the content.\n\nIn the same way you can open editors that are not file based, such as the terminal. Note that these tabs still have the full object structure as described above.\n\n```\ntabManager.openEditor(\"terminal\", function(err, tab){\n    if (err) return console.error(err);\n    \n    var terminal = tab.editor;\n    terminal.write(\"ls\\n\");\n});\n```\n\nThe [open()](https://docs.c9.io/api/#!/api/tabManager-method-open) method allows a more granular level of control opening tabs. It allows you to focus a newly created tab, set the pane it is created in and force a different editor than the default one.\n\n```\ntabManager.open({\n    path: \"image.png\",\n    editorType: \"hex\", // Note that this is an example. Cloud9 currently doesn't have an hex editor\n    focus: true,\n    pane: tabManager.getPanes()[1] // An example of getting the 2nd pane\n}, function(err, tab){\n    if (err) return console.error(err); \n});\n```\n\n### Opening New Files\n\nThe easiest way to create a new file is via the `newfile` command, which opens a new tab with an empty unnamed file.\n\n```\ncommands.exec(\"newfile\");\n```\n\nWhen you want more control opening a new file then use the `open()` method for that.\n\n```\ntabs.open({\n    path: \"/path/to/new/filename\",\n    value: \"The value of your file\",\n    active: true,\n    document: {\n        meta: {\n            newfile: true\n        }\n    }\n}, function(err, tab) {\n    if (err)\n        return console.error(err);\n});\n```\n\nThe `newfile` property on the meta object is used by the tabManager to not attempt to download the file from the path specified when opening the tab.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"The meta object\",\n  \"body\": \"The `meta` object, available on most plugins (e.g. document, tab, menu) allows you to set properties that are not directly part of the API for that plugin, but which properties can be used by other plugins. For instance the save plugin will check for `meta.ignoreSave` on a document and will not warn when a document with changes is closed when that property is set. \\n\\nAny plugin can extend the `meta` object of a plugin with custom properties. Note that properties starting with `$` are not saved in the object state, while all other properties are and are thus preserved between reloads of the IDE.\"\n}\n[/block]\n### Loading Content from an Alternative Source\n\nWhen you want to load data into a tab from another source than a file set the `value` property to `-1`. The callback will be called synchronously with a function as the third argument to be called when the contents is loaded.\n\n```javascript\ntabs.open({\n    value: -1,\n    active: true\n}, function(err, tab, done) {    \n    getDataFromSomewhere(function(err, data){\n        if (err) {\n            tab.className.add(\"error\");\n            return console.error(err);\n        }\n    \n        tab.document.value = data;\n        done();\n    });\n});\n```\n\nIt's recommended to update the [progress state](http://cloud9-sdk.readme.io/v0.1/docs/documents#progress) of the document if possible.\n\n## Active vs Focussed Tabs\n\nThere are three distinct states a tab can be in. Inactive, active and focussed. When a tab is inactive it's content is not visible. When a tab is active it's button is selected and the content of the document is displayed in the editor. When a tab is focussed, any input such as keyboard input is send to that editor. A focussed tab is always active. There can only be one focussed tab in Cloud9 at one time, while there can be multiple active tabs - one per pane.\n\nSet a tab active either via it's path or reference:\n```\ntabManager.activateTab(\"/path/to/file.js\");\ntabManager.activateTab(myTab);\n```\n\nFocus a tab like this:\n\n```\ntabManager.focusTab(\"/path/to/file.js\");\ntabManager.focusTab(myTab);\n```\n\nFetch the focussed tab via `tabManager.focussedTab` when you want to apply an operation to a certain tab.\n\n```\nvar tab = tabManager.focussedTab;\nif (tab.editorType == \"ace\") {\n    performOperation(tab);\n}\n```\n\n## Events\n\nThe `tabManager` has over 20 events, such as `tabCreate`, `tabAfterActivate`, `tabDestroy`, etc. See the [reference guide](https://docs.c9.io/api/#!/api/tabManager) for a complete list.\n\nThe [open](https://docs.c9.io/api/#!/api/tabManager-event-open) and [ready](https://docs.c9.io/api/#!/api/tabManager-event-ready) events are worth mentioning specifically. The `open` event is fired for each tab that is opened via the `open()` method (or openFile, openEditor) after its contents is loaded.\n\n```\ntabManager.on(\"open\", function(e){\n    if (e.tab.path.match(/^\\/some\\/path/)) {\n        // Do something\n    }\n});\n```\n\nThe `ready` event is fired after Cloud9 has started and all the tabs from the previous session have been opened (which includes loading the content). \n```\ntabManager.on(\"ready\", function(e){\n    console.log(\"All tabs are open\");\n});\n```\n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Sticky Event\",\n  \"body\": \"The `ready` event is a so-called `sticky` event, which means that if it has already fired when you set the listener it will fire immediately (synchronously).\"\n}\n[/block]\n## Getting a Reference to Tabs\n\nTabs that have a file associated to it have their `path` property set. To get a reference to a tab like that use the `findTab()` method.\n\n```\nvar tab = tabManager.findTab(\"/path/to/file.js\");\n```\n\nif a tab doesn't have a file associated, such as a terminal, then you can look them up by their name, which was automatically assigned to them when they were created.\n\nYou can retrieve a list of tabs via the `getTabs()` method. \n\n```\nvar allFileTabs = tabManager.getTabs().filter(function(tab){\n    return tab.path ? true : false;\n});\n```\n\n## Preview\n\nUsers of cloud9 can preview the contents of tabs. For instance, when pressing the spacebar in the tree a preview tab opens that goes away as soon as the user hits spacebar again or selects another tab. When the user edits the document in the previewed tab, the tab is opened permanently.\n\nThis behavior is provided by the `tabManager` via the `preview()` method. This method works in the same way as the the `open()` method with a limited set of the options.\n\n```\ntabManager.preview({\n    path: \"image.png\",\n}, function(err, tab){\n    if (err) return console.error(err); \n});\n```\n\nThere can only be one preview at one time. The properties `tabManager.previewTab` is set to the tab that is previewed or null if there is none.\n\n# Tab\n\n*For a full reference to the properties, methods and events of a tab object see [the reference guide](https://docs.c9.io/api/#!/api/Tab)*\n\n## Background Color\n\nYou can set the background color of a tab. This color is only shown when the tab is active and usually determined by the editor that is loaded.\n\n```\ntab.backgroundColor = \"rgb(255,0,0\"); // A red tab button\n```\n\n## CSS States\n\nManage the css classes of a tab button via the `classList` property. Special classes are `dark`, `error`, `loading` and `running` which you can add to a tab to specify an appropriate state.\n\n```\ntab.classList.add(\"loading\");\ntab.classList.remove(\"loading\");\n```\n\n## Properties\n\nThe tab object has a reference to it's `.pane` and the `.document` that is attached to the tab. When the tab has been active at least once the `.editor` property references the editor that displays the document. It's important to realize that when a tab has not yet been active the `.editor` property is `null`. Use the `.editorType` property to get the name of the editor that will be used to display the document.\n\n## Closing a Tab\n\nTo close a tab call `tab.close()`.\n\n## The Meta Object\n\nThe `meta` property of the tab is similar to the [document's meta object](http://cloud9-sdk.readme.io/v0.1/docs/documents#the-meta-object). The following table lists the properties on the meta object set by the different Cloud9 plugins.\n[block:html]\n{\n  \"html\": \"<table>\\n  <tr><th>Property</th><th>Plugin</th><th>Description</th>\\n  <tr><td>$loadingMetadata</td><td>metadata</td><td>During the load phase of meta data</td></tr>\\n  <tr><td>.$closing</td><td>tab</td><td>During the close phase of tab</td></tr>\\n  <tr><td>$ignore</td><td>terminal</td><td>The terminal will not ask the confirm message when the tab is closed.</td></tr>\\n</table>\"\n}\n[/block]\n\n\n## Switching Editors\n\nTo programmatically change the editor that is used for a certain document called `switchEditor`.\n\n```\ntab.switchEditor(\"imgeditor\", function(){\n     // Switch is complete\n});\n```","excerpt":"","slug":"tabs","type":"basic","title":"Tabs"}
Tabs are an important part of the Cloud9 UI. Tabs house documents which are displayed by editors. Tabs themselves live in panes and by default Cloud9 starts up with a single pane. Users can divide the UI into multiple panes and open / move tabs between panes. Tabs are controlled by the `tabManager` plugin, which offers an API to control the tabs and panes in Cloud9. # The Tab Manager Use the `tabManager` plugin to open tabs, look for already opened tabs and to listen for tabs being opened by other plugins. The focussed and active state of tabs is also handled by the `tabManager`. In addition the tabManager works closely together with other areas that house tabs such as the `console` plugin which is responsible for the console in the bottom of the screen. ## Object structure Besides tabs and panes there are several other objects involved in displaying content and making it editable. The following hierarchy describes the relationships between those objects. - [Pane](https://docs.c9.io/api/#!/api/Pane) - Represent a single pane, housing multiple tabs - [Editor](https://docs.c9.io/api/#!/api/Editor) - The editor responsible for displaying the document in the tab - [Tab](https://docs.c9.io/api/#!/api/Tab) - A single tab (button) in a pane - [Document](https://docs.c9.io/api/#!/api/Document) - The representation of a file in the tab - [Session](https://docs.c9.io/api/#!/api/Session) - The session information of the editor - [UndoManager](https://docs.c9.io/api/#!/api/UndoManager) - The object that manages the undo stack for this document It is important to note that the `Editor` plugin(s) are related to the pane, not the tab. There's only one instance of a certain editor for each pane. The editor is responsible for displaying the content of a document based on the tab that is active. There can be a maximum of one tab active per pane. ## Opening tabs The most basic way to open a tab is based on a file. Simply specify the filename to open a tab. ``` tabManager.openFile("file.js", function(err, tab){ if (err) return console.error(err); console.log("file.js was opened with content", tab.document.value); }); ``` The default editor for the extension (in this case `.js`) is chosen from the installed editors and used to display the content. In the same way you can open editors that are not file based, such as the terminal. Note that these tabs still have the full object structure as described above. ``` tabManager.openEditor("terminal", function(err, tab){ if (err) return console.error(err); var terminal = tab.editor; terminal.write("ls\n"); }); ``` The [open()](https://docs.c9.io/api/#!/api/tabManager-method-open) method allows a more granular level of control opening tabs. It allows you to focus a newly created tab, set the pane it is created in and force a different editor than the default one. ``` tabManager.open({ path: "image.png", editorType: "hex", // Note that this is an example. Cloud9 currently doesn't have an hex editor focus: true, pane: tabManager.getPanes()[1] // An example of getting the 2nd pane }, function(err, tab){ if (err) return console.error(err); }); ``` ### Opening New Files The easiest way to create a new file is via the `newfile` command, which opens a new tab with an empty unnamed file. ``` commands.exec("newfile"); ``` When you want more control opening a new file then use the `open()` method for that. ``` tabs.open({ path: "/path/to/new/filename", value: "The value of your file", active: true, document: { meta: { newfile: true } } }, function(err, tab) { if (err) return console.error(err); }); ``` The `newfile` property on the meta object is used by the tabManager to not attempt to download the file from the path specified when opening the tab. [block:callout] { "type": "warning", "title": "The meta object", "body": "The `meta` object, available on most plugins (e.g. document, tab, menu) allows you to set properties that are not directly part of the API for that plugin, but which properties can be used by other plugins. For instance the save plugin will check for `meta.ignoreSave` on a document and will not warn when a document with changes is closed when that property is set. \n\nAny plugin can extend the `meta` object of a plugin with custom properties. Note that properties starting with `$` are not saved in the object state, while all other properties are and are thus preserved between reloads of the IDE." } [/block] ### Loading Content from an Alternative Source When you want to load data into a tab from another source than a file set the `value` property to `-1`. The callback will be called synchronously with a function as the third argument to be called when the contents is loaded. ```javascript tabs.open({ value: -1, active: true }, function(err, tab, done) { getDataFromSomewhere(function(err, data){ if (err) { tab.className.add("error"); return console.error(err); } tab.document.value = data; done(); }); }); ``` It's recommended to update the [progress state](http://cloud9-sdk.readme.io/v0.1/docs/documents#progress) of the document if possible. ## Active vs Focussed Tabs There are three distinct states a tab can be in. Inactive, active and focussed. When a tab is inactive it's content is not visible. When a tab is active it's button is selected and the content of the document is displayed in the editor. When a tab is focussed, any input such as keyboard input is send to that editor. A focussed tab is always active. There can only be one focussed tab in Cloud9 at one time, while there can be multiple active tabs - one per pane. Set a tab active either via it's path or reference: ``` tabManager.activateTab("/path/to/file.js"); tabManager.activateTab(myTab); ``` Focus a tab like this: ``` tabManager.focusTab("/path/to/file.js"); tabManager.focusTab(myTab); ``` Fetch the focussed tab via `tabManager.focussedTab` when you want to apply an operation to a certain tab. ``` var tab = tabManager.focussedTab; if (tab.editorType == "ace") { performOperation(tab); } ``` ## Events The `tabManager` has over 20 events, such as `tabCreate`, `tabAfterActivate`, `tabDestroy`, etc. See the [reference guide](https://docs.c9.io/api/#!/api/tabManager) for a complete list. The [open](https://docs.c9.io/api/#!/api/tabManager-event-open) and [ready](https://docs.c9.io/api/#!/api/tabManager-event-ready) events are worth mentioning specifically. The `open` event is fired for each tab that is opened via the `open()` method (or openFile, openEditor) after its contents is loaded. ``` tabManager.on("open", function(e){ if (e.tab.path.match(/^\/some\/path/)) { // Do something } }); ``` The `ready` event is fired after Cloud9 has started and all the tabs from the previous session have been opened (which includes loading the content). ``` tabManager.on("ready", function(e){ console.log("All tabs are open"); }); ``` [block:callout] { "type": "success", "title": "Sticky Event", "body": "The `ready` event is a so-called `sticky` event, which means that if it has already fired when you set the listener it will fire immediately (synchronously)." } [/block] ## Getting a Reference to Tabs Tabs that have a file associated to it have their `path` property set. To get a reference to a tab like that use the `findTab()` method. ``` var tab = tabManager.findTab("/path/to/file.js"); ``` if a tab doesn't have a file associated, such as a terminal, then you can look them up by their name, which was automatically assigned to them when they were created. You can retrieve a list of tabs via the `getTabs()` method. ``` var allFileTabs = tabManager.getTabs().filter(function(tab){ return tab.path ? true : false; }); ``` ## Preview Users of cloud9 can preview the contents of tabs. For instance, when pressing the spacebar in the tree a preview tab opens that goes away as soon as the user hits spacebar again or selects another tab. When the user edits the document in the previewed tab, the tab is opened permanently. This behavior is provided by the `tabManager` via the `preview()` method. This method works in the same way as the the `open()` method with a limited set of the options. ``` tabManager.preview({ path: "image.png", }, function(err, tab){ if (err) return console.error(err); }); ``` There can only be one preview at one time. The properties `tabManager.previewTab` is set to the tab that is previewed or null if there is none. # Tab *For a full reference to the properties, methods and events of a tab object see [the reference guide](https://docs.c9.io/api/#!/api/Tab)* ## Background Color You can set the background color of a tab. This color is only shown when the tab is active and usually determined by the editor that is loaded. ``` tab.backgroundColor = "rgb(255,0,0"); // A red tab button ``` ## CSS States Manage the css classes of a tab button via the `classList` property. Special classes are `dark`, `error`, `loading` and `running` which you can add to a tab to specify an appropriate state. ``` tab.classList.add("loading"); tab.classList.remove("loading"); ``` ## Properties The tab object has a reference to it's `.pane` and the `.document` that is attached to the tab. When the tab has been active at least once the `.editor` property references the editor that displays the document. It's important to realize that when a tab has not yet been active the `.editor` property is `null`. Use the `.editorType` property to get the name of the editor that will be used to display the document. ## Closing a Tab To close a tab call `tab.close()`. ## The Meta Object The `meta` property of the tab is similar to the [document's meta object](http://cloud9-sdk.readme.io/v0.1/docs/documents#the-meta-object). The following table lists the properties on the meta object set by the different Cloud9 plugins. [block:html] { "html": "<table>\n <tr><th>Property</th><th>Plugin</th><th>Description</th>\n <tr><td>$loadingMetadata</td><td>metadata</td><td>During the load phase of meta data</td></tr>\n <tr><td>.$closing</td><td>tab</td><td>During the close phase of tab</td></tr>\n <tr><td>$ignore</td><td>terminal</td><td>The terminal will not ask the confirm message when the tab is closed.</td></tr>\n</table>" } [/block] ## Switching Editors To programmatically change the editor that is used for a certain document called `switchEditor`. ``` tab.switchEditor("imgeditor", function(){ // Switch is complete }); ```