Commit 9c0883ff authored by Andrew Gibiansky's avatar Andrew Gibiansky

Removing setuptools. Hoogle is much prettier now.

parent a097310e
...@@ -5,6 +5,8 @@ Custom IHaskell CSS. ...@@ -5,6 +5,8 @@ Custom IHaskell CSS.
/* Styles used for the Hoogle display in the pager */ /* Styles used for the Hoogle display in the pager */
.hoogle-doc { .hoogle-doc {
display: block; display: block;
padding-bottom: 1.3em;
padding-left: 0.4em;
} }
.hoogle-code { .hoogle-code {
display: block; display: block;
...@@ -18,13 +20,20 @@ Custom IHaskell CSS. ...@@ -18,13 +20,20 @@ Custom IHaskell CSS.
color: green; color: green;
font-weight: bold; font-weight: bold;
} }
.hoogle-package { .hoogle-head {
font-weight: bold; font-weight: bold;
} }
.hoogle-package-name { .hoogle-sub {
display: block;
margin-left: 0.4em;
}
.hoogle-package {
font-weight: bold; font-weight: bold;
font-style: italic; font-style: italic;
} }
.hoogle-module {
font-weight: bold;
}
/* Styles used for basic displays */ /* Styles used for basic displays */
.get-type { .get-type {
......
...@@ -52,7 +52,7 @@ $([IPython.events]).on('app_initialized.NotebookApp', function(){ ...@@ -52,7 +52,7 @@ $([IPython.events]).on('app_initialized.NotebookApp', function(){
// Prevent the pager from surrounding everything with a <pre> // Prevent the pager from surrounding everything with a <pre>
IPython.Pager.prototype.append_text = function (text) { IPython.Pager.prototype.append_text = function (text) {
this.pager_element.find(".container").append($('<div/>').html(text)); this.pager_element.find(".container").append($('<div/>').html(IPython.utils.autoLinkUrls(text)));
}; };
}); });
......
...@@ -610,21 +610,11 @@ evalCommand _ (Directive GetInfo str) state = safely state $ do ...@@ -610,21 +610,11 @@ evalCommand _ (Directive GetInfo str) state = safely state $ do
evalCommand _ (Directive SearchHoogle query) state = safely state $ do evalCommand _ (Directive SearchHoogle query) state = safely state $ do
results <- liftIO $ Hoogle.search query results <- liftIO $ Hoogle.search query
let output = unlines $ map (Hoogle.render Hoogle.HTML) results return $ hoogleResults state results
return EvalOut {
evalStatus = Success,
evalResult = [],
evalState = state,
evalPager = output
}
evalCommand _ (Directive GetDoc query) state = safely state $ evalCommand _ (Directive GetDoc query) state = safely state $ do
return EvalOut { results <- liftIO $ Hoogle.document query
evalStatus = Success, return $ hoogleResults state results
evalResult = [],
evalState = state,
evalPager = "Hoogle documentation queries not implemented yet."
}
evalCommand output (Statement stmt) state = wrapExecution state $ do evalCommand output (Statement stmt) state = wrapExecution state $ do
write $ "Statement:\n" ++ stmt write $ "Statement:\n" ++ stmt
...@@ -813,6 +803,21 @@ evalCommand _ (ParseError loc err) state = do ...@@ -813,6 +803,21 @@ evalCommand _ (ParseError loc err) state = do
evalPager = "" evalPager = ""
} }
hoogleResults :: KernelState -> [Hoogle.HoogleResult] -> EvalOut
hoogleResults state results = EvalOut {
evalStatus = Success,
evalResult = [],
evalState = state,
evalPager = output
}
where
fmt =
case getFrontend state of
IPythonNotebook -> Hoogle.HTML
IPythonConsole -> Hoogle.Plain
output = unlines $ map (Hoogle.render fmt) results
-- Read from a file handle until we hit a delimiter or until we've read -- Read from a file handle until we hit a delimiter or until we've read
-- as many characters as requested -- as many characters as requested
readChars :: Handle -> String -> Int -> IO String readChars :: Handle -> String -> Int -> IO String
......
...@@ -3,14 +3,17 @@ module IHaskell.Eval.Hoogle ( ...@@ -3,14 +3,17 @@ module IHaskell.Eval.Hoogle (
search, search,
document, document,
render, render,
OutputFormat(..) OutputFormat(..),
HoogleResult
) where ) where
import ClassyPrelude import ClassyPrelude hiding (span, div)
import Text.Printf import Text.Printf
import Network.HTTP import Network.HTTP
import Data.Aeson import Data.Aeson
import Data.String.Utils import Data.String.Utils
import Data.List (elemIndex, (!!), last)
import Control.Monad (guard)
import qualified Data.ByteString.Lazy.Char8 as Char import qualified Data.ByteString.Lazy.Char8 as Char
...@@ -32,6 +35,7 @@ data HoogleResult ...@@ -32,6 +35,7 @@ data HoogleResult
= SearchResult HoogleResponse = SearchResult HoogleResponse
| DocResult HoogleResponse | DocResult HoogleResponse
| NoResult String | NoResult String
deriving Show
instance FromJSON [HoogleResponse] where instance FromJSON [HoogleResponse] where
parseJSON (Object obj) = do parseJSON (Object obj) = do
...@@ -73,7 +77,10 @@ search string = do ...@@ -73,7 +77,10 @@ search string = do
Right json -> Right json ->
case eitherDecode $ Char.pack json of case eitherDecode $ Char.pack json of
Left err -> [NoResult err] Left err -> [NoResult err]
Right results -> map SearchResult results Right results ->
case map SearchResult results of
[] -> [NoResult "no matching identifiers found."]
res -> res
-- | Look up an identifier on Hoogle. -- | Look up an identifier on Hoogle.
-- Return documentation for that identifier. If there are many -- Return documentation for that identifier. If there are many
...@@ -81,9 +88,17 @@ search string = do ...@@ -81,9 +88,17 @@ search string = do
document :: String -> IO [HoogleResult] document :: String -> IO [HoogleResult]
document string = do document string = do
matchingResults <- filter matches <$> search string matchingResults <- filter matches <$> search string
return $ map toDocResult matchingResults let results = map toDocResult matchingResults
return $ case results of
[] -> [NoResult "no matching identifiers found."]
res -> res
where where
matches (SearchResult resp) = startswith "string" $ self resp matches (SearchResult resp) =
case split " " $ self resp of
name:_ -> strip string == strip name
_ -> False
matches _ = False
toDocResult (SearchResult resp) = DocResult resp toDocResult (SearchResult resp) = DocResult resp
-- | Render a Hoogle search result into an output format. -- | Render a Hoogle search result into an output format.
...@@ -115,38 +130,97 @@ renderHtml (NoResult resp) = ...@@ -115,38 +130,97 @@ renderHtml (NoResult resp) =
printf "<span class='err-msg'>No result: %s</span>" resp printf "<span class='err-msg'>No result: %s</span>" resp
renderHtml (DocResult resp) = renderHtml (DocResult resp) =
printf "%s<br/><a href='%s'>...more...</a><br/><div class='hoogle-doc'>%s</div>" renderSelf (self resp) (location resp)
(renderSelf $ self resp) ++
(location resp) renderDocs (docs resp)
(renderDocs $ docs resp)
renderHtml (SearchResult resp) = renderHtml (SearchResult resp) =
printf "%s<br/><a href='%s'>...more...</a><br/><div class='hoogle-doc'>%s</div>" renderSelf (self resp) (location resp)
(renderSelf $ self resp) ++
(location resp) renderDocs (docs resp)
(renderDocs $ docs resp)
renderSelf :: String -> String renderSelf :: String -> String -> String
renderSelf string renderSelf string loc
| startswith "package" string | startswith "package" string
= printf "%s <span class='hoogle-package-name'>%s</span>" pkg $ replace "package" "" string = pkg ++ " " ++ span "hoogle-package" (link loc $ extractPackage string)
| startswith "module" string
= let package = extractPackageName loc in
mod ++ " " ++
span "hoogle-module" (link loc $ extractModule string) ++
packageSub package
| otherwise | otherwise
= printf "<span class='hoogle-name'>%s</span>" $ strip string = let [name, args] = split "::" string
package = extractPackageName loc
modname = extractModuleName loc in
span "hoogle-name" (unicodeReplace $
link loc (strip name) ++
" :: " ++
strip args)
++ packageAndModuleSub package modname
where where
pkg = "<span class='hoogle-package'>package</span>" :: String extractPackage = strip . replace "package" ""
extractModule = strip . replace "module" ""
pkg = span "hoogle-head" "package"
mod = span "hoogle-head" "module"
unicodeReplace :: String -> String
unicodeReplace =
replace "forall" "&#x2200;" .
replace "=>" "&#x21D2;" .
replace "->" "&#x2192;" .
replace "::" "&#x2237;"
packageSub Nothing = ""
packageSub (Just package) =
span "hoogle-sub" $
"(" ++ pkg ++ " " ++ span "hoogle-package" package ++ ")"
packageAndModuleSub Nothing _ = ""
packageAndModuleSub (Just package) Nothing = packageSub (Just package)
packageAndModuleSub (Just package) (Just modname) =
span "hoogle-sub" $
"(" ++ pkg ++ " " ++ span "hoogle-package" package ++
", " ++ mod ++ " " ++ span "hoogle-module" modname ++ ")"
renderDocs :: String -> String renderDocs :: String -> String
renderDocs doc = renderDocs doc =
let groups = groupBy bothAreCode $ lines doc let groups = groupBy bothAreCode $ lines doc
nonull = filter (not . null . strip)
bothAreCode s1 s2 = bothAreCode s1 s2 =
startswith ">" (strip s1) && startswith ">" (strip s1) &&
startswith ">" (strip s2) startswith ">" (strip s2)
isCode (s:_) = startswith ">" $ strip s isCode (s:_) = startswith ">" $ strip s
makeBlock lines = makeBlock lines =
if isCode lines if isCode lines
then printf "<div class='hoogle-code'>%s<div>" $ unlines lines then div "hoogle-code" $ unlines $ nonull lines
else printf "<div class='hoogle-text'>%s<div>" $ unlines lines else div "hoogle-text" $ unlines $ nonull lines
in in
unlines $ map makeBlock groups div "hoogle-doc" $ unlines $ map makeBlock groups
extractPackageName :: String -> Maybe String
extractPackageName link = do
let pieces = split "/" link
archiveLoc <- elemIndex "archive" pieces
latestLoc <- elemIndex "latest" pieces
guard $ latestLoc - archiveLoc == 2
return $ pieces !! (latestLoc - 1)
extractModuleName :: String -> Maybe String
extractModuleName link = do
let pieces = split "/" link
guard $ not $ null pieces
let html = last pieces
mod = replace "-" "." $ takeWhile (/= '.') html
return mod
div :: String -> String -> String
div = printf "<div class='%s'>%s</div>"
span :: String -> String -> String
span = printf "<span class='%s'>%s</span>"
link :: String -> String -> String
link = printf "<a target='_blank' href='%s'>%s</a>"
...@@ -205,10 +205,13 @@ installPipDependencies = withTmpDir $ \tmpDir -> ...@@ -205,10 +205,13 @@ installPipDependencies = withTmpDir $ \tmpDir ->
mapM_ (installDependency tmpDir) mapM_ (installDependency tmpDir)
[ [
("pyzmq", "14.0.1") ("pyzmq", "14.0.1")
, ("setuptools", "2.0.2") -- This cannot go first in the dependenc list, because its setup.py is broken.
, ("MarkupSafe", "0.18") -- Neither can this
, ("tornado","3.1.1") , ("tornado","3.1.1")
, ("jinja2","2.7.1") , ("jinja2","2.7.1")
-- The following cannot go first in the dependency list, because
-- their setup.py are broken and require the directory to exist
-- already.
, ("MarkupSafe", "0.18")
--, ("setuptools", "2.0.2")
] ]
where where
installDependency :: FilePath -> (Text, Text) -> Sh () installDependency :: FilePath -> (Text, Text) -> Sh ()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment