1 -----------------------------------------------------------------------------
2 -- $Id: InteractiveUI.hs,v 1.1 2000/11/16 10:48:22 simonmar Exp $
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2000
8 -----------------------------------------------------------------------------
10 module InteractiveUI where
24 -----------------------------------------------------------------------------
27 \ _____ __ __ ____ _________________________________________________\n\
28 \(| || || (| |) GHC Interactive, version 5.00 \n\
29 \|| __ ||___|| || () For Haskell 98. \n\
30 \|| |) ||---|| || || http://www.haskell.org/ghc \n\
31 \|| || || || || (| Bug reports to: glasgow-haskell-bugs@haskell.org \n\
32 \(|___|| || || (|__|) \\\\______________________________________________________\n"
34 commands :: [(String, String -> GHCi ())]
36 ("cd", changeDirectory),
40 ("reload", reloadModule),
47 shortHelpText = "use :? for help.\n"
50 \ <expr> evaluate <expr>\n\
51 \ :cd <dir> change directory to <dir>\n\
52 \ :help display this list of commands\n\
53 \ :? display this list of commands\n\
54 \ :load <filename> load a module (and it dependents)\n\
55 \ :reload reload the current program\n\
56 \ :set <opetion> ... set options\n\
57 \ :type <expr> show the type of <expr>\n\
59 \ :!<command> run the shell command <command>\n\
62 interactiveUI :: CmState -> IO ()
64 hPutStr stdout ghciWelcomeMsg
66 hSetBuffering stdout NoBuffering
70 _ <- (unGHCi uiLoop) GHCiState{ current_module = mkModuleName "Prelude",
79 l <- io (readline (moduleNameUserString (current_module st) ++ ">"))
81 l <- io (hGetLine stdin)
93 runCommand c = myCatch (doCommand c)
94 (\e -> io (hPutStr stdout ("Error: " ++ show e)))
96 doCommand (':' : command) = specialCommand command
98 io (hPutStrLn stdout ("Run expression: " ++ expr))
101 specialCommand str = do
102 let (cmd,rest) = break isSpace str
103 case [ (s,f) | (s,f) <- commands, prefixMatch cmd s ] of
104 [] -> io $ hPutStr stdout ("uknown command `:" ++ cmd ++ "'\n"
107 cs -> io $ hPutStrLn stdout ("prefix " ++ cmd ++
108 " matches multiple commands (" ++
109 foldr1 (\a b -> a ++ ',':b) (map fst cs) ++ ")")
111 noArgs c = io (hPutStr stdout ("command `:" ++ c ++ "' takes no arguments"))
113 -----------------------------------------------------------------------------
116 -- ToDo: don't forget to catch errors
118 help :: String -> GHCi ()
119 help _ = io (putStr helpText)
121 changeDirectory :: String -> GHCi ()
122 changeDirectory = io . setCurrentDirectory
124 loadModule :: String -> GHCi ()
126 state <- getGHCiState
127 (new_cmstate, mod) <- io (cmLoadModule (cmstate state) ({-ToDo!!-}mkModuleName path))
128 setGHCiState state{cmstate=new_cmstate, target=Just path}
130 reloadModule :: String -> GHCi ()
132 state <- getGHCiState
134 Nothing -> io (hPutStr stdout "no current target")
135 Just path -> do (new_cmstate, mod) <- io (cmLoadModule (cmstate state) (mkModuleName path))
136 setGHCiState state{cmstate=new_cmstate}
137 reloadModule _ = noArgs ":reload"
139 setOptions :: String -> GHCi ()
140 setOptions = panic "setOptions"
142 typeOfExpr :: String -> GHCi ()
143 typeOfExpr = panic "typeOfExpr"
145 quit :: String -> GHCi ()
148 shellEscape :: String -> GHCi ()
149 shellEscape str = io (system str >> return ())
151 -----------------------------------------------------------------------------
154 data GHCiState = GHCiState
156 current_module :: ModuleName,
157 target :: Maybe FilePath,
161 newtype GHCi a = GHCi { unGHCi :: GHCiState -> IO (GHCiState, a) }
163 instance Monad GHCi where
164 (GHCi m) >>= k = GHCi $ \s -> m s >>= \(s,a) -> unGHCi (k a) s
165 return a = GHCi $ \s -> return (s,a)
167 getGHCiState = GHCi $ \s -> return (s,s)
168 setGHCiState s = GHCi $ \_ -> return (s,())
170 io m = GHCi $ \s -> m >>= \a -> return (s,a)
172 myCatch (GHCi m) h = GHCi $ \s -> catch (m s) (\e -> unGHCi (h e) s)