editor.js
141 lines
| 4.6 KiB
| application/javascript
|
JavascriptLexer
Thomas Kluyver
|
r19013 | // Copyright (c) IPython Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||||
define([ | ||||
'jquery', | ||||
'base/js/utils', | ||||
'codemirror/lib/codemirror', | ||||
'codemirror/mode/meta', | ||||
Min RK
|
r19303 | 'codemirror/addon/comment/comment', | ||
'codemirror/addon/dialog/dialog', | ||||
'codemirror/addon/edit/closebrackets', | ||||
'codemirror/addon/edit/matchbrackets', | ||||
'codemirror/addon/search/searchcursor', | ||||
'codemirror/addon/search/search', | ||||
'codemirror/keymap/emacs', | ||||
'codemirror/keymap/sublime', | ||||
'codemirror/keymap/vim', | ||||
Thomas Kluyver
|
r19013 | ], | ||
function($, | ||||
utils, | ||||
CodeMirror | ||||
) { | ||||
Min RK
|
r19303 | "use strict"; | ||
Thomas Kluyver
|
r19013 | var Editor = function(selector, options) { | ||
Min RK
|
r19303 | var that = this; | ||
Thomas Kluyver
|
r19013 | this.selector = selector; | ||
this.contents = options.contents; | ||||
this.events = options.events; | ||||
this.base_url = options.base_url; | ||||
this.file_path = options.file_path; | ||||
Min RK
|
r19303 | this.config = options.config; | ||
this.codemirror = new CodeMirror($(this.selector)[0]); | ||||
Min RK
|
r19304 | this.generation = -1; | ||
Thomas Kluyver
|
r19013 | |||
Thomas Kluyver
|
r19020 | // It appears we have to set commands on the CodeMirror class, not the | ||
// instance. I'd like to be wrong, but since there should only be one CM | ||||
// instance on the page, this is good enough for now. | ||||
CodeMirror.commands.save = $.proxy(this.save, this); | ||||
Thomas Kluyver
|
r19015 | this.save_enabled = false; | ||
Min RK
|
r19303 | |||
this.config.loaded.then(function () { | ||||
// load codemirror config | ||||
var cfg = that.config.data.Editor || {}; | ||||
var cmopts = $.extend(true, {}, // true = recursive copy | ||||
Editor.default_codemirror_options, | ||||
cfg.codemirror_options || {} | ||||
); | ||||
Min RK
|
r19309 | that._set_codemirror_options(cmopts); | ||
Min RK
|
r19303 | that.events.trigger('config_changed.Editor', {config: that.config}); | ||
}); | ||||
}; | ||||
// default CodeMirror options | ||||
Editor.default_codemirror_options = { | ||||
extraKeys: { | ||||
"Tab" : "indentMore", | ||||
}, | ||||
indentUnit: 4, | ||||
theme: "ipython", | ||||
lineNumbers: true, | ||||
Thomas Kluyver
|
r19013 | }; | ||
Editor.prototype.load = function() { | ||||
Min RK
|
r19303 | /** load the file */ | ||
Thomas Kluyver
|
r19015 | var that = this; | ||
Thomas Kluyver
|
r19013 | var cm = this.codemirror; | ||
Min RK
|
r19303 | return this.contents.get(this.file_path, {type: 'file', format: 'text'}) | ||
Thomas Kluyver
|
r19015 | .then(function(model) { | ||
cm.setValue(model.content); | ||||
Scott Sanderson
|
r19089 | |||
// Setting the file's initial value creates a history entry, | ||||
// which we don't want. | ||||
cm.clearHistory(); | ||||
Thomas Kluyver
|
r19015 | // Find and load the highlighting mode | ||
Nicholas Bollweg (Nick)
|
r19290 | utils.requireCodeMirrorMode(model.mimetype, function(spec) { | ||
var mode = CodeMirror.getMode({}, spec); | ||||
cm.setOption('mode', mode); | ||||
}); | ||||
Thomas Kluyver
|
r19015 | that.save_enabled = true; | ||
Min RK
|
r19304 | that.generation = cm.changeGeneration(); | ||
Thomas Kluyver
|
r19015 | }, | ||
function(error) { | ||||
cm.setValue("Error! " + error.message + | ||||
"\nSaving disabled."); | ||||
that.save_enabled = false; | ||||
Thomas Kluyver
|
r19013 | } | ||
Thomas Kluyver
|
r19015 | ); | ||
Thomas Kluyver
|
r19013 | }; | ||
Editor.prototype.save = function() { | ||||
Min RK
|
r19303 | /** save the file */ | ||
Thomas Kluyver
|
r19015 | if (!this.save_enabled) { | ||
console.log("Not saving, save disabled"); | ||||
return; | ||||
} | ||||
Thomas Kluyver
|
r19013 | var model = { | ||
Thomas Kluyver
|
r19015 | path: this.file_path, | ||
Thomas Kluyver
|
r19013 | type: 'file', | ||
format: 'text', | ||||
content: this.codemirror.getValue(), | ||||
}; | ||||
var that = this; | ||||
Min RK
|
r19304 | // record change generation for isClean | ||
this.generation = this.codemirror.changeGeneration(); | ||||
Min RK
|
r19303 | return this.contents.save(this.file_path, model).then(function() { | ||
Thomas Kluyver
|
r19017 | that.events.trigger("save_succeeded.TextEditor"); | ||
Thomas Kluyver
|
r19013 | }); | ||
}; | ||||
Min RK
|
r19303 | |||
Editor.prototype._set_codemirror_options = function (options) { | ||||
// update codemirror options from a dict | ||||
for (var opt in options) { | ||||
Min RK
|
r19309 | if (!options.hasOwnProperty(opt)) { | ||
continue; | ||||
} | ||||
Min RK
|
r19311 | var value = options[opt]; | ||
if (value === null) { | ||||
value = CodeMirror.defaults[opt]; | ||||
} | ||||
this.codemirror.setOption(opt, value); | ||||
Min RK
|
r19303 | } | ||
}; | ||||
Editor.prototype.update_codemirror_options = function (options) { | ||||
/** update codemirror options locally and save changes in config */ | ||||
var that = this; | ||||
this._set_codemirror_options(options); | ||||
return this.config.update({ | ||||
Editor: { | ||||
codemirror_options: options | ||||
} | ||||
}).then( | ||||
that.events.trigger('config_changed.Editor', {config: that.config}) | ||||
); | ||||
}; | ||||
Thomas Kluyver
|
r19013 | |||
return {Editor: Editor}; | ||||
}); | ||||