editor: remember user language choices per file extension

When the language is selected manually, record the file extension and choice in config
so that future files opened with the same extension use the same mode.

This allows users to teach the editor about file extensions CodeMirror doesn't know about.
pull/2418/head
Min RK 9 years ago
parent 6cebd3ef66
commit a2f6a8c3bb

@ -32,6 +32,8 @@ function(
this.base_url = options.base_url;
this.file_path = options.file_path;
this.config = options.config;
this.file_extension_modes = options.file_extension_modes || {};
this.codemirror = new CodeMirror($(this.selector)[0]);
this.codemirror.on('changes', function(cm, changes){
that._clean_state();
@ -54,6 +56,14 @@ function(
);
that._set_codemirror_options(cmopts);
that.events.trigger('config_changed.Editor', {config: that.config});
if (cfg.file_extension_modes) {
// check for file extension in user preferences
var modename = cfg.file_extension_modes[that._get_file_extension()];
if (modename) {
var modeinfo = CodeMirror.findModeByName(modename);
that.set_codemirror_mode(modeinfo);
}
}
that._clean_state();
});
this.clean_sel = $('<div/>');
@ -99,7 +109,7 @@ function(
}
);
};
Editor.prototype._set_mode_for_model = function (model) {
/** Set the CodeMirror mode based on the file model */
@ -107,20 +117,28 @@ function(
// first by mime-type, then by file extension
var modeinfo;
// mimetype is unset on file rename
if (model.mimetype) {
modeinfo = CodeMirror.findModeByMIME(model.mimetype);
var ext = this._get_file_extension();
if (ext) {
// check if a mode has been remembered for this extension
var modename = this.file_extension_modes[ext];
if (modename) {
modeinfo = CodeMirror.findModeByName(modename);
}
}
// prioritize CodeMirror's filename identification
if (!modeinfo || modeinfo.mode === "null") {
// find by mime failed, use find by ext
var ext_idx = model.name.lastIndexOf('.');
if (ext_idx > 0) {
// CodeMirror.findModeByExtension wants extension without '.'
modeinfo = CodeMirror.findModeByExtension(
model.name.slice(ext_idx + 1).toLowerCase());
modeinfo = CodeMirror.findModeByFileName(model.name);
// codemirror's filename identification is case-sensitive.
// try once more with lowercase extension
if (!modeinfo && ext) {
// CodeMirror wants lowercase ext without leading '.'
modeinfo = CodeMirror.findModeByExtension(ext.slice(1).toLowerCase());
}
}
if (model.mimetype && (!modeinfo || modeinfo.mode === "null")) {
// mimetype is not set on file rename
modeinfo = CodeMirror.findModeByMIME(model.mimetype);
}
if (modeinfo) {
this.set_codemirror_mode(modeinfo);
}
@ -134,11 +152,41 @@ function(
that.events.trigger("mode_changed.Editor", modeinfo);
});
};
Editor.prototype.save_codemirror_mode = function (modeinfo) {
/** save the selected codemirror mode for the current extension in config */
var update_mode_map = {};
var ext = this._get_file_extension();
// no extension, nothing to save
// TODO: allow remembering no-extension things like Makefile?
if (!ext) return;
update_mode_map[ext] = modeinfo.name;
return this.config.update({
Editor: {
file_extension_modes: update_mode_map,
}
})
};
Editor.prototype.get_filename = function () {
return utils.url_path_split(this.file_path)[1];
};
Editor.prototype._get_file_extension = function () {
/** return file extension *including* .
Returns undefined if no extension is found.
*/
var filename = this.get_filename();
var ext_idx = filename.lastIndexOf('.');
if (ext_idx < 0) {
return;
} else {
return filename.slice(ext_idx);
}
};
Editor.prototype.rename = function (new_name) {
/** rename the file */
var that = this;
@ -203,7 +251,7 @@ function(
});
var that = this;
};
Editor.prototype.update_codemirror_options = function (options) {
/** update codemirror options locally and save changes in config */
var that = this;

@ -146,6 +146,8 @@ define([
function make_set_mode(info) {
return function () {
editor.set_codemirror_mode(info);
// save codemirror mode for extension when explicitly selected
editor.save_codemirror_mode(info);
};
}
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {

Loading…
Cancel
Save