Skip to content

Instantly share code, notes, and snippets.

@tonyfast
Forked from bollwyvl/README.md
Created February 22, 2016 16:55
Show Gist options
  • Save tonyfast/7c6af9fcd147bb95547d to your computer and use it in GitHub Desktop.
Save tonyfast/7c6af9fcd147bb95547d to your computer and use it in GitHub Desktop.
IPython Notebook Javascript Editor Enhancements
// %%javascript
/*
# WHAT IS THIS
Once run in a notebook, you wil have a "Widget Editing" toolbar.
When selected, and enabled in a cell with the `%%javascript` magic applied
it will apply some options (see `cm_options`)
below... most importantly, it will use jshint to give you useful
syntax feedback vs "Go look in the console and despair".
# HOW TO USE
- paste this this directly into a notebook
- uncomment the first line, `%%javascript`
- run the cell
- copy this into your `.ipython/profile_default/custom/` as `widgedit.js`
- add `require(["custom/widgedit"]);` to `custom.js`
*/
;(function(IPython, CodeMirror, require, cm){
"use strict";
// going to install this as a toolbar
var ctb = IPython.CellToolbar,
// this is the meta namespace
ns = "widgedit",
// the `require` namespace for codemirror
cm_path = "components/codemirror/",
// start with these, tweak them with other options:
// http://codemirror.net/doc/manual.html#config
cm_options = {
// i pretty much always want line numbers
lineNumbers: true,
// i pretty much always want lint
gutters: ["CodeMirror-lint-markers"],
lint: true,
// i like a clear distinction between python and js
theme: "vibrant-ink",
// so many callbacks
indentUnit: 2
},
// the default options
reset_options = {
lineNumbers: false,
gutters: [],
lint: false,
theme: "default",
indentUnit: 4
};
require(
[
"underscore",
"jquery",
"http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js",
cm_path + "addon/lint/lint",
cm_path + "addon/lint/javascript-lint"
],
function(_, $){
// make sure the namespaced metadata exists
var ensure_ns = function(cell){
var meta = cell.metadata[ns] = cell.metadata[ns] ?
cell.metadata[ns] : {};
meta.cm_options = meta.cm_options ? meta.cm_options : {};
return meta;
},
// insert a CodeMirror addon/theme stylesheet, if it isn't already there
cm_stylesheet = function(id, url){
if($("style#" + id).length){ return; }
$("head").append($("<style/>", {id: id})
.text(
'@import url("' + window.location.origin +
"/static/" + cm_path + url + '.css")'
)
);
},
// the main function
cm_tweak_js = function(cell){
var editor = cell.code_mirror,
opts = {},
meta = ensure_ns(cell);
// only update editors we care about, reset ones we might have messed
if(!editor){
return;
}else if(meta.enabled && editor.options.mode === "magic_javascript"){
opts = _.extend({}, cm_options, meta.cm_options);
}else{
opts = reset_options;
}
// handle the options that may have been set
_.map(opts, function(val, key){
// handle special cases
switch(key){
case "lint":
if(!val){
editor.setOption(key, false);
return;
}
cm_stylesheet("cm-js-lint", "addon/lint/lint");
return editor.setOption("lintWith", {
getAnnotations: function(text, options){
return CodeMirror.lint.javascript(
text.replace(/^%%.*/, ''),
options
);
}
});
break;
case "theme":
if(val !== "default"){
cm_stylesheet("cm-js-theme-" + val, "theme/" + val);
}
break;
}
// actually apply the options
editor.setOption(key, val);
});
};
// setup the GUI
var commands = {
theme: ctb.utils.select_ui_generator(
[
["-", "default"],
["3024-day"],
["3024-night"],
["ambiance"],
["ambiance-mobile"],
["base16-dark"],
["base16-light"],
["blackboard"],
["cobalt"],
["eclipse"],
["elegant"],
["erlang-dark"],
["lesser-dark"],
["mbo"],
["mdn-like"],
["midnight"],
["monokai"],
["neat"],
["night"],
["paraiso-dark"],
["paraiso-light"],
["pastel-on-dark"],
["rubyblue"],
["solarized"],
["the-matrix"],
["tomorrow-night-eighties"],
["twilight"],
["vibrant-ink"],
["xq-dark"],
["xq-light"]
],
function(cell, value){
var meta = ensure_ns(cell);
meta.cm_options.theme = value;
cm_tweak_js(cell);
},
function(cell){
return ensure_ns(cell).cm_options.theme;
},
"Theme"
),
mode: ctb.utils.checkbox_ui_generator(
"JS Enhancements",
function(cell, value){
var meta = ensure_ns(cell);
meta.enabled = value;
cm_tweak_js(cell);
},
function(cell){
cm_tweak_js(cell);
return ensure_ns(cell).enabled;
}
)
};
//install the items
ctb.register_preset(
'Widget Editing',
_.map(commands, function(cmd, key){
ctb.register_callback(ns + "." + key, cmd);
return ns + "." + key;
})
);
} // the `require` callback
); // the `require`
}).call(this, IPython, CodeMirror, require);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment