1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2005
8 -----------------------------------------------------------------------------
14 #include "HsVersions.h"
16 #if defined(GHCI) && defined(BREAKPOINT)
17 import GHC.Exts ( Int(..), Ptr(..), int2Addr# )
18 import Foreign.StablePtr ( deRefStablePtr, castPtrToStablePtr )
19 import System.IO.Unsafe ( unsafePerformIO )
20 import Var ( Id, globaliseId, idName, idType )
21 import HscTypes ( Session(..), InteractiveContext(..), HscEnv(..)
22 , extendTypeEnvWithIds )
23 import RdrName ( extendLocalRdrEnv, mkRdrUnqual, lookupLocalRdrEnv )
24 import NameEnv ( delListFromNameEnv )
25 import TcType ( tidyTopType )
26 import qualified Id ( setIdType )
27 import IdInfo ( GlobalIdDetails(..) )
28 import Linker ( HValue, extendLinkEnv, withExtendedLinkEnv,
30 import PrelNames ( breakpointJumpName, breakpointCondJumpName )
35 import GHC ( Session, dopt, DynFlag(..), Target(..),
36 TargetId(..), DynFlags(..),
37 pprModule, Type, Module, ModuleName, SuccessFlag(..),
38 TyThing(..), Name, LoadHowMuch(..), Phase,
39 GhcException(..), showGhcException,
40 CheckedModule(..), SrcLoc )
41 import DynFlags ( allFlags )
42 import Packages ( PackageState(..) )
43 import PackageConfig ( InstalledPackageInfo(..) )
44 import UniqFM ( eltsUFM )
48 -- for createtags (should these come via GHC?)
49 import Name ( nameSrcLoc, nameModule, nameOccName )
50 import OccName ( pprOccName )
51 import SrcLoc ( isGoodSrcLoc, srcLocFile, srcLocLine, srcLocCol )
53 -- Other random utilities
54 import Digraph ( flattenSCCs )
55 import BasicTypes ( failed, successIf )
56 import Panic ( panic, installSignalHandlers )
58 import StaticFlags ( opt_IgnoreDotGhci )
59 import Linker ( showLinkerState, linkPackages )
60 import Util ( removeSpaces, handle, global, toArgs,
61 looksLikeModuleName, prefixMatch, sortLe )
63 #ifndef mingw32_HOST_OS
65 #if __GLASGOW_HASKELL__ > 504
69 import GHC.ConsoleHandler ( flushConsole )
70 import System.Win32 ( setConsoleCP, setConsoleOutputCP )
74 import Control.Concurrent ( yield ) -- Used in readline loop
75 import System.Console.Readline as Readline
80 import Control.Exception as Exception
82 -- import Control.Concurrent
86 import Data.Int ( Int64 )
87 import Data.Maybe ( isJust, isNothing, fromMaybe, catMaybes )
90 import System.Environment
91 import System.Exit ( exitWith, ExitCode(..) )
92 import System.Directory
94 import System.IO.Error as IO
96 import Control.Monad as Monad
97 import Foreign.StablePtr ( newStablePtr )
99 import GHC.Exts ( unsafeCoerce# )
100 import GHC.IOBase ( IOErrorType(InvalidArgument) )
102 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
104 import System.Posix.Internals ( setNonBlockingFD )
106 -----------------------------------------------------------------------------
110 " / _ \\ /\\ /\\/ __(_)\n"++
111 " / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n"++
112 "/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n"++
113 "\\____/\\/ /_/\\____/|_| Type :? for help.\n"
115 type Command = (String, String -> GHCi Bool, Bool, String -> IO [String])
116 cmdName (n,_,_,_) = n
118 GLOBAL_VAR(commands, builtin_commands, [Command])
120 builtin_commands :: [Command]
122 ("add", keepGoingPaths addModule, False, completeFilename),
123 ("browse", keepGoing browseCmd, False, completeModule),
124 ("cd", keepGoing changeDirectory, False, completeFilename),
125 ("def", keepGoing defineMacro, False, completeIdentifier),
126 ("help", keepGoing help, False, completeNone),
127 ("?", keepGoing help, False, completeNone),
128 ("info", keepGoing info, False, completeIdentifier),
129 ("load", keepGoingPaths loadModule_, False, completeHomeModuleOrFile),
130 ("module", keepGoing setContext, False, completeModule),
131 ("main", keepGoing runMain, False, completeIdentifier),
132 ("reload", keepGoing reloadModule, False, completeNone),
133 ("check", keepGoing checkModule, False, completeHomeModule),
134 ("set", keepGoing setCmd, True, completeSetOptions),
135 ("show", keepGoing showCmd, False, completeNone),
136 ("etags", keepGoing createETagsFileCmd, False, completeFilename),
137 ("ctags", keepGoing createCTagsFileCmd, False, completeFilename),
138 ("type", keepGoing typeOfExpr, False, completeIdentifier),
139 ("kind", keepGoing kindOfType, False, completeIdentifier),
140 ("unset", keepGoing unsetOptions, True, completeSetOptions),
141 ("undef", keepGoing undefineMacro, False, completeMacro),
142 ("quit", quit, False, completeNone)
145 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
146 keepGoing a str = a str >> return False
148 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
149 keepGoingPaths a str = a (toArgs str) >> return False
151 shortHelpText = "use :? for help.\n"
153 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
155 " Commands available from the prompt:\n" ++
157 " <stmt> evaluate/run <stmt>\n" ++
158 " :add <filename> ... add module(s) to the current target set\n" ++
159 " :browse [*]<module> display the names defined by <module>\n" ++
160 " :cd <dir> change directory to <dir>\n" ++
161 " :def <cmd> <expr> define a command :<cmd>\n" ++
162 " :help, :? display this list of commands\n" ++
163 " :info [<name> ...] display information about the given names\n" ++
164 " :load <filename> ... load module(s) and their dependents\n" ++
165 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
166 " :main [<arguments> ...] run the main function with the given arguments\n" ++
167 " :reload reload the current module set\n" ++
169 " :set <option> ... set options\n" ++
170 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
171 " :set prog <progname> set the value returned by System.getProgName\n" ++
172 " :set prompt <prompt> set the prompt used in GHCi\n" ++
174 " :show modules show the currently loaded modules\n" ++
175 " :show bindings show the current bindings made at the prompt\n" ++
177 " :ctags [<file>] create tags file for Vi (default: \"tags\")\n" ++
178 " :etags [<file>] create tags file for Emacs (defauilt: \"TAGS\")\n" ++
179 " :type <expr> show the type of <expr>\n" ++
180 " :kind <type> show the kind of <type>\n" ++
181 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
182 " :unset <option> ... unset options\n" ++
183 " :quit exit GHCi\n" ++
184 " :!<command> run the shell command <command>\n" ++
186 " Options for ':set' and ':unset':\n" ++
188 " +r revert top-level expressions after each evaluation\n" ++
189 " +s print timing/memory stats after each evaluation\n" ++
190 " +t print type after evaluation\n" ++
191 " -<flags> most GHC command line flags can also be set here\n" ++
192 " (eg. -v2, -fglasgow-exts, etc.)\n"
195 #if defined(GHCI) && defined(BREAKPOINT)
196 globaliseAndTidy :: Id -> Id
198 -- Give the Id a Global Name, and tidy its type
199 = Id.setIdType (globaliseId VanillaGlobal id) tidy_type
201 tidy_type = tidyTopType (idType id)
204 printScopeMsg :: Session -> String -> [Id] -> IO ()
205 printScopeMsg session location ids
206 = GHC.getPrintUnqual session >>= \unqual ->
207 printForUser stdout unqual $
208 text "Local bindings in scope:" $$
209 nest 2 (pprWithCommas showId ids)
210 where showId id = ppr (idName id) <+> dcolon <+> ppr (idType id)
212 jumpCondFunction :: Session -> Int -> [HValue] -> String -> Bool -> b -> b
213 jumpCondFunction session ptr hValues location True b = b
214 jumpCondFunction session ptr hValues location False b
215 = jumpFunction session ptr hValues location b
217 jumpFunction :: Session -> Int -> [HValue] -> String -> b -> b
218 jumpFunction session@(Session ref) (I# idsPtr) hValues location b
220 do ids <- deRefStablePtr (castPtrToStablePtr (Ptr (int2Addr# idsPtr)))
221 let names = map idName ids
222 ASSERT (length names == length hValues) return ()
223 printScopeMsg session location ids
224 hsc_env <- readIORef ref
226 let ictxt = hsc_IC hsc_env
227 global_ids = map globaliseAndTidy ids
228 rn_env = ic_rn_local_env ictxt
229 type_env = ic_type_env ictxt
230 bound_names = map idName global_ids
231 new_rn_env = extendLocalRdrEnv rn_env bound_names
232 -- Remove any shadowed bindings from the type_env;
233 -- they are inaccessible but might, I suppose, cause
234 -- a space leak if we leave them there
235 shadowed = [ n | name <- bound_names,
236 let rdr_name = mkRdrUnqual (nameOccName name),
237 Just n <- [lookupLocalRdrEnv rn_env rdr_name] ]
238 filtered_type_env = delListFromNameEnv type_env shadowed
239 new_type_env = extendTypeEnvWithIds filtered_type_env global_ids
240 new_ic = ictxt { ic_rn_local_env = new_rn_env,
241 ic_type_env = new_type_env }
242 writeIORef ref (hsc_env { hsc_IC = new_ic })
243 is_tty <- hIsTerminalDevice stdin
244 prel_mod <- GHC.findModule session prel_name Nothing
245 withExtendedLinkEnv (zip names hValues) $
246 startGHCi (interactiveLoop is_tty True)
247 GHCiState{ progname = "<interactive>",
249 prompt = location++"> ",
253 writeIORef ref hsc_env
254 putStrLn $ "Returning to normal execution..."
258 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
259 interactiveUI session srcs maybe_expr = do
260 #if defined(GHCI) && defined(BREAKPOINT)
261 initDynLinker =<< GHC.getSessionDynFlags session
262 extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
263 ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))]
265 -- HACK! If we happen to get into an infinite loop (eg the user
266 -- types 'let x=x in x' at the prompt), then the thread will block
267 -- on a blackhole, and become unreachable during GC. The GC will
268 -- detect that it is unreachable and send it the NonTermination
269 -- exception. However, since the thread is unreachable, everything
270 -- it refers to might be finalized, including the standard Handles.
271 -- This sounds like a bug, but we don't have a good solution right
277 -- Initialise buffering for the *interpreted* I/O system
278 initInterpBuffering session
280 when (isNothing maybe_expr) $ do
281 -- Only for GHCi (not runghc and ghc -e):
282 -- Turn buffering off for the compiled program's stdout/stderr
284 -- Turn buffering off for GHCi's stdout
286 hSetBuffering stdout NoBuffering
287 -- We don't want the cmd line to buffer any input that might be
288 -- intended for the program, so unbuffer stdin.
289 hSetBuffering stdin NoBuffering
291 -- initial context is just the Prelude
292 prel_mod <- GHC.findModule session prel_name Nothing
293 GHC.setContext session [] [prel_mod]
297 Readline.setAttemptedCompletionFunction (Just completeWord)
298 --Readline.parseAndBind "set show-all-if-ambiguous 1"
300 let symbols = "!#$%&*+/<=>?@\\^|-~"
301 specials = "(),;[]`{}"
303 word_break_chars = spaces ++ specials ++ symbols
305 Readline.setBasicWordBreakCharacters word_break_chars
306 Readline.setCompleterWordBreakCharacters word_break_chars
309 startGHCi (runGHCi srcs maybe_expr)
310 GHCiState{ progname = "<interactive>",
318 Readline.resetTerminal Nothing
323 prel_name = GHC.mkModuleName "Prelude"
325 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
326 runGHCi paths maybe_expr = do
327 let read_dot_files = not opt_IgnoreDotGhci
329 when (read_dot_files) $ do
332 exists <- io (doesFileExist file)
334 dir_ok <- io (checkPerms ".")
335 file_ok <- io (checkPerms file)
336 when (dir_ok && file_ok) $ do
337 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
340 Right hdl -> fileLoop hdl False
342 when (read_dot_files) $ do
343 -- Read in $HOME/.ghci
344 either_dir <- io (IO.try (getEnv "HOME"))
348 cwd <- io (getCurrentDirectory)
349 when (dir /= cwd) $ do
350 let file = dir ++ "/.ghci"
351 ok <- io (checkPerms file)
353 either_hdl <- io (IO.try (openFile file ReadMode))
356 Right hdl -> fileLoop hdl False
358 -- Perform a :load for files given on the GHCi command line
359 -- When in -e mode, if the load fails then we want to stop
360 -- immediately rather than going on to evaluate the expression.
361 when (not (null paths)) $ do
362 ok <- ghciHandle (\e -> do showException e; return Failed) $
364 when (isJust maybe_expr && failed ok) $
365 io (exitWith (ExitFailure 1))
367 -- if verbosity is greater than 0, or we are connected to a
368 -- terminal, display the prompt in the interactive loop.
369 is_tty <- io (hIsTerminalDevice stdin)
370 dflags <- getDynFlags
371 let show_prompt = verbosity dflags > 0 || is_tty
376 #if defined(mingw32_HOST_OS)
377 -- The win32 Console API mutates the first character of
378 -- type-ahead when reading from it in a non-buffered manner. Work
379 -- around this by flushing the input buffer of type-ahead characters,
380 -- but only if stdin is available.
381 flushed <- io (IO.try (GHC.ConsoleHandler.flushConsole stdin))
383 Left err | isDoesNotExistError err -> return ()
384 | otherwise -> io (ioError err)
385 Right () -> return ()
387 -- initialise the console if necessary
390 -- enter the interactive loop
391 interactiveLoop is_tty show_prompt
393 -- just evaluate the expression we were given
398 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
401 interactiveLoop is_tty show_prompt =
402 -- Ignore ^C exceptions caught here
403 ghciHandleDyn (\e -> case e of
405 #if defined(mingw32_HOST_OS)
408 interactiveLoop is_tty show_prompt
409 _other -> return ()) $
411 ghciUnblock $ do -- unblock necessary if we recursed from the
412 -- exception handler above.
414 -- read commands from stdin
418 else fileLoop stdin show_prompt
420 fileLoop stdin show_prompt
424 -- NOTE: We only read .ghci files if they are owned by the current user,
425 -- and aren't world writable. Otherwise, we could be accidentally
426 -- running code planted by a malicious third party.
428 -- Furthermore, We only read ./.ghci if . is owned by the current user
429 -- and isn't writable by anyone else. I think this is sufficient: we
430 -- don't need to check .. and ../.. etc. because "." always refers to
431 -- the same directory while a process is running.
433 checkPerms :: String -> IO Bool
435 #ifdef mingw32_HOST_OS
438 Util.handle (\_ -> return False) $ do
439 st <- getFileStatus name
441 if fileOwner st /= me then do
442 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
445 let mode = fileMode st
446 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
447 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
449 putStrLn $ "*** WARNING: " ++ name ++
450 " is writable by someone else, IGNORING!"
455 fileLoop :: Handle -> Bool -> GHCi ()
456 fileLoop hdl show_prompt = do
457 session <- getSession
458 (mod,imports) <- io (GHC.getContext session)
460 when show_prompt (io (putStr (mkPrompt mod imports (prompt st))))
461 l <- io (IO.try (hGetLine hdl))
463 Left e | isEOFError e -> return ()
464 | InvalidArgument <- etype -> return ()
465 | otherwise -> io (ioError e)
466 where etype = ioeGetErrorType e
467 -- treat InvalidArgument in the same way as EOF:
468 -- this can happen if the user closed stdin, or
469 -- perhaps did getContents which closes stdin at
472 case removeSpaces l of
473 "" -> fileLoop hdl show_prompt
474 l -> do quit <- runCommand l
475 if quit then return () else fileLoop hdl show_prompt
477 stringLoop :: [String] -> GHCi Bool{-True: we quit-}
478 stringLoop [] = return False
479 stringLoop (s:ss) = do
480 case removeSpaces s of
482 l -> do quit <- runCommand l
483 if quit then return True else stringLoop ss
485 mkPrompt toplevs exports prompt
486 = showSDoc $ f prompt
488 f ('%':'s':xs) = perc_s <> f xs
489 f ('%':'%':xs) = char '%' <> f xs
490 f (x:xs) = char x <> f xs
493 perc_s = hsep (map (\m -> char '*' <> ppr (GHC.moduleName m)) toplevs) <+>
494 hsep (map (ppr . GHC.moduleName) exports)
498 readlineLoop :: GHCi ()
500 session <- getSession
501 (mod,imports) <- io (GHC.getContext session)
503 saveSession -- for use by completion
505 l <- io (readline (mkPrompt mod imports (prompt st))
506 `finally` setNonBlockingFD 0)
507 -- readline sometimes puts stdin into blocking mode,
508 -- so we need to put it back for the IO library
513 case removeSpaces l of
518 if quit then return () else readlineLoop
521 runCommand :: String -> GHCi Bool
522 runCommand c = ghciHandle handler (doCommand c)
524 doCommand (':' : command) = specialCommand command
526 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
529 -- This version is for the GHC command-line option -e. The only difference
530 -- from runCommand is that it catches the ExitException exception and
531 -- exits, rather than printing out the exception.
532 runCommandEval c = ghciHandle handleEval (doCommand c)
534 handleEval (ExitException code) = io (exitWith code)
535 handleEval e = do handler e
536 io (exitWith (ExitFailure 1))
538 doCommand (':' : command) = specialCommand command
540 = do nms <- runStmt stmt
542 Nothing -> io (exitWith (ExitFailure 1))
543 -- failure to run the command causes exit(1) for ghc -e.
544 _ -> finishEvalExpr nms
546 -- This is the exception handler for exceptions generated by the
547 -- user's code; it normally just prints out the exception. The
548 -- handler must be recursive, in case showing the exception causes
549 -- more exceptions to be raised.
551 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
552 -- raising another exception. We therefore don't put the recursive
553 -- handler arond the flushing operation, so if stderr is closed
554 -- GHCi will just die gracefully rather than going into an infinite loop.
555 handler :: Exception -> GHCi Bool
556 handler exception = do
558 io installSignalHandlers
559 ghciHandle handler (showException exception >> return False)
561 showException (DynException dyn) =
562 case fromDynamic dyn of
563 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
564 Just Interrupted -> io (putStrLn "Interrupted.")
565 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
566 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
567 Just other_ghc_ex -> io (print other_ghc_ex)
569 showException other_exception
570 = io (putStrLn ("*** Exception: " ++ show other_exception))
572 runStmt :: String -> GHCi (Maybe [Name])
574 | null (filter (not.isSpace) stmt) = return (Just [])
576 = do st <- getGHCiState
577 session <- getSession
578 result <- io $ withProgName (progname st) $ withArgs (args st) $
579 GHC.runStmt session stmt
581 GHC.RunFailed -> return Nothing
582 GHC.RunException e -> throw e -- this is caught by runCommand(Eval)
583 GHC.RunOk names -> return (Just names)
585 -- possibly print the type and revert CAFs after evaluating an expression
586 finishEvalExpr mb_names
587 = do b <- isOptionSet ShowType
588 session <- getSession
591 Just names -> when b (mapM_ (showTypeOfName session) names)
594 io installSignalHandlers
595 b <- isOptionSet RevertCAFs
596 io (when b revertCAFs)
599 showTypeOfName :: Session -> Name -> GHCi ()
600 showTypeOfName session n
601 = do maybe_tything <- io (GHC.lookupName session n)
602 case maybe_tything of
604 Just thing -> showTyThing thing
606 showForUser :: SDoc -> GHCi String
608 session <- getSession
609 unqual <- io (GHC.getPrintUnqual session)
610 return $! showSDocForUser unqual doc
612 specialCommand :: String -> GHCi Bool
613 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
614 specialCommand str = do
615 let (cmd,rest) = break isSpace str
616 maybe_cmd <- io (lookupCommand cmd)
618 Nothing -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
619 ++ shortHelpText) >> return False)
620 Just (_,f,_,_) -> f (dropWhile isSpace rest)
622 lookupCommand :: String -> IO (Maybe Command)
623 lookupCommand str = do
624 cmds <- readIORef commands
625 -- look for exact match first, then the first prefix match
626 case [ c | c <- cmds, str == cmdName c ] of
627 c:_ -> return (Just c)
628 [] -> case [ c | c@(s,_,_,_) <- cmds, prefixMatch str s ] of
630 c:_ -> return (Just c)
632 -----------------------------------------------------------------------------
633 -- To flush buffers for the *interpreted* computation we need
634 -- to refer to *its* stdout/stderr handles
636 GLOBAL_VAR(flush_interp, error "no flush_interp", IO ())
637 GLOBAL_VAR(turn_off_buffering, error "no flush_stdout", IO ())
639 no_buf_cmd = "System.IO.hSetBuffering System.IO.stdout System.IO.NoBuffering" ++
640 " Prelude.>> System.IO.hSetBuffering System.IO.stderr System.IO.NoBuffering"
641 flush_cmd = "System.IO.hFlush System.IO.stdout Prelude.>> System.IO.hFlush IO.stderr"
643 initInterpBuffering :: Session -> IO ()
644 initInterpBuffering session
645 = do maybe_hval <- GHC.compileExpr session no_buf_cmd
648 Just hval -> writeIORef turn_off_buffering (unsafeCoerce# hval :: IO ())
649 other -> panic "interactiveUI:setBuffering"
651 maybe_hval <- GHC.compileExpr session flush_cmd
653 Just hval -> writeIORef flush_interp (unsafeCoerce# hval :: IO ())
654 _ -> panic "interactiveUI:flush"
659 flushInterpBuffers :: GHCi ()
661 = io $ do Monad.join (readIORef flush_interp)
664 turnOffBuffering :: IO ()
666 = do Monad.join (readIORef turn_off_buffering)
669 -----------------------------------------------------------------------------
672 help :: String -> GHCi ()
673 help _ = io (putStr helpText)
675 info :: String -> GHCi ()
676 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
677 info s = do { let names = words s
678 ; session <- getSession
679 ; dflags <- getDynFlags
680 ; let exts = dopt Opt_GlasgowExts dflags
681 ; mapM_ (infoThing exts session) names }
683 infoThing exts session str = io $ do
684 names <- GHC.parseName session str
685 let filtered = filterOutChildren names
686 mb_stuffs <- mapM (GHC.getInfo session) filtered
687 unqual <- GHC.getPrintUnqual session
688 putStrLn (showSDocForUser unqual $
689 vcat (intersperse (text "") $
690 [ pprInfo exts stuff | Just stuff <- mb_stuffs ]))
692 -- Filter out names whose parent is also there Good
693 -- example is '[]', which is both a type and data
694 -- constructor in the same type
695 filterOutChildren :: [Name] -> [Name]
696 filterOutChildren names = filter (not . parent_is_there) names
697 where parent_is_there n
698 | Just p <- GHC.nameParent_maybe n = p `elem` names
701 pprInfo exts (thing, fixity, insts)
702 = pprTyThingInContextLoc exts thing
703 $$ show_fixity fixity
704 $$ vcat (map GHC.pprInstance insts)
707 | fix == GHC.defaultFixity = empty
708 | otherwise = ppr fix <+> ppr (GHC.getName thing)
710 -----------------------------------------------------------------------------
713 runMain :: String -> GHCi ()
715 let ss = concat $ intersperse "," (map (\ s -> ('"':s)++"\"") (toArgs args))
716 runCommand $ '[': ss ++ "] `System.Environment.withArgs` main"
719 addModule :: [FilePath] -> GHCi ()
721 io (revertCAFs) -- always revert CAFs on load/add.
722 files <- mapM expandPath files
723 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
724 session <- getSession
725 io (mapM_ (GHC.addTarget session) targets)
726 ok <- io (GHC.load session LoadAllTargets)
729 changeDirectory :: String -> GHCi ()
730 changeDirectory dir = do
731 session <- getSession
732 graph <- io (GHC.getModuleGraph session)
733 when (not (null graph)) $
734 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
735 io (GHC.setTargets session [])
736 io (GHC.load session LoadAllTargets)
737 setContextAfterLoad session []
738 io (GHC.workingDirectoryChanged session)
739 dir <- expandPath dir
740 io (setCurrentDirectory dir)
742 defineMacro :: String -> GHCi ()
744 let (macro_name, definition) = break isSpace s
745 cmds <- io (readIORef commands)
747 then throwDyn (CmdLineError "invalid macro name")
749 if (macro_name `elem` map cmdName cmds)
750 then throwDyn (CmdLineError
751 ("command '" ++ macro_name ++ "' is already defined"))
754 -- give the expression a type signature, so we can be sure we're getting
755 -- something of the right type.
756 let new_expr = '(' : definition ++ ") :: String -> IO String"
758 -- compile the expression
760 maybe_hv <- io (GHC.compileExpr cms new_expr)
763 Just hv -> io (writeIORef commands --
764 (cmds ++ [(macro_name, runMacro hv, False, completeNone)]))
766 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
768 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
769 stringLoop (lines str)
771 undefineMacro :: String -> GHCi ()
772 undefineMacro macro_name = do
773 cmds <- io (readIORef commands)
774 if (macro_name `elem` map cmdName builtin_commands)
775 then throwDyn (CmdLineError
776 ("command '" ++ macro_name ++ "' cannot be undefined"))
778 if (macro_name `notElem` map cmdName cmds)
779 then throwDyn (CmdLineError
780 ("command '" ++ macro_name ++ "' not defined"))
782 io (writeIORef commands (filter ((/= macro_name) . cmdName) cmds))
785 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
786 loadModule fs = timeIt (loadModule' fs)
788 loadModule_ :: [FilePath] -> GHCi ()
789 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
791 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
792 loadModule' files = do
793 session <- getSession
796 io (GHC.setTargets session [])
797 io (GHC.load session LoadAllTargets)
800 let (filenames, phases) = unzip files
801 exp_filenames <- mapM expandPath filenames
802 let files' = zip exp_filenames phases
803 targets <- io (mapM (uncurry GHC.guessTarget) files')
805 -- NOTE: we used to do the dependency anal first, so that if it
806 -- fails we didn't throw away the current set of modules. This would
807 -- require some re-working of the GHC interface, so we'll leave it
808 -- as a ToDo for now.
810 io (GHC.setTargets session targets)
811 ok <- io (GHC.load session LoadAllTargets)
815 checkModule :: String -> GHCi ()
817 let modl = GHC.mkModuleName m
818 session <- getSession
819 result <- io (GHC.checkModule session modl)
821 Nothing -> io $ putStrLn "Nothing"
822 Just r -> io $ putStrLn (showSDoc (
823 case checkedModuleInfo r of
824 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
826 (local,global) = partition ((== modl) . GHC.moduleName . GHC.nameModule) scope
828 (text "global names: " <+> ppr global) $$
829 (text "local names: " <+> ppr local)
831 afterLoad (successIf (isJust result)) session
833 reloadModule :: String -> GHCi ()
835 io (revertCAFs) -- always revert CAFs on reload.
836 session <- getSession
837 ok <- io (GHC.load session LoadAllTargets)
840 io (revertCAFs) -- always revert CAFs on reload.
841 session <- getSession
842 ok <- io (GHC.load session (LoadUpTo (GHC.mkModuleName m)))
845 afterLoad ok session = do
846 io (revertCAFs) -- always revert CAFs on load.
847 graph <- io (GHC.getModuleGraph session)
848 graph' <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph
849 setContextAfterLoad session graph'
850 modulesLoadedMsg ok (map GHC.ms_mod_name graph')
851 #if defined(GHCI) && defined(BREAKPOINT)
852 io (extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
853 ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))])
856 setContextAfterLoad session [] = do
857 prel_mod <- getPrelude
858 io (GHC.setContext session [] [prel_mod])
859 setContextAfterLoad session ms = do
860 -- load a target if one is available, otherwise load the topmost module.
861 targets <- io (GHC.getTargets session)
862 case [ m | Just m <- map (findTarget ms) targets ] of
864 let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in
865 load_this (last graph')
870 = case filter (`matches` t) ms of
874 summary `matches` Target (TargetModule m) _
875 = GHC.ms_mod_name summary == m
876 summary `matches` Target (TargetFile f _) _
877 | Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
878 summary `matches` target
881 load_this summary | m <- GHC.ms_mod summary = do
882 b <- io (GHC.moduleIsInterpreted session m)
883 if b then io (GHC.setContext session [m] [])
885 prel_mod <- getPrelude
886 io (GHC.setContext session [] [prel_mod,m])
889 modulesLoadedMsg :: SuccessFlag -> [ModuleName] -> GHCi ()
890 modulesLoadedMsg ok mods = do
891 dflags <- getDynFlags
892 when (verbosity dflags > 0) $ do
894 | null mods = text "none."
896 punctuate comma (map ppr mods)) <> text "."
899 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
901 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
904 typeOfExpr :: String -> GHCi ()
906 = do cms <- getSession
907 maybe_ty <- io (GHC.exprType cms str)
910 Just ty -> do ty' <- cleanType ty
911 tystr <- showForUser (ppr ty')
912 io (putStrLn (str ++ " :: " ++ tystr))
914 kindOfType :: String -> GHCi ()
916 = do cms <- getSession
917 maybe_ty <- io (GHC.typeKind cms str)
920 Just ty -> do tystr <- showForUser (ppr ty)
921 io (putStrLn (str ++ " :: " ++ tystr))
923 quit :: String -> GHCi Bool
926 shellEscape :: String -> GHCi Bool
927 shellEscape str = io (system str >> return False)
929 -----------------------------------------------------------------------------
930 -- create tags file for currently loaded modules.
932 createETagsFileCmd, createCTagsFileCmd :: String -> GHCi ()
934 createCTagsFileCmd "" = ghciCreateTagsFile CTags "tags"
935 createCTagsFileCmd file = ghciCreateTagsFile CTags file
937 createETagsFileCmd "" = ghciCreateTagsFile ETags "TAGS"
938 createETagsFileCmd file = ghciCreateTagsFile ETags file
940 data TagsKind = ETags | CTags
942 ghciCreateTagsFile :: TagsKind -> FilePath -> GHCi ()
943 ghciCreateTagsFile kind file = do
944 session <- getSession
945 io $ createTagsFile session kind file
948 -- - remove restriction that all modules must be interpreted
949 -- (problem: we don't know source locations for entities unless
950 -- we compiled the module.
952 -- - extract createTagsFile so it can be used from the command-line
953 -- (probably need to fix first problem before this is useful).
955 createTagsFile :: Session -> TagsKind -> FilePath -> IO ()
956 createTagsFile session tagskind tagFile = do
957 graph <- GHC.getModuleGraph session
958 let ms = map GHC.ms_mod graph
960 is_interpreted <- GHC.moduleIsInterpreted session m
961 -- should we just skip these?
962 when (not is_interpreted) $
963 throwDyn (CmdLineError ("module '"
964 ++ GHC.moduleNameString (GHC.moduleName m)
965 ++ "' is not interpreted"))
966 mbModInfo <- GHC.getModuleInfo session m
968 | Just modinfo <- mbModInfo,
969 Just unqual <- GHC.modInfoPrintUnqualified modinfo = unqual
970 | otherwise = GHC.alwaysQualify
973 Just modInfo -> return $! listTags unqual modInfo
976 mtags <- mapM tagModule ms
977 either_res <- collateAndWriteTags tagskind tagFile $ concat mtags
979 Left e -> hPutStrLn stderr $ ioeGetErrorString e
982 listTags :: PrintUnqualified -> GHC.ModuleInfo -> [TagInfo]
983 listTags unqual modInfo =
984 [ tagInfo unqual name loc
985 | name <- GHC.modInfoExports modInfo
986 , let loc = nameSrcLoc name
990 type TagInfo = (String -- tag name
993 ,Int -- column number
996 -- get tag info, for later translation into Vim or Emacs style
997 tagInfo :: PrintUnqualified -> Name -> SrcLoc -> TagInfo
998 tagInfo unqual name loc
999 = ( showSDocForUser unqual $ pprOccName (nameOccName name)
1000 , showSDocForUser unqual $ ftext (srcLocFile loc)
1005 collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
1006 collateAndWriteTags CTags file tagInfos = do -- ctags style, Vim et al
1007 let tags = unlines $ sortLe (<=) $ nub $ map showTag tagInfos
1008 IO.try (writeFile file tags)
1009 collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
1010 let byFile op (_,f1,_,_) (_,f2,_,_) = f1 `op` f2
1011 groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
1012 tagGroups <- mapM tagFileGroup groups
1013 IO.try (writeFile file $ concat tagGroups)
1015 tagFileGroup group@[] = throwDyn (CmdLineError "empty tag file group??")
1016 tagFileGroup group@((_,fileName,_,_):_) = do
1017 file <- readFile fileName -- need to get additional info from sources..
1018 let byLine (_,_,l1,_) (_,_,l2,_) = l1 <= l2
1019 sortedGroup = sortLe byLine group
1020 tags = unlines $ perFile sortedGroup 1 0 $ lines file
1021 return $ "\x0c\n" ++ fileName ++ "," ++ show (length tags) ++ "\n" ++ tags
1022 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos (line:lines) | lNo>count =
1023 perFile (tagInfo:tags) (count+1) (pos+length line) lines
1024 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos lines@(line:_) | lNo==count =
1025 showETag tagInfo line pos : perFile tags count pos lines
1026 perFile tags count pos lines = []
1028 -- simple ctags format, for Vim et al
1029 showTag :: TagInfo -> String
1030 showTag (tag,file,lineNo,colNo)
1031 = tag ++ "\t" ++ file ++ "\t" ++ show lineNo
1033 -- etags format, for Emacs/XEmacs
1034 showETag :: TagInfo -> String -> Int -> String
1035 showETag (tag,file,lineNo,colNo) line charPos
1036 = take colNo line ++ tag
1038 ++ "\x01" ++ show lineNo
1039 ++ "," ++ show charPos
1041 -----------------------------------------------------------------------------
1042 -- Browsing a module's contents
1044 browseCmd :: String -> GHCi ()
1047 ['*':m] | looksLikeModuleName m -> browseModule m False
1048 [m] | looksLikeModuleName m -> browseModule m True
1049 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
1051 browseModule m exports_only = do
1053 modl <- io $ GHC.findModule s (GHC.mkModuleName m) Nothing
1054 is_interpreted <- io (GHC.moduleIsInterpreted s modl)
1055 when (not is_interpreted && not exports_only) $
1056 throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
1058 -- Temporarily set the context to the module we're interested in,
1059 -- just so we can get an appropriate PrintUnqualified
1060 (as,bs) <- io (GHC.getContext s)
1061 prel_mod <- getPrelude
1062 io (if exports_only then GHC.setContext s [] [prel_mod,modl]
1063 else GHC.setContext s [modl] [])
1064 unqual <- io (GHC.getPrintUnqual s)
1065 io (GHC.setContext s as bs)
1067 mb_mod_info <- io $ GHC.getModuleInfo s modl
1069 Nothing -> throwDyn (CmdLineError ("unknown module: " ++ m))
1072 | exports_only = GHC.modInfoExports mod_info
1073 | otherwise = fromMaybe [] (GHC.modInfoTopLevelScope mod_info)
1075 filtered = filterOutChildren names
1077 things <- io $ mapM (GHC.lookupName s) filtered
1079 dflags <- getDynFlags
1080 let exts = dopt Opt_GlasgowExts dflags
1081 io (putStrLn (showSDocForUser unqual (
1082 vcat (map (pprTyThingInContext exts) (catMaybes things))
1084 -- ToDo: modInfoInstances currently throws an exception for
1085 -- package modules. When it works, we can do this:
1086 -- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
1088 -----------------------------------------------------------------------------
1089 -- Setting the module context
1092 | all sensible mods = fn mods
1093 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
1095 (fn, mods) = case str of
1096 '+':stuff -> (addToContext, words stuff)
1097 '-':stuff -> (removeFromContext, words stuff)
1098 stuff -> (newContext, words stuff)
1100 sensible ('*':m) = looksLikeModuleName m
1101 sensible m = looksLikeModuleName m
1103 separate :: Session -> [String] -> [Module] -> [Module]
1104 -> GHCi ([Module],[Module])
1105 separate session [] as bs = return (as,bs)
1106 separate session (('*':str):ms) as bs = do
1107 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1108 b <- io $ GHC.moduleIsInterpreted session m
1109 if b then separate session ms (m:as) bs
1110 else throwDyn (CmdLineError ("module '"
1111 ++ GHC.moduleNameString (GHC.moduleName m)
1112 ++ "' is not interpreted"))
1113 separate session (str:ms) as bs = do
1114 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1115 separate session ms as (m:bs)
1117 newContext :: [String] -> GHCi ()
1118 newContext strs = do
1120 (as,bs) <- separate s strs [] []
1121 prel_mod <- getPrelude
1122 let bs' = if null as && prel_mod `notElem` bs then prel_mod:bs else bs
1123 io $ GHC.setContext s as bs'
1126 addToContext :: [String] -> GHCi ()
1127 addToContext strs = do
1129 (as,bs) <- io $ GHC.getContext s
1131 (new_as,new_bs) <- separate s strs [] []
1133 let as_to_add = new_as \\ (as ++ bs)
1134 bs_to_add = new_bs \\ (as ++ bs)
1136 io $ GHC.setContext s (as ++ as_to_add) (bs ++ bs_to_add)
1139 removeFromContext :: [String] -> GHCi ()
1140 removeFromContext strs = do
1142 (as,bs) <- io $ GHC.getContext s
1144 (as_to_remove,bs_to_remove) <- separate s strs [] []
1146 let as' = as \\ (as_to_remove ++ bs_to_remove)
1147 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1149 io $ GHC.setContext s as' bs'
1151 ----------------------------------------------------------------------------
1154 -- set options in the interpreter. Syntax is exactly the same as the
1155 -- ghc command line, except that certain options aren't available (-C,
1158 -- This is pretty fragile: most options won't work as expected. ToDo:
1159 -- figure out which ones & disallow them.
1161 setCmd :: String -> GHCi ()
1163 = do st <- getGHCiState
1164 let opts = options st
1165 io $ putStrLn (showSDoc (
1166 text "options currently set: " <>
1169 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1173 ("args":args) -> setArgs args
1174 ("prog":prog) -> setProg prog
1175 ("prompt":prompt) -> setPrompt (dropWhile isSpace $ drop 6 $ dropWhile isSpace str)
1176 wds -> setOptions wds
1180 setGHCiState st{ args = args }
1184 setGHCiState st{ progname = prog }
1186 io (hPutStrLn stderr "syntax: :set prog <progname>")
1188 setPrompt value = do
1191 then io $ hPutStrLn stderr $ "syntax: :set prompt <prompt>, currently \"" ++ prompt st ++ "\""
1192 else setGHCiState st{ prompt = remQuotes value }
1194 remQuotes ('\"':xs) | not (null xs) && last xs == '\"' = init xs
1198 do -- first, deal with the GHCi opts (+s, +t, etc.)
1199 let (plus_opts, minus_opts) = partition isPlus wds
1200 mapM_ setOpt plus_opts
1202 -- then, dynamic flags
1203 dflags <- getDynFlags
1204 let pkg_flags = packageFlags dflags
1205 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1207 if (not (null leftovers))
1208 then throwDyn (CmdLineError ("unrecognised flags: " ++
1212 new_pkgs <- setDynFlags dflags'
1214 -- if the package flags changed, we should reset the context
1215 -- and link the new packages.
1216 dflags <- getDynFlags
1217 when (packageFlags dflags /= pkg_flags) $ do
1218 io $ hPutStrLn stderr "package flags have changed, ressetting and loading new packages..."
1219 session <- getSession
1220 io (GHC.setTargets session [])
1221 io (GHC.load session LoadAllTargets)
1222 io (linkPackages dflags new_pkgs)
1223 setContextAfterLoad session []
1227 unsetOptions :: String -> GHCi ()
1229 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1230 let opts = words str
1231 (minus_opts, rest1) = partition isMinus opts
1232 (plus_opts, rest2) = partition isPlus rest1
1234 if (not (null rest2))
1235 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1238 mapM_ unsetOpt plus_opts
1240 -- can't do GHC flags for now
1241 if (not (null minus_opts))
1242 then throwDyn (CmdLineError "can't unset GHC command-line flags")
1245 isMinus ('-':s) = True
1248 isPlus ('+':s) = True
1252 = case strToGHCiOpt str of
1253 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1254 Just o -> setOption o
1257 = case strToGHCiOpt str of
1258 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1259 Just o -> unsetOption o
1261 strToGHCiOpt :: String -> (Maybe GHCiOption)
1262 strToGHCiOpt "s" = Just ShowTiming
1263 strToGHCiOpt "t" = Just ShowType
1264 strToGHCiOpt "r" = Just RevertCAFs
1265 strToGHCiOpt _ = Nothing
1267 optToStr :: GHCiOption -> String
1268 optToStr ShowTiming = "s"
1269 optToStr ShowType = "t"
1270 optToStr RevertCAFs = "r"
1272 -- ---------------------------------------------------------------------------
1277 ["modules" ] -> showModules
1278 ["bindings"] -> showBindings
1279 ["linker"] -> io showLinkerState
1280 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
1283 session <- getSession
1284 let show_one ms = do m <- io (GHC.showModule session ms)
1286 graph <- io (GHC.getModuleGraph session)
1287 mapM_ show_one graph
1291 unqual <- io (GHC.getPrintUnqual s)
1292 bindings <- io (GHC.getBindings s)
1293 mapM_ showTyThing bindings
1296 showTyThing (AnId id) = do
1297 ty' <- cleanType (GHC.idType id)
1298 str <- showForUser (ppr id <> text " :: " <> ppr ty')
1300 showTyThing _ = return ()
1302 -- if -fglasgow-exts is on we show the foralls, otherwise we don't.
1303 cleanType :: Type -> GHCi Type
1305 dflags <- getDynFlags
1306 if dopt Opt_GlasgowExts dflags
1308 else return $! GHC.dropForAlls ty
1310 -- -----------------------------------------------------------------------------
1313 completeNone :: String -> IO [String]
1314 completeNone w = return []
1317 completeWord :: String -> Int -> Int -> IO (Maybe (String, [String]))
1318 completeWord w start end = do
1319 line <- Readline.getLineBuffer
1321 ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w
1323 | Just c <- is_cmd line -> do
1324 maybe_cmd <- lookupCommand c
1325 let (n,w') = selectWord (words' 0 line)
1327 Nothing -> return Nothing
1328 Just (_,_,False,complete) -> wrapCompleter complete w
1329 Just (_,_,True,complete) -> let complete' w = do rets <- complete w
1330 return (map (drop n) rets)
1331 in wrapCompleter complete' w'
1333 --printf "complete %s, start = %d, end = %d\n" w start end
1334 wrapCompleter completeIdentifier w
1335 where words' _ [] = []
1336 words' n str = let (w,r) = break isSpace str
1337 (s,r') = span isSpace r
1338 in (n,w):words' (n+length w+length s) r'
1339 -- In a Haskell expression we want to parse 'a-b' as three words
1340 -- where a compiler flag (ie. -fno-monomorphism-restriction) should
1341 -- only be a single word.
1342 selectWord [] = (0,w)
1343 selectWord ((offset,x):xs)
1344 | offset+length x >= start = (start-offset,take (end-offset) x)
1345 | otherwise = selectWord xs
1348 | ((':':w) : _) <- words (dropWhile isSpace line) = Just w
1349 | otherwise = Nothing
1352 cmds <- readIORef commands
1353 return (filter (w `isPrefixOf`) (map (':':) (map cmdName cmds)))
1355 completeMacro w = do
1356 cmds <- readIORef commands
1357 let cmds' = [ cmd | cmd <- map cmdName cmds, cmd `elem` map cmdName builtin_commands ]
1358 return (filter (w `isPrefixOf`) cmds')
1360 completeIdentifier w = do
1362 rdrs <- GHC.getRdrNamesInScope s
1363 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
1365 completeModule w = do
1367 dflags <- GHC.getSessionDynFlags s
1368 let pkg_mods = allExposedModules dflags
1369 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) pkg_mods))
1371 completeHomeModule w = do
1373 g <- GHC.getModuleGraph s
1374 let home_mods = map GHC.ms_mod_name g
1375 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) home_mods))
1377 completeSetOptions w = do
1378 return (filter (w `isPrefixOf`) options)
1379 where options = "args":"prog":allFlags
1381 completeFilename = Readline.filenameCompletionFunction
1383 completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
1385 unionComplete :: (String -> IO [String]) -> (String -> IO [String]) -> String -> IO [String]
1386 unionComplete f1 f2 w = do
1391 wrapCompleter :: (String -> IO [String]) -> String -> IO (Maybe (String,[String]))
1392 wrapCompleter fun w = do
1395 [] -> return Nothing
1396 [x] -> return (Just (x,[]))
1397 xs -> case getCommonPrefix xs of
1398 "" -> return (Just ("",xs))
1399 pref -> return (Just (pref,xs))
1401 getCommonPrefix :: [String] -> String
1402 getCommonPrefix [] = ""
1403 getCommonPrefix (s:ss) = foldl common s ss
1404 where common s "" = s
1406 common (c:cs) (d:ds)
1407 | c == d = c : common cs ds
1410 allExposedModules :: DynFlags -> [ModuleName]
1411 allExposedModules dflags
1412 = map GHC.mkModuleName (concat (map exposedModules (filter exposed (eltsUFM pkg_db))))
1414 pkg_db = pkgIdMap (pkgState dflags)
1416 completeCmd = completeNone
1417 completeMacro = completeNone
1418 completeIdentifier = completeNone
1419 completeModule = completeNone
1420 completeHomeModule = completeNone
1421 completeSetOptions = completeNone
1422 completeFilename = completeNone
1423 completeHomeModuleOrFile=completeNone
1426 -----------------------------------------------------------------------------
1429 data GHCiState = GHCiState
1434 session :: GHC.Session,
1435 options :: [GHCiOption],
1440 = ShowTiming -- show time/allocs after evaluation
1441 | ShowType -- show the type of expressions
1442 | RevertCAFs -- revert CAFs after every evaluation
1445 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
1447 startGHCi :: GHCi a -> GHCiState -> IO a
1448 startGHCi g state = do ref <- newIORef state; unGHCi g ref
1450 instance Monad GHCi where
1451 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
1452 return a = GHCi $ \s -> return a
1454 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
1455 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
1456 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
1458 getGHCiState = GHCi $ \r -> readIORef r
1459 setGHCiState s = GHCi $ \r -> writeIORef r s
1461 -- for convenience...
1462 getSession = getGHCiState >>= return . session
1463 getPrelude = getGHCiState >>= return . prelude
1465 GLOBAL_VAR(saved_sess, no_saved_sess, Session)
1466 no_saved_sess = error "no saved_ses"
1467 saveSession = getSession >>= io . writeIORef saved_sess
1468 splatSavedSession = io (writeIORef saved_sess no_saved_sess)
1469 restoreSession = readIORef saved_sess
1473 io (GHC.getSessionDynFlags s)
1474 setDynFlags dflags = do
1476 io (GHC.setSessionDynFlags s dflags)
1478 isOptionSet :: GHCiOption -> GHCi Bool
1480 = do st <- getGHCiState
1481 return (opt `elem` options st)
1483 setOption :: GHCiOption -> GHCi ()
1485 = do st <- getGHCiState
1486 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1488 unsetOption :: GHCiOption -> GHCi ()
1490 = do st <- getGHCiState
1491 setGHCiState (st{ options = filter (/= opt) (options st) })
1493 io :: IO a -> GHCi a
1494 io m = GHCi { unGHCi = \s -> m >>= return }
1496 -----------------------------------------------------------------------------
1497 -- recursive exception handlers
1499 -- Don't forget to unblock async exceptions in the handler, or if we're
1500 -- in an exception loop (eg. let a = error a in a) the ^C exception
1501 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1503 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1504 ghciHandle h (GHCi m) = GHCi $ \s ->
1505 Exception.catch (m s)
1506 (\e -> unGHCi (ghciUnblock (h e)) s)
1508 ghciUnblock :: GHCi a -> GHCi a
1509 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1511 -----------------------------------------------------------------------------
1512 -- timing & statistics
1514 timeIt :: GHCi a -> GHCi a
1516 = do b <- isOptionSet ShowTiming
1519 else do allocs1 <- io $ getAllocations
1520 time1 <- io $ getCPUTime
1522 allocs2 <- io $ getAllocations
1523 time2 <- io $ getCPUTime
1524 io $ printTimes (fromIntegral (allocs2 - allocs1))
1528 foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
1529 -- defined in ghc/rts/Stats.c
1531 printTimes :: Integer -> Integer -> IO ()
1532 printTimes allocs psecs
1533 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1534 secs_str = showFFloat (Just 2) secs
1535 putStrLn (showSDoc (
1536 parens (text (secs_str "") <+> text "secs" <> comma <+>
1537 text (show allocs) <+> text "bytes")))
1539 -----------------------------------------------------------------------------
1546 -- Have to turn off buffering again, because we just
1547 -- reverted stdout, stderr & stdin to their defaults.
1549 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1550 -- Make it "safe", just in case
1552 -- ----------------------------------------------------------------------------
1555 expandPath :: String -> GHCi String
1557 case dropWhile isSpace path of
1559 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1560 return (tilde ++ '/':d)
1564 -- ----------------------------------------------------------------------------
1565 -- Windows console setup
1567 setUpConsole :: IO ()
1569 #ifdef mingw32_HOST_OS
1570 -- On Windows we need to set a known code page, otherwise the characters
1571 -- we read from the console will be be in some strange encoding, and
1572 -- similarly for characters we write to the console.
1574 -- At the moment, GHCi pretends all input is Latin-1. In the
1575 -- future we should support UTF-8, but for now we set the code pages
1578 -- It seems you have to set the font in the console window to
1579 -- a Unicode font in order for output to work properly,
1580 -- otherwise non-ASCII characters are mapped wrongly. sigh.
1581 -- (see MSDN for SetConsoleOutputCP()).
1583 setConsoleCP 28591 -- ISO Latin-1
1584 setConsoleOutputCP 28591 -- ISO Latin-1