Commit 59322359 authored by Andrew Gibiansky's avatar Andrew Gibiansky

Adding displayFromChan, as per aavogt's PR.

parent 79db72cf
......@@ -6,7 +6,9 @@ import IHaskell.Display
import Text.Printf
instance Show a => IHaskellDisplay (Maybe a) where
display just = return $ Display [stringDisplay, htmlDisplay]
display just = do
printDisplay $ Display [stringDisplay, htmlDisplay]
return $ Display [stringDisplay, htmlDisplay]
where
stringDisplay = plain (show just)
htmlDisplay = html str
......
......@@ -43,7 +43,7 @@ import Language.Haskell.TH.Quote
rDisp = QuasiQuoter { quoteExp = \s -> [| do
result <- $(quoteExp r s)
p <- rDisplayAll
atomically (writeTChan displayChan p)
printDisplay p
return result
|] }
......
......@@ -57,7 +57,7 @@ library
aeson >=0.6 && < 0.8,
base64-bytestring >=1.0,
bytestring >=0.10,
cereal ==0.3.*,
cereal >=0.3,
classy-prelude >=0.7,
cmdargs >=0.10,
containers >=0.5,
......@@ -110,8 +110,9 @@ library
IHaskell.Flags
IHaskell.Types
IHaskell.BrokenPackages
other-modules:
Paths_ihaskell
-- other-modules:
-- Paths_ihaskell
executable IHaskell
-- .hs or .lhs file containing the Main module.
......@@ -125,7 +126,7 @@ executable IHaskell
base ==4.6.*,
aeson >=0.6 && < 0.8,
bytestring >=0.10,
cereal ==0.3.*,
cereal >=0.3,
classy-prelude >=0.7,
containers >=0.5,
directory -any,
......@@ -147,7 +148,7 @@ Test-Suite hspec
aeson >=0.6 && < 0.8,
base64-bytestring >=1.0,
bytestring >=0.10,
cereal ==0.3.*,
cereal >=0.3,
classy-prelude >=0.7,
cmdargs >=0.10,
containers >=0.5,
......
......@@ -90,7 +90,7 @@ instance ToJSON Profile where
]
instance FromJSON Transport where
parseJSON (String mech) = do
parseJSON (String mech) =
case mech of
"tcp" -> return TCP
_ -> fail $ "Unknown transport mechanism " ++ Text.unpack mech
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,6 +7,10 @@ module IHaskell.Display (
encode64, base64,
Display(..),
DisplayData(..),
printDisplay,
-- Internal only use
displayFromChan
) where
import ClassyPrelude
......@@ -16,6 +20,10 @@ import Data.String.Utils (rstrip)
import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Char8 as Char
import Control.Concurrent.STM.TChan
import Control.Monad.STM
import System.IO.Unsafe (unsafePerformIO)
import IHaskell.Types
type Base64 = Text
......@@ -97,3 +105,28 @@ base64 = decodeUtf8 . Base64.encode
-- Serialize displays to a ByteString.
serializeDisplay :: Display -> ByteString
serializeDisplay = Serialize.encode
-- | Items written to this chan will be included in the output sent
-- to the frontend (ultimately the browser), the next time IHaskell
-- has an item to display.
{-# NOINLINE displayChan #-}
displayChan :: TChan Display
displayChan = unsafePerformIO newTChanIO
-- | Take everything that was put into the 'displayChan' at that point
-- out, and make a 'Display' out of it.
displayFromChan :: IO (Maybe Display)
displayFromChan =
Just . many <$> unfoldM (atomically $ tryReadTChan displayChan)
-- | This is unfoldM from monad-loops. It repeatedly runs an IO action
-- until it return Nothing, and puts all the Justs in a list.
-- If you find yourself using more functionality from monad-loops, just add
-- the package dependency instead of copying more code from it.
unfoldM :: IO (Maybe a) -> IO [a]
unfoldM f = maybe (return []) (\r -> (r:) <$> unfoldM f) =<< f
-- | Write to the display channel. The contents will be displayed in the
-- notebook once the current execution call ends.
printDisplay :: IHaskellDisplay a => a -> IO ()
printDisplay disp = display disp >>= atomically . writeTChan displayChan
......@@ -51,7 +51,7 @@ import GhcMonad (liftIO, withSession)
import GHC hiding (Stmt, TypeSig)
import GHC.Paths
import Exception hiding (evaluate)
import Outputable
import Outputable hiding ((<>))
import Packages
import Module
import qualified Pretty
......@@ -249,9 +249,17 @@ evaluate kernelState code output = do
runUntilFailure state (cmd:rest) = do
evalOut <- evalCommand output cmd state
-- Output things only if they are non-empty.
let result = evalResult evalOut
-- Get displayed channel outputs.
-- Merge them with normal display outputs.
dispsIO <- extractValue "IHaskell.Display.displayFromChan"
dispsMay <- liftIO dispsIO
let result =
case dispsMay of
Nothing -> evalResult evalOut
Just disps -> evalResult evalOut <> disps
helpStr = evalPager evalOut
-- Output things only if they are non-empty.
unless (noResults result && null helpStr) $
liftIO $ output $ FinalResult result helpStr
......@@ -262,6 +270,13 @@ evaluate kernelState code output = do
storeItCommand execCount = Statement $ printf "let it%d = it" execCount
extractValue :: Typeable a => String -> Interpreter a
extractValue expr = do
compiled <- dynCompileExpr expr
case fromDynamic compiled of
Nothing -> error "Expecting value!"
Just result -> return result
safely :: KernelState -> Interpreter EvalOut -> Interpreter EvalOut
safely state = ghandle handler . ghandle sourceErrorHandler
where
......
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