editor progress

- load/store codemirror config
- fill out menus a bit:
  - Edit/find,replace
  - View/toggle line numbers
This commit is contained in:
Min RK 2014-11-26 13:05:02 -08:00
parent 0b46e2aff2
commit 0efd335553
4 changed files with 117 additions and 25 deletions

View File

@ -6,20 +6,31 @@ define([
'base/js/utils', 'base/js/utils',
'codemirror/lib/codemirror', 'codemirror/lib/codemirror',
'codemirror/mode/meta', 'codemirror/mode/meta',
'codemirror/addon/search/search' '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',
], ],
function($, function($,
utils, utils,
CodeMirror CodeMirror
) { ) {
"use strict";
var Editor = function(selector, options) { var Editor = function(selector, options) {
var that = this;
this.selector = selector; this.selector = selector;
this.contents = options.contents; this.contents = options.contents;
this.events = options.events; this.events = options.events;
this.base_url = options.base_url; this.base_url = options.base_url;
this.file_path = options.file_path; this.file_path = options.file_path;
this.config = options.config;
this.codemirror = CodeMirror($(this.selector)[0]); this.codemirror = new CodeMirror($(this.selector)[0]);
// It appears we have to set commands on the CodeMirror class, not the // 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. I'd like to be wrong, but since there should only be one CM
@ -27,12 +38,34 @@ function($,
CodeMirror.commands.save = $.proxy(this.save, this); CodeMirror.commands.save = $.proxy(this.save, this);
this.save_enabled = false; this.save_enabled = false;
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 || {}
);
that.set_codemirror_options(cmopts, false);
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,
}; };
Editor.prototype.load = function() { Editor.prototype.load = function() {
/** load the file */
var that = this; var that = this;
var cm = this.codemirror; var cm = this.codemirror;
this.contents.get(this.file_path, {type: 'file', format: 'text'}) return this.contents.get(this.file_path, {type: 'file', format: 'text'})
.then(function(model) { .then(function(model) {
cm.setValue(model.content); cm.setValue(model.content);
@ -56,6 +89,7 @@ function($,
}; };
Editor.prototype.save = function() { Editor.prototype.save = function() {
/** save the file */
if (!this.save_enabled) { if (!this.save_enabled) {
console.log("Not saving, save disabled"); console.log("Not saving, save disabled");
return; return;
@ -67,10 +101,30 @@ function($,
content: this.codemirror.getValue(), content: this.codemirror.getValue(),
}; };
var that = this; var that = this;
this.contents.save(this.file_path, model).then(function() { return this.contents.save(this.file_path, model).then(function() {
that.events.trigger("save_succeeded.TextEditor"); that.events.trigger("save_succeeded.TextEditor");
}); });
}; };
Editor.prototype._set_codemirror_options = function (options) {
// update codemirror options from a dict
for (var opt in options) {
this.codemirror.setOption(opt, options[opt]);
}
};
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})
);
};
return {Editor: Editor}; return {Editor: Editor};
}); });

View File

@ -36,6 +36,7 @@ require([
events: events, events: events,
contents: contents, contents: contents,
file_path: file_path, file_path: file_path,
config: config,
}); });
// Make it available for debugging // Make it available for debugging
@ -44,6 +45,7 @@ require([
var menus = new menubar.MenuBar('#menubar', { var menus = new menubar.MenuBar('#menubar', {
base_url: base_url, base_url: base_url,
editor: editor, editor: editor,
events: events,
}); });
var notification_area = new notificationarea.EditorNotificationArea( var notification_area = new notificationarea.EditorNotificationArea(

View File

@ -29,6 +29,7 @@ define([
this.base_url = options.base_url || utils.get_body_data("baseUrl"); this.base_url = options.base_url || utils.get_body_data("baseUrl");
this.selector = selector; this.selector = selector;
this.editor = options.editor; this.editor = options.editor;
this.events = options.events;
if (this.selector !== undefined) { if (this.selector !== undefined) {
this.element = $(selector); this.element = $(selector);
@ -41,8 +42,31 @@ define([
* File * File
*/ */
var that = this; var that = this;
this.element.find('#save_file').click(function () { var editor = that.editor;
that.editor.save(); this.element.find('#save-file').click(function () {
editor.save();
});
// Edit
this.element.find('#menu-find').click(function () {
editor.codemirror.execCommand("find");
});
this.element.find('#menu-replace').click(function () {
editor.codemirror.execCommand("replace");
});
// View
this.element.find('#menu-line-numbers').click(function () {
var current = editor.codemirror.getOption('lineNumbers');
var value = Boolean(1-current);
editor.update_codemirror_options({lineNumbers: value});
});
this.events.on("config_changed.Editor", function () {
var lineNumbers = editor.codemirror.getOption('lineNumbers');
var text = lineNumbers ? "Hide" : "Show";
text = text + " Line Numbers";
that.element.find('#menu-line-numbers').find("a").text(text);
}); });
}; };

View File

@ -36,7 +36,7 @@ data-file-path="{{file_path}}"
{% block site %} {% block site %}
<div id="menubar-container" class="container"> <div id="menubar-container" class="container">
<div id="menubar"> <div id="menubar">
<div id="menus" class="navbar navbar-default" role="navigation"> <div id="menus" class="navbar navbar-default" role="navigation">
<div class="container-fluid"> <div class="container-fluid">
<button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
@ -49,15 +49,27 @@ data-file-path="{{file_path}}"
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a> <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
<ul id="file_menu" class="dropdown-menu"> <ul id="file-menu" class="dropdown-menu">
<li id="save_file"><a href="#">Save</a></li> <li id="new-file"><a href="#">New</a></li>
<li id="save-file"><a href="#">Save</a></li>
</ul>
</li>
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
<ul id="edit-menu" class="dropdown-menu">
<li id="menu-find"><a href="#">Find</a></li>
<li id="menu-replace"><a href="#">Find &amp; Replace</a></li>
</ul>
</li>
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
<ul id="view-menu" class="dropdown-menu">
<li id="menu-line-numbers"><a href="#">Hide Line Numbers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div id="texteditor-container" class="container"></div> <div id="texteditor-container" class="container"></div>