From 5f045009257969472c215e4c9ba5675c55d3cf1d Mon Sep 17 00:00:00 2001 From: Andrew Gibiansky Date: Mon, 19 May 2014 20:26:36 -0700 Subject: [PATCH] now detects ipython version 0.* and cries about it --- notebooks/Test.ipynb | 209 +++++++++++++++++++++++++++++++++++++++- src/IHaskell/IPython.hs | 3 +- 2 files changed, 208 insertions(+), 4 deletions(-) diff --git a/notebooks/Test.ipynb b/notebooks/Test.ipynb index c2150c15..7f218ee6 100644 --- a/notebooks/Test.ipynb +++ b/notebooks/Test.ipynb @@ -143,13 +143,216 @@ "// Do not load this script again.\n", "window.parsecWidgetRegistered = true;\n", "\n", + "// Codemirror lint.js\n", + "// Must be included here, otherwise linting cannot happen the first time the widget is loaded.\n", + "(function() {\n", + " \"use strict\";\n", + " var GUTTER_ID = \"CodeMirror-lint-markers\";\n", + " var SEVERITIES = /^(?:error|warning)$/;\n", + "\n", + " function showTooltip(e, content) {\n", + " var tt = document.createElement(\"div\");\n", + " tt.className = \"CodeMirror-lint-tooltip\";\n", + " tt.appendChild(content.cloneNode(true));\n", + " document.body.appendChild(tt);\n", + "\n", + " function position(e) {\n", + " if (!tt.parentNode) return CodeMirror.off(document, \"mousemove\", position);\n", + " tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + \"px\";\n", + " tt.style.left = (e.clientX + 5) + \"px\";\n", + " }\n", + " CodeMirror.on(document, \"mousemove\", position);\n", + " position(e);\n", + " if (tt.style.opacity != null) tt.style.opacity = 1;\n", + " return tt;\n", + " }\n", + " function rm(elt) {\n", + " if (elt.parentNode) elt.parentNode.removeChild(elt);\n", + " }\n", + " function hideTooltip(tt) {\n", + " if (!tt.parentNode) return;\n", + " if (tt.style.opacity == null) rm(tt);\n", + " tt.style.opacity = 0;\n", + " setTimeout(function() { rm(tt); }, 600);\n", + " }\n", + "\n", + " function showTooltipFor(e, content, node) {\n", + " var tooltip = showTooltip(e, content);\n", + " function hide() {\n", + " CodeMirror.off(node, \"mouseout\", hide);\n", + " if (tooltip) { hideTooltip(tooltip); tooltip = null; }\n", + " }\n", + " var poll = setInterval(function() {\n", + " if (tooltip) for (var n = node;; n = n.parentNode) {\n", + " if (n == document.body) return;\n", + " if (!n) { hide(); break; }\n", + " }\n", + " if (!tooltip) return clearInterval(poll);\n", + " }, 400);\n", + " CodeMirror.on(node, \"mouseout\", hide);\n", + " }\n", + "\n", + " function LintState(cm, options, hasGutter) {\n", + " this.marked = [];\n", + " this.options = options;\n", + " this.timeout = null;\n", + " this.hasGutter = hasGutter;\n", + " this.onMouseOver = function(e) { onMouseOver(cm, e); };\n", + " }\n", + "\n", + " function parseOptions(cm, options) {\n", + " if (options instanceof Function) return {getAnnotations: options};\n", + " if (!options || options === true) options = {};\n", + " if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), \"lint\");\n", + " if (!options.getAnnotations) throw new Error(\"Required option 'getAnnotations' missing (lint addon)\");\n", + " return options;\n", + " }\n", + "\n", + " function clearMarks(cm) {\n", + " var state = cm.state.lint;\n", + " if (state.hasGutter) cm.clearGutter(GUTTER_ID);\n", + " for (var i = 0; i < state.marked.length; ++i)\n", + " state.marked[i].clear();\n", + " state.marked.length = 0;\n", + " }\n", + "\n", + " function makeMarker(labels, severity, multiple, tooltips) {\n", + " var marker = document.createElement(\"div\"), inner = marker;\n", + " marker.className = \"CodeMirror-lint-marker-\" + severity;\n", + " if (multiple) {\n", + " inner = marker.appendChild(document.createElement(\"div\"));\n", + " inner.className = \"CodeMirror-lint-marker-multiple\";\n", + " }\n", + "\n", + " if (tooltips != false) CodeMirror.on(inner, \"mouseover\", function(e) {\n", + " showTooltipFor(e, labels, inner);\n", + " });\n", + "\n", + " return marker;\n", + " }\n", + "\n", + " function getMaxSeverity(a, b) {\n", + " if (a == \"error\") return a;\n", + " else return b;\n", + " }\n", + "\n", + " function groupByLine(annotations) {\n", + " var lines = [];\n", + " for (var i = 0; i < annotations.length; ++i) {\n", + " var ann = annotations[i], line = ann.from.line;\n", + " (lines[line] || (lines[line] = [])).push(ann);\n", + " }\n", + " return lines;\n", + " }\n", + "\n", + " function annotationTooltip(ann) {\n", + " var severity = ann.severity;\n", + " if (!SEVERITIES.test(severity)) severity = \"error\";\n", + " var tip = document.createElement(\"div\");\n", + " tip.className = \"CodeMirror-lint-message-\" + severity;\n", + " tip.appendChild(document.createTextNode(ann.message));\n", + " return tip;\n", + " }\n", + "\n", + " function startLinting(cm) {\n", + " var state = cm.state.lint, options = state.options;\n", + " if (options.async)\n", + " options.getAnnotations(cm, updateLinting, options);\n", + " else\n", + " updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));\n", + " }\n", + "\n", + " function updateLinting(cm, annotationsNotSorted) {\n", + " clearMarks(cm);\n", + " var state = cm.state.lint, options = state.options;\n", + "\n", + " var annotations = groupByLine(annotationsNotSorted);\n", + "\n", + " for (var line = 0; line < annotations.length; ++line) {\n", + " var anns = annotations[line];\n", + " if (!anns) continue;\n", + "\n", + " var maxSeverity = null;\n", + " var tipLabel = state.hasGutter && document.createDocumentFragment();\n", + "\n", + " for (var i = 0; i < anns.length; ++i) {\n", + " var ann = anns[i];\n", + " var severity = ann.severity;\n", + " if (!SEVERITIES.test(severity)) severity = \"error\";\n", + " maxSeverity = getMaxSeverity(maxSeverity, severity);\n", + "\n", + " if (options.formatAnnotation) ann = options.formatAnnotation(ann);\n", + " if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));\n", + "\n", + " if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {\n", + " className: \"CodeMirror-lint-mark-\" + severity,\n", + " __annotation: ann\n", + " }));\n", + " }\n", + "\n", + " if (state.hasGutter)\n", + " cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,\n", + " state.options.tooltips));\n", + " }\n", + " if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);\n", + " }\n", + "\n", + " function onChange(cm) {\n", + " var state = cm.state.lint;\n", + " clearTimeout(state.timeout);\n", + " state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);\n", + " }\n", + "\n", + " function popupSpanTooltip(ann, e) {\n", + " var target = e.target || e.srcElement;\n", + " showTooltipFor(e, annotationTooltip(ann), target);\n", + " }\n", + "\n", + " // When the mouseover fires, the cursor might not actually be over\n", + " // the character itself yet. These pairs of x,y offsets are used to\n", + " // probe a few nearby points when no suitable marked range is found.\n", + " var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];\n", + "\n", + " function onMouseOver(cm, e) {\n", + " if (!/\\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;\n", + " for (var i = 0; i < nearby.length; i += 2) {\n", + " var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],\n", + " top: e.clientY + nearby[i + 1]}));\n", + " for (var j = 0; j < spans.length; ++j) {\n", + " var span = spans[j], ann = span.__annotation;\n", + " if (ann) return popupSpanTooltip(ann, e);\n", + " }\n", + " }\n", + " }\n", + "\n", + " function optionHandler(cm, val, old) {\n", + " if (old && old != CodeMirror.Init) {\n", + " clearMarks(cm);\n", + " cm.off(\"change\", onChange);\n", + " CodeMirror.off(cm.getWrapperElement(), \"mouseover\", cm.state.lint.onMouseOver);\n", + " delete cm.state.lint;\n", + " }\n", + "\n", + " if (val) {\n", + " var gutters = cm.getOption(\"gutters\"), hasLintGutter = false;\n", + " for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;\n", + " var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);\n", + " cm.on(\"change\", onChange);\n", + " if (state.options.tooltips != false)\n", + " CodeMirror.on(cm.getWrapperElement(), \"mouseover\", state.onMouseOver);\n", + "\n", + " startLinting(cm);\n", + " }\n", + " }\n", + "\n", + " CodeMirror.defineOption(\"lintWith\", false, optionHandler); // deprecated\n", + " CodeMirror.defineOption(\"lint\", false, optionHandler); // deprecated\n", + "})();\n", + "\n", "var parsecWidgetCounter = 0;\n", "\n", "// Register the comm target.\n", "var ParsecWidget = function (comm) {\n", - " // Load linting.\n", - " require([\"/static/components/codemirror/addon/lint/lint.js\"]);\n", - "\n", " this.comm = comm;\n", " this.comm.on_msg($.proxy(this.handler, this));\n", "\n", diff --git a/src/IHaskell/IPython.hs b/src/IHaskell/IPython.hs index 2bf27511..03724b4c 100644 --- a/src/IHaskell/IPython.hs +++ b/src/IHaskell/IPython.hs @@ -183,7 +183,8 @@ setupIPython DefaultIPython = do case parseVersion output of Just (2:_) -> putStrLn "Using system-wide IPython." Just (1:_) -> badIPython "Detected old version of IPython. IHaskell requires 2.0.0 or up." - Nothing -> badIPython "Detected IPython, but could not parse version number." + Just (0:_) -> badIPython "Detected old version of IPython. IHaskell requires 2.0.0 or up." + _ -> badIPython "Detected IPython, but could not parse version number." badIPython :: Text -> IO () badIPython reason = void $ do