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 ("e", keepGoing editFile, False, completeFilename),
127 -- Hugs users are accustomed to :e, so make sure it doesn't overlap
128 ("edit", keepGoing editFile, False, completeFilename),
129 ("help", keepGoing help, False, completeNone),
130 ("?", keepGoing help, False, completeNone),
131 ("info", keepGoing info, False, completeIdentifier),
132 ("load", keepGoingPaths loadModule_, False, completeHomeModuleOrFile),
133 ("module", keepGoing setContext, False, completeModule),
134 ("main", keepGoing runMain, False, completeIdentifier),
135 ("reload", keepGoing reloadModule, False, completeNone),
136 ("check", keepGoing checkModule, False, completeHomeModule),
137 ("set", keepGoing setCmd, True, completeSetOptions),
138 ("show", keepGoing showCmd, False, completeNone),
139 ("etags", keepGoing createETagsFileCmd, False, completeFilename),
140 ("ctags", keepGoing createCTagsFileCmd, False, completeFilename),
141 ("type", keepGoing typeOfExpr, False, completeIdentifier),
142 ("kind", keepGoing kindOfType, False, completeIdentifier),
143 ("unset", keepGoing unsetOptions, True, completeSetOptions),
144 ("undef", keepGoing undefineMacro, False, completeMacro),
145 ("quit", quit, False, completeNone)
148 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
149 keepGoing a str = a str >> return False
151 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
152 keepGoingPaths a str = a (toArgs str) >> return False
154 shortHelpText = "use :? for help.\n"
156 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
158 " Commands available from the prompt:\n" ++
160 " <stmt> evaluate/run <stmt>\n" ++
161 " :add <filename> ... add module(s) to the current target set\n" ++
162 " :browse [*]<module> display the names defined by <module>\n" ++
163 " :cd <dir> change directory to <dir>\n" ++
164 " :def <cmd> <expr> define a command :<cmd>\n" ++
165 " :edit <file> edit file\n" ++
166 " :edit edit last module\n" ++
167 " :help, :? display this list of commands\n" ++
168 " :info [<name> ...] display information about the given names\n" ++
169 " :load <filename> ... load module(s) and their dependents\n" ++
170 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
171 " :main [<arguments> ...] run the main function with the given arguments\n" ++
172 " :reload reload the current module set\n" ++
174 " :set <option> ... set options\n" ++
175 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
176 " :set prog <progname> set the value returned by System.getProgName\n" ++
177 " :set prompt <prompt> set the prompt used in GHCi\n" ++
178 " :set editor <cmd> set the comand used for :edit\n" ++
180 " :show modules show the currently loaded modules\n" ++
181 " :show bindings show the current bindings made at the prompt\n" ++
183 " :ctags [<file>] create tags file for Vi (default: \"tags\")\n" ++
184 " :etags [<file>] create tags file for Emacs (defauilt: \"TAGS\")\n" ++
185 " :type <expr> show the type of <expr>\n" ++
186 " :kind <type> show the kind of <type>\n" ++
187 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
188 " :unset <option> ... unset options\n" ++
189 " :quit exit GHCi\n" ++
190 " :!<command> run the shell command <command>\n" ++
192 " Options for ':set' and ':unset':\n" ++
194 " +r revert top-level expressions after each evaluation\n" ++
195 " +s print timing/memory stats after each evaluation\n" ++
196 " +t print type after evaluation\n" ++
197 " -<flags> most GHC command line flags can also be set here\n" ++
198 " (eg. -v2, -fglasgow-exts, etc.)\n"
201 #if defined(GHCI) && defined(BREAKPOINT)
202 globaliseAndTidy :: Id -> Id
204 -- Give the Id a Global Name, and tidy its type
205 = Id.setIdType (globaliseId VanillaGlobal id) tidy_type
207 tidy_type = tidyTopType (idType id)
210 printScopeMsg :: Session -> String -> [Id] -> IO ()
211 printScopeMsg session location ids
212 = GHC.getPrintUnqual session >>= \unqual ->
213 printForUser stdout unqual $
214 text "Local bindings in scope:" $$
215 nest 2 (pprWithCommas showId ids)
216 where showId id = ppr (idName id) <+> dcolon <+> ppr (idType id)
218 jumpCondFunction :: Session -> Int -> [HValue] -> String -> Bool -> b -> b
219 jumpCondFunction session ptr hValues location True b = b
220 jumpCondFunction session ptr hValues location False b
221 = jumpFunction session ptr hValues location b
223 jumpFunction :: Session -> Int -> [HValue] -> String -> b -> b
224 jumpFunction session@(Session ref) (I# idsPtr) hValues location b
226 do ids <- deRefStablePtr (castPtrToStablePtr (Ptr (int2Addr# idsPtr)))
227 let names = map idName ids
228 ASSERT (length names == length hValues) return ()
229 printScopeMsg session location ids
230 hsc_env <- readIORef ref
232 let ictxt = hsc_IC hsc_env
233 global_ids = map globaliseAndTidy ids
234 rn_env = ic_rn_local_env ictxt
235 type_env = ic_type_env ictxt
236 bound_names = map idName global_ids
237 new_rn_env = extendLocalRdrEnv rn_env bound_names
238 -- Remove any shadowed bindings from the type_env;
239 -- they are inaccessible but might, I suppose, cause
240 -- a space leak if we leave them there
241 shadowed = [ n | name <- bound_names,
242 let rdr_name = mkRdrUnqual (nameOccName name),
243 Just n <- [lookupLocalRdrEnv rn_env rdr_name] ]
244 filtered_type_env = delListFromNameEnv type_env shadowed
245 new_type_env = extendTypeEnvWithIds filtered_type_env global_ids
246 new_ic = ictxt { ic_rn_local_env = new_rn_env,
247 ic_type_env = new_type_env }
248 writeIORef ref (hsc_env { hsc_IC = new_ic })
249 is_tty <- hIsTerminalDevice stdin
250 prel_mod <- GHC.findModule session prel_name Nothing
251 default_editor <- findEditor
252 withExtendedLinkEnv (zip names hValues) $
253 startGHCi (interactiveLoop is_tty True)
254 GHCiState{ progname = "<interactive>",
256 prompt = location++"> ",
257 editor = default_editor,
261 writeIORef ref hsc_env
262 putStrLn $ "Returning to normal execution..."
270 -- ToDo: mingw32_HOST_OS
271 win <- getWindowsDirectory
272 return (win `joinFileName` "notepad.exe")
277 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
278 interactiveUI session srcs maybe_expr = do
279 #if defined(GHCI) && defined(BREAKPOINT)
280 initDynLinker =<< GHC.getSessionDynFlags session
281 extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
282 ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))]
284 -- HACK! If we happen to get into an infinite loop (eg the user
285 -- types 'let x=x in x' at the prompt), then the thread will block
286 -- on a blackhole, and become unreachable during GC. The GC will
287 -- detect that it is unreachable and send it the NonTermination
288 -- exception. However, since the thread is unreachable, everything
289 -- it refers to might be finalized, including the standard Handles.
290 -- This sounds like a bug, but we don't have a good solution right
296 -- Initialise buffering for the *interpreted* I/O system
297 initInterpBuffering session
299 when (isNothing maybe_expr) $ do
300 -- Only for GHCi (not runghc and ghc -e):
301 -- Turn buffering off for the compiled program's stdout/stderr
303 -- Turn buffering off for GHCi's stdout
305 hSetBuffering stdout NoBuffering
306 -- We don't want the cmd line to buffer any input that might be
307 -- intended for the program, so unbuffer stdin.
308 hSetBuffering stdin NoBuffering
310 -- initial context is just the Prelude
311 prel_mod <- GHC.findModule session prel_name Nothing
312 GHC.setContext session [] [prel_mod]
316 Readline.setAttemptedCompletionFunction (Just completeWord)
317 --Readline.parseAndBind "set show-all-if-ambiguous 1"
319 let symbols = "!#$%&*+/<=>?@\\^|-~"
320 specials = "(),;[]`{}"
322 word_break_chars = spaces ++ specials ++ symbols
324 Readline.setBasicWordBreakCharacters word_break_chars
325 Readline.setCompleterWordBreakCharacters word_break_chars
328 default_editor <- findEditor
330 startGHCi (runGHCi srcs maybe_expr)
331 GHCiState{ progname = "<interactive>",
334 editor = default_editor,
340 Readline.resetTerminal Nothing
345 prel_name = GHC.mkModuleName "Prelude"
347 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
348 runGHCi paths maybe_expr = do
349 let read_dot_files = not opt_IgnoreDotGhci
351 when (read_dot_files) $ do
354 exists <- io (doesFileExist file)
356 dir_ok <- io (checkPerms ".")
357 file_ok <- io (checkPerms file)
358 when (dir_ok && file_ok) $ do
359 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
362 Right hdl -> fileLoop hdl False
364 when (read_dot_files) $ do
365 -- Read in $HOME/.ghci
366 either_dir <- io (IO.try (getEnv "HOME"))
370 cwd <- io (getCurrentDirectory)
371 when (dir /= cwd) $ do
372 let file = dir ++ "/.ghci"
373 ok <- io (checkPerms file)
375 either_hdl <- io (IO.try (openFile file ReadMode))
378 Right hdl -> fileLoop hdl False
380 -- Perform a :load for files given on the GHCi command line
381 -- When in -e mode, if the load fails then we want to stop
382 -- immediately rather than going on to evaluate the expression.
383 when (not (null paths)) $ do
384 ok <- ghciHandle (\e -> do showException e; return Failed) $
386 when (isJust maybe_expr && failed ok) $
387 io (exitWith (ExitFailure 1))
389 -- if verbosity is greater than 0, or we are connected to a
390 -- terminal, display the prompt in the interactive loop.
391 is_tty <- io (hIsTerminalDevice stdin)
392 dflags <- getDynFlags
393 let show_prompt = verbosity dflags > 0 || is_tty
398 #if defined(mingw32_HOST_OS)
399 -- The win32 Console API mutates the first character of
400 -- type-ahead when reading from it in a non-buffered manner. Work
401 -- around this by flushing the input buffer of type-ahead characters,
402 -- but only if stdin is available.
403 flushed <- io (IO.try (GHC.ConsoleHandler.flushConsole stdin))
405 Left err | isDoesNotExistError err -> return ()
406 | otherwise -> io (ioError err)
407 Right () -> return ()
409 -- initialise the console if necessary
412 -- enter the interactive loop
413 interactiveLoop is_tty show_prompt
415 -- just evaluate the expression we were given
420 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
423 interactiveLoop is_tty show_prompt =
424 -- Ignore ^C exceptions caught here
425 ghciHandleDyn (\e -> case e of
427 #if defined(mingw32_HOST_OS)
430 interactiveLoop is_tty show_prompt
431 _other -> return ()) $
433 ghciUnblock $ do -- unblock necessary if we recursed from the
434 -- exception handler above.
436 -- read commands from stdin
440 else fileLoop stdin show_prompt
442 fileLoop stdin show_prompt
446 -- NOTE: We only read .ghci files if they are owned by the current user,
447 -- and aren't world writable. Otherwise, we could be accidentally
448 -- running code planted by a malicious third party.
450 -- Furthermore, We only read ./.ghci if . is owned by the current user
451 -- and isn't writable by anyone else. I think this is sufficient: we
452 -- don't need to check .. and ../.. etc. because "." always refers to
453 -- the same directory while a process is running.
455 checkPerms :: String -> IO Bool
457 #ifdef mingw32_HOST_OS
460 Util.handle (\_ -> return False) $ do
461 st <- getFileStatus name
463 if fileOwner st /= me then do
464 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
467 let mode = fileMode st
468 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
469 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
471 putStrLn $ "*** WARNING: " ++ name ++
472 " is writable by someone else, IGNORING!"
477 fileLoop :: Handle -> Bool -> GHCi ()
478 fileLoop hdl show_prompt = do
479 session <- getSession
480 (mod,imports) <- io (GHC.getContext session)
482 when show_prompt (io (putStr (mkPrompt mod imports (prompt st))))
483 l <- io (IO.try (hGetLine hdl))
485 Left e | isEOFError e -> return ()
486 | InvalidArgument <- etype -> return ()
487 | otherwise -> io (ioError e)
488 where etype = ioeGetErrorType e
489 -- treat InvalidArgument in the same way as EOF:
490 -- this can happen if the user closed stdin, or
491 -- perhaps did getContents which closes stdin at
494 case removeSpaces l of
495 "" -> fileLoop hdl show_prompt
496 l -> do quit <- runCommand l
497 if quit then return () else fileLoop hdl show_prompt
499 stringLoop :: [String] -> GHCi Bool{-True: we quit-}
500 stringLoop [] = return False
501 stringLoop (s:ss) = do
502 case removeSpaces s of
504 l -> do quit <- runCommand l
505 if quit then return True else stringLoop ss
507 mkPrompt toplevs exports prompt
508 = showSDoc $ f prompt
510 f ('%':'s':xs) = perc_s <> f xs
511 f ('%':'%':xs) = char '%' <> f xs
512 f (x:xs) = char x <> f xs
515 perc_s = hsep (map (\m -> char '*' <> ppr (GHC.moduleName m)) toplevs) <+>
516 hsep (map (ppr . GHC.moduleName) exports)
520 readlineLoop :: GHCi ()
522 session <- getSession
523 (mod,imports) <- io (GHC.getContext session)
525 saveSession -- for use by completion
527 l <- io (readline (mkPrompt mod imports (prompt st))
528 `finally` setNonBlockingFD 0)
529 -- readline sometimes puts stdin into blocking mode,
530 -- so we need to put it back for the IO library
535 case removeSpaces l of
540 if quit then return () else readlineLoop
543 runCommand :: String -> GHCi Bool
544 runCommand c = ghciHandle handler (doCommand c)
546 doCommand (':' : command) = specialCommand command
548 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
551 -- This version is for the GHC command-line option -e. The only difference
552 -- from runCommand is that it catches the ExitException exception and
553 -- exits, rather than printing out the exception.
554 runCommandEval c = ghciHandle handleEval (doCommand c)
556 handleEval (ExitException code) = io (exitWith code)
557 handleEval e = do handler e
558 io (exitWith (ExitFailure 1))
560 doCommand (':' : command) = specialCommand command
562 = do nms <- runStmt stmt
564 Nothing -> io (exitWith (ExitFailure 1))
565 -- failure to run the command causes exit(1) for ghc -e.
566 _ -> finishEvalExpr nms
568 -- This is the exception handler for exceptions generated by the
569 -- user's code; it normally just prints out the exception. The
570 -- handler must be recursive, in case showing the exception causes
571 -- more exceptions to be raised.
573 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
574 -- raising another exception. We therefore don't put the recursive
575 -- handler arond the flushing operation, so if stderr is closed
576 -- GHCi will just die gracefully rather than going into an infinite loop.
577 handler :: Exception -> GHCi Bool
578 handler exception = do
580 io installSignalHandlers
581 ghciHandle handler (showException exception >> return False)
583 showException (DynException dyn) =
584 case fromDynamic dyn of
585 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
586 Just Interrupted -> io (putStrLn "Interrupted.")
587 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
588 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
589 Just other_ghc_ex -> io (print other_ghc_ex)
591 showException other_exception
592 = io (putStrLn ("*** Exception: " ++ show other_exception))
594 runStmt :: String -> GHCi (Maybe [Name])
596 | null (filter (not.isSpace) stmt) = return (Just [])
598 = do st <- getGHCiState
599 session <- getSession
600 result <- io $ withProgName (progname st) $ withArgs (args st) $
601 GHC.runStmt session stmt
603 GHC.RunFailed -> return Nothing
604 GHC.RunException e -> throw e -- this is caught by runCommand(Eval)
605 GHC.RunOk names -> return (Just names)
607 -- possibly print the type and revert CAFs after evaluating an expression
608 finishEvalExpr mb_names
609 = do b <- isOptionSet ShowType
610 session <- getSession
613 Just names -> when b (mapM_ (showTypeOfName session) names)
616 io installSignalHandlers
617 b <- isOptionSet RevertCAFs
618 io (when b revertCAFs)
621 showTypeOfName :: Session -> Name -> GHCi ()
622 showTypeOfName session n
623 = do maybe_tything <- io (GHC.lookupName session n)
624 case maybe_tything of
626 Just thing -> showTyThing thing
628 showForUser :: SDoc -> GHCi String
630 session <- getSession
631 unqual <- io (GHC.getPrintUnqual session)
632 return $! showSDocForUser unqual doc
634 specialCommand :: String -> GHCi Bool
635 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
636 specialCommand str = do
637 let (cmd,rest) = break isSpace str
638 maybe_cmd <- io (lookupCommand cmd)
640 Nothing -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
641 ++ shortHelpText) >> return False)
642 Just (_,f,_,_) -> f (dropWhile isSpace rest)
644 lookupCommand :: String -> IO (Maybe Command)
645 lookupCommand str = do
646 cmds <- readIORef commands
647 -- look for exact match first, then the first prefix match
648 case [ c | c <- cmds, str == cmdName c ] of
649 c:_ -> return (Just c)
650 [] -> case [ c | c@(s,_,_,_) <- cmds, prefixMatch str s ] of
652 c:_ -> return (Just c)
654 -----------------------------------------------------------------------------
655 -- To flush buffers for the *interpreted* computation we need
656 -- to refer to *its* stdout/stderr handles
658 GLOBAL_VAR(flush_interp, error "no flush_interp", IO ())
659 GLOBAL_VAR(turn_off_buffering, error "no flush_stdout", IO ())
661 no_buf_cmd = "System.IO.hSetBuffering System.IO.stdout System.IO.NoBuffering" ++
662 " Prelude.>> System.IO.hSetBuffering System.IO.stderr System.IO.NoBuffering"
663 flush_cmd = "System.IO.hFlush System.IO.stdout Prelude.>> System.IO.hFlush IO.stderr"
665 initInterpBuffering :: Session -> IO ()
666 initInterpBuffering session
667 = do maybe_hval <- GHC.compileExpr session no_buf_cmd
670 Just hval -> writeIORef turn_off_buffering (unsafeCoerce# hval :: IO ())
671 other -> panic "interactiveUI:setBuffering"
673 maybe_hval <- GHC.compileExpr session flush_cmd
675 Just hval -> writeIORef flush_interp (unsafeCoerce# hval :: IO ())
676 _ -> panic "interactiveUI:flush"
681 flushInterpBuffers :: GHCi ()
683 = io $ do Monad.join (readIORef flush_interp)
686 turnOffBuffering :: IO ()
688 = do Monad.join (readIORef turn_off_buffering)
691 -----------------------------------------------------------------------------
694 help :: String -> GHCi ()
695 help _ = io (putStr helpText)
697 info :: String -> GHCi ()
698 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
699 info s = do { let names = words s
700 ; session <- getSession
701 ; dflags <- getDynFlags
702 ; let exts = dopt Opt_GlasgowExts dflags
703 ; mapM_ (infoThing exts session) names }
705 infoThing exts session str = io $ do
706 names <- GHC.parseName session str
707 let filtered = filterOutChildren names
708 mb_stuffs <- mapM (GHC.getInfo session) filtered
709 unqual <- GHC.getPrintUnqual session
710 putStrLn (showSDocForUser unqual $
711 vcat (intersperse (text "") $
712 [ pprInfo exts stuff | Just stuff <- mb_stuffs ]))
714 -- Filter out names whose parent is also there Good
715 -- example is '[]', which is both a type and data
716 -- constructor in the same type
717 filterOutChildren :: [Name] -> [Name]
718 filterOutChildren names = filter (not . parent_is_there) names
719 where parent_is_there n
720 | Just p <- GHC.nameParent_maybe n = p `elem` names
723 pprInfo exts (thing, fixity, insts)
724 = pprTyThingInContextLoc exts thing
725 $$ show_fixity fixity
726 $$ vcat (map GHC.pprInstance insts)
729 | fix == GHC.defaultFixity = empty
730 | otherwise = ppr fix <+> ppr (GHC.getName thing)
732 -----------------------------------------------------------------------------
735 runMain :: String -> GHCi ()
737 let ss = concat $ intersperse "," (map (\ s -> ('"':s)++"\"") (toArgs args))
738 runCommand $ '[': ss ++ "] `System.Environment.withArgs` main"
741 addModule :: [FilePath] -> GHCi ()
743 io (revertCAFs) -- always revert CAFs on load/add.
744 files <- mapM expandPath files
745 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
746 session <- getSession
747 io (mapM_ (GHC.addTarget session) targets)
748 ok <- io (GHC.load session LoadAllTargets)
751 changeDirectory :: String -> GHCi ()
752 changeDirectory dir = do
753 session <- getSession
754 graph <- io (GHC.getModuleGraph session)
755 when (not (null graph)) $
756 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
757 io (GHC.setTargets session [])
758 io (GHC.load session LoadAllTargets)
759 setContextAfterLoad session []
760 io (GHC.workingDirectoryChanged session)
761 dir <- expandPath dir
762 io (setCurrentDirectory dir)
764 editFile :: String -> GHCi ()
767 -- find the name of the "topmost" file loaded
768 session <- getSession
769 graph0 <- io (GHC.getModuleGraph session)
770 graph1 <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph0
771 let graph2 = flattenSCCs (GHC.topSortModuleGraph True graph1 Nothing)
772 case GHC.ml_hs_file (GHC.ms_location (last graph2)) of
773 Just file -> do_edit file
774 Nothing -> throwDyn (CmdLineError "unknown file name")
775 | otherwise = do_edit str
781 throwDyn (CmdLineError "editor not set, use :set editor")
782 io $ system (cmd ++ ' ':file)
785 defineMacro :: String -> GHCi ()
787 let (macro_name, definition) = break isSpace s
788 cmds <- io (readIORef commands)
790 then throwDyn (CmdLineError "invalid macro name")
792 if (macro_name `elem` map cmdName cmds)
793 then throwDyn (CmdLineError
794 ("command '" ++ macro_name ++ "' is already defined"))
797 -- give the expression a type signature, so we can be sure we're getting
798 -- something of the right type.
799 let new_expr = '(' : definition ++ ") :: String -> IO String"
801 -- compile the expression
803 maybe_hv <- io (GHC.compileExpr cms new_expr)
806 Just hv -> io (writeIORef commands --
807 (cmds ++ [(macro_name, runMacro hv, False, completeNone)]))
809 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
811 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
812 stringLoop (lines str)
814 undefineMacro :: String -> GHCi ()
815 undefineMacro macro_name = do
816 cmds <- io (readIORef commands)
817 if (macro_name `elem` map cmdName builtin_commands)
818 then throwDyn (CmdLineError
819 ("command '" ++ macro_name ++ "' cannot be undefined"))
821 if (macro_name `notElem` map cmdName cmds)
822 then throwDyn (CmdLineError
823 ("command '" ++ macro_name ++ "' not defined"))
825 io (writeIORef commands (filter ((/= macro_name) . cmdName) cmds))
828 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
829 loadModule fs = timeIt (loadModule' fs)
831 loadModule_ :: [FilePath] -> GHCi ()
832 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
834 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
835 loadModule' files = do
836 session <- getSession
839 io (GHC.setTargets session [])
840 io (GHC.load session LoadAllTargets)
843 let (filenames, phases) = unzip files
844 exp_filenames <- mapM expandPath filenames
845 let files' = zip exp_filenames phases
846 targets <- io (mapM (uncurry GHC.guessTarget) files')
848 -- NOTE: we used to do the dependency anal first, so that if it
849 -- fails we didn't throw away the current set of modules. This would
850 -- require some re-working of the GHC interface, so we'll leave it
851 -- as a ToDo for now.
853 io (GHC.setTargets session targets)
854 ok <- io (GHC.load session LoadAllTargets)
858 checkModule :: String -> GHCi ()
860 let modl = GHC.mkModuleName m
861 session <- getSession
862 result <- io (GHC.checkModule session modl)
864 Nothing -> io $ putStrLn "Nothing"
865 Just r -> io $ putStrLn (showSDoc (
866 case checkedModuleInfo r of
867 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
869 (local,global) = partition ((== modl) . GHC.moduleName . GHC.nameModule) scope
871 (text "global names: " <+> ppr global) $$
872 (text "local names: " <+> ppr local)
874 afterLoad (successIf (isJust result)) session
876 reloadModule :: String -> GHCi ()
878 io (revertCAFs) -- always revert CAFs on reload.
879 session <- getSession
880 ok <- io (GHC.load session LoadAllTargets)
883 io (revertCAFs) -- always revert CAFs on reload.
884 session <- getSession
885 ok <- io (GHC.load session (LoadUpTo (GHC.mkModuleName m)))
888 afterLoad ok session = do
889 io (revertCAFs) -- always revert CAFs on load.
890 graph <- io (GHC.getModuleGraph session)
891 graph' <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph
892 setContextAfterLoad session graph'
893 modulesLoadedMsg ok (map GHC.ms_mod_name graph')
894 #if defined(GHCI) && defined(BREAKPOINT)
895 io (extendLinkEnv [(breakpointJumpName,unsafeCoerce# (jumpFunction session))
896 ,(breakpointCondJumpName,unsafeCoerce# (jumpCondFunction session))])
899 setContextAfterLoad session [] = do
900 prel_mod <- getPrelude
901 io (GHC.setContext session [] [prel_mod])
902 setContextAfterLoad session ms = do
903 -- load a target if one is available, otherwise load the topmost module.
904 targets <- io (GHC.getTargets session)
905 case [ m | Just m <- map (findTarget ms) targets ] of
907 let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in
908 load_this (last graph')
913 = case filter (`matches` t) ms of
917 summary `matches` Target (TargetModule m) _
918 = GHC.ms_mod_name summary == m
919 summary `matches` Target (TargetFile f _) _
920 | Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
921 summary `matches` target
924 load_this summary | m <- GHC.ms_mod summary = do
925 b <- io (GHC.moduleIsInterpreted session m)
926 if b then io (GHC.setContext session [m] [])
928 prel_mod <- getPrelude
929 io (GHC.setContext session [] [prel_mod,m])
932 modulesLoadedMsg :: SuccessFlag -> [ModuleName] -> GHCi ()
933 modulesLoadedMsg ok mods = do
934 dflags <- getDynFlags
935 when (verbosity dflags > 0) $ do
937 | null mods = text "none."
939 punctuate comma (map ppr mods)) <> text "."
942 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
944 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
947 typeOfExpr :: String -> GHCi ()
949 = do cms <- getSession
950 maybe_ty <- io (GHC.exprType cms str)
953 Just ty -> do ty' <- cleanType ty
954 tystr <- showForUser (ppr ty')
955 io (putStrLn (str ++ " :: " ++ tystr))
957 kindOfType :: String -> GHCi ()
959 = do cms <- getSession
960 maybe_ty <- io (GHC.typeKind cms str)
963 Just ty -> do tystr <- showForUser (ppr ty)
964 io (putStrLn (str ++ " :: " ++ tystr))
966 quit :: String -> GHCi Bool
969 shellEscape :: String -> GHCi Bool
970 shellEscape str = io (system str >> return False)
972 -----------------------------------------------------------------------------
973 -- create tags file for currently loaded modules.
975 createETagsFileCmd, createCTagsFileCmd :: String -> GHCi ()
977 createCTagsFileCmd "" = ghciCreateTagsFile CTags "tags"
978 createCTagsFileCmd file = ghciCreateTagsFile CTags file
980 createETagsFileCmd "" = ghciCreateTagsFile ETags "TAGS"
981 createETagsFileCmd file = ghciCreateTagsFile ETags file
983 data TagsKind = ETags | CTags
985 ghciCreateTagsFile :: TagsKind -> FilePath -> GHCi ()
986 ghciCreateTagsFile kind file = do
987 session <- getSession
988 io $ createTagsFile session kind file
991 -- - remove restriction that all modules must be interpreted
992 -- (problem: we don't know source locations for entities unless
993 -- we compiled the module.
995 -- - extract createTagsFile so it can be used from the command-line
996 -- (probably need to fix first problem before this is useful).
998 createTagsFile :: Session -> TagsKind -> FilePath -> IO ()
999 createTagsFile session tagskind tagFile = do
1000 graph <- GHC.getModuleGraph session
1001 let ms = map GHC.ms_mod graph
1003 is_interpreted <- GHC.moduleIsInterpreted session m
1004 -- should we just skip these?
1005 when (not is_interpreted) $
1006 throwDyn (CmdLineError ("module '"
1007 ++ GHC.moduleNameString (GHC.moduleName m)
1008 ++ "' is not interpreted"))
1009 mbModInfo <- GHC.getModuleInfo session m
1011 | Just modinfo <- mbModInfo,
1012 Just unqual <- GHC.modInfoPrintUnqualified modinfo = unqual
1013 | otherwise = GHC.alwaysQualify
1016 Just modInfo -> return $! listTags unqual modInfo
1019 mtags <- mapM tagModule ms
1020 either_res <- collateAndWriteTags tagskind tagFile $ concat mtags
1022 Left e -> hPutStrLn stderr $ ioeGetErrorString e
1023 Right _ -> return ()
1025 listTags :: PrintUnqualified -> GHC.ModuleInfo -> [TagInfo]
1026 listTags unqual modInfo =
1027 [ tagInfo unqual name loc
1028 | name <- GHC.modInfoExports modInfo
1029 , let loc = nameSrcLoc name
1033 type TagInfo = (String -- tag name
1034 ,String -- file name
1036 ,Int -- column number
1039 -- get tag info, for later translation into Vim or Emacs style
1040 tagInfo :: PrintUnqualified -> Name -> SrcLoc -> TagInfo
1041 tagInfo unqual name loc
1042 = ( showSDocForUser unqual $ pprOccName (nameOccName name)
1043 , showSDocForUser unqual $ ftext (srcLocFile loc)
1048 collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
1049 collateAndWriteTags CTags file tagInfos = do -- ctags style, Vim et al
1050 let tags = unlines $ sortLe (<=) $ nub $ map showTag tagInfos
1051 IO.try (writeFile file tags)
1052 collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
1053 let byFile op (_,f1,_,_) (_,f2,_,_) = f1 `op` f2
1054 groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
1055 tagGroups <- mapM tagFileGroup groups
1056 IO.try (writeFile file $ concat tagGroups)
1058 tagFileGroup group@[] = throwDyn (CmdLineError "empty tag file group??")
1059 tagFileGroup group@((_,fileName,_,_):_) = do
1060 file <- readFile fileName -- need to get additional info from sources..
1061 let byLine (_,_,l1,_) (_,_,l2,_) = l1 <= l2
1062 sortedGroup = sortLe byLine group
1063 tags = unlines $ perFile sortedGroup 1 0 $ lines file
1064 return $ "\x0c\n" ++ fileName ++ "," ++ show (length tags) ++ "\n" ++ tags
1065 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos (line:lines) | lNo>count =
1066 perFile (tagInfo:tags) (count+1) (pos+length line) lines
1067 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos lines@(line:_) | lNo==count =
1068 showETag tagInfo line pos : perFile tags count pos lines
1069 perFile tags count pos lines = []
1071 -- simple ctags format, for Vim et al
1072 showTag :: TagInfo -> String
1073 showTag (tag,file,lineNo,colNo)
1074 = tag ++ "\t" ++ file ++ "\t" ++ show lineNo
1076 -- etags format, for Emacs/XEmacs
1077 showETag :: TagInfo -> String -> Int -> String
1078 showETag (tag,file,lineNo,colNo) line charPos
1079 = take colNo line ++ tag
1081 ++ "\x01" ++ show lineNo
1082 ++ "," ++ show charPos
1084 -----------------------------------------------------------------------------
1085 -- Browsing a module's contents
1087 browseCmd :: String -> GHCi ()
1090 ['*':m] | looksLikeModuleName m -> browseModule m False
1091 [m] | looksLikeModuleName m -> browseModule m True
1092 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
1094 browseModule m exports_only = do
1096 modl <- io $ GHC.findModule s (GHC.mkModuleName m) Nothing
1097 is_interpreted <- io (GHC.moduleIsInterpreted s modl)
1098 when (not is_interpreted && not exports_only) $
1099 throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
1101 -- Temporarily set the context to the module we're interested in,
1102 -- just so we can get an appropriate PrintUnqualified
1103 (as,bs) <- io (GHC.getContext s)
1104 prel_mod <- getPrelude
1105 io (if exports_only then GHC.setContext s [] [prel_mod,modl]
1106 else GHC.setContext s [modl] [])
1107 unqual <- io (GHC.getPrintUnqual s)
1108 io (GHC.setContext s as bs)
1110 mb_mod_info <- io $ GHC.getModuleInfo s modl
1112 Nothing -> throwDyn (CmdLineError ("unknown module: " ++ m))
1115 | exports_only = GHC.modInfoExports mod_info
1116 | otherwise = fromMaybe [] (GHC.modInfoTopLevelScope mod_info)
1118 filtered = filterOutChildren names
1120 things <- io $ mapM (GHC.lookupName s) filtered
1122 dflags <- getDynFlags
1123 let exts = dopt Opt_GlasgowExts dflags
1124 io (putStrLn (showSDocForUser unqual (
1125 vcat (map (pprTyThingInContext exts) (catMaybes things))
1127 -- ToDo: modInfoInstances currently throws an exception for
1128 -- package modules. When it works, we can do this:
1129 -- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
1131 -----------------------------------------------------------------------------
1132 -- Setting the module context
1135 | all sensible mods = fn mods
1136 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
1138 (fn, mods) = case str of
1139 '+':stuff -> (addToContext, words stuff)
1140 '-':stuff -> (removeFromContext, words stuff)
1141 stuff -> (newContext, words stuff)
1143 sensible ('*':m) = looksLikeModuleName m
1144 sensible m = looksLikeModuleName m
1146 separate :: Session -> [String] -> [Module] -> [Module]
1147 -> GHCi ([Module],[Module])
1148 separate session [] as bs = return (as,bs)
1149 separate session (('*':str):ms) as bs = do
1150 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1151 b <- io $ GHC.moduleIsInterpreted session m
1152 if b then separate session ms (m:as) bs
1153 else throwDyn (CmdLineError ("module '"
1154 ++ GHC.moduleNameString (GHC.moduleName m)
1155 ++ "' is not interpreted"))
1156 separate session (str:ms) as bs = do
1157 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1158 separate session ms as (m:bs)
1160 newContext :: [String] -> GHCi ()
1161 newContext strs = do
1163 (as,bs) <- separate s strs [] []
1164 prel_mod <- getPrelude
1165 let bs' = if null as && prel_mod `notElem` bs then prel_mod:bs else bs
1166 io $ GHC.setContext s as bs'
1169 addToContext :: [String] -> GHCi ()
1170 addToContext strs = do
1172 (as,bs) <- io $ GHC.getContext s
1174 (new_as,new_bs) <- separate s strs [] []
1176 let as_to_add = new_as \\ (as ++ bs)
1177 bs_to_add = new_bs \\ (as ++ bs)
1179 io $ GHC.setContext s (as ++ as_to_add) (bs ++ bs_to_add)
1182 removeFromContext :: [String] -> GHCi ()
1183 removeFromContext strs = do
1185 (as,bs) <- io $ GHC.getContext s
1187 (as_to_remove,bs_to_remove) <- separate s strs [] []
1189 let as' = as \\ (as_to_remove ++ bs_to_remove)
1190 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1192 io $ GHC.setContext s as' bs'
1194 ----------------------------------------------------------------------------
1197 -- set options in the interpreter. Syntax is exactly the same as the
1198 -- ghc command line, except that certain options aren't available (-C,
1201 -- This is pretty fragile: most options won't work as expected. ToDo:
1202 -- figure out which ones & disallow them.
1204 setCmd :: String -> GHCi ()
1206 = do st <- getGHCiState
1207 let opts = options st
1208 io $ putStrLn (showSDoc (
1209 text "options currently set: " <>
1212 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1215 = case toArgs str of
1216 ("args":args) -> setArgs args
1217 ("prog":prog) -> setProg prog
1218 ("prompt":prompt) -> setPrompt (after 6)
1219 ("editor":cmd) -> setEditor (after 6)
1220 wds -> setOptions wds
1221 where after n = dropWhile isSpace $ drop n $ dropWhile isSpace str
1225 setGHCiState st{ args = args }
1229 setGHCiState st{ progname = prog }
1231 io (hPutStrLn stderr "syntax: :set prog <progname>")
1235 setGHCiState st{ editor = cmd }
1237 setPrompt value = do
1240 then io $ hPutStrLn stderr $ "syntax: :set prompt <prompt>, currently \"" ++ prompt st ++ "\""
1241 else setGHCiState st{ prompt = remQuotes value }
1243 remQuotes ('\"':xs) | not (null xs) && last xs == '\"' = init xs
1247 do -- first, deal with the GHCi opts (+s, +t, etc.)
1248 let (plus_opts, minus_opts) = partition isPlus wds
1249 mapM_ setOpt plus_opts
1251 -- then, dynamic flags
1252 dflags <- getDynFlags
1253 let pkg_flags = packageFlags dflags
1254 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1256 if (not (null leftovers))
1257 then throwDyn (CmdLineError ("unrecognised flags: " ++
1261 new_pkgs <- setDynFlags dflags'
1263 -- if the package flags changed, we should reset the context
1264 -- and link the new packages.
1265 dflags <- getDynFlags
1266 when (packageFlags dflags /= pkg_flags) $ do
1267 io $ hPutStrLn stderr "package flags have changed, ressetting and loading new packages..."
1268 session <- getSession
1269 io (GHC.setTargets session [])
1270 io (GHC.load session LoadAllTargets)
1271 io (linkPackages dflags new_pkgs)
1272 setContextAfterLoad session []
1276 unsetOptions :: String -> GHCi ()
1278 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1279 let opts = words str
1280 (minus_opts, rest1) = partition isMinus opts
1281 (plus_opts, rest2) = partition isPlus rest1
1283 if (not (null rest2))
1284 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1287 mapM_ unsetOpt plus_opts
1289 -- can't do GHC flags for now
1290 if (not (null minus_opts))
1291 then throwDyn (CmdLineError "can't unset GHC command-line flags")
1294 isMinus ('-':s) = True
1297 isPlus ('+':s) = True
1301 = case strToGHCiOpt str of
1302 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1303 Just o -> setOption o
1306 = case strToGHCiOpt str of
1307 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1308 Just o -> unsetOption o
1310 strToGHCiOpt :: String -> (Maybe GHCiOption)
1311 strToGHCiOpt "s" = Just ShowTiming
1312 strToGHCiOpt "t" = Just ShowType
1313 strToGHCiOpt "r" = Just RevertCAFs
1314 strToGHCiOpt _ = Nothing
1316 optToStr :: GHCiOption -> String
1317 optToStr ShowTiming = "s"
1318 optToStr ShowType = "t"
1319 optToStr RevertCAFs = "r"
1321 -- ---------------------------------------------------------------------------
1326 ["modules" ] -> showModules
1327 ["bindings"] -> showBindings
1328 ["linker"] -> io showLinkerState
1329 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
1332 session <- getSession
1333 let show_one ms = do m <- io (GHC.showModule session ms)
1335 graph <- io (GHC.getModuleGraph session)
1336 mapM_ show_one graph
1340 unqual <- io (GHC.getPrintUnqual s)
1341 bindings <- io (GHC.getBindings s)
1342 mapM_ showTyThing bindings
1345 showTyThing (AnId id) = do
1346 ty' <- cleanType (GHC.idType id)
1347 str <- showForUser (ppr id <> text " :: " <> ppr ty')
1349 showTyThing _ = return ()
1351 -- if -fglasgow-exts is on we show the foralls, otherwise we don't.
1352 cleanType :: Type -> GHCi Type
1354 dflags <- getDynFlags
1355 if dopt Opt_GlasgowExts dflags
1357 else return $! GHC.dropForAlls ty
1359 -- -----------------------------------------------------------------------------
1362 completeNone :: String -> IO [String]
1363 completeNone w = return []
1366 completeWord :: String -> Int -> Int -> IO (Maybe (String, [String]))
1367 completeWord w start end = do
1368 line <- Readline.getLineBuffer
1370 ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w
1372 | Just c <- is_cmd line -> do
1373 maybe_cmd <- lookupCommand c
1374 let (n,w') = selectWord (words' 0 line)
1376 Nothing -> return Nothing
1377 Just (_,_,False,complete) -> wrapCompleter complete w
1378 Just (_,_,True,complete) -> let complete' w = do rets <- complete w
1379 return (map (drop n) rets)
1380 in wrapCompleter complete' w'
1382 --printf "complete %s, start = %d, end = %d\n" w start end
1383 wrapCompleter completeIdentifier w
1384 where words' _ [] = []
1385 words' n str = let (w,r) = break isSpace str
1386 (s,r') = span isSpace r
1387 in (n,w):words' (n+length w+length s) r'
1388 -- In a Haskell expression we want to parse 'a-b' as three words
1389 -- where a compiler flag (ie. -fno-monomorphism-restriction) should
1390 -- only be a single word.
1391 selectWord [] = (0,w)
1392 selectWord ((offset,x):xs)
1393 | offset+length x >= start = (start-offset,take (end-offset) x)
1394 | otherwise = selectWord xs
1397 | ((':':w) : _) <- words (dropWhile isSpace line) = Just w
1398 | otherwise = Nothing
1401 cmds <- readIORef commands
1402 return (filter (w `isPrefixOf`) (map (':':) (map cmdName cmds)))
1404 completeMacro w = do
1405 cmds <- readIORef commands
1406 let cmds' = [ cmd | cmd <- map cmdName cmds, cmd `elem` map cmdName builtin_commands ]
1407 return (filter (w `isPrefixOf`) cmds')
1409 completeIdentifier w = do
1411 rdrs <- GHC.getRdrNamesInScope s
1412 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
1414 completeModule w = do
1416 dflags <- GHC.getSessionDynFlags s
1417 let pkg_mods = allExposedModules dflags
1418 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) pkg_mods))
1420 completeHomeModule w = do
1422 g <- GHC.getModuleGraph s
1423 let home_mods = map GHC.ms_mod_name g
1424 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) home_mods))
1426 completeSetOptions w = do
1427 return (filter (w `isPrefixOf`) options)
1428 where options = "args":"prog":allFlags
1430 completeFilename = Readline.filenameCompletionFunction
1432 completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
1434 unionComplete :: (String -> IO [String]) -> (String -> IO [String]) -> String -> IO [String]
1435 unionComplete f1 f2 w = do
1440 wrapCompleter :: (String -> IO [String]) -> String -> IO (Maybe (String,[String]))
1441 wrapCompleter fun w = do
1444 [] -> return Nothing
1445 [x] -> return (Just (x,[]))
1446 xs -> case getCommonPrefix xs of
1447 "" -> return (Just ("",xs))
1448 pref -> return (Just (pref,xs))
1450 getCommonPrefix :: [String] -> String
1451 getCommonPrefix [] = ""
1452 getCommonPrefix (s:ss) = foldl common s ss
1453 where common s "" = s
1455 common (c:cs) (d:ds)
1456 | c == d = c : common cs ds
1459 allExposedModules :: DynFlags -> [ModuleName]
1460 allExposedModules dflags
1461 = map GHC.mkModuleName (concat (map exposedModules (filter exposed (eltsUFM pkg_db))))
1463 pkg_db = pkgIdMap (pkgState dflags)
1465 completeCmd = completeNone
1466 completeMacro = completeNone
1467 completeIdentifier = completeNone
1468 completeModule = completeNone
1469 completeHomeModule = completeNone
1470 completeSetOptions = completeNone
1471 completeFilename = completeNone
1472 completeHomeModuleOrFile=completeNone
1475 -----------------------------------------------------------------------------
1478 data GHCiState = GHCiState
1484 session :: GHC.Session,
1485 options :: [GHCiOption],
1490 = ShowTiming -- show time/allocs after evaluation
1491 | ShowType -- show the type of expressions
1492 | RevertCAFs -- revert CAFs after every evaluation
1495 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
1497 startGHCi :: GHCi a -> GHCiState -> IO a
1498 startGHCi g state = do ref <- newIORef state; unGHCi g ref
1500 instance Monad GHCi where
1501 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
1502 return a = GHCi $ \s -> return a
1504 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
1505 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
1506 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
1508 getGHCiState = GHCi $ \r -> readIORef r
1509 setGHCiState s = GHCi $ \r -> writeIORef r s
1511 -- for convenience...
1512 getSession = getGHCiState >>= return . session
1513 getPrelude = getGHCiState >>= return . prelude
1515 GLOBAL_VAR(saved_sess, no_saved_sess, Session)
1516 no_saved_sess = error "no saved_ses"
1517 saveSession = getSession >>= io . writeIORef saved_sess
1518 splatSavedSession = io (writeIORef saved_sess no_saved_sess)
1519 restoreSession = readIORef saved_sess
1523 io (GHC.getSessionDynFlags s)
1524 setDynFlags dflags = do
1526 io (GHC.setSessionDynFlags s dflags)
1528 isOptionSet :: GHCiOption -> GHCi Bool
1530 = do st <- getGHCiState
1531 return (opt `elem` options st)
1533 setOption :: GHCiOption -> GHCi ()
1535 = do st <- getGHCiState
1536 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1538 unsetOption :: GHCiOption -> GHCi ()
1540 = do st <- getGHCiState
1541 setGHCiState (st{ options = filter (/= opt) (options st) })
1543 io :: IO a -> GHCi a
1544 io m = GHCi { unGHCi = \s -> m >>= return }
1546 -----------------------------------------------------------------------------
1547 -- recursive exception handlers
1549 -- Don't forget to unblock async exceptions in the handler, or if we're
1550 -- in an exception loop (eg. let a = error a in a) the ^C exception
1551 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1553 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1554 ghciHandle h (GHCi m) = GHCi $ \s ->
1555 Exception.catch (m s)
1556 (\e -> unGHCi (ghciUnblock (h e)) s)
1558 ghciUnblock :: GHCi a -> GHCi a
1559 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1561 -----------------------------------------------------------------------------
1562 -- timing & statistics
1564 timeIt :: GHCi a -> GHCi a
1566 = do b <- isOptionSet ShowTiming
1569 else do allocs1 <- io $ getAllocations
1570 time1 <- io $ getCPUTime
1572 allocs2 <- io $ getAllocations
1573 time2 <- io $ getCPUTime
1574 io $ printTimes (fromIntegral (allocs2 - allocs1))
1578 foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
1579 -- defined in ghc/rts/Stats.c
1581 printTimes :: Integer -> Integer -> IO ()
1582 printTimes allocs psecs
1583 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1584 secs_str = showFFloat (Just 2) secs
1585 putStrLn (showSDoc (
1586 parens (text (secs_str "") <+> text "secs" <> comma <+>
1587 text (show allocs) <+> text "bytes")))
1589 -----------------------------------------------------------------------------
1596 -- Have to turn off buffering again, because we just
1597 -- reverted stdout, stderr & stdin to their defaults.
1599 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1600 -- Make it "safe", just in case
1602 -- ----------------------------------------------------------------------------
1605 expandPath :: String -> GHCi String
1607 case dropWhile isSpace path of
1609 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1610 return (tilde ++ '/':d)
1614 -- ----------------------------------------------------------------------------
1615 -- Windows console setup
1617 setUpConsole :: IO ()
1619 #ifdef mingw32_HOST_OS
1620 -- On Windows we need to set a known code page, otherwise the characters
1621 -- we read from the console will be be in some strange encoding, and
1622 -- similarly for characters we write to the console.
1624 -- At the moment, GHCi pretends all input is Latin-1. In the
1625 -- future we should support UTF-8, but for now we set the code pages
1628 -- It seems you have to set the font in the console window to
1629 -- a Unicode font in order for output to work properly,
1630 -- otherwise non-ASCII characters are mapped wrongly. sigh.
1631 -- (see MSDN for SetConsoleOutputCP()).
1633 setConsoleCP 28591 -- ISO Latin-1
1634 setConsoleOutputCP 28591 -- ISO Latin-1