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 - 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
- Document - The representation of a file in the tab
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() 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.
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 formeta.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.
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 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 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.
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");
});
Sticky Event
The
ready
event is a so-calledsticky
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.
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
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. The following table lists the properties on the meta object set by the different Cloud9 plugins.
Property | Plugin | Description |
---|---|---|
$loadingMetadata | metadata | During the load phase of meta data |
.$closing | tab | During the close phase of tab |
$ignore | terminal | The terminal will not ask the confirm message when the tab is closed. |
Switching Editors
To programmatically change the editor that is used for a certain document called switchEditor
.
tab.switchEditor("imgeditor", function(){
// Switch is complete
});
Updated less than a minute ago