Fixing unshowable displays, adding pager docs

This commit is contained in:
Andrew Gibiansky 2015-03-03 17:54:44 -08:00
parent b2dfd0e48f
commit 6b6a9b8936
2 changed files with 406 additions and 62 deletions

View File

@ -382,7 +382,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 9,
"metadata": {
"collapsed": false
},
@ -512,7 +512,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 10,
"metadata": {
"collapsed": false
},
@ -534,9 +534,152 @@
"hidden": false
},
"source": [
"If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane. However, it looks approximately like this:\n",
"If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane that pops up after this is evaluated. However, you can disable the interactive pager, and instead just show the output below the cell:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"-- Only takes effect on later cells, so stick it in its own cell.\n",
":opt no-pager"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style>/*\n",
"Custom IHaskell CSS.\n",
"*/\n",
"\n",
"![](https://raw.githubusercontent.com/gibiansky/IHaskell/master/demo/info-demo.png)"
"/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
" display: block;\n",
" padding-bottom: 1.3em;\n",
" padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
" display: block;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
"}\n",
".hoogle-text {\n",
" display: block;\n",
"}\n",
".hoogle-name {\n",
" color: green;\n",
" font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
" display: block;\n",
" margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
" font-weight: bold;\n",
" font-style: italic;\n",
"}\n",
".hoogle-module {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
" font-weight: bold;\n",
"}\n",
"\n",
"/* Styles used for basic displays */\n",
".get-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" display: block;\n",
" white-space: pre;\n",
"}\n",
"\n",
".show-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" margin-left: 1em;\n",
"}\n",
"\n",
".mono {\n",
" font-family: monospace;\n",
" display: block;\n",
"}\n",
"\n",
".err-msg {\n",
" color: red;\n",
" font-style: italic;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
" display: block;\n",
"}\n",
"\n",
"#unshowable {\n",
" color: red;\n",
" font-weight: bold;\n",
"}\n",
"\n",
".err-msg.in.collapse {\n",
" padding-top: 0.7em;\n",
"}\n",
"\n",
"/* Code that will get highlighted before it is highlighted */\n",
".highlight-code {\n",
" white-space: pre;\n",
" font-family: monospace;\n",
"}\n",
"\n",
"/* Hlint styles */\n",
".suggestion-warning { \n",
" font-weight: bold;\n",
" color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
" font-weight: bold;\n",
" color: red;\n",
"}\n",
".suggestion-name {\n",
" font-weight: bold;\n",
"}\n",
"</style><div style='background: rgb(247, 247, 247);'><form><textarea id='code'>class (Real a, Enum a) => Integral a where\n",
" quot :: a -> a -> a\n",
" rem :: a -> a -> a\n",
" div :: a -> a -> a\n",
" mod :: a -> a -> a\n",
" quotRem :: a -> a -> (a, a)\n",
" divMod :: a -> a -> (a, a)\n",
" toInteger :: a -> Integer\n",
" \t-- Defined in GHC.Real\n",
"instance Integral a => Integral (Tagged s a) -- Defined in Data.Tagged\n",
"instance Integral Integer -- Defined in GHC.Real\n",
"instance Integral Int -- Defined in GHC.Real</textarea></form></div><script>CodeMirror.fromTextArea(document.getElementById('code'), {mode: 'haskell', readOnly: 'nocursor'});</script>\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
":info Integral"
]
},
{
@ -550,7 +693,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 13,
"metadata": {
"collapsed": false
},
@ -592,7 +735,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 14,
"metadata": {
"collapsed": false
},
@ -614,7 +757,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 15,
"metadata": {
"collapsed": false
},
@ -644,7 +787,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 16,
"metadata": {
"collapsed": false
},
@ -986,7 +1129,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 17,
"metadata": {
"collapsed": false
},
@ -1306,7 +1449,13 @@
".suggestion-name {\n",
" font-weight: bold;\n",
"}\n",
"</style><span class='err-msg'>No instance for (Show NoShow) arising from a use of print<br/>In a stmt of an interactive GHCi command: print it</span>"
"</style><div class='collapse-group'><span class='btn btn-default' href='#' id='unshowable'>Unshowable:<span class='show-type'>NoShow</span></span><span class='err-msg collapse'>No instance for (Show NoShow) arising from a use of print<br/>In a stmt of an interactive GHCi command: print it</span></div><script>$('#unshowable').on('click', function(e) {\n",
" e.preventDefault();\n",
" var $this = $(this);\n",
" var $collapse = $this.closest('.collapse-group').find('.err-msg');\n",
" $collapse.collapse('toggle');\n",
"});\n",
"</script>"
],
"text/plain": [
"No instance for (Show NoShow) arising from a use of print\n",
@ -1338,7 +1487,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 18,
"metadata": {
"collapsed": false
},
@ -1711,7 +1860,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 19,
"metadata": {
"collapsed": false
},
@ -1982,7 +2131,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 20,
"metadata": {
"collapsed": false
},
@ -2032,7 +2181,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 21,
"metadata": {
"collapsed": false
},
@ -2087,7 +2236,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 22,
"metadata": {
"collapsed": false
},
@ -2122,7 +2271,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 23,
"metadata": {
"collapsed": false
},
@ -2138,6 +2287,11 @@
}
],
"source": [
"-- This import is unnecessary, but ensures that\n",
"-- you actually have the magic library installed. Otherwise,\n",
"-- the bytestring will get displayed as a large string!\n",
"import IHaskell.Display.Magic\n",
"\n",
"import qualified Data.ByteString as B\n",
"B.readFile \"code/IHaskell/images/ihaskell-notebook.png\""
]
@ -2155,7 +2309,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 24,
"metadata": {
"collapsed": false
},
@ -2334,7 +2488,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 25,
"metadata": {
"collapsed": false
},
@ -2347,7 +2501,7 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": 26,
"metadata": {
"collapsed": false
},
@ -2378,7 +2532,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 27,
"metadata": {
"collapsed": false
},
@ -2387,6 +2541,113 @@
"data": {},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style>/*\n",
"Custom IHaskell CSS.\n",
"*/\n",
"\n",
"/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
" display: block;\n",
" padding-bottom: 1.3em;\n",
" padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
" display: block;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
"}\n",
".hoogle-text {\n",
" display: block;\n",
"}\n",
".hoogle-name {\n",
" color: green;\n",
" font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
" display: block;\n",
" margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
" font-weight: bold;\n",
" font-style: italic;\n",
"}\n",
".hoogle-module {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
" font-weight: bold;\n",
"}\n",
"\n",
"/* Styles used for basic displays */\n",
".get-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" display: block;\n",
" white-space: pre;\n",
"}\n",
"\n",
".show-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" margin-left: 1em;\n",
"}\n",
"\n",
".mono {\n",
" font-family: monospace;\n",
" display: block;\n",
"}\n",
"\n",
".err-msg {\n",
" color: red;\n",
" font-style: italic;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
" display: block;\n",
"}\n",
"\n",
"#unshowable {\n",
" color: red;\n",
" font-weight: bold;\n",
"}\n",
"\n",
".err-msg.in.collapse {\n",
" padding-top: 0.7em;\n",
"}\n",
"\n",
"/* Code that will get highlighted before it is highlighted */\n",
".highlight-code {\n",
" white-space: pre;\n",
" font-family: monospace;\n",
"}\n",
"\n",
"/* Hlint styles */\n",
".suggestion-warning { \n",
" font-weight: bold;\n",
" color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
" font-weight: bold;\n",
" color: red;\n",
"}\n",
".suggestion-name {\n",
" font-weight: bold;\n",
"}\n",
"</style><span class='hoogle-name'><a target='_blank' href='http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:filterM'>filterM</a> &#x2237; Monad m &#x21D2; (a &#x2192; m Bool) &#x2192; [a] &#x2192; m [a]</span><span class='hoogle-sub'>(<span class='hoogle-head'>package</span> <span class='hoogle-package'>base</span>, <span class='hoogle-head'>module</span> <span class='hoogle-module'>Control.Monad</span>)</span><div class='hoogle-doc'><div class='hoogle-text'>This generalizes the list-based filter function. \n",
"</div>\n",
"</div>\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
@ -2399,29 +2660,121 @@
"hidden": false
},
"source": [
"Like with `:info`, the Hoogle directives use the IPython documentation pager to show you their output. You can press Escape to dismiss the pager. If you're reading this in it's HTML form, the output looks like this:\n",
"\n",
"![](https://raw.githubusercontent.com/gibiansky/IHaskell/master/demo/doc-demo.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
"hidden": false
},
"source": [
"The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature."
"The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature. This will show you documentation for things that match the desired type signature, as demonstrated below. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations."
]
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {},
"data": {
"text/html": [
"<style>/*\n",
"Custom IHaskell CSS.\n",
"*/\n",
"\n",
"/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
" display: block;\n",
" padding-bottom: 1.3em;\n",
" padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
" display: block;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
"}\n",
".hoogle-text {\n",
" display: block;\n",
"}\n",
".hoogle-name {\n",
" color: green;\n",
" font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
" display: block;\n",
" margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
" font-weight: bold;\n",
" font-style: italic;\n",
"}\n",
".hoogle-module {\n",
" font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
" font-weight: bold;\n",
"}\n",
"\n",
"/* Styles used for basic displays */\n",
".get-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" display: block;\n",
" white-space: pre;\n",
"}\n",
"\n",
".show-type {\n",
" color: green;\n",
" font-weight: bold;\n",
" font-family: monospace;\n",
" margin-left: 1em;\n",
"}\n",
"\n",
".mono {\n",
" font-family: monospace;\n",
" display: block;\n",
"}\n",
"\n",
".err-msg {\n",
" color: red;\n",
" font-style: italic;\n",
" font-family: monospace;\n",
" white-space: pre;\n",
" display: block;\n",
"}\n",
"\n",
"#unshowable {\n",
" color: red;\n",
" font-weight: bold;\n",
"}\n",
"\n",
".err-msg.in.collapse {\n",
" padding-top: 0.7em;\n",
"}\n",
"\n",
"/* Code that will get highlighted before it is highlighted */\n",
".highlight-code {\n",
" white-space: pre;\n",
" font-family: monospace;\n",
"}\n",
"\n",
"/* Hlint styles */\n",
".suggestion-warning { \n",
" font-weight: bold;\n",
" color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
" font-weight: bold;\n",
" color: red;\n",
"}\n",
".suggestion-name {\n",
" font-weight: bold;\n",
"}\n",
"</style><span class='err-msg'>InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\"</span>"
],
"text/plain": [
"InvalidUrlException \"https://www.haskell.org/hoogle/?hoogle=:: [a] -> [(a, b)]&mode=json\" \"Invalid URL\""
]
},
"metadata": {},
"output_type": "display_data"
}
@ -2430,17 +2783,6 @@
":hoogle :: [a] -> [(a, b)]"
]
},
{
"cell_type": "markdown",
"metadata": {
"hidden": false
},
"source": [
"The pager will show you documentation for things that could have that type signature or a similar one. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations:\n",
"\n",
"![](https://raw.githubusercontent.com/gibiansky/IHaskell/master/demo/hoogle-demo.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
@ -2452,7 +2794,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 29,
"metadata": {
"collapsed": false
},
@ -2475,10 +2817,11 @@
"Any prefix of the commands will also suffice, e.g. use :ty for :type.\n",
"\n",
"Options:\n",
" lint - enable or disable linting.\n",
" svg - use svg output (cannot be resized).\n",
" show-types - show types of all bound names\n",
" show-errors - display Show instance missing errors normally."
" lint enable or disable linting.\n",
" svg use svg output (cannot be resized).\n",
" show-types show types of all bound names\n",
" show-errors display Show instance missing errors normally.\n",
" pager use the pager to display results of :info, :doc, :hoogle, etc."
]
},
"metadata": {},
@ -2500,7 +2843,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 30,
"metadata": {
"collapsed": false
},
@ -2525,7 +2868,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 31,
"metadata": {
"collapsed": false
},
@ -2566,7 +2909,7 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 32,
"metadata": {
"collapsed": false
},
@ -2695,7 +3038,7 @@
},
{
"cell_type": "code",
"execution_count": 30,
"execution_count": 33,
"metadata": {
"collapsed": false
},

View File

@ -649,10 +649,11 @@ evalCommand _ (Directive GetHelp _) state = do
,"Any prefix of the commands will also suffice, e.g. use :ty for :type."
,""
,"Options:"
," lint - enable or disable linting."
," svg - use svg output (cannot be resized)."
," show-types - show types of all bound names"
," show-errors - display Show instance missing errors normally."
," lint enable or disable linting."
," svg use svg output (cannot be resized)."
," show-types show types of all bound names"
," show-errors display Show instance missing errors normally."
," pager use the pager to display results of :info, :doc, :hoogle, etc."
]
-- This is taken largely from GHCi's info section in InteractiveUI.
@ -801,9 +802,9 @@ evalCommand output (Expression expr) state = do
isShowError (ManyDisplay _) = False
isShowError (Display errs) =
-- Note that we rely on this error message being 'type cleaned', so
-- that `Show` is not displayed as GHC.Show.Show.
-- that `Show` is not displayed as GHC.Show.Show. This is also very fragile!
startswith "No instance for (Show" msg &&
isInfixOf " arising from a use of `print'" msg
isInfixOf "print it" msg
where msg = extractPlain errs
isSvg (DisplayData mime _) = mime == MimeSvg
@ -879,7 +880,7 @@ evalCommand output (Expression expr) state = do
postprocess (DisplayData MimeHtml _) = html $ printf fmt unshowableType (formatErrorWithClass "err-msg collapse" text) script
where
fmt = "<div class='collapse-group'><span class='btn' href='#' id='unshowable'>Unshowable:<span class='show-type'>%s</span></span>%s</div><script>%s</script>"
fmt = "<div class='collapse-group'><span class='btn btn-default' href='#' id='unshowable'>Unshowable:<span class='show-type'>%s</span></span>%s</div><script>%s</script>"
script = unlines [
"$('#unshowable').on('click', function(e) {",
" e.preventDefault();",