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 ...@@ -6,7 +6,9 @@ import IHaskell.Display
import Text.Printf import Text.Printf
instance Show a => IHaskellDisplay (Maybe a) where 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 where
stringDisplay = plain (show just) stringDisplay = plain (show just)
htmlDisplay = html str htmlDisplay = html str
......
...@@ -43,7 +43,7 @@ import Language.Haskell.TH.Quote ...@@ -43,7 +43,7 @@ import Language.Haskell.TH.Quote
rDisp = QuasiQuoter { quoteExp = \s -> [| do rDisp = QuasiQuoter { quoteExp = \s -> [| do
result <- $(quoteExp r s) result <- $(quoteExp r s)
p <- rDisplayAll p <- rDisplayAll
atomically (writeTChan displayChan p) printDisplay p
return result return result
|] } |] }
......
...@@ -57,7 +57,7 @@ library ...@@ -57,7 +57,7 @@ library
aeson >=0.6 && < 0.8, aeson >=0.6 && < 0.8,
base64-bytestring >=1.0, base64-bytestring >=1.0,
bytestring >=0.10, bytestring >=0.10,
cereal ==0.3.*, cereal >=0.3,
classy-prelude >=0.7, classy-prelude >=0.7,
cmdargs >=0.10, cmdargs >=0.10,
containers >=0.5, containers >=0.5,
...@@ -110,8 +110,9 @@ library ...@@ -110,8 +110,9 @@ library
IHaskell.Flags IHaskell.Flags
IHaskell.Types IHaskell.Types
IHaskell.BrokenPackages IHaskell.BrokenPackages
other-modules:
Paths_ihaskell Paths_ihaskell
-- other-modules:
-- Paths_ihaskell
executable IHaskell executable IHaskell
-- .hs or .lhs file containing the Main module. -- .hs or .lhs file containing the Main module.
...@@ -125,7 +126,7 @@ executable IHaskell ...@@ -125,7 +126,7 @@ executable IHaskell
base ==4.6.*, base ==4.6.*,
aeson >=0.6 && < 0.8, aeson >=0.6 && < 0.8,
bytestring >=0.10, bytestring >=0.10,
cereal ==0.3.*, cereal >=0.3,
classy-prelude >=0.7, classy-prelude >=0.7,
containers >=0.5, containers >=0.5,
directory -any, directory -any,
...@@ -147,7 +148,7 @@ Test-Suite hspec ...@@ -147,7 +148,7 @@ Test-Suite hspec
aeson >=0.6 && < 0.8, aeson >=0.6 && < 0.8,
base64-bytestring >=1.0, base64-bytestring >=1.0,
bytestring >=0.10, bytestring >=0.10,
cereal ==0.3.*, cereal >=0.3,
classy-prelude >=0.7, classy-prelude >=0.7,
cmdargs >=0.10, cmdargs >=0.10,
containers >=0.5, containers >=0.5,
......
...@@ -90,7 +90,7 @@ instance ToJSON Profile where ...@@ -90,7 +90,7 @@ instance ToJSON Profile where
] ]
instance FromJSON Transport where instance FromJSON Transport where
parseJSON (String mech) = do parseJSON (String mech) =
case mech of case mech of
"tcp" -> return TCP "tcp" -> return TCP
_ -> fail $ "Unknown transport mechanism " ++ Text.unpack mech _ -> 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 ( ...@@ -7,6 +7,10 @@ module IHaskell.Display (
encode64, base64, encode64, base64,
Display(..), Display(..),
DisplayData(..), DisplayData(..),
printDisplay,
-- Internal only use
displayFromChan
) where ) where
import ClassyPrelude import ClassyPrelude
...@@ -16,6 +20,10 @@ import Data.String.Utils (rstrip) ...@@ -16,6 +20,10 @@ 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 qualified Data.ByteString.Char8 as Char
import Control.Concurrent.STM.TChan
import Control.Monad.STM
import System.IO.Unsafe (unsafePerformIO)
import IHaskell.Types import IHaskell.Types
type Base64 = Text type Base64 = Text
...@@ -97,3 +105,28 @@ base64 = decodeUtf8 . Base64.encode ...@@ -97,3 +105,28 @@ base64 = decodeUtf8 . Base64.encode
-- Serialize displays to a ByteString. -- Serialize displays to a ByteString.
serializeDisplay :: Display -> ByteString serializeDisplay :: Display -> ByteString
serializeDisplay = Serialize.encode 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) ...@@ -51,7 +51,7 @@ import GhcMonad (liftIO, withSession)
import GHC hiding (Stmt, TypeSig) import GHC hiding (Stmt, TypeSig)
import GHC.Paths import GHC.Paths
import Exception hiding (evaluate) import Exception hiding (evaluate)
import Outputable import Outputable hiding ((<>))
import Packages import Packages
import Module import Module
import qualified Pretty import qualified Pretty
...@@ -249,9 +249,17 @@ evaluate kernelState code output = do ...@@ -249,9 +249,17 @@ evaluate kernelState code output = do
runUntilFailure state (cmd:rest) = do runUntilFailure state (cmd:rest) = do
evalOut <- evalCommand output cmd state evalOut <- evalCommand output cmd state
-- Output things only if they are non-empty. -- Get displayed channel outputs.
let result = evalResult evalOut -- 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 helpStr = evalPager evalOut
-- Output things only if they are non-empty.
unless (noResults result && null helpStr) $ unless (noResults result && null helpStr) $
liftIO $ output $ FinalResult result helpStr liftIO $ output $ FinalResult result helpStr
...@@ -262,6 +270,13 @@ evaluate kernelState code output = do ...@@ -262,6 +270,13 @@ evaluate kernelState code output = do
storeItCommand execCount = Statement $ printf "let it%d = it" execCount 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 :: KernelState -> Interpreter EvalOut -> Interpreter EvalOut
safely state = ghandle handler . ghandle sourceErrorHandler safely state = ghandle handler . ghandle sourceErrorHandler
where 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