-
-
Save tonyfast/7c6af9fcd147bb95547d to your computer and use it in GitHub Desktop.
IPython Notebook Javascript Editor Enhancements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// %%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