key setting to it's default
+ */
+ resetValue: function() {
+ this.set(this.defaultValue);
+ }
+};
+oop.implement(Setting.prototype, EventEmitter);
+
+
+/**
+ * A base class for all the various methods of storing settings.
+ * Usage: + *
+ * // Create manually, or require 'settings' from the container.
+ * // This is the manual version:
+ * // Add a new setting
+ * settings.addSetting({ name:'foo', ... });
+ * // Display the default value
+ * alert(settings.get('foo'));
+ * // Alter the value, which also publishes the change etc.
+ * settings.set('foo', 'bar');
+ * // Reset the value to the default
+ * settings.resetValue('foo');
+ *
+ * @constructor
+ */
+function Settings(persister) {
+ // Storage for deactivated values
+ this._deactivated = {};
+
+ // Storage for the active settings
+ this._settings = {};
+ // We often want sorted setting names. Cache
+ this._settingNames = [];
+
+ if (persister) {
+ this.setPersister(persister);
+ }
+};
+
+Settings.prototype = {
+ /**
+ * Function to add to the list of available settings.
+ * Example usage: + *
+ * settings.addSetting({
+ * name: 'tabsize', // For use in settings.get('X')
+ * type: 'number', // To allow value checking.
+ * defaultValue: 4 // Default value for use when none is directly set
+ * });
+ *
+ * @param {object} settingSpec Object containing name/type/defaultValue members.
+ */
+ addSetting: function(settingSpec) {
+ var setting = new Setting(settingSpec, this);
+ this._settings[setting.name] = setting;
+ this._settingNames.push(setting.name);
+ this._settingNames.sort();
+ },
+
+ addSettings: function addSettings(settings) {
+ Object.keys(settings).forEach(function (name) {
+ var setting = settings[name];
+ if (!('name' in setting)) setting.name = name;
+ this.addSetting(setting);
+ }, this);
+ },
+
+ removeSetting: function(setting) {
+ var name = (typeof setting === 'string' ? setting : setting.name);
+ setting = this._settings[name];
+ delete this._settings[name];
+ util.arrayRemove(this._settingNames, name);
+ settings.removeAllListeners('change');
+ },
+
+ removeSettings: function removeSettings(settings) {
+ Object.keys(settings).forEach(function(name) {
+ var setting = settings[name];
+ if (!('name' in setting)) setting.name = name;
+ this.removeSettings(setting);
+ }, this);
+ },
+
+ getSettings: function() {
+ return Object.keys(this._settings).map(function(name) {
+ return this._settings[name];
+ }, this);
+ },
+
+ getSettingNames: function() {
+ return this._settingNames;
+ },
+
+ getSetting: function(name) {
+ return this._settings[name];
+ },
+
+ /**
+ * A Persister is able to store settings. It is an object that defines
+ * two functions:
+ * loadInitialValues(settings) and persistValue(settings, key, value).
+ */
+ setPersister: function(persister) {
+ this._persister = persister;
+ if (persister) {
+ persister.loadInitialValues(this);
+ }
+ },
+
+ resetAll: function() {
+ this.getSettingNames().forEach(function(key) {
+ this.resetValue(key);
+ }, this);
+ },
+
+ /**
+ * Retrieve a list of the known settings and their values
+ */
+ _list: function() {
+ var reply = [];
+ this.getSettingNames().forEach(function(setting) {
+ reply.push({
+ 'key': setting,
+ 'value': this.getSetting(setting).get()
+ });
+ }, this);
+ return reply;
+ },
+
+ /**
+ * Prime the local cache with the defaults.
+ */
+ _loadDefaultValues: function() {
+ this._loadFromObject(this._getDefaultValues());
+ },
+
+ /**
+ * Utility to load settings from an object
+ */
+ _loadFromObject: function(data) {
+ // We iterate over data rather than keys so we don't forget values
+ // which don't have a setting yet.
+ for (var key in data) {
+ if (data.hasOwnProperty(key)) {
+ var setting = this._settings[key];
+ if (setting) {
+ var value = setting.type.parseString(data[key]);
+ this.set(key, value);
+ } else {
+ this.set(key, data[key]);
+ }
+ }
+ }
+ },
+
+ /**
+ * Utility to grab all the settings and export them into an object
+ */
+ _saveToObject: function() {
+ return this.getSettingNames().map(function(key) {
+ return this._settings[key].type.stringify(this.get(key));
+ }.bind(this));
+ },
+
+ /**
+ * The default initial settings
+ */
+ _getDefaultValues: function() {
+ return this.getSettingNames().map(function(key) {
+ return this._settings[key].spec.defaultValue;
+ }.bind(this));
+ }
+};
+exports.settings = new Settings();
+
+/**
+ * Save the settings in a cookie
+ * This code has not been tested since reboot
+ * @constructor
+ */
+function CookiePersister() {
+};
+
+CookiePersister.prototype = {
+ loadInitialValues: function(settings) {
+ settings._loadDefaultValues();
+ var data = cookie.get('settings');
+ settings._loadFromObject(JSON.parse(data));
+ },
+
+ persistValue: function(settings, key, value) {
+ try {
+ var stringData = JSON.stringify(settings._saveToObject());
+ cookie.set('settings', stringData);
+ } catch (ex) {
+ console.error('Unable to JSONify the settings! ' + ex);
+ return;
+ }
+ }
+};
+
+exports.CookiePersister = CookiePersister;
+
+
+/**
+ * EVIL: This relies on us using settingValue in the same event as setting
+ * The alternative is to have some central place where we store the current
+ * command line, but this might be a lesser evil for now.
+ */
+var lastSetting;
+
+/**
+ * Select from the available settings
+ */
+var setting = new SelectionType({
+ name: 'setting',
+ data: function() {
+ return env.settings.getSettings();
+ },
+ noMatch: function() {
+ lastSetting = null;
+ }
+});
+(function() {
+ var originalStringify = setting.stringify;
+ setting.stringify = function(setting) {
+ lastSetting = setting;
+ return originalStringify.call(this, setting);
+ };
+
+ var originalParse = setting.parse;
+ setting.parse = function(arg) {
+ var conversion = originalParse.call(this, arg);
+ lastSetting = conversion.value;
+ return conversion;
+ };
+})();
+
+/**
+ * Something of a hack to allow the set command to give a clearer definition
+ * of the type to the command line.
+ */
+var settingValue = new DeferredType({
+ name: 'settingValue',
+ defer: function() {
+ if (lastSetting) {
+ return lastSetting.type;
+ }
+ else {
+ // console.error('Missing lastSetting. Defaulting to blank');
+ return types.getType('blank');
+ }
+ }
+});
+
+var env;
+
+
+/**
+ * Registration and de-registration.
+ */
+exports.startup = function(data) {
+ env = data.env;
+ types.registerType(setting);
+ types.registerType(settingValue);
+};
+
+exports.shutdown = function(data) {
+ types.unregisterType(setting);
+ types.unregisterType(settingValue);
+};
+
+
+});
diff --git a/lib/ace/settings/default-settings.js b/lib/ace/settings/default-settings.js
index cb1092aa..9008d2c0 100644
--- a/lib/ace/settings/default-settings.js
+++ b/lib/ace/settings/default-settings.js
@@ -84,13 +84,13 @@ var settings = {
}
};
-exports.startup = function startup(data, reason) {
+exports.startup = function startup(data) {
env = data.env;
types.registerTypes(settingTypes);
data.env.settings.addSettings(settings);
};
-exports.shutdown = function shutdown(data, reason) {
+exports.shutdown = function shutdown(data) {
data.env.settings.removeSettings(settings);
};
diff --git a/support/cockpit b/support/cockpit
index aa56894e..e20180cc 160000
--- a/support/cockpit
+++ b/support/cockpit
@@ -1 +1 @@
-Subproject commit aa56894ef1cfa30ab038d77fbc79f72416eb43e6
+Subproject commit e20180cc3311b0d366e2624ddd1b150767bb41e4