--
-----------------------------------------------------------------------------
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
module GhciMonad where
#include "HsVersions.h"
import qualified GHC
-import Outputable hiding (printForUser)
+import Outputable hiding (printForUser, printForUserPartWay)
import qualified Outputable
import Panic hiding (showException)
import Util
import SrcLoc
import Module
import ObjLink
+import StaticFlags
import Data.Maybe
import Numeric
-----------------------------------------------------------------------------
-- GHCi monad
+type Command = (String, String -> GHCi Bool, Maybe String, String -> IO [String])
+
data GHCiState = GHCiState
{
progname :: String,
prelude :: GHC.Module,
break_ctr :: !Int,
breaks :: ![(Int, BreakLocation)],
- tickarrays :: ModuleEnv TickArray
+ tickarrays :: ModuleEnv TickArray,
-- tickarrays caches the TickArray for loaded modules,
-- so that we don't rebuild it each time the user sets
-- a breakpoint.
+ -- ":" at the GHCi prompt repeats the last command, so we
+ -- remember is here:
+ last_command :: Maybe Command,
+ cmdqueue :: [String],
+ remembered_ctx :: [(CtxtCmd, [String], [String])]
+ -- we remember the :module commands between :loads, so that
+ -- on a :reload we can replay them. See bugs #2049,
+ -- #1873, #1360. Previously we tried to remember modules that
+ -- were supposed to be in the context but currently had errors,
+ -- but this was complicated. Just replaying the :module commands
+ -- seems to be the right thing.
}
+data CtxtCmd
+ = SetContext
+ | AddModules
+ | RemModules
+
type TickArray = Array Int [(BreakIndex,SrcSpan)]
data GHCiOption
{ breakModule :: !GHC.Module
, breakLoc :: !SrcSpan
, breakTick :: {-# UNPACK #-} !Int
+ , onBreakCmd :: String
}
- deriving Eq
+
+instance Eq BreakLocation where
+ loc1 == loc2 = breakModule loc1 == breakModule loc2 &&
+ breakTick loc1 == breakTick loc2
prettyLocations :: [(Int, BreakLocation)] -> SDoc
prettyLocations [] = text "No active breakpoints."
prettyLocations locs = vcat $ map (\(i, loc) -> brackets (int i) <+> ppr loc) $ reverse $ locs
instance Outputable BreakLocation where
- ppr loc = (ppr $ breakModule loc) <+> ppr (breakLoc loc)
+ ppr loc = (ppr $ breakModule loc) <+> ppr (breakLoc loc) <+>
+ if null (onBreakCmd loc)
+ then empty
+ else doubleQuotes (text (onBreakCmd loc))
recordBreak :: BreakLocation -> GHCi (Bool{- was already present -}, Int)
recordBreak brkLoc = do
(GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
return a = GHCi $ \s -> return a
+instance Functor GHCi where
+ fmap f m = m >>= return . f
+
ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
ghciHandleDyn h (GHCi m) = GHCi $ \s ->
Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
unqual <- io (GHC.getPrintUnqual session)
io $ Outputable.printForUser stdout unqual doc
+printForUserPartWay :: SDoc -> GHCi ()
+printForUserPartWay doc = do
+ session <- getSession
+ unqual <- io (GHC.getPrintUnqual session)
+ io $ Outputable.printForUserPartWay stdout opt_PprUserLength unqual doc
+
-- --------------------------------------------------------------------------
-- timing & statistics