+isPlus ('+':s) = True
+isPlus _ = False
+
+setOpt ('+':str)
+ = case strToGHCiOpt str of
+ Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
+ Just o -> setOption o
+
+unsetOpt ('+':str)
+ = case strToGHCiOpt str of
+ Nothing -> io (putStrLn ("unknown option: `" ++ str ++ "'"))
+ Just o -> unsetOption o
+
+strToGHCiOpt :: String -> (Maybe GHCiOption)
+strToGHCiOpt "s" = Just ShowTiming
+strToGHCiOpt "t" = Just ShowType
+strToGHCiOpt _ = Nothing
+
+optToStr :: GHCiOption -> String
+optToStr ShowTiming = "s"
+optToStr ShowType = "t"
+
+
+-----------------------------------------------------------------------------
+-- Code to do last-expression-entered stuff. (a.k.a the $$ facility)
+
+-- Take a string and replace $$s in it with the last expr, if any.
+expandExpr :: String -> GHCi String
+expandExpr str
+ = do mle <- getLastExpr
+ return (outside mle str)
+ where
+ outside mle ('$':'$':cs)
+ = case mle of
+ Just le -> " (" ++ le ++ ") " ++ outside mle cs
+ Nothing -> outside mle cs
+
+ outside mle [] = []
+ outside mle ('"':str) = '"' : inside2 mle str -- "
+ outside mle ('\'':str) = '\'' : inside1 mle str -- '
+ outside mle (c:cs) = c : outside mle cs
+
+ inside2 mle ('"':cs) = '"' : outside mle cs -- "
+ inside2 mle (c:cs) = c : inside2 mle cs
+ inside2 mle [] = []
+
+ inside1 mle ('\'':cs) = '\'': outside mle cs
+ inside1 mle (c:cs) = c : inside1 mle cs
+ inside1 mle [] = []
+
+
+rememberExpr :: String -> GHCi ()
+rememberExpr str
+ = do let cleaned = (clean . reverse . clean . reverse) str
+ let forget_me_not | null cleaned = Nothing
+ | otherwise = Just cleaned
+ setLastExpr forget_me_not
+ where
+ clean = dropWhile isSpace