src/extensions/default/CodeFolding/Prefs.js
/**
* Wrapper around brackets pref system to ensure preferences are stored in in one single object instead of using multiple keys.
* This is to make it easy for the user who edits their preferences file to easily manage the potentially numerous lines of preferences generated by the persisting code-folding state.
* @author Patrick Oladimeji
* @date 3/22/14 20:39:53 PM
*/
define(function (require, exports, module) {
"use strict";
var ProjectManager = brackets.getModule("project/ProjectManager"),
PreferencesManager = brackets.getModule("preferences/PreferencesManager"),
Strings = brackets.getModule("strings"),
prefs = PreferencesManager.getExtensionPrefs("code-folding"),
FOLDS_PREF_KEY = "code-folding.folds",
// preference key strings are here for now since they are not used in any UI
ENABLE_CODE_FOLDING = "Enable code folding",
MIN_FOLD_SIZE = "Minimum fold size",
SAVE_FOLD_STATES = "Save fold states",
ALWAYS_USE_INDENT_FOLD = "Always use indent fold",
HIDE_FOLD_BUTTONS = "Hide fold triangles",
MAX_FOLD_LEVEL = "Max fold level",
MAKE_SELECTIONS_FOLDABLE = "Makes selections foldable";
//default preference values
prefs.definePreference("enabled", "boolean", true,
{name: ENABLE_CODE_FOLDING, description: Strings.DESCRIPTION_CODE_FOLDING_ENABLED});
prefs.definePreference("minFoldSize", "number", 2,
{name: MIN_FOLD_SIZE, description: Strings.DESCRIPTION_CODE_FOLDING_MIN_FOLD_SIZE});
prefs.definePreference("saveFoldStates", "boolean", true,
{name: SAVE_FOLD_STATES, description: Strings.DESCRIPTION_CODE_FOLDING_SAVE_FOLD_STATES});
prefs.definePreference("alwaysUseIndentFold", "boolean", false,
{name: ALWAYS_USE_INDENT_FOLD, description: Strings.DESCRIPTION_CODE_FOLDING_ALWAY_USE_INDENT_FOLD});
prefs.definePreference("hideUntilMouseover", "boolean", false,
{name: HIDE_FOLD_BUTTONS, description: Strings.DESCRIPTION_CODE_FOLDING_HIDE_UNTIL_MOUSEOVER});
prefs.definePreference("maxFoldLevel", "number", 2,
{name: MAX_FOLD_LEVEL, description: Strings.DESCRIPTION_CODE_FOLDING_MAX_FOLD_LEVEL});
prefs.definePreference("makeSelectionsFoldable", "boolean", true,
{name: MAKE_SELECTIONS_FOLDABLE, description: Strings.DESCRIPTION_CODE_FOLDING_MAKE_SELECTIONS_FOLDABLE});
PreferencesManager.stateManager.definePreference(FOLDS_PREF_KEY, "object", {});
/**
* Simplifies the fold ranges into an array of pairs of numbers.
* @param {!Object} folds the raw fold ranges indexed by line numbers
* @return {Object} an object whose keys are line numbers and the values are array
* of two 2-element arrays. First array contains [from.line, from.ch] and the second contains [to.line, to.ch]
*/
function simplify(folds) {
if (!folds) {
return;
}
var res = {}, range;
Object.keys(folds).forEach(function (line) {
range = folds[line];
res[line] = Array.isArray(range) ? range : [[range.from.line, range.from.ch], [range.to.line, range.to.ch]];
});
return res;
}
/**
* Inflates the fold ranges stored as simplified numeric arrays. The inflation converts the data into
* objects whose keys are line numbers and whose values are objects in the format {from: {line, ch}, to: {line, ch}}.
* @param {Object} folds the simplified fold ranges
* @return {Object} the converted fold ranges
*/
function inflate(folds) {
if (!folds) {
return;
}
//transform the folds into objects with from and to properties
var ranges = {}, obj;
Object.keys(folds).forEach(function (line) {
obj = folds[line];
ranges[line] = {from: {line: obj[0][0], ch: obj[0][1]}, to: {line: obj[1][0], ch: obj[1][1]}};
});
return ranges;
}
/**
* Returns a 'context' object for getting/setting project-specific view state preferences.
* Similar to code in MultiRangeInlineEditor._getPrefsContext()...
*/
function getViewStateContext() {
var projectRoot = ProjectManager.getProjectRoot(); // note: null during unit tests!
return { location : { scope: "user",
layer: "project",
layerID: projectRoot && projectRoot.fullPath } };
}
/**
* Gets the line folds saved for the specified path.
* @param {string} path the document path
* @return {Object} the line folds for the document at the specified path
*/
function getFolds(path) {
var context = getViewStateContext();
var folds = PreferencesManager.getViewState(FOLDS_PREF_KEY, context);
return inflate(folds[path]);
}
/**
* Saves the line folds for the specified path
* @param {!string} path the path to the document
* @param {Object} folds the fold ranges to save for the current document
*/
function setFolds(path, folds) {
var context = getViewStateContext();
var allFolds = PreferencesManager.getViewState(FOLDS_PREF_KEY, context);
allFolds[path] = simplify(folds);
PreferencesManager.setViewState(FOLDS_PREF_KEY, allFolds, context);
}
/**
* Get the code folding setting with the specified key from the store
* @param {!string} key The key for the setting to retrieve
* @return {string} the setting with the specified key
*/
function getSetting(key) {
return prefs.get(key);
}
/**
* Clears all the saved line folds for all documents.
*/
function clearAllFolds() {
PreferencesManager.setViewState(FOLDS_PREF_KEY, {});
}
module.exports.getFolds = getFolds;
module.exports.setFolds = setFolds;
module.exports.getSetting = getSetting;
module.exports.clearAllFolds = clearAllFolds;
module.exports.prefsObject = prefs;
});