Settings and Preferences

There are many reasons why plugins need to store persistent data across sessions. Often this can be data specific to a user, the state of the plugin and it's UI or things related to the project.

The settings plugin allows plugins to store settings in a tree like structure, similar to other key value stores like redis or the windows registry. There are three root contexts in which data can be stored. The user, project and state.

User settings are loaded on each workspace that the user is logged in to. Preference like the selected theme and keyboard shortcuts are stored in the user context. Settings that are specific to a project are stored in the project context. These settings are stored in the .c9/project.settings relative to the project directory. Settings like the tab distances are stored here. Anyone using that project will load these settings. Finally the application state is stored in the state context. Settings like a panel's width or the selection state of the tree are stored here.

As a plugin developer you choose where to store which setting. First specify the defaults:

settings.on("read", function(){
    settings.setDefaults("user/my-plugin", [
        ["someKey", "value"],
        ["otherKey", "value"]
    ]);
}, plugin);

In this case we're adding some user settings. Set and fetch the values like this:

settings.set("user/my-plugin/@someKey", 100);
settings.getNumber("user/my-plugin/@someKey");

Often you'll want to listen to changes to a key. For instance when a user changes a setting via the preference pane. To respond to the change of a setting use the following code:

settings.on("user/my-plugin/@someKey", function(value){
    console.log("Value changed to:", value);
}, plugin);

Note that the plugin is passed as the 3rd argument to make sure this event handler is cleaned when the plugin unloads.

Preferences

When you want to enable a user to configure some of these settings, use the preferences API to add some UI elements to the preference pane.

Simply describe the widget, the place of the widget in the navigation tree and the setting it is operating on.

prefs.add({
    "Example" : {
        position: 450,
        "My Plugin" : {
            position: 100,
            "First Setting": {
                type: "checkbox",
                setting: "user/my-plugin/@first",
                position: 100
            }
        }
    }
}, plugin);

Similar to the menus, use the position index to specify how to sort the vertical position of your widget.

🚧

Positioning using an index

Throughout Cloud9 you'll see APIs that allow you to sort your items using integers. By using an int to set the position it is possible to determine the approximate position of, for instance an item in a menu without having any knowledge about other plugins that are loaded. Usually all plugins are a-like and there are no special ranges. Simply choose a position that makes sense to you and use it.

To see what the position ints are simply load Cloud9 with ?menus=1 in the url.

The next example show's how to create a dropdown:

"Second Setting": {
    type: "dropdown",
    setting: "user/my-plugin/@second",
    width: "185",
    position: 200,
    items: [
        { value: "you", caption: "You" },
        { value: "me", caption: "Me" },
        { value: "all", caption: "All" }
    ]
}