-----------------------------------------------------------------------------
--- $Id: InteractiveUI.hs,v 1.9 2000/11/21 15:00:58 simonmar Exp $
+-- $Id: InteractiveUI.hs,v 1.14 2000/11/22 17:51:16 simonmar Exp $
--
-- GHC Interactive User Interface
--
import Linker
import Module
import Outputable
-import Panic
import Util
import Exception
commands :: [(String, String -> GHCi ())]
commands = [
+ ("add", addModule),
("cd", changeDirectory),
("help", help),
("?", help),
("load", loadModule),
+ ("module", setContext),
("reload", reloadModule),
("set", setOptions),
("type", typeOfExpr),
helpText = "\
\ <expr> evaluate <expr>\n\
+\ :add <filename> add a module to the current set\n\
\ :cd <dir> change directory to <dir>\n\
-\ :help display this list of commands\n\
-\ :? display this list of commands\n\
+\ :help, :? display this list of commands\n\
\ :load <filename> load a module (and it dependents)\n\
-\ :reload reload the current program\n\
-\ :set <opetion> ... set options\n\
+\ :module <mod> set the context for expression evaluation to <mod>\n\
+\ :reload reload the current module set\n\
+\ :set <option> ... set options\n\
\ :type <expr> show the type of <expr>\n\
\ :quit exit GHCi\n\
\ :!<command> run the shell command <command>\n\
\"
-interactiveUI :: CmState -> IO ()
-interactiveUI st = do
+interactiveUI :: CmState -> [ModuleName] -> IO ()
+interactiveUI st mods = do
hPutStrLn stdout ghciWelcomeMsg
hFlush stdout
hSetBuffering stdout NoBuffering
#ifndef NO_READLINE
Readline.initialize
#endif
- _ <- (unGHCi uiLoop) GHCiState{ modules = [],
- current_module = defaultCurrentModule,
- target = Nothing,
- cmstate = st }
+ let this_mod = case mods of
+ [] -> defaultCurrentModule
+ m:ms -> m
+
+ (unGHCi uiLoop) GHCiState{ modules = mods,
+ current_module = this_mod,
+ target = Nothing,
+ cmstate = st }
return ()
uiLoop :: GHCi ()
l <- io (hGetLine stdin)
#endif
case l of
- Nothing -> return ()
+ Nothing -> exitGHCi
Just "" -> uiLoop
Just l -> do
#ifndef NO_READLINE
runCommand l
uiLoop
+exitGHCi = io $ do putStrLn "Leaving GHCi."; exitWith ExitSuccess
+
-- Top level exception handler, just prints out the exception
-- and carries on.
runCommand c =
specialCommand str = do
let (cmd,rest) = break isSpace str
case [ (s,f) | (s,f) <- commands, prefixMatch cmd s ] of
- [] -> io $ hPutStr stdout ("uknown command `:" ++ cmd ++ "'\n"
+ [] -> io $ hPutStr stdout ("unknown command `:" ++ cmd ++ "'\n"
++ shortHelpText)
[(_,f)] -> f (dropWhile isSpace rest)
cs -> io $ hPutStrLn stdout ("prefix " ++ cmd ++
help :: String -> GHCi ()
help _ = io (putStr helpText)
+addModule :: String -> GHCi ()
+addModule _ = throwDyn (OtherError ":add not implemented")
+
+setContext :: String -> GHCi ()
+setContext ""
+ = throwDyn (OtherError "syntax: `:m <module>'")
+setContext m | not (isUpper (head m)) || not (all isAlphaNum (tail m))
+ = throwDyn (OtherError ("strange looking module name: `" ++ m ++ "'"))
+setContext m
+ = do st <- getGHCiState
+ setGHCiState st{current_module = mkModuleName m}
+
changeDirectory :: String -> GHCi ()
changeDirectory = io . setCurrentDirectory
loadModule :: String -> GHCi ()
loadModule path = do
state <- getGHCiState
- (new_cmstate, ok, mods) <- io (cmLoadModule (cmstate state) path)
+ cmstate1 <- io (cmUnload (cmstate state))
+ (cmstate2, ok, mods) <- io (cmLoadModule cmstate1 path)
let new_state = GHCiState {
- cmstate = new_cmstate,
+ cmstate = cmstate2,
modules = mods,
current_module = case mods of
[] -> defaultCurrentModule
state <- getGHCiState
case target state of
Nothing -> io (putStr "no current target\n")
- Just path -> do (new_cmstate, ok, mod)
- <- io (cmLoadModule (cmstate state) path)
- setGHCiState state{cmstate=new_cmstate}
+ Just path
+ -> do (new_cmstate, ok, mod) <- io (cmLoadModule (cmstate state) path)
+ setGHCiState state{cmstate=new_cmstate}
reloadModule _ = noArgs ":reload"
-- set options in the interpreter. Syntax is exactly the same as the
(current_module st) str)
case maybe_ty of
Nothing -> return ()
- Just ty -> io (putStrLn (showSDoc (ppr ty)))
+ Just (unqual, ty) -> io (printForUser stdout unqual (ppr ty))
quit :: String -> GHCi ()
-quit _ = return ()
+quit _ = exitGHCi
shellEscape :: String -> GHCi ()
shellEscape str = io (system str >> return ())