Commit f7296881 authored by Andrew Gibiansky's avatar Andrew Gibiansky

Removing classy-prelude from dependencies, creating small custom prelude

parent 5f271a9b
...@@ -60,9 +60,6 @@ library ...@@ -60,9 +60,6 @@ library
base64-bytestring >=1.0, base64-bytestring >=1.0,
bytestring >=0.10, bytestring >=0.10,
cereal >=0.3, cereal >=0.3,
classy-prelude >=0.10.5 && <0.11,
chunked-data ==0.1.*,
mono-traversable >=0.6,
cmdargs >=0.10, cmdargs >=0.10,
containers >=0.5, containers >=0.5,
directory -any, directory -any,
...@@ -74,10 +71,8 @@ library ...@@ -74,10 +71,8 @@ library
here ==1.2.*, here ==1.2.*,
hlint >=1.9 && <2.0, hlint >=1.9 && <2.0,
haskell-src-exts ==1.16.*, haskell-src-exts ==1.16.*,
hspec -any,
http-client == 0.4.*, http-client == 0.4.*,
http-client-tls == 0.2.*, http-client-tls == 0.2.*,
HUnit -any,
MissingH >=1.2, MissingH >=1.2,
mtl >=2.1, mtl >=2.1,
parsec -any, parsec -any,
...@@ -89,7 +84,6 @@ library ...@@ -89,7 +84,6 @@ library
strict >=0.3, strict >=0.3,
system-argv0 -any, system-argv0 -any,
system-filepath -any, system-filepath -any,
tar -any,
text >=0.11, text >=0.11,
transformers -any, transformers -any,
unix >= 2.6, unix >= 2.6,
...@@ -121,36 +115,72 @@ library ...@@ -121,36 +115,72 @@ library
IHaskell.Types IHaskell.Types
IHaskell.BrokenPackages IHaskell.BrokenPackages
Paths_ihaskell Paths_ihaskell
-- other-modules: other-modules:
-- Paths_ihaskell IHaskellPrelude
default-extensions:
NoImplicitPrelude
DoAndIfThenElse
OverloadedStrings
ExtendedDefaultRules
executable ihaskell executable ihaskell
-- .hs or .lhs file containing the Main module. -- .hs or .lhs file containing the Main module.
main-is: src/Main.hs main-is: Main.hs
hs-source-dirs: src
other-modules:
IHaskellPrelude
ghc-options: -threaded ghc-options: -threaded
-- Other library packages from which modules are imported. -- Other library packages from which modules are imported.
default-language: Haskell2010 default-language: Haskell2010
build-depends: build-depends:
aeson >=0.7 && < 0.9,
base >=4.6 && < 4.9, base >=4.6 && < 4.9,
aeson >=0.6 && < 0.9, base64-bytestring >=1.0,
bytestring >=0.10, bytestring >=0.10,
cereal >=0.3, cereal >=0.3,
classy-prelude >=0.10.5 && <0.11, cmdargs >=0.10,
chunked-data ==0.1.*,
mono-traversable >=0.6,
containers >=0.5, containers >=0.5,
directory -any, directory -any,
ghc >=7.6 && < 7.11, filepath -any,
ihaskell -any, ghc >=7.6 || < 7.11,
MissingH >=1.2, ghc-parser >=0.1.7,
ghc-paths ==0.1.*,
haskeline -any,
here ==1.2.*, here ==1.2.*,
text -any, hlint >=1.9 && <2.0,
ipython-kernel >= 0.6.1, haskell-src-exts ==1.16.*,
unix >= 2.6 http-client == 0.4.*,
http-client-tls == 0.2.*,
MissingH >=1.2,
mtl >=2.1,
parsec -any,
process >=1.1,
random >=1.0,
shelly >=1.5,
split >= 0.2,
stm -any,
strict >=0.3,
system-argv0 -any,
system-filepath -any,
text >=0.11,
transformers -any,
unix >= 2.6,
unordered-containers -any,
utf8-string -any,
uuid >=1.3,
vector -any,
ipython-kernel >=0.6.1
if flag(binPkgDb) if flag(binPkgDb)
build-depends: bin-package-db build-depends: bin-package-db
default-extensions:
NoImplicitPrelude
DoAndIfThenElse
OverloadedStrings
ExtendedDefaultRules
Test-Suite hspec Test-Suite hspec
Type: exitcode-stdio-1.0 Type: exitcode-stdio-1.0
Ghc-Options: -threaded Ghc-Options: -threaded
...@@ -163,9 +193,6 @@ Test-Suite hspec ...@@ -163,9 +193,6 @@ Test-Suite hspec
base64-bytestring >=1.0, base64-bytestring >=1.0,
bytestring >=0.10, bytestring >=0.10,
cereal >=0.3, cereal >=0.3,
classy-prelude >=0.10.5 && <0.11,
chunked-data ==0.1.*,
mono-traversable >=0.6,
cmdargs >=0.10, cmdargs >=0.10,
containers >=0.5, containers >=0.5,
directory -any, directory -any,
...@@ -190,7 +217,6 @@ Test-Suite hspec ...@@ -190,7 +217,6 @@ Test-Suite hspec
strict >=0.3, strict >=0.3,
system-argv0 -any, system-argv0 -any,
system-filepath -any, system-filepath -any,
tar -any,
text >=0.11, text >=0.11,
http-client == 0.4.*, http-client == 0.4.*,
http-client-tls == 0.2.*, http-client-tls == 0.2.*,
......
{-# LANGUAGE OverloadedStrings, NoImplicitPrelude, FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude, OverloadedStrings, FlexibleContexts #-}
module IHaskell.BrokenPackages (getBrokenPackages) where module IHaskell.BrokenPackages (getBrokenPackages) where
import ClassyPrelude hiding ((<|>)) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Text.Parsec import Text.Parsec
import Text.Parsec.String import Text.Parsec.String
...@@ -27,7 +32,7 @@ getBrokenPackages = shelly $ do ...@@ -27,7 +32,7 @@ getBrokenPackages = shelly $ do
-- Get rid of extraneous things -- Get rid of extraneous things
let rightStart str = startswith "There are problems" str || let rightStart str = startswith "There are problems" str ||
startswith " dependency" str startswith " dependency" str
ghcPkgOutput = unlines . filter rightStart . lines $ unpack checkOut ghcPkgOutput = unlines . filter rightStart . lines $ T.unpack checkOut
return $ return $
case parse (many check) "ghc-pkg output" ghcPkgOutput of case parse (many check) "ghc-pkg output" ghcPkgOutput of
......
{-# LANGUAGE NoImplicitPrelude #-}
-- | Description : mostly reversible conversion between ipynb and lhs -- | Description : mostly reversible conversion between ipynb and lhs
module IHaskell.Convert (convert) where module IHaskell.Convert (convert) where
import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Control.Monad.Identity (Identity(Identity), unless, when) import Control.Monad.Identity (Identity(Identity), unless, when)
import IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec) import IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec)
import IHaskell.Convert.IpynbToLhs (ipynbToLhs) import IHaskell.Convert.IpynbToLhs (ipynbToLhs)
......
{-# LANGUAGE NoImplicitPrelude #-}
-- | Description: interpret flags parsed by "IHaskell.Flags" -- | Description: interpret flags parsed by "IHaskell.Flags"
module IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec) where module IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec) where
import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import Control.Monad.Identity (Identity(Identity)) import Control.Monad.Identity (Identity(Identity))
import Data.Char (toLower) import Data.Char (toLower)
...@@ -17,7 +25,7 @@ data ConvertSpec f = ...@@ -17,7 +25,7 @@ data ConvertSpec f =
{ convertToIpynb :: f Bool { convertToIpynb :: f Bool
, convertInput :: f FilePath , convertInput :: f FilePath
, convertOutput :: f FilePath , convertOutput :: f FilePath
, convertLhsStyle :: f (LhsStyle T.Text) , convertLhsStyle :: f (LhsStyle LT.Text)
, convertOverwriteFiles :: Bool , convertOverwriteFiles :: Bool
} }
...@@ -28,7 +36,7 @@ fromJustConvertSpec convertSpec = convertSpec ...@@ -28,7 +36,7 @@ fromJustConvertSpec convertSpec = convertSpec
{ convertToIpynb = Identity toIpynb { convertToIpynb = Identity toIpynb
, convertInput = Identity inputFile , convertInput = Identity inputFile
, convertOutput = Identity outputFile , convertOutput = Identity outputFile
, convertLhsStyle = Identity $ fromMaybe (T.pack <$> lhsStyleBird) (convertLhsStyle convertSpec) , convertLhsStyle = Identity $ fromMaybe (LT.pack <$> lhsStyleBird) (convertLhsStyle convertSpec)
} }
where where
toIpynb = fromMaybe (error "Error: direction for conversion unknown") toIpynb = fromMaybe (error "Error: direction for conversion unknown")
...@@ -63,10 +71,10 @@ mergeArg :: Argument -> ConvertSpec Maybe -> ConvertSpec Maybe ...@@ -63,10 +71,10 @@ mergeArg :: Argument -> ConvertSpec Maybe -> ConvertSpec Maybe
mergeArg OverwriteFiles convertSpec = convertSpec { convertOverwriteFiles = True } mergeArg OverwriteFiles convertSpec = convertSpec { convertOverwriteFiles = True }
mergeArg (ConvertLhsStyle lhsStyle) convertSpec mergeArg (ConvertLhsStyle lhsStyle) convertSpec
| Just previousLhsStyle <- convertLhsStyle convertSpec, | Just previousLhsStyle <- convertLhsStyle convertSpec,
previousLhsStyle /= fmap T.pack lhsStyle previousLhsStyle /= fmap LT.pack lhsStyle
= error $ printf "Conflicting lhs styles requested: <%s> and <%s>" (show lhsStyle) = error $ printf "Conflicting lhs styles requested: <%s> and <%s>" (show lhsStyle)
(show previousLhsStyle) (show previousLhsStyle)
| otherwise = convertSpec { convertLhsStyle = Just (T.pack <$> lhsStyle) } | otherwise = convertSpec { convertLhsStyle = Just (LT.pack <$> lhsStyle) }
mergeArg (ConvertFrom inputFile) convertSpec mergeArg (ConvertFrom inputFile) convertSpec
| Just previousInputFile <- convertInput convertSpec, | Just previousInputFile <- convertInput convertSpec,
previousInputFile /= inputFile previousInputFile /= inputFile
......
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
module IHaskell.Convert.IpynbToLhs (ipynbToLhs) where module IHaskell.Convert.IpynbToLhs (ipynbToLhs) where
import Control.Applicative ((<$>)) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Data.Aeson (decode, Object, Value(Array, Object, String)) import Data.Aeson (decode, Object, Value(Array, Object, String))
import qualified Data.ByteString.Lazy as L (readFile)
import qualified Data.HashMap.Strict as M (lookup)
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>), Monoid(mempty)) import Data.Monoid ((<>), Monoid(mempty))
import qualified Data.Text.Lazy as T (concat, fromStrict, Text, unlines)
import qualified Data.Text.Lazy.IO as T (writeFile)
import Data.Vector (Vector) import Data.Vector (Vector)
import Data.HashMap.Strict (lookup)
import qualified Data.Text.Lazy.IO as LTIO
import qualified Data.Vector as V (map, mapM, toList) import qualified Data.Vector as V (map, mapM, toList)
import IHaskell.Flags (LhsStyle(..)) import IHaskell.Flags (LhsStyle(..))
ipynbToLhs :: LhsStyle T.Text ipynbToLhs :: LhsStyle LText
-> FilePath -- ^ the filename of an ipython notebook -> FilePath -- ^ the filename of an ipython notebook
-> FilePath -- ^ the filename of the literate haskell to write -> FilePath -- ^ the filename of the literate haskell to write
-> IO () -> IO ()
ipynbToLhs sty from to = do ipynbToLhs sty from to = do
Just (js :: Object) <- decode <$> L.readFile from Just (js :: Object) <- decode <$> LBS.readFile from
case M.lookup "cells" js of case lookup "cells" js of
Just (Array cells) -> Just (Array cells) ->
T.writeFile to $ T.unlines $ V.toList $ V.map (\(Object y) -> convCell sty y) cells LTIO.writeFile to $ LT.unlines $ V.toList $ V.map (\(Object y) -> convCell sty y) cells
_ -> error "IHaskell.Convert.ipynbTolhs: json does not follow expected schema" _ -> error "IHaskell.Convert.ipynbTolhs: json does not follow expected schema"
concatWithPrefix :: T.Text -- ^ the prefix to add to every line concatWithPrefix :: LT.Text -- ^ the prefix to add to every line
-> Vector Value -- ^ a json array of text lines -> Vector Value -- ^ a json array of text lines
-> Maybe T.Text -> Maybe LT.Text
concatWithPrefix p arr = T.concat . map (p <>) . V.toList <$> V.mapM toStr arr concatWithPrefix p arr = LT.concat . map (p <>) . V.toList <$> V.mapM toStr arr
toStr :: Value -> Maybe T.Text toStr :: Value -> Maybe LT.Text
toStr (String x) = Just (T.fromStrict x) toStr (String x) = Just (LT.fromStrict x)
toStr _ = Nothing toStr _ = Nothing
-- | @convCell sty cell@ converts a single cell in JSON into text suitable for the type of lhs file -- | @convCell sty cell@ converts a single cell in JSON into text suitable for the type of lhs file
-- described by the @sty@ -- described by the @sty@
convCell :: LhsStyle T.Text -> Object -> T.Text convCell :: LhsStyle LT.Text -> Object -> LT.Text
convCell _sty object convCell _sty object
| Just (String "markdown") <- M.lookup "cell_type" object, | Just (String "markdown") <- lookup "cell_type" object,
Just (Array xs) <- M.lookup "source" object, Just (Array xs) <- lookup "source" object,
~(Just s) <- concatWithPrefix "" xs ~(Just s) <- concatWithPrefix "" xs
= s = s
convCell sty object convCell sty object
| Just (String "code") <- M.lookup "cell_type" object, | Just (String "code") <- lookup "cell_type" object,
Just (Array i) <- M.lookup "source" object, Just (Array i) <- lookup "source" object,
Just (Array o) <- M.lookup "outputs" object, Just (Array o) <- lookup "outputs" object,
~(Just i) <- concatWithPrefix (lhsCodePrefix sty) i, ~(Just i) <- concatWithPrefix (lhsCodePrefix sty) i,
o <- fromMaybe mempty (convOutputs sty o) o <- fromMaybe mempty (convOutputs sty o)
= "\n" <> = "\n" <>
lhsBeginCode sty <> i <> lhsEndCode sty <> "\n" <> o <> "\n" lhsBeginCode sty <> i <> lhsEndCode sty <> "\n" <> o <> "\n"
convCell _ _ = "IHaskell.Convert.convCell: unknown cell" convCell _ _ = "IHaskell.Convert.convCell: unknown cell"
convOutputs :: LhsStyle T.Text convOutputs :: LhsStyle LT.Text
-> Vector Value -- ^ JSON array of output lines containing text or markup -> Vector Value -- ^ JSON array of output lines containing text or markup
-> Maybe T.Text -> Maybe LT.Text
convOutputs sty array = do convOutputs sty array = do
outputLines <- V.mapM (getTexts (lhsOutputPrefix sty)) array outputLines <- V.mapM (getTexts (lhsOutputPrefix sty)) array
return $ lhsBeginOutput sty <> T.concat (V.toList outputLines) <> lhsEndOutput sty return $ lhsBeginOutput sty <> LT.concat (V.toList outputLines) <> lhsEndOutput sty
getTexts :: T.Text -> Value -> Maybe T.Text getTexts :: LT.Text -> Value -> Maybe LT.Text
getTexts p (Object object) getTexts p (Object object)
| Just (Array text) <- M.lookup "text" object = concatWithPrefix p text | Just (Array text) <- lookup "text" object = concatWithPrefix p text
getTexts _ _ = Nothing getTexts _ _ = Nothing
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
module IHaskell.Convert.LhsToIpynb (lhsToIpynb) where module IHaskell.Convert.LhsToIpynb (lhsToIpynb) where
import Control.Applicative ((<$>)) import IHaskellPrelude
import Control.Monad (mplus) import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Data.Aeson ((.=), encode, object, Value(Array, Bool, Number, String, Null)) import Data.Aeson ((.=), encode, object, Value(Array, Bool, Number, String, Null))
import qualified Data.ByteString.Lazy as L (writeFile)
import Data.Char (isSpace) import Data.Char (isSpace)
import Data.Monoid (Monoid(mempty))
import qualified Data.Text as TS (Text)
import qualified Data.Text.Lazy as T (dropWhile, lines, stripPrefix, Text, toStrict, snoc, strip)
import qualified Data.Text.Lazy.IO as T (readFile)
import qualified Data.Vector as V (fromList, singleton) import qualified Data.Vector as V (fromList, singleton)
import qualified Data.List as List
import IHaskell.Flags (LhsStyle(LhsStyle)) import IHaskell.Flags (LhsStyle(LhsStyle))
lhsToIpynb :: LhsStyle T.Text -> FilePath -> FilePath -> IO () lhsToIpynb :: LhsStyle LText -> FilePath -> FilePath -> IO ()
lhsToIpynb sty from to = do lhsToIpynb sty from to = do
classed <- classifyLines sty . T.lines <$> T.readFile from classed <- classifyLines sty . LT.lines . LT.pack <$> readFile from
L.writeFile to . encode . encodeCells $ groupClassified classed LBS.writeFile to . encode . encodeCells $ groupClassified classed
data CellLine a = CodeLine a data CellLine a = CodeLine a
| OutputLine a | OutputLine a
...@@ -50,40 +52,39 @@ data Cell a = Code a a ...@@ -50,40 +52,39 @@ data Cell a = Code a a
| Markdown a | Markdown a
deriving Show deriving Show
encodeCells :: [Cell [T.Text]] -> Value encodeCells :: [Cell [LText]] -> Value
encodeCells xs = object $ encodeCells xs = object $
["cells" .= Array (V.fromList (map cellToVal xs))] "cells" .= Array (V.fromList (map cellToVal xs)) : boilerplate
++ boilerplate
cellToVal :: Cell [LText] -> Value
cellToVal :: Cell [T.Text] -> Value cellToVal (Code i o) = object
cellToVal (Code i o) = object $ [ "cell_type" .= String "code"
[ "cell_type" .= String "code" , "execution_count" .= Null
, "execution_count" .= Null , "metadata" .= object ["collapsed" .= Bool False]
, "metadata" .= object ["collapsed" .= Bool False] , "source" .= arrayFromTxt i
, "source" .= arrayFromTxt i , "outputs" .= Array
, "outputs" .= Array (V.fromList
(V.fromList [object
([object [ "text" .= arrayFromTxt o
[ "text" .= arrayFromTxt o , "metadata" .= object []
, "metadata" .= object [] , "output_type" .= String "display_data"
, "output_type" .= String "display_data" ] | _ <- take 1 o])
] | _ <- take 1 o])) ]
] cellToVal (Markdown txt) = object
cellToVal (Markdown txt) = object $
[ "cell_type" .= String "markdown" [ "cell_type" .= String "markdown"
, "metadata" .= object ["hidden" .= Bool False] , "metadata" .= object ["hidden" .= Bool False]
, "source" .= arrayFromTxt txt , "source" .= arrayFromTxt txt
] ]
-- | arrayFromTxt makes a JSON array of string s -- | arrayFromTxt makes a JSON array of string s
arrayFromTxt :: [T.Text] -> Value arrayFromTxt :: [LText] -> Value
arrayFromTxt i = Array (V.fromList $ map stringify i) arrayFromTxt i = Array (V.fromList $ map stringify i)
where where
stringify = String . T.toStrict . flip T.snoc '\n' stringify = String . LT.toStrict . flip LT.snoc '\n'
-- | ihaskell needs this boilerplate at the upper level to interpret the json describing cells and -- | ihaskell needs this boilerplate at the upper level to interpret the json describing cells and
-- output correctly. -- output correctly.
boilerplate :: [(TS.Text, Value)] boilerplate :: [(T.Text, Value)]
boilerplate = boilerplate =
["metadata" .= object [kernelspec, lang], "nbformat" .= Number 4, "nbformat_minor" .= Number 0] ["metadata" .= object [kernelspec, lang], "nbformat" .= Number 4, "nbformat_minor" .= Number 0]
where where
...@@ -94,18 +95,18 @@ boilerplate = ...@@ -94,18 +95,18 @@ boilerplate =
] ]
lang = "language_info" .= object ["name" .= String "haskell", "version" .= String VERSION_ghc] lang = "language_info" .= object ["name" .= String "haskell", "version" .= String VERSION_ghc]
groupClassified :: [CellLine T.Text] -> [Cell [T.Text]] groupClassified :: [CellLine LText] -> [Cell [LText]]
groupClassified (CodeLine a:x) groupClassified (CodeLine a:x)
| (c, x) <- span isCode x, | (c, x) <- List.span isCode x,
(_, x) <- span isEmptyMD x, (_, x) <- List.span isEmptyMD x,
(o, x) <- span isOutput x (o, x) <- List.span isOutput x
= Code (a : map untag c) (map untag o) : groupClassified x = Code (a : map untag c) (map untag o) : groupClassified x
groupClassified (MarkdownLine a:x) groupClassified (MarkdownLine a:x)
| (m, x) <- span isMD x = Markdown (a : map untag m) : groupClassified x | (m, x) <- List.span isMD x = Markdown (a : map untag m) : groupClassified x
groupClassified (OutputLine a:x) = Markdown [a] : groupClassified x groupClassified (OutputLine a:x) = Markdown [a] : groupClassified x
groupClassified [] = [] groupClassified [] = []
classifyLines :: LhsStyle T.Text -> [T.Text] -> [CellLine T.Text] classifyLines :: LhsStyle LText -> [LText] -> [CellLine LText]
classifyLines sty@(LhsStyle c o _ _ _ _) (l:ls) = classifyLines sty@(LhsStyle c o _ _ _ _) (l:ls) =
case (sp c, sp o) of case (sp c, sp o) of
(Just a, Nothing) -> CodeLine a : classifyLines sty ls (Just a, Nothing) -> CodeLine a : classifyLines sty ls
...@@ -113,9 +114,9 @@ classifyLines sty@(LhsStyle c o _ _ _ _) (l:ls) = ...@@ -113,9 +114,9 @@ classifyLines sty@(LhsStyle c o _ _ _ _) (l:ls) =
(Nothing, Nothing) -> MarkdownLine l : classifyLines sty ls (Nothing, Nothing) -> MarkdownLine l : classifyLines sty ls
_ -> error "IHaskell.Convert.classifyLines" _ -> error "IHaskell.Convert.classifyLines"
where where
sp x = T.stripPrefix (dropSpace x) (dropSpace l) `mplus` blankCodeLine x sp x = LT.stripPrefix (dropSpace x) (dropSpace l) `mplus` blankCodeLine x
blankCodeLine x = if T.strip x == T.strip l blankCodeLine x = if LT.strip x == LT.strip l
then Just "" then Just ""
else Nothing else Nothing
dropSpace = T.dropWhile isSpace dropSpace = LT.dropWhile isSpace
classifyLines _ [] = [] classifyLines _ [] = []
...@@ -48,18 +48,26 @@ module IHaskell.Display ( ...@@ -48,18 +48,26 @@ module IHaskell.Display (
Widget(..), Widget(..),
) where ) where
import ClassyPrelude import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Data.Serialize as Serialize import Data.Serialize as Serialize
import Data.ByteString hiding (map, pack)
import Data.String.Utils (rstrip) import Data.String.Utils (rstrip)
import qualified Data.ByteString.Base64 as Base64 import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Char8 as Char
import Data.Aeson (Value) import Data.Aeson (Value)
import System.Directory (getTemporaryDirectory, setCurrentDirectory) import System.Directory (getTemporaryDirectory, setCurrentDirectory)
import Control.Concurrent.STM (atomically)
import Control.Exception (try)
import Control.Concurrent.STM.TChan import Control.Concurrent.STM.TChan
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Text.Encoding as E
import IHaskell.Types import IHaskell.Types
type Base64 = Text type Base64 = Text
...@@ -92,23 +100,23 @@ many = ManyDisplay ...@@ -92,23 +100,23 @@ many = ManyDisplay
-- | Generate a plain text display. -- | Generate a plain text display.
plain :: String -> DisplayData plain :: String -> DisplayData
plain = DisplayData PlainText . pack . rstrip plain = DisplayData PlainText . T.pack . rstrip
-- | Generate an HTML display. -- | Generate an HTML display.
html :: String -> DisplayData html :: String -> DisplayData
html = DisplayData MimeHtml . pack html = DisplayData MimeHtml . T.pack
-- | Generate an SVG display. -- | Generate an SVG display.
svg :: String -> DisplayData svg :: String -> DisplayData
svg = DisplayData MimeSvg . pack svg = DisplayData MimeSvg . T.pack
-- | Generate a LaTeX display. -- | Generate a LaTeX display.
latex :: String -> DisplayData latex :: String -> DisplayData
latex = DisplayData MimeLatex . pack latex = DisplayData MimeLatex . T.pack
-- | Generate a Javascript display. -- | Generate a Javascript display.
javascript :: String -> DisplayData javascript :: String -> DisplayData
javascript = DisplayData MimeJavascript . pack javascript = DisplayData MimeJavascript . T.pack
-- | Generate a PNG display of the given width and height. Data must be provided in a Base64 encoded -- | Generate a PNG display of the given width and height. Data must be provided in a Base64 encoded
-- manner, suitable for embedding into HTML. The @base64@ function may be used to encode data into -- manner, suitable for embedding into HTML. The @base64@ function may be used to encode data into
...@@ -124,11 +132,11 @@ jpg width height = DisplayData (MimeJpg width height) ...@@ -124,11 +132,11 @@ jpg width height = DisplayData (MimeJpg width height)
-- | Convert from a string into base 64 encoded data. -- | Convert from a string into base 64 encoded data.
encode64 :: String -> Base64 encode64 :: String -> Base64
encode64 str = base64 $ Char.pack str encode64 str = base64 $ CBS.pack str
-- | Convert from a ByteString into base 64 encoded data. -- | Convert from a ByteString into base 64 encoded data.
base64 :: ByteString -> Base64 base64 :: ByteString -> Base64
base64 = decodeUtf8 . Base64.encode base64 = E.decodeUtf8 . Base64.encode
-- | For internal use within IHaskell. Serialize displays to a ByteString. -- | For internal use within IHaskell. Serialize displays to a ByteString.
serializeDisplay :: Display -> ByteString serializeDisplay :: Display -> ByteString
......
{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings, DoAndIfThenElse #-} {-# LANGUAGE NoImplicitPrelude, CPP, OverloadedStrings, DoAndIfThenElse #-}
{-# LANGUAGE TypeFamilies, FlexibleContexts #-} {-# LANGUAGE TypeFamilies, FlexibleContexts #-}
{- | {- |
...@@ -13,7 +13,12 @@ This has a limited amount of context sensitivity. It distinguishes between four ...@@ -13,7 +13,12 @@ This has a limited amount of context sensitivity. It distinguishes between four
-} -}
module IHaskell.Eval.Completion (complete, completionTarget, completionType, CompletionType(..)) where module IHaskell.Eval.Completion (complete, completionTarget, completionType, CompletionType(..)) where
import ClassyPrelude hiding (init, last, head, liftIO) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import Data.ByteString.UTF8 hiding (drop, take, lines, length) import Data.ByteString.UTF8 hiding (drop, take, lines, length)
...@@ -34,11 +39,12 @@ import DynFlags ...@@ -34,11 +39,12 @@ import DynFlags
import GhcMonad import GhcMonad
import PackageConfig import PackageConfig
import Outputable (showPpr) import Outputable (showPpr)
import MonadUtils (MonadIO)
import System.Directory import System.Directory
import System.FilePath import System.FilePath
import MonadUtils (MonadIO) import Control.Exception (try)
import System.Console.Haskeline.Completion import System.Console.Haskeline.Completion
...@@ -155,7 +161,7 @@ getTrueModuleName name = do ...@@ -155,7 +161,7 @@ getTrueModuleName name = do
onlyImportDecl _ = Nothing onlyImportDecl _ = Nothing
-- Get all imports that we use. -- Get all imports that we use.
imports <- ClassyPrelude.catMaybes <$> map onlyImportDecl <$> getContext imports <- catMaybes <$> map onlyImportDecl <$> getContext
-- Find the ones that have a qualified name attached. If this name isn't one of them, it already is -- Find the ones that have a qualified name attached. If this name isn't one of them, it already is
-- the true name. -- the true name.
......
{-# LANGUAGE DoAndIfThenElse, NoOverloadedStrings, TypeSynonymInstances, GADTs, CPP #-} {-# LANGUAGE NoImplicitPrelude, DoAndIfThenElse, NoOverloadedStrings, TypeSynonymInstances, GADTs, CPP #-}
{- | Description : Wrapper around GHC API, exposing a single `evaluate` interface that runs {- | Description : Wrapper around GHC API, exposing a single `evaluate` interface that runs
a statement, declaration, import, or directive. a statement, declaration, import, or directive.
...@@ -15,7 +15,13 @@ module IHaskell.Eval.Evaluate ( ...@@ -15,7 +15,13 @@ module IHaskell.Eval.Evaluate (
formatType, formatType,
) where ) where
import ClassyPrelude hiding (init, last, liftIO, head, hGetContents, tail, try) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Control.Concurrent (forkIO, threadDelay) import Control.Concurrent (forkIO, threadDelay)
import Prelude (putChar, head, tail, last, init, (!!)) import Prelude (putChar, head, tail, last, init, (!!))
import Data.List.Utils import Data.List.Utils
...@@ -68,8 +74,6 @@ import FastString ...@@ -68,8 +74,6 @@ import FastString
import Bag import Bag
import ErrUtils (errMsgShortDoc, errMsgExtraInfo) import ErrUtils (errMsgShortDoc, errMsgExtraInfo)
import qualified System.IO.Strict as StrictIO
import IHaskell.Types import IHaskell.Types
import IHaskell.IPython import IHaskell.IPython
import IHaskell.Eval.Parser import IHaskell.Eval.Parser
...@@ -403,7 +407,7 @@ evalCommand _ (Module contents) state = wrapExecution state $ do ...@@ -403,7 +407,7 @@ evalCommand _ (Module contents) state = wrapExecution state $ do
filename = last namePieces ++ ".hs" filename = last namePieces ++ ".hs"
liftIO $ do liftIO $ do
createDirectoryIfMissing True directory createDirectoryIfMissing True directory
writeFile (fpFromString $ directory ++ filename) contents writeFile (directory ++ filename) contents
-- Clear old modules of this name -- Clear old modules of this name
let modName = intercalate "." namePieces let modName = intercalate "." namePieces
...@@ -565,7 +569,7 @@ evalCommand _ (Directive LoadFile names) state = wrapExecution state $ do ...@@ -565,7 +569,7 @@ evalCommand _ (Directive LoadFile names) state = wrapExecution state $ do
let filename = if endswith ".hs" name let filename = if endswith ".hs" name
then name then name
else name ++ ".hs" else name ++ ".hs"
contents <- readFile $ fpFromString filename contents <- liftIO $ readFile filename
modName <- intercalate "." <$> getModuleName contents modName <- intercalate "." <$> getModuleName contents
doLoadModule filename modName doLoadModule filename modName
return (ManyDisplay displays) return (ManyDisplay displays)
...@@ -1016,7 +1020,7 @@ doLoadModule name modName = do ...@@ -1016,7 +1020,7 @@ doLoadModule name modName = do
setSessionDynFlags setSessionDynFlags
flags flags
{ hscTarget = objTarget flags { hscTarget = objTarget flags
, log_action = \dflags sev srcspan ppr msg -> modifyIORef errRef (showSDoc flags msg :) , log_action = \dflags sev srcspan ppr msg -> modifyIORef' errRef (showSDoc flags msg :)
} }
-- Load the new target. -- Load the new target.
......
...@@ -8,16 +8,19 @@ module IHaskell.Eval.Hoogle ( ...@@ -8,16 +8,19 @@ module IHaskell.Eval.Hoogle (
HoogleResult, HoogleResult,
) where ) where
import ClassyPrelude hiding (last, span, div) import IHaskellPrelude
import Text.Printf import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Network.HTTP.Client import Network.HTTP.Client
import Network.HTTP.Client.TLS import Network.HTTP.Client.TLS
import Data.Aeson import Data.Aeson
import Data.String.Utils import Data.String.Utils
import Data.List (elemIndex, (!!), last) import qualified Data.List as List
import Data.Char (isAscii, isAlphaNum) import Data.Char (isAscii, isAlphaNum)
import qualified Data.ByteString.Lazy.Char8 as Char
import qualified Prelude as P
import IHaskell.IPython import IHaskell.IPython
...@@ -52,11 +55,8 @@ instance FromJSON HoogleResponse where ...@@ -52,11 +55,8 @@ instance FromJSON HoogleResponse where
query :: String -> IO (Either String String) query :: String -> IO (Either String String)
query str = do query str = do
request <- parseUrl $ queryUrl $ urlEncode str request <- parseUrl $ queryUrl $ urlEncode str
response <- try $ withManager tlsManagerSettings $ httpLbs request catch (Right . CBS.unpack . LBS.toStrict . responseBody <$> withManager tlsManagerSettings (httpLbs request))
return $ (\e -> return $ Left $ show (e :: SomeException))
case response of
Left err -> Left $ show (err :: SomeException)
Right resp -> Right $ Char.unpack $ responseBody resp
where where
queryUrl :: String -> String queryUrl :: String -> String
...@@ -66,25 +66,25 @@ query str = do ...@@ -66,25 +66,25 @@ query str = do
urlEncode :: String -> String urlEncode :: String -> String
urlEncode [] = [] urlEncode [] = []
urlEncode (ch:t) urlEncode (ch:t)
| (isAscii ch && isAlphaNum ch) || ch `P.elem` ("-_.~" :: String) = ch : urlEncode t | (isAscii ch && isAlphaNum ch) || ch `elem` ("-_.~" :: String) = ch : urlEncode t
| not (isAscii ch) = P.foldr escape (urlEncode t) (eightBs [] (P.fromEnum ch)) | not (isAscii ch) = foldr escape (urlEncode t) (eightBs [] (fromEnum ch))
| otherwise = escape (P.fromEnum ch) (urlEncode t) | otherwise = escape (fromEnum ch) (urlEncode t)
where where
escape :: Int -> String -> String escape :: Int -> String -> String
escape b rs = '%' : showH (b `P.div` 16) (showH (b `mod` 16) rs) escape b rs = '%' : showH (b `div` 16) (showH (b `mod` 16) rs)
showH :: Int -> String -> String showH :: Int -> String -> String
showH x xs showH x xs
| x <= 9 = toEnum (o_0 + x) : xs | x <= 9 = toEnum (o_0 + x) : xs
| otherwise = toEnum (o_A + (x - 10)) : xs | otherwise = toEnum (o_A + (x - 10)) : xs
where where
o_0 = P.fromEnum '0' o_0 = fromEnum '0'
o_A = P.fromEnum 'A' o_A = fromEnum 'A'
eightBs :: [Int] -> Int -> [Int] eightBs :: [Int] -> Int -> [Int]
eightBs acc x eightBs acc x
| x <= 255 = x : acc | x <= 255 = x : acc
| otherwise = eightBs ((x `mod` 256) : acc) (x `P.div` 256) | otherwise = eightBs ((x `mod` 256) : acc) (x `div` 256)
-- | Search for a query on Hoogle. Return all search results. -- | Search for a query on Hoogle. Return all search results.
search :: String -> IO [HoogleResult] search :: String -> IO [HoogleResult]
...@@ -94,7 +94,7 @@ search string = do ...@@ -94,7 +94,7 @@ search string = do
case response of case response of
Left err -> [NoResult err] Left err -> [NoResult err]
Right json -> Right json ->
case eitherDecode $ Char.pack json of case eitherDecode $ LBS.fromStrict$ CBS.pack json of
Left err -> [NoResult err] Left err -> [NoResult err]
Right results -> Right results ->
case map SearchResult results of case map SearchResult results of
...@@ -216,7 +216,7 @@ renderSelf string loc ...@@ -216,7 +216,7 @@ renderSelf string loc
renderDocs :: String -> String renderDocs :: String -> String
renderDocs doc = renderDocs doc =
let groups = groupBy bothAreCode $ lines doc let groups = List.groupBy bothAreCode $ lines doc
nonull = filter (not . null . strip) nonull = filter (not . null . strip)
bothAreCode s1 s2 = bothAreCode s1 s2 =
startswith ">" (strip s1) && startswith ">" (strip s1) &&
...@@ -224,28 +224,28 @@ renderDocs doc = ...@@ -224,28 +224,28 @@ renderDocs doc =
isCode (s:_) = startswith ">" $ strip s isCode (s:_) = startswith ">" $ strip s
makeBlock lines = makeBlock lines =
if isCode lines if isCode lines
then div "hoogle-code" $ unlines $ nonull lines then div' "hoogle-code" $ unlines $ nonull lines
else div "hoogle-text" $ unlines $ nonull lines else div' "hoogle-text" $ unlines $ nonull lines
in div "hoogle-doc" $ unlines $ map makeBlock groups in div' "hoogle-doc" $ unlines $ map makeBlock groups
extractPackageName :: String -> Maybe String extractPackageName :: String -> Maybe String
extractPackageName link = do extractPackageName link = do
let pieces = split "/" link let pieces = split "/" link
archiveLoc <- elemIndex "archive" pieces archiveLoc <- List.elemIndex "archive" pieces
latestLoc <- elemIndex "latest" pieces latestLoc <- List.elemIndex "latest" pieces
guard $ latestLoc - archiveLoc == 2 guard $ latestLoc - archiveLoc == 2
return $ pieces !! (latestLoc - 1) return $ pieces List.!! (latestLoc - 1)
extractModuleName :: String -> Maybe String extractModuleName :: String -> Maybe String
extractModuleName link = do extractModuleName link = do
let pieces = split "/" link let pieces = split "/" link
guard $ not $ null pieces guard $ not $ null pieces
let html = last pieces let html = fromJust $ lastMay pieces
mod = replace "-" "." $ takeWhile (/= '.') html mod = replace "-" "." $ takeWhile (/= '.') html
return mod return mod
div :: String -> String -> String div' :: String -> String -> String
div = printf "<div class='%s'>%s</div>" div' = printf "<div class='%s'>%s</div>"
span :: String -> String -> String span :: String -> String -> String
span = printf "<span class='%s'>%s</span>" span = printf "<span class='%s'>%s</span>"
......
...@@ -3,7 +3,12 @@ ...@@ -3,7 +3,12 @@
{- | Description : Inspect type and function information and documentation. -} {- | Description : Inspect type and function information and documentation. -}
module IHaskell.Eval.Info (info) where module IHaskell.Eval.Info (info) where
import ClassyPrelude hiding (liftIO) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import IHaskell.Eval.Evaluate (typeCleaner, Interpreter) import IHaskell.Eval.Evaluate (typeCleaner, Interpreter)
......
{-# LANGUAGE CPP, NoImplicitPrelude, OverloadedStrings, DoAndIfThenElse, FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude, CPP, OverloadedStrings, DoAndIfThenElse, FlexibleContexts #-}
{- | {- |
Description: Generates inspections when asked for by the frontend. Description: Generates inspections when asked for by the frontend.
...@@ -6,7 +6,13 @@ Description: Generates inspections when asked for by the frontend. ...@@ -6,7 +6,13 @@ Description: Generates inspections when asked for by the frontend.
-} -}
module IHaskell.Eval.Inspect (inspect) where module IHaskell.Eval.Inspect (inspect) where
import ClassyPrelude import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import qualified Prelude as P import qualified Prelude as P
import Data.List.Split (splitOn) import Data.List.Split (splitOn)
......
{-# LANGUAGE FlexibleContexts, NoImplicitPrelude, QuasiQuotes, ViewPatterns #-} {-# LANGUAGE NoImplicitPrelude, FlexibleContexts, QuasiQuotes, ViewPatterns #-}
module IHaskell.Eval.Lint (lint) where module IHaskell.Eval.Lint (lint) where
import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Data.String.Utils (replace, startswith, strip, split) import Data.String.Utils (replace, startswith, strip, split)
import Prelude (head, tail, last) import Prelude (head, tail, last)
import ClassyPrelude hiding (last)
import Control.Monad import Control.Monad
import Data.List (findIndex) import Data.List (findIndex)
import Text.Printf import Text.Printf
......
{-# LANGUAGE NoImplicitPrelude #-}
-- | This module splits a shell command line into a list of strings, -- | This module splits a shell command line into a list of strings,
-- one for each command / filename -- one for each command / filename
module IHaskell.Eval.ParseShell (parseShell) where module IHaskell.Eval.ParseShell (parseShell) where
import Prelude hiding (words) import IHaskellPrelude
import Text.ParserCombinators.Parsec hiding (manyTill) import qualified Data.Text as T
import Control.Applicative hiding ((<|>), many, optional) import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Text.ParserCombinators.Parsec
eol :: Parser Char eol :: Parser Char
eol = oneOf "\n\r" <?> "end of line" eol = oneOf "\n\r" <?> "end of line"
...@@ -12,18 +18,18 @@ eol = oneOf "\n\r" <?> "end of line" ...@@ -12,18 +18,18 @@ eol = oneOf "\n\r" <?> "end of line"
quote :: Parser Char quote :: Parser Char
quote = char '\"' quote = char '\"'
-- | @manyTill p end@ from hidden @manyTill@ in that it appends the result of @end@ -- | @manyTillEnd p end@ from normal @manyTill@ in that it appends the result of @end@
manyTill :: Parser a -> Parser [a] -> Parser [a] manyTillEnd :: Parser a -> Parser [a] -> Parser [a]
manyTill p end = scan manyTillEnd p end = scan
where where
scan = end <|> do scan = end <|> do
x <- p x <- p
xs <- scan xs <- scan
return $ x : xs return $ x : xs
manyTill1 p end = do manyTillEnd1 p end = do
x <- p x <- p
xs <- manyTill p end xs <- manyTillEnd p end
return $ x : xs return $ x : xs
unescapedChar :: Parser Char -> Parser String unescapedChar :: Parser Char -> Parser String
...@@ -34,9 +40,9 @@ unescapedChar p = try $ do ...@@ -34,9 +40,9 @@ unescapedChar p = try $ do
quotedString = do quotedString = do
quote <?> "expected starting quote" quote <?> "expected starting quote"
(manyTill anyChar (unescapedChar quote) <* quote) <?> "unexpected in quoted String " (manyTillEnd anyChar (unescapedChar quote) <* quote) <?> "unexpected in quoted String "
unquotedString = manyTill1 anyChar end unquotedString = manyTillEnd1 anyChar end
where where
end = unescapedChar space end = unescapedChar space
<|> (lookAhead eol >> return []) <|> (lookAhead eol >> return [])
...@@ -47,14 +53,14 @@ separator :: Parser String ...@@ -47,14 +53,14 @@ separator :: Parser String
separator = many1 space <?> "separator" separator = many1 space <?> "separator"
-- | Input must terminate in a space character (like a \n) -- | Input must terminate in a space character (like a \n)
words :: Parser [String] shellWords :: Parser [String]
words = try (eof *> return []) <|> do shellWords = try (eof *> return []) <|> do
x <- word x <- word
rest1 <- lookAhead (many anyToken) rest1 <- lookAhead (many anyToken)
ss <- separator ss <- separator
rest2 <- lookAhead (many anyToken) rest2 <- lookAhead (many anyToken)
xs <- words xs <- shellWords
return $ x : xs return $ x : xs
parseShell :: String -> Either ParseError [String] parseShell :: String -> Either ParseError [String]
parseShell string = parse words "shell" (string ++ "\n") parseShell string = parse shellWords "shell" (string ++ "\n")
...@@ -15,7 +15,12 @@ module IHaskell.Eval.Parser ( ...@@ -15,7 +15,12 @@ module IHaskell.Eval.Parser (
PragmaType(..), PragmaType(..),
) where ) where
import ClassyPrelude hiding (head, liftIO, maximumBy) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Data.List (maximumBy, inits) import Data.List (maximumBy, inits)
import Data.String.Utils (startswith, strip, split) import Data.String.Utils (startswith, strip, split)
......
{-# LANGUAGE CPP, NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude, CPP #-}
module IHaskell.Eval.Util ( module IHaskell.Eval.Util (
-- * Initialization -- * Initialization
...@@ -23,7 +23,12 @@ module IHaskell.Eval.Util ( ...@@ -23,7 +23,12 @@ module IHaskell.Eval.Util (
pprLanguages, pprLanguages,
) where ) where
import ClassyPrelude hiding ((<>)) import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
-- GHC imports. -- GHC imports.
import DynFlags import DynFlags
...@@ -34,7 +39,6 @@ import HsImpExp ...@@ -34,7 +39,6 @@ import HsImpExp
import HscTypes import HscTypes
import InteractiveEval import InteractiveEval
import Module import Module
import Outputable
import Packages import Packages
import RdrName import RdrName
import NameSet import NameSet
...@@ -44,6 +48,7 @@ import InstEnv (ClsInst(..)) ...@@ -44,6 +48,7 @@ import InstEnv (ClsInst(..))
import Unify (tcMatchTys) import Unify (tcMatchTys)
import VarSet (mkVarSet) import VarSet (mkVarSet)
import qualified Pretty import qualified Pretty
import qualified Outputable as O
import Control.Monad (void) import Control.Monad (void)
import Data.Function (on) import Data.Function (on)
...@@ -80,15 +85,15 @@ flagSpecFlag (_, flag, _) = flag ...@@ -80,15 +85,15 @@ flagSpecFlag (_, flag, _) = flag
-- | Pretty-print dynamic flags (taken from 'InteractiveUI' module of `ghc-bin`) -- | Pretty-print dynamic flags (taken from 'InteractiveUI' module of `ghc-bin`)
pprDynFlags :: Bool -- ^ Whether to include flags which are on by default pprDynFlags :: Bool -- ^ Whether to include flags which are on by default
-> DynFlags -> DynFlags
-> SDoc -> O.SDoc
pprDynFlags show_all dflags = pprDynFlags show_all dflags =
vcat O.vcat
[ text "GHCi-specific dynamic flag settings:" $$ [ O.text "GHCi-specific dynamic flag settings:" O.$$
nest 2 (vcat (map (setting opt) ghciFlags)) O.nest 2 (O.vcat (map (setting opt) ghciFlags))
, text "other dynamic, non-language, flag settings:" $$ , O.text "other dynamic, non-language, flag settings:" O.$$
nest 2 (vcat (map (setting opt) others)) O.nest 2 (O.vcat (map (setting opt) others))
, text "warning settings:" $$ , O.text "warning settings:" O.$$
nest 2 (vcat (map (setting wopt) DynFlags.fWarningFlags)) O.nest 2 (O.vcat (map (setting wopt) DynFlags.fWarningFlags))
] ]
where where
...@@ -98,9 +103,9 @@ pprDynFlags show_all dflags = ...@@ -98,9 +103,9 @@ pprDynFlags show_all dflags =
opt = dopt opt = dopt
#endif #endif
setting test flag setting test flag
| quiet = empty | quiet = O.empty :: O.SDoc
| is_on = fstr name | is_on = fstr name :: O.SDoc
| otherwise = fnostr name | otherwise = fnostr name :: O.SDoc
where where
name = flagSpecName flag name = flagSpecName flag
f = flagSpecFlag flag f = flagSpecFlag flag
...@@ -109,9 +114,9 @@ pprDynFlags show_all dflags = ...@@ -109,9 +114,9 @@ pprDynFlags show_all dflags =
default_dflags = defaultDynFlags (settings dflags) default_dflags = defaultDynFlags (settings dflags)
fstr str = text "-f" <> text str fstr, fnostr :: String -> O.SDoc
fstr str = O.text "-f" O.<> O.text str
fnostr str = text "-fno-" <> text str fnostr str = O.text "-fno-" O.<> O.text str
(ghciFlags, others) = partition (\f -> flagSpecFlag f `elem` flgs) DynFlags.fFlags (ghciFlags, others) = partition (\f -> flagSpecFlag f `elem` flgs) DynFlags.fFlags
...@@ -129,22 +134,22 @@ flgs3 = [Opt_PrintBindResult, Opt_BreakOnException, Opt_BreakOnError, Opt_PrintE ...@@ -129,22 +134,22 @@ flgs3 = [Opt_PrintBindResult, Opt_BreakOnException, Opt_BreakOnError, Opt_PrintE
-- `ghc-bin`) -- `ghc-bin`)
pprLanguages :: Bool -- ^ Whether to include flags which are on by default pprLanguages :: Bool -- ^ Whether to include flags which are on by default
-> DynFlags -> DynFlags
-> SDoc -> O.SDoc
pprLanguages show_all dflags = pprLanguages show_all dflags =
vcat O.vcat
[text "base language is: " <> [O.text "base language is: " O.<>
case language dflags of case language dflags of
Nothing -> text "Haskell2010" Nothing -> O.text "Haskell2010"
Just Haskell98 -> text "Haskell98" Just Haskell98 -> O.text "Haskell98"
Just Haskell2010 -> text "Haskell2010", (if show_all Just Haskell2010 -> O.text "Haskell2010", (if show_all
then text "all active language options:" then O.text "all active language options:"
else text "with the following modifiers:") $$ else O.text "with the following modifiers:") O.$$
nest 2 (vcat (map (setting xopt) DynFlags.xFlags))] O.nest 2 (O.vcat (map (setting xopt) DynFlags.xFlags))]
where where
setting test flag setting test flag
| quiet = empty | quiet = O.empty
| is_on = text "-X" <> text name | is_on = O.text "-X" O.<> O.text name
| otherwise = text "-XNo" <> text name | otherwise = O.text "-XNo" O.<> O.text name
where where
name = flagSpecName flag name = flagSpecName flag
f = flagSpecFlag flag f = flagSpecFlag flag
...@@ -196,13 +201,13 @@ setFlags ext = do ...@@ -196,13 +201,13 @@ setFlags ext = do
-- does not impose an arbitrary width limit on the output (in terms of number of columns). Instead, -- does not impose an arbitrary width limit on the output (in terms of number of columns). Instead,
-- it respsects the 'pprCols' field in the structure returned by 'getSessionDynFlags', and thus -- it respsects the 'pprCols' field in the structure returned by 'getSessionDynFlags', and thus
-- gives a configurable width of output. -- gives a configurable width of output.
doc :: GhcMonad m => SDoc -> m String doc :: GhcMonad m => O.SDoc -> m String
doc sdoc = do doc sdoc = do
flags <- getSessionDynFlags flags <- getSessionDynFlags
unqual <- getPrintUnqual unqual <- getPrintUnqual
let style = mkUserStyle unqual AllTheWay let style = O.mkUserStyle unqual O.AllTheWay
let cols = pprCols flags let cols = pprCols flags
d = runSDoc sdoc (initSDocContext flags style) d = O.runSDoc sdoc (O.initSDocContext flags style)
return $ Pretty.fullRender Pretty.PageMode cols 1.5 string_txt "" d return $ Pretty.fullRender Pretty.PageMode cols 1.5 string_txt "" d
where where
...@@ -298,7 +303,7 @@ evalDeclarations decl = do ...@@ -298,7 +303,7 @@ evalDeclarations decl = do
names <- runDecls decl names <- runDecls decl
cleanUpDuplicateInstances cleanUpDuplicateInstances
flags <- getSessionDynFlags flags <- getSessionDynFlags
return $ map (replace ":Interactive." "" . showPpr flags) names return $ map (replace ":Interactive." "" . O.showPpr flags) names
cleanUpDuplicateInstances :: GhcMonad m => m () cleanUpDuplicateInstances :: GhcMonad m => m ()
cleanUpDuplicateInstances = modifySession $ \hscEnv -> cleanUpDuplicateInstances = modifySession $ \hscEnv ->
...@@ -326,7 +331,7 @@ getType :: GhcMonad m => String -> m String ...@@ -326,7 +331,7 @@ getType :: GhcMonad m => String -> m String
getType expr = do getType expr = do
result <- exprType expr result <- exprType expr
flags <- getSessionDynFlags flags <- getSessionDynFlags
let typeStr = showSDocUnqual flags $ ppr result let typeStr = O.showSDocUnqual flags $ O.ppr result
return typeStr return typeStr
-- | A wrapper around @getInfo@. Return info about each name in the string. -- | A wrapper around @getInfo@. Return info about each name in the string.
...@@ -363,16 +368,16 @@ getDescription str = do ...@@ -363,16 +368,16 @@ getDescription str = do
#if MIN_VERSION_ghc(7,8,0) #if MIN_VERSION_ghc(7,8,0)
printInfo (thing, fixity, classInstances, famInstances) = printInfo (thing, fixity, classInstances, famInstances) =
pprTyThingInContextLoc thing $$ pprTyThingInContextLoc thing O.$$
showFixity thing fixity $$ showFixity thing fixity O.$$
vcat (map GHC.pprInstance classInstances) $$ O.vcat (map GHC.pprInstance classInstances) O.$$
vcat (map GHC.pprFamInst famInstances) O.vcat (map GHC.pprFamInst famInstances)
#else #else
printInfo (thing, fixity, classInstances) = printInfo (thing, fixity, classInstances) =
pprTyThingInContextLoc False thing $$ showFixity thing fixity $$ pprTyThingInContextLoc False thing O.$$ showFixity thing fixity O.$$
vcat (map GHC.pprInstance classInstances) O.vcat (map GHC.pprInstance classInstances)
#endif #endif
showFixity thing fixity = showFixity thing fixity =
if fixity == GHC.defaultFixity if fixity == GHC.defaultFixity
then empty then O.empty
else ppr fixity <+> pprInfixName (getName thing) else O.ppr fixity O.<+> pprInfixName (getName thing)
...@@ -11,7 +11,13 @@ module IHaskell.Flags ( ...@@ -11,7 +11,13 @@ module IHaskell.Flags (
help, help,
) where ) where
import ClassyPrelude import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import System.Console.CmdArgs.Explicit import System.Console.CmdArgs.Explicit
import System.Console.CmdArgs.Text import System.Console.CmdArgs.Text
import Data.List (findIndex) import Data.List (findIndex)
...@@ -63,7 +69,7 @@ parseFlags flags = ...@@ -63,7 +69,7 @@ parseFlags flags =
Nothing -> Nothing ->
-- Treat no mode as 'console'. -- Treat no mode as 'console'.
if "--help" `elem` flags if "--help" `elem` flags
then Left $ pack (showText (Wrap 100) $ helpText [] HelpFormatAll ihaskellArgs) then Left $ showText (Wrap 100) $ helpText [] HelpFormatAll ihaskellArgs
else process ihaskellArgs flags else process ihaskellArgs flags
Just 0 -> process ihaskellArgs flags Just 0 -> process ihaskellArgs flags
...@@ -139,13 +145,13 @@ convert = mode "convert" (Args ConvertLhs []) description unnamedArg convertFlag ...@@ -139,13 +145,13 @@ convert = mode "convert" (Args ConvertLhs []) description unnamedArg convertFlag
consStyle style (Args mode prev) = Args mode (ConvertLhsStyle style : prev) consStyle style (Args mode prev) = Args mode (ConvertLhsStyle style : prev)
storeFormat constructor str (Args mode prev) = storeFormat constructor str (Args mode prev) =
case toLower str of case T.toLower (T.pack str) of
"lhs" -> Right $ Args mode $ constructor LhsMarkdown : prev "lhs" -> Right $ Args mode $ constructor LhsMarkdown : prev
"ipynb" -> Right $ Args mode $ constructor IpynbFile : prev "ipynb" -> Right $ Args mode $ constructor IpynbFile : prev
_ -> Left $ "Unknown format requested: " ++ str _ -> Left $ "Unknown format requested: " ++ str
storeLhs str previousArgs = storeLhs str previousArgs =
case toLower str of case T.toLower (T.pack str) of
"bird" -> success lhsStyleBird "bird" -> success lhsStyleBird
"tex" -> success lhsStyleTex "tex" -> success lhsStyleTex
_ -> Left $ "Unknown lhs style: " ++ str _ -> Left $ "Unknown lhs style: " ++ str
......
This diff is collapsed.
{-# LANGUAGE OverloadedStrings, DoAndIfThenElse #-} {-# LANGUAGE NoImplicitPrelude, OverloadedStrings, DoAndIfThenElse #-}
-- | This module provides a way in which the Haskell standard input may be forwarded to the IPython -- | This module provides a way in which the Haskell standard input may be forwarded to the IPython
-- frontend and thus allows the notebook to use the standard input. -- frontend and thus allows the notebook to use the standard input.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
-- communication. For this, use @recordKernelProfile@ once the profile is known. Both this and -- communication. For this, use @recordKernelProfile@ once the profile is known. Both this and
-- @recordParentHeader@ take a directory name where they can store this data. -- @recordParentHeader@ take a directory name where they can store this data.
-- --
--
-- Finally, the module must know what @execute_request@ message is currently being replied to (which -- Finally, the module must know what @execute_request@ message is currently being replied to (which
-- will request the input). Thus, every time the language kernel receives an @execute_request@ -- will request the input). Thus, every time the language kernel receives an @execute_request@
-- message, it should inform this module via @recordParentHeader@, so that the module may generate -- message, it should inform this module via @recordParentHeader@, so that the module may generate
...@@ -24,13 +25,19 @@ ...@@ -24,13 +25,19 @@
-- the host code. -- the host code.
module IHaskell.IPython.Stdin (fixStdin, recordParentHeader, recordKernelProfile) where module IHaskell.IPython.Stdin (fixStdin, recordParentHeader, recordKernelProfile) where
import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import Control.Concurrent import Control.Concurrent
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import Control.Concurrent.Chan import Control.Concurrent.Chan
import Control.Monad import Control.Monad
import GHC.IO.Handle import GHC.IO.Handle
import GHC.IO.Handle.Types import GHC.IO.Handle.Types
import System.IO
import System.Posix.IO import System.Posix.IO
import System.IO.Unsafe import System.IO.Unsafe
import qualified Data.Map as Map import qualified Data.Map as Map
...@@ -48,7 +55,7 @@ stdinInterface = unsafePerformIO newEmptyMVar ...@@ -48,7 +55,7 @@ stdinInterface = unsafePerformIO newEmptyMVar
fixStdin :: String -> IO () fixStdin :: String -> IO ()
fixStdin dir = do fixStdin dir = do
-- Initialize the stdin interface. -- Initialize the stdin interface.
profile <- read <$> readFile (dir ++ "/.kernel-profile") profile <- fromJust . readMay <$> readFile (dir ++ "/.kernel-profile")
interface <- serveStdin profile interface <- serveStdin profile
putMVar stdinInterface interface putMVar stdinInterface interface
void $ forkIO $ stdinOnce dir void $ forkIO $ stdinOnce dir
...@@ -87,7 +94,7 @@ getInputLine dir = do ...@@ -87,7 +94,7 @@ getInputLine dir = do
-- Send a request for input. -- Send a request for input.
uuid <- UUID.random uuid <- UUID.random
parentHeader <- read <$> readFile (dir ++ "/.last-req-header") parentHeader <- fromJust . readMay <$> readFile (dir ++ "/.last-req-header")
let header = MessageHeader let header = MessageHeader
{ username = username parentHeader { username = username parentHeader
, identifiers = identifiers parentHeader , identifiers = identifiers parentHeader
......
...@@ -30,11 +30,16 @@ module IHaskell.Types ( ...@@ -30,11 +30,16 @@ module IHaskell.Types (
KernelSpec(..), KernelSpec(..),
) where ) where
import ClassyPrelude import IHaskellPrelude
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
import qualified Data.ByteString.Char8 as Char import qualified Data.ByteString.Char8 as Char
import Data.Serialize import Data.Serialize
import GHC.Generics import GHC.Generics
import Data.Map (Map, empty)
import Data.Aeson (Value) import Data.Aeson (Value)
import IHaskell.IPython.Kernel import IHaskell.IPython.Kernel
...@@ -103,9 +108,6 @@ instance Monoid Display where ...@@ -103,9 +108,6 @@ instance Monoid Display where
a `mappend` ManyDisplay b = ManyDisplay (a : b) a `mappend` ManyDisplay b = ManyDisplay (a : b)
a `mappend` b = ManyDisplay [a, b] a `mappend` b = ManyDisplay [a, b]
instance Semigroup Display where
a <> b = a `mappend` b
-- | All state stored in the kernel between executions. -- | All state stored in the kernel between executions.
data KernelState = data KernelState =
KernelState KernelState
...@@ -128,7 +130,7 @@ defaultKernelState = KernelState ...@@ -128,7 +130,7 @@ defaultKernelState = KernelState
, useShowErrors = False , useShowErrors = False
, useShowTypes = False , useShowTypes = False
, usePager = True , usePager = True
, openComms = empty , openComms = mempty
, kernelDebug = False , kernelDebug = False
} }
...@@ -177,4 +179,4 @@ data EvaluationResult = ...@@ -177,4 +179,4 @@ data EvaluationResult =
-- pager. -- pager.
, startComms :: [CommInfo] -- ^ Comms to start. , startComms :: [CommInfo] -- ^ Comms to start.
} }
deriving Show deriving Show
\ No newline at end of file
module IHaskellPrelude (
module IHaskellPrelude,
module X,
-- Select reexports
Data.Typeable.Proxy,
Data.Typeable.Typeable,
Data.Typeable.cast,
GHC.Exts.IsString,
GHC.Exts.IsList,
System.IO.hPutStrLn,
System.IO.hPutStr,
System.IO.hPutChar,
System.IO.hPrint,
System.IO.stdout,
System.IO.stderr,
System.IO.stdin,
System.IO.getChar,
System.IO.getLine,
System.IO.writeFile,
System.IO.Handle,
System.IO.Strict.readFile,
System.IO.Strict.getContents,
System.IO.Strict.hGetContents,
Control.Exception.catch,
Control.Exception.SomeException,
Control.Applicative.Applicative(..),
Control.Applicative.ZipList(..),
(Control.Applicative.<$>),
Control.Concurrent.MVar.MVar,
Control.Concurrent.MVar.newMVar,
Control.Concurrent.MVar.newEmptyMVar,
Control.Concurrent.MVar.isEmptyMVar,
Control.Concurrent.MVar.readMVar,
Control.Concurrent.MVar.takeMVar,
Control.Concurrent.MVar.putMVar,
Control.Concurrent.MVar.modifyMVar,
Control.Concurrent.MVar.modifyMVar_,
Data.IORef.IORef,
Data.IORef.readIORef,
Data.IORef.writeIORef,
Data.IORef.modifyIORef',
Data.IORef.newIORef,
-- Miscellaneous names
Data.Map.Map,
GHC.IO.FilePath,
Data.Text.Text,
Data.ByteString.ByteString,
Text.Printf.printf,
Data.Function.on,
) where
import Prelude
import Data.Monoid as X
import Data.Tuple as X
import Control.Monad as X
import Data.Maybe as X
import Data.Either as X
import Control.Monad.IO.Class as X
import Data.Ord as X
import GHC.Show as X
import GHC.Enum as X
import GHC.Num as X
import GHC.Real as X
import GHC.Base as X hiding (Any)
import Data.List as X hiding (head, last, tail, init, transpose, subsequences, permutations,
foldl, foldl1, maximum, minimum, scanl, scanl1, scanr, scanr1, span, break,
mapAccumL, mapAccumR, dropWhileEnd, (!!), elemIndices,
elemIndex, findIndex, findIndices, zip5, zip6, zip7, zipWith5,
zipWith6, zipWith7, unzip5, unzip6, unzip6, delete, union, lookup,
intersect, insert, deleteBy, deleteFirstBy, unionBy,
intersectBy, group, groupBy, insertBy, maximumBy, minimumBy,
genericLength, genericDrop, genericTake, genericSplitAt,
genericIndex, genericReplicate, inits, tails)
import qualified Control.Applicative
import qualified Data.Typeable
import qualified Data.IORef
import qualified Data.Map
import qualified Data.Text
import qualified Data.Text.Lazy
import qualified Data.ByteString
import qualified Data.ByteString.Lazy
import qualified Data.Function
import qualified GHC.Exts
import qualified System.IO
import qualified System.IO.Strict
import qualified GHC.IO
import qualified Text.Printf
import qualified Control.Exception
import qualified Control.Concurrent.MVar
import qualified Data.List
import qualified Prelude as P
type LByteString = Data.ByteString.Lazy.ByteString
type LText = Data.Text.Lazy.Text
(headMay, tailMay, lastMay, initMay, maximumMay, minimumMay) =
(wrapEmpty head, wrapEmpty tail, wrapEmpty last, wrapEmpty init, wrapEmpty maximum, wrapEmpty minimum)
where
wrapEmpty :: ([a] -> b) -> [a] -> Maybe b
wrapEmpty _ [] = Nothing
wrapEmpty f xs = Just (f xs)
maximumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
maximumByMay _ [] = Nothing
maximumByMay f xs = Just (Data.List.maximumBy f xs)
minimumByMay :: (a -> a -> Ordering) -> [a] -> Maybe a
minimumByMay _ [] = Nothing
minimumByMay f xs = Just (Data.List.minimumBy f xs)
readMay :: Read a => String -> Maybe a
readMay = fmap fst . headMay . reads
putStrLn :: (MonadIO m) => String -> m ()
putStrLn = liftIO . P.putStrLn
putStr :: (MonadIO m) => String -> m ()
putStr = liftIO . P.putStr
putChar:: MonadIO m => Char -> m ()
putChar = liftIO . P.putChar
print :: (MonadIO m, Show a) => a -> m ()
print = liftIO . P.print
...@@ -4,22 +4,24 @@ ...@@ -4,22 +4,24 @@
-- Chans to communicate with the ZeroMQ sockets. -- Chans to communicate with the ZeroMQ sockets.
module Main (main) where module Main (main) where
-- Prelude imports. import IHaskellPrelude
import ClassyPrelude hiding (last, liftIO, readChan, writeChan) import qualified Data.Text as T
import Prelude (last, read) import qualified Data.Text.Lazy as LT
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as CBS
-- Standard library imports. -- Standard library imports.
import Control.Concurrent (threadDelay) import Control.Concurrent (threadDelay)
import Control.Concurrent.Chan import Control.Concurrent.Chan
import Data.Aeson import Data.Aeson
import Data.Text (strip)
import System.Directory import System.Directory
import System.Exit (exitSuccess) import System.Exit (exitSuccess)
import Text.Printf import System.Environment (getArgs)
import System.Posix.Signals import System.Posix.Signals
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.String.Here (hereFile) import Data.String.Here (hereFile)
import qualified Data.Text as T import qualified Data.Text.Encoding as E
-- IHaskell imports. -- IHaskell imports.
import IHaskell.Convert (convert) import IHaskell.Convert (convert)
...@@ -33,7 +35,6 @@ import IHaskell.IPython ...@@ -33,7 +35,6 @@ import IHaskell.IPython
import IHaskell.Types import IHaskell.Types
import IHaskell.IPython.ZeroMQ import IHaskell.IPython.ZeroMQ
import IHaskell.IPython.Types import IHaskell.IPython.Types
import qualified Data.ByteString.Char8 as Chars
import qualified IHaskell.IPython.Message.UUID as UUID import qualified IHaskell.IPython.Message.UUID as UUID
import qualified IHaskell.IPython.Stdin as Stdin import qualified IHaskell.IPython.Stdin as Stdin
...@@ -42,7 +43,7 @@ import GHC hiding (extensions, language) ...@@ -42,7 +43,7 @@ import GHC hiding (extensions, language)
-- | Compute the GHC API version number using the dist/build/autogen/cabal_macros.h -- | Compute the GHC API version number using the dist/build/autogen/cabal_macros.h
ghcVersionInts :: [Int] ghcVersionInts :: [Int]
ghcVersionInts = map read . words . map dotToSpace $ VERSION_ghc ghcVersionInts = map (fromJust . readMay) . words . map dotToSpace $ VERSION_ghc
where where
dotToSpace '.' = ' ' dotToSpace '.' = ' '
dotToSpace x = x dotToSpace x = x
...@@ -52,18 +53,18 @@ ihaskellCSS = [hereFile|html/custom.css|] ...@@ -52,18 +53,18 @@ ihaskellCSS = [hereFile|html/custom.css|]
consoleBanner :: Text consoleBanner :: Text
consoleBanner = consoleBanner =
"Welcome to IHaskell! Run `IHaskell --help` for more information.\n" ++ "Welcome to IHaskell! Run `IHaskell --help` for more information.\n" <>
"Enter `:help` to learn more about IHaskell built-ins." "Enter `:help` to learn more about IHaskell built-ins."
main :: IO () main :: IO ()
main = do main = do
args <- parseFlags <$> map unpack <$> getArgs args <- parseFlags <$> getArgs
case args of case args of
Left errorMessage -> hPutStrLn stderr errorMessage Left errorMessage -> hPutStrLn stderr errorMessage
Right args -> ihaskell args Right args -> ihaskell args
ihaskell :: Args -> IO () ihaskell :: Args -> IO ()
ihaskell (Args (ShowHelp help) _) = putStrLn $ pack help ihaskell (Args (ShowHelp help) _) = putStrLn help
ihaskell (Args ConvertLhs args) = showingHelp ConvertLhs args $ convert args ihaskell (Args ConvertLhs args) = showingHelp ConvertLhs args $ convert args
ihaskell (Args InstallKernelSpec args) = showingHelp InstallKernelSpec args $ do ihaskell (Args InstallKernelSpec args) = showingHelp InstallKernelSpec args $ do
let kernelSpecOpts = parseKernelArgs args let kernelSpecOpts = parseKernelArgs args
...@@ -76,7 +77,7 @@ showingHelp :: IHaskellMode -> [Argument] -> IO () -> IO () ...@@ -76,7 +77,7 @@ showingHelp :: IHaskellMode -> [Argument] -> IO () -> IO ()
showingHelp mode flags act = showingHelp mode flags act =
case find (== Help) flags of case find (== Help) flags of
Just _ -> Just _ ->
putStrLn $ pack $ help mode putStrLn $ help mode
Nothing -> Nothing ->
act act
...@@ -101,7 +102,7 @@ runKernel kernelOpts profileSrc = do ...@@ -101,7 +102,7 @@ runKernel kernelOpts profileSrc = do
libdir = kernelSpecGhcLibdir kernelOpts libdir = kernelSpecGhcLibdir kernelOpts
-- Parse the profile file. -- Parse the profile file.
Just profile <- liftM decode . readFile . fpFromString $ profileSrc Just profile <- liftM decode $ LBS.readFile profileSrc
-- Necessary for `getLine` and their ilk to work. -- Necessary for `getLine` and their ilk to work.
dir <- getIHaskellDir dir <- getIHaskellDir
...@@ -131,7 +132,7 @@ runKernel kernelOpts profileSrc = do ...@@ -131,7 +132,7 @@ runKernel kernelOpts profileSrc = do
confFile <- liftIO $ kernelSpecConfFile kernelOpts confFile <- liftIO $ kernelSpecConfFile kernelOpts
case confFile of case confFile of
Just filename -> liftIO (readFile $ fpFromString filename) >>= evaluator Just filename -> liftIO (readFile filename) >>= evaluator
Nothing -> return () Nothing -> return ()
forever $ do forever $ do
...@@ -247,12 +248,14 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do ...@@ -247,12 +248,14 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
header <- dupHeader replyHeader DisplayDataMessage header <- dupHeader replyHeader DisplayDataMessage
send $ PublishDisplayData header "haskell" $ map (convertSvgToHtml . prependCss) outs send $ PublishDisplayData header "haskell" $ map (convertSvgToHtml . prependCss) outs
convertSvgToHtml (DisplayData MimeSvg svg) = html $ makeSvgImg $ base64 $ encodeUtf8 svg convertSvgToHtml (DisplayData MimeSvg svg) = html $ makeSvgImg $ base64 $ E.encodeUtf8 svg
convertSvgToHtml x = x convertSvgToHtml x = x
makeSvgImg base64data = unpack $ "<img src=\"data:image/svg+xml;base64," ++ base64data ++ "\"/>"
makeSvgImg :: Base64 -> String
makeSvgImg base64data = T.unpack $ "<img src=\"data:image/svg+xml;base64," <> base64data <> "\"/>"
prependCss (DisplayData MimeHtml html) = prependCss (DisplayData MimeHtml html) =
DisplayData MimeHtml $concat ["<style>", pack ihaskellCSS, "</style>", html] DisplayData MimeHtml $ mconcat ["<style>", T.pack ihaskellCSS, "</style>", html]
prependCss x = x prependCss x = x
startComm :: CommInfo -> IO () startComm :: CommInfo -> IO ()
...@@ -304,10 +307,10 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do ...@@ -304,10 +307,10 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
let execCount = getExecutionCounter state let execCount = getExecutionCounter state
-- Let all frontends know the execution count and code that's about to run -- Let all frontends know the execution count and code that's about to run
inputHeader <- liftIO $ dupHeader replyHeader InputMessage inputHeader <- liftIO $ dupHeader replyHeader InputMessage
send $ PublishInput inputHeader (unpack code) execCount send $ PublishInput inputHeader (T.unpack code) execCount
-- Run code and publish to the frontend as we go. -- Run code and publish to the frontend as we go.
updatedState <- evaluate state (unpack code) publish updatedState <- evaluate state (T.unpack code) publish
-- Notify the frontend that we're done computing. -- Notify the frontend that we're done computing.
idleHeader <- liftIO $ dupHeader replyHeader StatusMessage idleHeader <- liftIO $ dupHeader replyHeader StatusMessage
...@@ -329,15 +332,15 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do ...@@ -329,15 +332,15 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
replyTo _ req@CompleteRequest{} replyHeader state = do replyTo _ req@CompleteRequest{} replyHeader state = do
let code = getCode req let code = getCode req
pos = getCursorPos req pos = getCursorPos req
(matchedText, completions) <- complete (unpack code) pos (matchedText, completions) <- complete (T.unpack code) pos
let start = pos - length matchedText let start = pos - length matchedText
end = pos end = pos
reply = CompleteReply replyHeader (map pack completions) start end Map.empty True reply = CompleteReply replyHeader (map T.pack completions) start end Map.empty True
return (state, reply) return (state, reply)
replyTo _ req@InspectRequest{} replyHeader state = do replyTo _ req@InspectRequest{} replyHeader state = do
result <- inspect (unpack $ inspectCode req) (inspectCursorPos req) result <- inspect (T.unpack $ inspectCode req) (inspectCursorPos req)
let reply = let reply =
case result of case result of
Just (Display datas) -> InspectReply Just (Display datas) -> InspectReply
...@@ -365,7 +368,7 @@ handleComm replier kernelState req replyHeader = do ...@@ -365,7 +368,7 @@ handleComm replier kernelState req replyHeader = do
communicate value = do communicate value = do
head <- dupHeader replyHeader CommDataMessage head <- dupHeader replyHeader CommDataMessage
replier $ CommData head uuid value replier $ CommData head uuid value
case lookup uuid widgets of case Map.lookup uuid widgets of
Nothing -> fail $ "no widget with uuid " ++ show uuid Nothing -> fail $ "no widget with uuid " ++ show uuid
Just (Widget widget) -> Just (Widget widget) ->
case msgType $ header req of case msgType $ header req of
......
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