Commit a43bbb90 authored by Andrew Gibiansky's avatar Andrew Gibiansky

Completing reformatting and adding it to test suite

parent 2f060497
......@@ -48,6 +48,7 @@ script:
- travis_retry cabal configure --enable-tests
- travis_retry cabal test --show-details=always
- ./verify_formatting.py
- cabal sdist
# The following scriptlet checks that the resulting source distribution can be built & installed
......
......@@ -2,7 +2,7 @@
module IHaskell.Convert (convert) where
import Control.Monad.Identity (Identity(Identity), unless, when)
import IHaskell.Convert.Args (ConvertSpec(ConvertSpec, convertInput, convertLhsStyle, convertOutput, convertOverwriteFiles, convertToIpynb), fromJustConvertSpec, toConvertSpec)
import IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec)
import IHaskell.Convert.IpynbToLhs (ipynbToLhs)
import IHaskell.Convert.LhsToIpynb (lhsToIpynb)
import IHaskell.Flags (Argument)
......
......@@ -50,7 +50,6 @@ isFormatSpec (ConvertToFormat _) = True
isFormatSpec (ConvertFromFormat _) = True
isFormatSpec _ = False
toConvertSpec :: [Argument] -> ConvertSpec Maybe
toConvertSpec args = mergeArgs otherArgs (mergeArgs formatSpecArgs initialConvertSpec)
where
......
......@@ -13,8 +13,7 @@ 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 qualified Data.Vector as V (map, mapM, toList)
import IHaskell.Flags (LhsStyle(lhsBeginCode, lhsBeginOutput, lhsCodePrefix, lhsEndCode,
lhsEndOutput, lhsOutputPrefix))
import IHaskell.Flags (LhsStyle(..))
ipynbToLhs :: LhsStyle T.Text
-> FilePath -- ^ the filename of an ipython notebook
......
......@@ -41,7 +41,6 @@ isEmptyMD :: (Eq a, Monoid a) => CellLine a -> Bool
isEmptyMD (MarkdownLine a) = a == mempty
isEmptyMD _ = False
untag :: CellLine t -> t
untag (CodeLine a) = a
untag (OutputLine a) = a
......
......@@ -86,8 +86,6 @@ instance IHaskellDisplay a => IHaskellDisplay [a] where
displays <- mapM display disps
return $ ManyDisplay displays
-- | Encode many displays into a single one. All will be output.
many :: [Display] -> Display
many = ManyDisplay
......
......@@ -60,6 +60,7 @@ data CompletionType = Empty
extName (FlagSpec { flagSpecName = name }) = name
#else
extName (name, _, _) = name
exposedName = id
#endif
complete :: String -> Int -> Interpreter (String, [String])
......@@ -250,13 +251,14 @@ completionTarget code cursor = expandCompletionPiece pieceToComplete
where
pieceToComplete = map fst <$> find (elem cursor . map snd) pieces
pieces = splitAlongCursor $ split splitter $ zip code [1 ..]
splitter = defaultSplitter {
-- Split using only the characters, which are the first elements of
-- the (char, index) tuple
delimiter = Delimiter [uncurry isDelim],
-- Condense multiple delimiters into one and then drop
-- them.
condensePolicy = Condense, delimPolicy = Drop }
splitter = defaultSplitter
{
-- Split using only the characters, which are the first elements of the (char, index) tuple
delimiter = Delimiter [uncurry isDelim]
-- Condense multiple delimiters into one and then drop them.
, condensePolicy = Condense
, delimPolicy = Drop
}
isDelim :: Char -> Int -> Bool
isDelim char idx = char `elem` neverIdent || isSymbol char
......
......@@ -6,7 +6,12 @@
This module exports all functions used for evaluation of IHaskell input.
-}
module IHaskell.Eval.Evaluate (
interpret, evaluate, Interpreter, liftIO, typeCleaner, globalImports
interpret,
evaluate,
Interpreter,
liftIO,
typeCleaner,
globalImports,
) where
import ClassyPrelude hiding (init, last, liftIO, head, hGetContents, tail, try)
......@@ -77,16 +82,25 @@ import qualified IHaskell.IPython.Message.UUID as UUID
import Paths_ihaskell (version)
import Data.Version (versionBranch)
data ErrorOccurred = Success | Failure deriving (Show, Eq)
data ErrorOccurred = Success
| Failure
deriving (Show, Eq)
-- | Set GHC's verbosity for debugging
ghcVerbosity :: Maybe Int
ghcVerbosity = Nothing -- Just 5
ignoreTypePrefixes :: [String]
ignoreTypePrefixes = ["GHC.Types", "GHC.Base", "GHC.Show", "System.IO",
"GHC.Float", ":Interactive", "GHC.Num", "GHC.IO",
"GHC.Integer.Type"]
ignoreTypePrefixes = [ "GHC.Types"
, "GHC.Base"
, "GHC.Show"
, "System.IO"
, "GHC.Float"
, ":Interactive"
, "GHC.Num"
, "GHC.IO"
, "GHC.Integer.Type"
]
typeCleaner :: String -> String
typeCleaner = useStringType . foldl' (.) id (map (`replace` "") fullPrefixes)
......@@ -98,14 +112,12 @@ write :: GhcMonad m => KernelState -> String -> m ()
write state x = when (kernelDebug state) $ liftIO $ hPutStrLn stderr $ "DEBUG: " ++ x
type Interpreter = Ghc
#if MIN_VERSION_ghc(7, 8, 0)
-- GHC 7.8 exports a MonadIO instance for Ghc
#else
instance MonadIO.MonadIO Interpreter where
liftIO = MonadUtils.liftIO
#endif
globalImports :: [String]
globalImports =
[ "import IHaskell.Display()"
......@@ -118,23 +130,23 @@ globalImports =
, "import qualified Language.Haskell.TH as IHaskellTH"
]
-- | Run an interpreting action. This is effectively runGhc with
-- initialization and importing. First argument indicates whether `stdin`
-- is handled specially, which cannot be done in a testing environment.
-- | Run an interpreting action. This is effectively runGhc with initialization and importing. First
-- argument indicates whether `stdin` is handled specially, which cannot be done in a testing
-- environment.
interpret :: String -> Bool -> Interpreter a -> IO a
interpret libdir allowedStdin action = runGhc (Just libdir) $ do
-- If we're in a sandbox, add the relevant package database
sandboxPackages <- liftIO getSandboxPackageConf
initGhci sandboxPackages
case ghcVerbosity of
Just verb -> do dflags <- getSessionDynFlags
Just verb -> do
dflags <- getSessionDynFlags
void $ setSessionDynFlags $ dflags { verbosity = verb }
Nothing -> return ()
initializeImports
-- Close stdin so it can't be used.
-- Otherwise it'll block the kernel forever.
-- Close stdin so it can't be used. Otherwise it'll block the kernel forever.
dir <- liftIO getIHaskellDir
let cmd = printf "IHaskell.IPython.Stdin.fixStdin \"%s\"" dir
when allowedStdin $ void $
......@@ -144,13 +156,11 @@ interpret libdir allowedStdin action = runGhc (Just libdir) $ do
-- Run the rest of the interpreter
action
#if MIN_VERSION_ghc(7,10,0)
packageIdString' dflags = packageKeyPackageIdString dflags
#else
packageIdString' dflags = packageIdString
#endif
-- | Initialize our GHC session with imports and a value for 'it'.
initializeImports :: Interpreter ()
initializeImports = do
......@@ -219,8 +229,8 @@ initializeImports = do
-- | Give a value for the `it` variable.
initializeItVariable :: Interpreter ()
initializeItVariable = do
-- This is required due to the way we handle `it` in the wrapper
-- statements - if it doesn't exist, the first statement will fail.
-- This is required due to the way we handle `it` in the wrapper statements - if it doesn't exist,
-- the first statement will fail.
void $ runStmt "let it = ()" RunToCompletion
-- | Publisher for IHaskell outputs. The first argument indicates whether this output is final
......@@ -501,8 +511,7 @@ evalCommand output (Directive LoadModule mods) state = wrapExecution state $ do
'-' -> (words remainder, True)
_ -> (words stripped, False)
forM_ modules $ \modl ->
if removeModule
forM_ modules $ \modl -> if removeModule
then removeImport modl
else evalImport $ "import " ++ modl
......@@ -512,25 +521,26 @@ evalCommand a (Directive SetOption opts) state = do
write state $ "Option: " ++ opts
let (existing, nonExisting) = partition optionExists $ words opts
if not $ null nonExisting
then
let err = "No such options: " ++ intercalate ", " nonExisting in
return EvalOut {
evalStatus = Failure,
evalResult = displayError err,
evalState = state,
evalPager = "",
evalComms = []
then let err = "No such options: " ++ intercalate ", " nonExisting
in return
EvalOut
{ evalStatus = Failure
, evalResult = displayError err
, evalState = state
, evalPager = ""
, evalComms = []
}
else
let options = mapMaybe findOption $ words opts
updater = foldl' (.) id $ map getUpdateKernelState options in
return EvalOut {
evalStatus = Success,
evalResult = mempty,
evalState = updater state,
evalPager = "",
evalComms = []
else let options = mapMaybe findOption $ words opts
updater = foldl' (.) id $ map getUpdateKernelState options
in return
EvalOut
{ evalStatus = Success
, evalResult = mempty
, evalState = updater state
, evalPager = ""
, evalComms = []
}
where
optionExists = isJust . findOption
findOption opt =
......@@ -538,7 +548,7 @@ evalCommand a (Directive SetOption opts) state = do
evalCommand _ (Directive GetType expr) state = wrapExecution state $ do
write state $ "Type: " ++ expr
formatType <$> ((expr ++ " :: ") ++ ) <$> getType expr
formatType <$> ((expr ++ " :: ") ++) <$> getType expr
evalCommand _ (Directive GetKind expr) state = wrapExecution state $ do
write state $ "Kind: " ++ expr
......@@ -651,8 +661,6 @@ evalCommand publish (Directive ShellCmd ('!':cmd)) state = wrapExecution state $
pipe <- fdToHandle readEnd
return (pipe, handle)
#endif
-- This is taken largely from GHCi's info section in InteractiveUI.
evalCommand _ (Directive GetHelp _) state = do
write state "Help via :help or :?."
......@@ -895,13 +903,9 @@ evalCommand output (Expression expr) state = do
state' = state { openComms = newComms }
-- Store the fact that we should start this comm.
return evalOut
{ evalComms = CommInfo
widget
uuid
(targetName
widget) : evalComms
return
evalOut
{ evalComms = CommInfo widget uuid (targetName widget) : evalComms evalOut
, evalState = state'
}
......@@ -916,7 +920,8 @@ evalCommand output (Expression expr) state = do
postprocess (DisplayData MimeHtml _) = html $ printf
fmt
unshowableType
(formatErrorWithClass "err-msg collapse" text)
(formatErrorWithClass "err-msg collapse"
text)
script
where
fmt = "<div class='collapse-group'><span class='btn btn-default' href='#' id='unshowable'>Unshowable:<span class='show-type'>%s</span></span>%s</div><script>%s</script>"
......@@ -999,7 +1004,6 @@ hoogleResults state results =
-- Read from a file handle until we hit a delimiter or until we've read as many characters as
-- requested
readChars :: Handle -> String -> Int -> IO String
-- If we're done reading, return nothing.
readChars handle delims 0 = return []
......@@ -1017,7 +1021,6 @@ readChars handle delims nchars = do
-- An error occurs at the end of the stream, so just stop reading.
Left _ -> return []
doLoadModule :: String -> String -> Ghc Display
doLoadModule name modName = do
-- Remember which modules we've loaded before.
......@@ -1054,12 +1057,6 @@ doLoadModule name modName = do
Failed -> return $ displayError $ "Failed to load module " ++ modName
where
#if MIN_VERSION_ghc(7,8,0)
objTarget flags = defaultObjectTarget $ targetPlatform flags
#else
objTarget flags = defaultObjectTarget
#endif
unload :: [InteractiveImport] -> SomeException -> Ghc Display
unload imported exception = do
print $ show exception
......@@ -1069,14 +1066,18 @@ doLoadModule name modName = do
-- Switch to interpreted mode!
flags <- getSessionDynFlags
setSessionDynFlags flags{ hscTarget = HscInterpreted }
setSessionDynFlags flags { hscTarget = HscInterpreted }
-- Return to old context, make sure we have `it`.
setContext imported
initializeItVariable
return $ displayError $ "Failed to load module " ++ modName ++ ": " ++ show exception
#if MIN_VERSION_ghc(7,8,0)
objTarget flags = defaultObjectTarget $ targetPlatform flags
#else
objTarget flags = defaultObjectTarget
#endif
keepingItVariable :: Interpreter a -> Interpreter a
keepingItVariable act = do
-- Generate the it variable temp name
......@@ -1095,8 +1096,8 @@ capturedStatement :: (String -> IO ()) -- ^ Function used to publish int
-> String -- ^ Statement to evaluate.
-> Interpreter (String, RunResult) -- ^ Return the output and result.
capturedStatement output stmt = do
-- Generate random variable names to use so that we cannot accidentally
-- override the variables by using the right names in the terminal.
-- Generate random variable names to use so that we cannot accidentally override the variables by
-- using the right names in the terminal.
gen <- liftIO getStdGen
let
-- Variable names generation.
......@@ -1141,32 +1142,27 @@ capturedStatement output stmt = do
-- Initialize evaluation context.
void $ forM initStmts goStmt
-- Get the pipe to read printed output from.
-- This is effectively the source code of dynCompileExpr from GHC API's
-- InteractiveEval. However, instead of using a `Dynamic` as an
-- intermediary, it just directly reads the value. This is incredibly
-- unsafe! However, for some reason the `getContext` and `setContext`
-- required by dynCompileExpr (to import and clear Data.Dynamic) cause
-- issues with data declarations being updated (e.g. it drops newer
-- versions of data declarations for older ones for unknown reasons).
-- First, compile down to an HValue.
-- Get the pipe to read printed output from. This is effectively the source code of dynCompileExpr
-- from GHC API's InteractiveEval. However, instead of using a `Dynamic` as an intermediary, it just
-- directly reads the value. This is incredibly unsafe! However, for some reason the `getContext`
-- and `setContext` required by dynCompileExpr (to import and clear Data.Dynamic) cause issues with
-- data declarations being updated (e.g. it drops newer versions of data declarations for older ones
-- for unknown reasons). First, compile down to an HValue.
Just (_, hValues, _) <- withSession $ liftIO . flip hscStmt pipeExpr
-- Then convert the HValue into an executable bit, and read the value.
pipe <- liftIO $ do
fd <- head <$> unsafeCoerce hValues
fdToHandle fd
-- Read from a file handle until we hit a delimiter or until we've read
-- as many characters as requested
let
readChars :: Handle -> String -> Int -> IO String
-- Read from a file handle until we hit a delimiter or until we've read as many characters as
-- requested
let readChars :: Handle -> String -> Int -> IO String
-- If we're done reading, return nothing.
readChars handle delims 0 = return []
readChars handle delims nchars = do
-- Try reading a single character. It will throw an exception if the
-- handle is already closed.
-- Try reading a single character. It will throw an exception if the handle is already closed.
tryRead <- gtry $ hGetChar handle :: IO (Either SomeException Char)
case tryRead of
Right char ->
......@@ -1175,7 +1171,7 @@ capturedStatement output stmt = do
then return [char]
else do
next <- readChars handle delims (nchars - 1)
return $ char:next
return $ char : next
-- An error occurs at the end of the stream, so just stop reading.
Left _ -> return []
......@@ -1187,8 +1183,8 @@ capturedStatement output stmt = do
-- Start a loop to publish intermediate results.
let
-- Compute how long to wait between reading pieces of the output.
-- `threadDelay` takes an argument of microseconds.
-- Compute how long to wait between reading pieces of the output. `threadDelay` takes an
-- argument of microseconds.
ms = 1000
delay = 100 * ms
......@@ -1229,9 +1225,8 @@ capturedStatement output stmt = do
-- Finalize evaluation context.
void $ forM postStmts goStmt
-- Once context is finalized, reading can finish.
-- Wait for reading to finish to that the output accumulator is
-- completely filled.
-- Once context is finalized, reading can finish. Wait for reading to finish to that the output
-- accumulator is completely filled.
liftIO $ takeMVar finishedReading
printedOutput <- liftIO $ readMVar outputAccum
......@@ -1257,7 +1252,6 @@ formatErrorWithClass cls =
startswith "No instance for (Show" err &&
isInfixOf " arising from a use of `print'" err
formatParseError :: StringLoc -> String -> ErrMsg
formatParseError (Loc line col) =
printf "Parse error (line %d, column %d): %s" line col
......
......@@ -128,7 +128,6 @@ render HTML = renderHtml
-- | Render a Hoogle result to plain text.
renderPlain :: HoogleResult -> String
renderPlain (NoResult res) =
"No response available: " ++ res
......
......@@ -194,7 +194,6 @@ htmlSuggestions = concatMap toHtml
floating :: String -> String -> String
floating dir thing = [i| <div class="suggestion-row" style="float: ${dir};">${thing}</div> |]
showSuggestion :: String -> String
showSuggestion = remove lintIdent . dropDo
where
......
......@@ -225,7 +225,6 @@ joinFunctions blocks =
conjoin :: [CodeBlock] -> CodeBlock
conjoin = Declaration . intercalate "\n" . map str
-- | Parse a pragma of the form {-# LANGUAGE ... #-}
parsePragma :: String -- ^ Pragma string.
-> Int -- ^ Line number at which the directive appears.
......@@ -245,7 +244,6 @@ parsePragma ('{':'-':'#':pragma) line =
parseDirective :: String -- ^ Directive string.
-> Int -- ^ Line number at which the directive appears.
-> CodeBlock -- ^ Directive code block or a parse error.
parseDirective (':':'!':directive) line = Directive ShellCmd $ '!' : directive
parseDirective (':':directive) line =
case find rightDirective directives of
......
......@@ -72,12 +72,11 @@ extensionFlag ext =
-- Check if a FlagSpec matches "No<ExtensionName>". In that case, we disable the extension.
flagMatchesNo ext fs = ext == "No" ++ flagSpecName fs
#if !MIN_VERSION_ghc(7,10,0)
flagSpecName (name, _, _) = name
flagSpecFlag (_, flag, _) = flag
#endif
-- | Pretty-print dynamic flags (taken from 'InteractiveUI' module of `ghc-bin`)
pprDynFlags :: Bool -- ^ Whether to include flags which are on by default
-> DynFlags
......@@ -111,17 +110,20 @@ pprDynFlags show_all dflags =
default_dflags = defaultDynFlags (settings dflags)
fstr str = text "-f" <> text str
fnostr str = text "-fno-" <> text str
(ghciFlags, others) = partition (\f -> flagSpecFlag f `elem` flgs) DynFlags.fFlags
flgs = concat [flgs1, flgs2, flgs3]
flgs1 = [Opt_PrintExplicitForalls]
#if MIN_VERSION_ghc(7,8,0)
flgs2 = [Opt_PrintExplicitKinds]
#else
flgs2 = []
#endif
flgs3 = [Opt_PrintBindResult, Opt_BreakOnException, Opt_BreakOnError, Opt_PrintEvldWithShow]
flgs3 = [Opt_PrintBindResult, Opt_BreakOnException, Opt_BreakOnError, Opt_PrintEvldWithShow]
-- | Pretty-print the base language and active options (taken from `InteractiveUI` module of
-- `ghc-bin`)
......@@ -319,7 +321,6 @@ cleanUpDuplicateInstances = modifySession $ \hscEnv ->
#else
instEq _ _ = False
#endif
-- | Get the type of an expression and convert it to a string.
getType :: GhcMonad m => String -> m String
getType expr = do
......
......@@ -44,7 +44,6 @@ data LhsStyle string =
}
deriving (Eq, Functor, Show)
data NotebookFormat = LhsMarkdown
| IpynbFile
deriving (Eq, Show)
......@@ -155,6 +154,7 @@ convert = mode "convert" (Args ConvertLhs []) description unnamedArg convertFlag
lhsStyleBird, lhsStyleTex :: LhsStyle String
lhsStyleBird = LhsStyle "> " "\n<< " "" "" "" ""
lhsStyleTex = LhsStyle "" "" "\\begin{code}" "\\end{code}" "\\begin{verbatim}" "\\end{verbatim}"
ihaskellArgs :: Mode Args
......
......@@ -196,7 +196,6 @@ subHome path = shelly $ do
home <- unpack <$> fromMaybe "~" <$> get_env "HOME"
return $ replace "~" home path
-- | Get the path to an executable. If it doensn't exist, fail with an error message complaining
-- about it.
path :: Text -> Sh FilePath
......
......@@ -41,8 +41,8 @@ import IHaskell.IPython.Kernel
-- | A class for displayable Haskell types.
--
-- IHaskell's displaying of results behaves as if these two
-- overlapping/undecidable instances also existed:
-- IHaskell's displaying of results behaves as if these two overlapping/undecidable instances also
-- existed:
--
-- > instance (Show a) => IHaskellDisplay a
-- > instance Show a where shows _ = id
......@@ -51,12 +51,10 @@ class IHaskellDisplay a where
-- | Display as an interactive widget.
class IHaskellDisplay a => IHaskellWidget a where
-- | Output target name for this widget.
-- The actual input parameter should be ignored.
-- | Output target name for this widget. The actual input parameter should be ignored.
targetName :: a -> String
-- | Called when the comm is opened. Allows additional messages to be sent
-- after comm open.
-- | Called when the comm is opened. Allows additional messages to be sent after comm open.
open :: a -- ^ Widget to open a comm port with.
-> (Value -> IO ()) -- ^ Way to respond to the message.
-> IO ()
......@@ -90,12 +88,12 @@ instance IHaskellWidget Widget where
instance Show Widget where
show _ = "<Widget>"
-- | Wrapper for ipython-kernel's DisplayData which allows sending multiple results from the same
-- expression.
data Display = Display [DisplayData]
| ManyDisplay [Display]
deriving (Show, Typeable, Generic)
instance Serialize Display
instance Monoid Display where
......@@ -103,7 +101,7 @@ instance Monoid Display where
ManyDisplay a `mappend` ManyDisplay b = ManyDisplay (a ++ b)
ManyDisplay a `mappend` 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
......
......@@ -196,7 +196,6 @@ createReplyHeader parent = do
-- | Compute a reply to a message.
replyTo :: ZeroMQInterface -> Message -> MessageHeader -> KernelState -> Interpreter (KernelState, Message)
-- Reply to kernel info requests with a kernel info reply. No computation needs to be done, as a
-- kernel info reply is a static object (all info is hard coded into the representation of that
-- message type).
......@@ -214,10 +213,9 @@ replyTo interface ShutdownRequest { restartPending = restartPending } replyHeade
writeChan (shellReplyChannel interface) $ ShutdownReply replyHeader restartPending
exitSuccess
-- Reply to an execution request. The reply itself does not require
-- computation, but this causes messages to be sent to the IOPub socket
-- with the output of the code in the execution request.
replyTo interface req@ExecuteRequest{ getCode = code } replyHeader state = do
-- Reply to an execution request. The reply itself does not require computation, but this causes
-- messages to be sent to the IOPub socket with the output of the code in the execution request.
replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
-- Convenience function to send a message to the IOPub socket.
let send msg = liftIO $ writeChan (iopubChannel interface) msg
......@@ -225,18 +223,16 @@ replyTo interface req@ExecuteRequest{ getCode = code } replyHeader state = do
dir <- liftIO getIHaskellDir
liftIO $ Stdin.recordParentHeader dir $ header req
-- Notify the frontend that the kernel is busy computing.
-- All the headers are copies of the reply header with a different
-- message type, because this preserves the session ID, parent header,
-- and other important information.
-- Notify the frontend that the kernel is busy computing. All the headers are copies of the reply
-- header with a different message type, because this preserves the session ID, parent header, and
-- other important information.
busyHeader <- liftIO $ dupHeader replyHeader StatusMessage
send $ PublishStatus busyHeader Busy
-- Construct a function for publishing output as this is going.
-- This function accepts a boolean indicating whether this is the final
-- output and the thing to display. Store the final outputs in a list so
-- that when we receive an updated non-final output, we can clear the
-- entire output and re-display with the updated output.
-- Construct a function for publishing output as this is going. This function accepts a boolean
-- indicating whether this is the final output and the thing to display. Store the final outputs in
-- a list so that when we receive an updated non-final output, we can clear the entire output and
-- re-display with the updated output.
displayed <- liftIO $ newMVar []
updateNeeded <- liftIO $ newMVar False
pagerOutput <- liftIO $ newMVar ""
......@@ -271,9 +267,10 @@ replyTo interface req@ExecuteRequest{ getCode = code } replyHeader state = do
publish :: EvaluationResult -> IO ()
publish result = do
let final = case result of
IntermediateResult {} -> False
FinalResult {} -> True
let final =
case result of
IntermediateResult{} -> False
FinalResult{} -> True
outs = outputs result
-- If necessary, clear all previous output and redraw.
......@@ -286,12 +283,11 @@ replyTo interface req@ExecuteRequest{ getCode = code } replyHeader state = do
-- Draw this message.
sendOutput outs
-- If this is the final message, add it to the list of completed
-- messages. If it isn't, make sure we clear it later by marking
-- update needed as true.
-- If this is the final message, add it to the list of completed messages. If it isn't, make sure we
-- clear it later by marking update needed as true.
modifyMVar_ updateNeeded (const $ return $ not final)
when final $ do
modifyMVar_ displayed (return . (outs:))
modifyMVar_ displayed (return . (outs :))
-- Start all comms that need to be started.
mapM_ startComm $ startComms result
......@@ -319,11 +315,12 @@ replyTo interface req@ExecuteRequest{ getCode = code } replyHeader state = do
pager <- if usePager state
then liftIO $ readMVar pagerOutput
else return ""
return (updatedState, ExecuteReply {
header = replyHeader,
pagerOutput = pager,
executionCounter = execCount,
status = Ok
return
(updatedState, ExecuteReply
{ header = replyHeader
, pagerOutput = pager
, executionCounter = execCount
, status = Ok
})
......@@ -352,10 +349,10 @@ replyTo _ ObjectInfoRequest { objectName = oname } replyHeader state = do
-- TODO: Implement history_reply.
replyTo _ HistoryRequest{} replyHeader state = do
let reply = HistoryReply {
header = replyHeader,
let reply = HistoryReply
{ header = replyHeader
-- FIXME
historyReply = []
, historyReply = []
}
return (state, reply)
......
......@@ -14,6 +14,11 @@ def hindent(contents):
def diff(src1, src2):
# Ignore trailing newlines
if src1[-1] == "\n":
src1 = src1[:-1]
if src2[-1] == "\n":
src2 = src2[:-1]
with open(".tmp1", "w") as f1:
f1.write(src1)
......@@ -40,8 +45,6 @@ for root, dirnames, filenames in os.walk("src"):
for filename in filenames:
if filename.endswith(".hs"):
sources.append(os.path.join(root, filename))
break
break
hindent_outputs = {}
......
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