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](πο»Ώ) - Represent a single pane, housing multiple tabs
ο»Ώ[Editor](πο»Ώ) - The editor responsible for displaying the document in the tab
ο»Ώ[Tab](πο»Ώ) - A single tab (button) in a pane
ο»Ώ[Document](πο»Ώ) - The representation of a file in the tab
ο»Ώ[Session](πο»Ώ) - The session information of the editor
ο»Ώ[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.
βxtabManager.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.
xxxxxxxxxx
1tabManager.openEditor("terminal", function(err, tab){
if (err) return console.error(err);
var terminal = tab.editor;
terminal.write("ls\n");
});
The [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.
xxxxxxxxxx
1tabManager.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.
xxxxxxxxxx
1commands.exec("newfile");
When you want more control opening a new file then use the `open()
` method for that.
xxxxxxxxxx
113tabs.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.
The meta object
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.Any 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.
### 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.
xxxxxxxxxx
114tabs.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](πο»Ώ) 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:
xxxxxxxxxx
1tabManager.activateTab("/path/to/file.js");
tabManager.activateTab(myTab);
Focus a tab like this:
xxxxxxxxxx
1tabManager.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.
xxxxxxxxxx
1var 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](πο»Ώ) for a complete list.
The [open](πο»Ώ) and [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.
xxxxxxxxxx
1tabManager.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).
xxxxxxxxxx
1tabManager.on("ready", function(e){
console.log("All tabs are open");
});
Sticky Event
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).
## 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.
xxxxxxxxxx
1var 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.
xxxxxxxxxx
1var 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.
xxxxxxxxxx
1tabManager.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](πο»Ώ)_
## 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.
xxxxxxxxxx
1tab.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.
xxxxxxxxxx
1tab.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](πο»Ώ). The following table lists the properties on the meta object set by the different Cloud9 plugins.
xxxxxxxxxx
1<table>
<tr><th>Property</th><th>Plugin</th><th>Description</th>
<tr><td>$loadingMetadata</td><td>metadata</td><td>During the load phase of meta data</td></tr>
<tr><td>.$closing</td><td>tab</td><td>During the close phase of tab</td></tr>
<tr><td>$ignore</td><td>terminal</td><td>The terminal will not ask the confirm message when the tab is closed.</td></tr>
</table>
## Switching Editors
To programmatically change the editor that is used for a certain document called `switchEditor
`.
xxxxxxxxxx
1tab.switchEditor("imgeditor", function(){
// Switch is complete
});
ο»Ώ