1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2005-2006
8 -----------------------------------------------------------------------------
9 module InteractiveUI ( interactiveUI ) where
11 #include "HsVersions.h"
19 import GHC ( Session, LoadHowMuch(..), Target(..), TargetId(..),
20 Type, Module, ModuleName, TyThing(..), Phase,
21 BreakIndex, SrcSpan, Resume, SingleStep )
27 import Outputable hiding (printForUser)
28 import Module -- for ModuleEnv
31 -- Other random utilities
33 import BasicTypes hiding (isTopLevel)
34 import Panic hiding (showException)
41 #ifndef mingw32_HOST_OS
42 import System.Posix hiding (getEnv)
44 import GHC.ConsoleHandler ( flushConsole )
45 import System.Win32 ( setConsoleCP, setConsoleOutputCP )
46 import qualified System.Win32
50 import Control.Concurrent ( yield ) -- Used in readline loop
51 import System.Console.Readline as Readline
56 import Control.Exception as Exception
57 -- import Control.Concurrent
59 import qualified Data.ByteString.Char8 as BS
63 import System.Environment
64 import System.Exit ( exitWith, ExitCode(..) )
65 import System.Directory
67 import System.IO.Error as IO
71 import Control.Monad as Monad
74 import Foreign.StablePtr ( newStablePtr )
75 import GHC.Exts ( unsafeCoerce# )
76 import GHC.IOBase ( IOErrorType(InvalidArgument) )
78 import Data.IORef ( IORef, readIORef, writeIORef )
80 import System.Posix.Internals ( setNonBlockingFD )
82 -----------------------------------------------------------------------------
86 " / _ \\ /\\ /\\/ __(_)\n"++
87 " / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n"++
88 "/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n"++
89 "\\____/\\/ /_/\\____/|_| Type :? for help.\n"
92 "GHCi, version " ++ cProjectVersion ++
93 ": http://www.haskell.org/ghc/ :? for help"
95 type Command = (String, String -> GHCi Bool, Bool, String -> IO [String])
98 GLOBAL_VAR(commands, builtin_commands, [Command])
100 builtin_commands :: [Command]
102 -- Hugs users are accustomed to :e, so make sure it doesn't overlap
103 ("?", keepGoing help, False, completeNone),
104 ("add", keepGoingPaths addModule, False, completeFilename),
105 ("abandon", keepGoing abandonCmd, False, completeNone),
106 ("break", keepGoing breakCmd, False, completeIdentifier),
107 ("back", keepGoing backCmd, False, completeNone),
108 ("browse", keepGoing browseCmd, False, completeModule),
109 ("cd", keepGoing changeDirectory, False, completeFilename),
110 ("check", keepGoing checkModule, False, completeHomeModule),
111 ("continue", keepGoing continueCmd, False, completeNone),
112 ("cmd", keepGoing cmdCmd, False, completeIdentifier),
113 ("ctags", keepGoing createCTagsFileCmd, False, completeFilename),
114 ("def", keepGoing defineMacro, False, completeIdentifier),
115 ("delete", keepGoing deleteCmd, False, completeNone),
116 ("e", keepGoing editFile, False, completeFilename),
117 ("edit", keepGoing editFile, False, completeFilename),
118 ("etags", keepGoing createETagsFileCmd, False, completeFilename),
119 ("force", keepGoing forceCmd, False, completeIdentifier),
120 ("forward", keepGoing forwardCmd, False, completeNone),
121 ("help", keepGoing help, False, completeNone),
122 ("history", keepGoing historyCmd, False, completeNone),
123 ("info", keepGoing info, False, completeIdentifier),
124 ("kind", keepGoing kindOfType, False, completeIdentifier),
125 ("load", keepGoingPaths loadModule_, False, completeHomeModuleOrFile),
126 ("list", keepGoing listCmd, False, completeNone),
127 ("module", keepGoing setContext, False, completeModule),
128 ("main", keepGoing runMain, False, completeIdentifier),
129 ("print", keepGoing printCmd, False, completeIdentifier),
130 ("quit", quit, False, completeNone),
131 ("reload", keepGoing reloadModule, False, completeNone),
132 ("set", keepGoing setCmd, True, completeSetOptions),
133 ("show", keepGoing showCmd, False, completeNone),
134 ("sprint", keepGoing sprintCmd, False, completeIdentifier),
135 ("step", keepGoing stepCmd, False, completeIdentifier),
136 ("type", keepGoing typeOfExpr, False, completeIdentifier),
137 ("trace", keepGoing traceCmd, False, completeIdentifier),
138 ("undef", keepGoing undefineMacro, False, completeMacro),
139 ("unset", keepGoing unsetOptions, True, completeSetOptions)
142 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
143 keepGoing a str = a str >> return False
145 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
146 keepGoingPaths a str = a (toArgs str) >> return False
148 shortHelpText = "use :? for help.\n"
151 " Commands available from the prompt:\n" ++
153 " <statement> evaluate/run <statement>\n" ++
154 " :add <filename> ... add module(s) to the current target set\n" ++
155 " :browse [*]<module> display the names defined by <module>\n" ++
156 " :cd <dir> change directory to <dir>\n" ++
157 " :cmd <expr> run the commands returned by <expr>::IO String\n" ++
158 " :ctags [<file>] create tags file for Vi (default: \"tags\")\n" ++
159 " :def <cmd> <expr> define a command :<cmd>\n" ++
160 " :edit <file> edit file\n" ++
161 " :edit edit last module\n" ++
162 " :etags [<file>] create tags file for Emacs (default: \"TAGS\")\n" ++
163 " :help, :? display this list of commands\n" ++
164 " :info [<name> ...] display information about the given names\n" ++
165 " :kind <type> show the kind of <type>\n" ++
166 " :load <filename> ... load module(s) and their dependents\n" ++
167 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
168 " :main [<arguments> ...] run the main function with the given arguments\n" ++
169 " :quit exit GHCi\n" ++
170 " :reload reload the current module set\n" ++
171 " :type <expr> show the type of <expr>\n" ++
172 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
173 " :!<command> run the shell command <command>\n" ++
175 " -- Commands for debugging:\n" ++
177 " :abandon at a breakpoint, abandon current computation\n" ++
178 " :back go back in the history (after :trace)\n" ++
179 " :break [<mod>] <l> [<col>] set a breakpoint at the specified location\n" ++
180 " :break <name> set a breakpoint on the specified function\n" ++
181 " :continue resume after a breakpoint\n" ++
182 " :delete <number> delete the specified breakpoint\n" ++
183 " :delete * delete all breakpoints\n" ++
184 " :force <expr> print <expr>, forcing unevaluated parts\n" ++
185 " :forward go forward in the history (after :back)\n" ++
186 " :history [<n>] show the last <n> items in the history (after :trace)\n" ++
187 " :print [<name> ...] prints a value without forcing its computation\n" ++
188 " :sprint [<name> ...] simplifed version of :print\n" ++
189 " :step single-step after stopping at a breakpoint\n"++
190 " :step <expr> single-step into <expr>\n"++
191 " :trace trace after stopping at a breakpoint\n"++
192 " :trace <expr> trace into <expr> (remembers breakpoints for :history)\n"++
195 " -- Commands for changing settings:\n" ++
197 " :set <option> ... set options\n" ++
198 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
199 " :set prog <progname> set the value returned by System.getProgName\n" ++
200 " :set prompt <prompt> set the prompt used in GHCi\n" ++
201 " :set editor <cmd> set the command used for :edit\n" ++
202 " :set stop <cmd> set the command to run when a breakpoint is hit\n" ++
203 " :unset <option> ... unset options\n" ++
205 " Options for ':set' and ':unset':\n" ++
207 " +r revert top-level expressions after each evaluation\n" ++
208 " +s print timing/memory stats after each evaluation\n" ++
209 " +t print type after evaluation\n" ++
210 " -<flags> most GHC command line flags can also be set here\n" ++
211 " (eg. -v2, -fglasgow-exts, etc.)\n" ++
213 " -- Commands for displaying information:\n" ++
215 " :show bindings show the current bindings made at the prompt\n" ++
216 " :show breaks show the active breakpoints\n" ++
217 " :show context show the breakpoint context\n" ++
218 " :show modules show the currently loaded modules\n" ++
219 " :show <setting> show anything that can be set with :set (e.g. args)\n" ++
226 win <- System.Win32.getWindowsDirectory
227 return (win `joinFileName` "notepad.exe")
232 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
233 interactiveUI session srcs maybe_expr = do
234 -- HACK! If we happen to get into an infinite loop (eg the user
235 -- types 'let x=x in x' at the prompt), then the thread will block
236 -- on a blackhole, and become unreachable during GC. The GC will
237 -- detect that it is unreachable and send it the NonTermination
238 -- exception. However, since the thread is unreachable, everything
239 -- it refers to might be finalized, including the standard Handles.
240 -- This sounds like a bug, but we don't have a good solution right
246 -- Initialise buffering for the *interpreted* I/O system
247 initInterpBuffering session
249 when (isNothing maybe_expr) $ do
250 -- Only for GHCi (not runghc and ghc -e):
252 -- Turn buffering off for the compiled program's stdout/stderr
254 -- Turn buffering off for GHCi's stdout
256 hSetBuffering stdout NoBuffering
257 -- We don't want the cmd line to buffer any input that might be
258 -- intended for the program, so unbuffer stdin.
259 hSetBuffering stdin NoBuffering
261 -- initial context is just the Prelude
262 prel_mod <- GHC.findModule session prel_name (Just basePackageId)
263 GHC.setContext session [] [prel_mod]
267 Readline.setAttemptedCompletionFunction (Just completeWord)
268 --Readline.parseAndBind "set show-all-if-ambiguous 1"
270 let symbols = "!#$%&*+/<=>?@\\^|-~"
271 specials = "(),;[]`{}"
273 word_break_chars = spaces ++ specials ++ symbols
275 Readline.setBasicWordBreakCharacters word_break_chars
276 Readline.setCompleterWordBreakCharacters word_break_chars
279 default_editor <- findEditor
281 startGHCi (runGHCi srcs maybe_expr)
282 GHCiState{ progname = "<interactive>",
286 editor = default_editor,
292 tickarrays = emptyModuleEnv,
297 Readline.resetTerminal Nothing
302 prel_name = GHC.mkModuleName "Prelude"
304 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
305 runGHCi paths maybe_expr = do
306 let read_dot_files = not opt_IgnoreDotGhci
308 when (read_dot_files) $ do
311 exists <- io (doesFileExist file)
313 dir_ok <- io (checkPerms ".")
314 file_ok <- io (checkPerms file)
315 when (dir_ok && file_ok) $ do
316 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
319 Right hdl -> fileLoop hdl False
321 when (read_dot_files) $ do
322 -- Read in $HOME/.ghci
323 either_dir <- io (IO.try (getEnv "HOME"))
327 cwd <- io (getCurrentDirectory)
328 when (dir /= cwd) $ do
329 let file = dir ++ "/.ghci"
330 ok <- io (checkPerms file)
332 either_hdl <- io (IO.try (openFile file ReadMode))
335 Right hdl -> fileLoop hdl False
337 -- Perform a :load for files given on the GHCi command line
338 -- When in -e mode, if the load fails then we want to stop
339 -- immediately rather than going on to evaluate the expression.
340 when (not (null paths)) $ do
341 ok <- ghciHandle (\e -> do showException e; return Failed) $
343 when (isJust maybe_expr && failed ok) $
344 io (exitWith (ExitFailure 1))
346 -- if verbosity is greater than 0, or we are connected to a
347 -- terminal, display the prompt in the interactive loop.
348 is_tty <- io (hIsTerminalDevice stdin)
349 dflags <- getDynFlags
350 let show_prompt = verbosity dflags > 0 || is_tty
355 #if defined(mingw32_HOST_OS)
356 -- The win32 Console API mutates the first character of
357 -- type-ahead when reading from it in a non-buffered manner. Work
358 -- around this by flushing the input buffer of type-ahead characters,
359 -- but only if stdin is available.
360 flushed <- io (IO.try (GHC.ConsoleHandler.flushConsole stdin))
362 Left err | isDoesNotExistError err -> return ()
363 | otherwise -> io (ioError err)
364 Right () -> return ()
366 -- initialise the console if necessary
369 let msg = if dopt Opt_ShortGhciBanner dflags
370 then ghciShortWelcomeMsg
372 when (verbosity dflags >= 1) $ io $ putStrLn msg
374 -- enter the interactive loop
375 interactiveLoop is_tty show_prompt
377 -- just evaluate the expression we were given
382 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
385 interactiveLoop is_tty show_prompt =
386 -- Ignore ^C exceptions caught here
387 ghciHandleDyn (\e -> case e of
389 #if defined(mingw32_HOST_OS)
392 interactiveLoop is_tty show_prompt
393 _other -> return ()) $
395 ghciUnblock $ do -- unblock necessary if we recursed from the
396 -- exception handler above.
398 -- read commands from stdin
402 else fileLoop stdin show_prompt
404 fileLoop stdin show_prompt
408 -- NOTE: We only read .ghci files if they are owned by the current user,
409 -- and aren't world writable. Otherwise, we could be accidentally
410 -- running code planted by a malicious third party.
412 -- Furthermore, We only read ./.ghci if . is owned by the current user
413 -- and isn't writable by anyone else. I think this is sufficient: we
414 -- don't need to check .. and ../.. etc. because "." always refers to
415 -- the same directory while a process is running.
417 checkPerms :: String -> IO Bool
419 #ifdef mingw32_HOST_OS
422 Util.handle (\_ -> return False) $ do
423 st <- getFileStatus name
425 if fileOwner st /= me then do
426 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
429 let mode = fileMode st
430 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
431 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
433 putStrLn $ "*** WARNING: " ++ name ++
434 " is writable by someone else, IGNORING!"
439 fileLoop :: Handle -> Bool -> GHCi ()
440 fileLoop hdl show_prompt = do
441 when show_prompt $ do
444 l <- io (IO.try (hGetLine hdl))
446 Left e | isEOFError e -> return ()
447 | InvalidArgument <- etype -> return ()
448 | otherwise -> io (ioError e)
449 where etype = ioeGetErrorType e
450 -- treat InvalidArgument in the same way as EOF:
451 -- this can happen if the user closed stdin, or
452 -- perhaps did getContents which closes stdin at
455 case removeSpaces l of
456 "" -> fileLoop hdl show_prompt
457 l -> do quit <- runCommands l
458 if quit then return () else fileLoop hdl show_prompt
461 session <- getSession
462 (toplevs,exports) <- io (GHC.getContext session)
463 resumes <- io $ GHC.getResumeContext session
469 let ix = GHC.resumeHistoryIx r
471 then return (brackets (ppr (GHC.resumeSpan r)) <> space)
473 let hist = GHC.resumeHistory r !! (ix-1)
474 span <- io $ GHC.getHistorySpan session hist
475 return (brackets (ppr (negate ix) <> char ':'
476 <+> ppr span) <> space)
478 dots | r:rs <- resumes, not (null rs) = text "... "
482 hsep (map (\m -> char '*' <> ppr (GHC.moduleName m)) toplevs) <+>
483 hsep (map (ppr . GHC.moduleName) exports)
485 deflt_prompt = dots <> context_bit <> modules_bit
487 f ('%':'s':xs) = deflt_prompt <> f xs
488 f ('%':'%':xs) = char '%' <> f xs
489 f (x:xs) = char x <> f xs
493 return (showSDoc (f (prompt st)))
497 readlineLoop :: GHCi ()
499 session <- getSession
500 (mod,imports) <- io (GHC.getContext session)
502 saveSession -- for use by completion
504 mb_span <- getCurrentBreakSpan
506 l <- io (readline prompt `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
517 quit <- runCommands l
518 if quit then return () else readlineLoop
521 runCommands :: String -> GHCi Bool
523 q <- ghciHandle handler (doCommand cmd)
524 if q then return True else runNext
530 c:cs -> do setGHCiState st{ cmdqueue = cs }
533 doCommand (':' : cmd) = specialCommand cmd
534 doCommand stmt = do timeIt $ runStmt stmt GHC.RunToCompletion
537 enqueueCommands :: [String] -> GHCi ()
538 enqueueCommands cmds = do
540 setGHCiState st{ cmdqueue = cmds ++ cmdqueue st }
543 -- This version is for the GHC command-line option -e. The only difference
544 -- from runCommand is that it catches the ExitException exception and
545 -- exits, rather than printing out the exception.
546 runCommandEval c = ghciHandle handleEval (doCommand c)
548 handleEval (ExitException code) = io (exitWith code)
549 handleEval e = do handler e
550 io (exitWith (ExitFailure 1))
552 doCommand (':' : command) = specialCommand command
554 = do r <- runStmt stmt GHC.RunToCompletion
556 False -> io (exitWith (ExitFailure 1))
557 -- failure to run the command causes exit(1) for ghc -e.
560 runStmt :: String -> SingleStep -> GHCi Bool
562 | null (filter (not.isSpace) stmt) = return False
563 | ["import", mod] <- words stmt = keepGoing setContext ('+':mod)
565 = do st <- getGHCiState
566 session <- getSession
567 result <- io $ withProgName (progname st) $ withArgs (args st) $
568 GHC.runStmt session stmt step
572 afterRunStmt :: GHC.RunResult -> GHCi Bool
573 -- False <=> the statement failed to compile
574 afterRunStmt (GHC.RunException e) = throw e
575 afterRunStmt run_result = do
576 session <- getSession
578 GHC.RunOk names -> do
579 show_types <- isOptionSet ShowType
580 when show_types $ printTypeOfNames session names
581 GHC.RunBreak _ names mb_info -> do
582 resumes <- io $ GHC.getResumeContext session
583 printForUser $ ptext SLIT("Stopped at") <+>
584 ppr (GHC.resumeSpan (head resumes))
585 printTypeOfNames session names
586 maybe (return ()) runBreakCmd mb_info
587 -- run the command set with ":set stop <cmd>"
589 enqueueCommands [stop st]
594 io installSignalHandlers
595 b <- isOptionSet RevertCAFs
596 io (when b revertCAFs)
598 return (case run_result of GHC.RunOk _ -> True; _ -> False)
600 runBreakCmd :: GHC.BreakInfo -> GHCi ()
601 runBreakCmd info = do
602 let mod = GHC.breakInfo_module info
603 nm = GHC.breakInfo_number info
605 case [ loc | (i,loc) <- breaks st,
606 breakModule loc == mod, breakTick loc == nm ] of
608 loc:_ | null cmd -> return ()
609 | otherwise -> do enqueueCommands [cmd]; return ()
610 where cmd = onBreakCmd loc
612 printTypeOfNames :: Session -> [Name] -> GHCi ()
613 printTypeOfNames session names
614 = mapM_ (printTypeOfName session) $ sortBy compareFun names
615 where compareWith n = (getOccString n, getSrcSpan n)
616 compareFun n1 n2 = compareWith n1 `compare` compareWith n2
618 printTypeOfName :: Session -> Name -> GHCi ()
619 printTypeOfName session n
620 = do maybe_tything <- io (GHC.lookupName session n)
621 case maybe_tything of
623 Just thing -> printTyThing thing
625 specialCommand :: String -> GHCi Bool
626 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
627 specialCommand str = do
628 let (cmd,rest) = break isSpace str
629 maybe_cmd <- io (lookupCommand cmd)
631 Nothing -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
632 ++ shortHelpText) >> return False)
633 Just (_,f,_,_) -> f (dropWhile isSpace rest)
635 lookupCommand :: String -> IO (Maybe Command)
636 lookupCommand str = do
637 cmds <- readIORef commands
638 -- look for exact match first, then the first prefix match
639 case [ c | c <- cmds, str == cmdName c ] of
640 c:_ -> return (Just c)
641 [] -> case [ c | c@(s,_,_,_) <- cmds, prefixMatch str s ] of
643 c:_ -> return (Just c)
646 getCurrentBreakSpan :: GHCi (Maybe SrcSpan)
647 getCurrentBreakSpan = do
648 session <- getSession
649 resumes <- io $ GHC.getResumeContext session
653 let ix = GHC.resumeHistoryIx r
655 then return (Just (GHC.resumeSpan r))
657 let hist = GHC.resumeHistory r !! (ix-1)
658 span <- io $ GHC.getHistorySpan session hist
661 -----------------------------------------------------------------------------
664 noArgs :: GHCi () -> String -> GHCi ()
666 noArgs m _ = io $ putStrLn "This command takes no arguments"
668 help :: String -> GHCi ()
669 help _ = io (putStr helpText)
671 info :: String -> GHCi ()
672 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
673 info s = do { let names = words s
674 ; session <- getSession
675 ; dflags <- getDynFlags
676 ; let exts = dopt Opt_GlasgowExts dflags
677 ; mapM_ (infoThing exts session) names }
679 infoThing exts session str = io $ do
680 names <- GHC.parseName session str
681 let filtered = filterOutChildren names
682 mb_stuffs <- mapM (GHC.getInfo session) filtered
683 unqual <- GHC.getPrintUnqual session
684 putStrLn (showSDocForUser unqual $
685 vcat (intersperse (text "") $
686 [ pprInfo exts stuff | Just stuff <- mb_stuffs ]))
688 -- Filter out names whose parent is also there Good
689 -- example is '[]', which is both a type and data
690 -- constructor in the same type
691 filterOutChildren :: [Name] -> [Name]
692 filterOutChildren names = filter (not . parent_is_there) names
693 where parent_is_there n
694 -- | Just p <- GHC.nameParent_maybe n = p `elem` names
698 pprInfo exts (thing, fixity, insts)
699 = pprTyThingInContextLoc exts thing
700 $$ show_fixity fixity
701 $$ vcat (map GHC.pprInstance insts)
704 | fix == GHC.defaultFixity = empty
705 | otherwise = ppr fix <+> ppr (GHC.getName thing)
707 runMain :: String -> GHCi ()
709 let ss = concat $ intersperse "," (map (\ s -> ('"':s)++"\"") (toArgs args))
710 enqueueCommands ['[': ss ++ "] `System.Environment.withArgs` main"]
712 addModule :: [FilePath] -> GHCi ()
714 io (revertCAFs) -- always revert CAFs on load/add.
715 files <- mapM expandPath files
716 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
717 session <- getSession
718 io (mapM_ (GHC.addTarget session) targets)
719 ok <- io (GHC.load session LoadAllTargets)
722 changeDirectory :: String -> GHCi ()
723 changeDirectory dir = do
724 session <- getSession
725 graph <- io (GHC.getModuleGraph session)
726 when (not (null graph)) $
727 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
728 io (GHC.setTargets session [])
729 io (GHC.load session LoadAllTargets)
730 setContextAfterLoad session []
731 io (GHC.workingDirectoryChanged session)
732 dir <- expandPath dir
733 io (setCurrentDirectory dir)
735 editFile :: String -> GHCi ()
737 do file <- if null str then chooseEditFile else return str
741 $ throwDyn (CmdLineError "editor not set, use :set editor")
742 io $ system (cmd ++ ' ':file)
745 -- The user didn't specify a file so we pick one for them.
746 -- Our strategy is to pick the first module that failed to load,
747 -- or otherwise the first target.
749 -- XXX: Can we figure out what happened if the depndecy analysis fails
750 -- (e.g., because the porgrammeer mistyped the name of a module)?
751 -- XXX: Can we figure out the location of an error to pass to the editor?
752 -- XXX: if we could figure out the list of errors that occured during the
753 -- last load/reaload, then we could start the editor focused on the first
755 chooseEditFile :: GHCi String
757 do session <- getSession
758 let hasFailed x = io $ fmap not $ GHC.isLoaded session $ GHC.ms_mod_name x
760 graph <- io (GHC.getModuleGraph session)
761 failed_graph <- filterM hasFailed graph
762 let order g = flattenSCCs $ GHC.topSortModuleGraph True g Nothing
764 x : _ -> GHC.ml_hs_file (GHC.ms_location x)
767 case pick (order failed_graph) of
768 Just file -> return file
770 do targets <- io (GHC.getTargets session)
771 case msum (map fromTarget targets) of
772 Just file -> return file
773 Nothing -> throwDyn (CmdLineError "No files to edit.")
775 where fromTarget (GHC.Target (GHC.TargetFile f _) _) = Just f
776 fromTarget _ = Nothing -- when would we get a module target?
778 defineMacro :: String -> GHCi ()
780 let (macro_name, definition) = break isSpace s
781 cmds <- io (readIORef commands)
783 then throwDyn (CmdLineError "invalid macro name")
785 if (macro_name `elem` map cmdName cmds)
786 then throwDyn (CmdLineError
787 ("command '" ++ macro_name ++ "' is already defined"))
790 -- give the expression a type signature, so we can be sure we're getting
791 -- something of the right type.
792 let new_expr = '(' : definition ++ ") :: String -> IO String"
794 -- compile the expression
796 maybe_hv <- io (GHC.compileExpr cms new_expr)
799 Just hv -> io (writeIORef commands --
800 (cmds ++ [(macro_name, runMacro hv, False, completeNone)]))
802 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
804 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
805 enqueueCommands (lines str)
808 undefineMacro :: String -> GHCi ()
809 undefineMacro macro_name = do
810 cmds <- io (readIORef commands)
811 if (macro_name `elem` map cmdName builtin_commands)
812 then throwDyn (CmdLineError
813 ("command '" ++ macro_name ++ "' cannot be undefined"))
815 if (macro_name `notElem` map cmdName cmds)
816 then throwDyn (CmdLineError
817 ("command '" ++ macro_name ++ "' not defined"))
819 io (writeIORef commands (filter ((/= macro_name) . cmdName) cmds))
821 cmdCmd :: String -> GHCi ()
823 let expr = '(' : str ++ ") :: IO String"
824 session <- getSession
825 maybe_hv <- io (GHC.compileExpr session expr)
829 cmds <- io $ (unsafeCoerce# hv :: IO String)
830 enqueueCommands (lines cmds)
833 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
834 loadModule fs = timeIt (loadModule' fs)
836 loadModule_ :: [FilePath] -> GHCi ()
837 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
839 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
840 loadModule' files = do
841 session <- getSession
844 discardActiveBreakPoints
845 io (GHC.setTargets session [])
846 io (GHC.load session LoadAllTargets)
849 let (filenames, phases) = unzip files
850 exp_filenames <- mapM expandPath filenames
851 let files' = zip exp_filenames phases
852 targets <- io (mapM (uncurry GHC.guessTarget) files')
854 -- NOTE: we used to do the dependency anal first, so that if it
855 -- fails we didn't throw away the current set of modules. This would
856 -- require some re-working of the GHC interface, so we'll leave it
857 -- as a ToDo for now.
859 io (GHC.setTargets session targets)
860 doLoad session LoadAllTargets
862 checkModule :: String -> GHCi ()
864 let modl = GHC.mkModuleName m
865 session <- getSession
866 result <- io (GHC.checkModule session modl)
868 Nothing -> io $ putStrLn "Nothing"
869 Just r -> io $ putStrLn (showSDoc (
870 case GHC.checkedModuleInfo r of
871 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
873 (local,global) = partition ((== modl) . GHC.moduleName . GHC.nameModule) scope
875 (text "global names: " <+> ppr global) $$
876 (text "local names: " <+> ppr local)
878 afterLoad (successIf (isJust result)) session
880 reloadModule :: String -> GHCi ()
882 io (revertCAFs) -- always revert CAFs on reload.
883 discardActiveBreakPoints
884 session <- getSession
885 doLoad session $ if null m then LoadAllTargets
886 else LoadUpTo (GHC.mkModuleName m)
889 doLoad session howmuch = do
890 -- turn off breakpoints before we load: we can't turn them off later, because
891 -- the ModBreaks will have gone away.
892 discardActiveBreakPoints
893 ok <- io (GHC.load session howmuch)
897 afterLoad ok session = do
898 io (revertCAFs) -- always revert CAFs on load.
900 graph <- io (GHC.getModuleGraph session)
901 graph' <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph
902 setContextAfterLoad session graph'
903 modulesLoadedMsg ok (map GHC.ms_mod_name graph')
905 setContextAfterLoad session [] = do
906 prel_mod <- getPrelude
907 io (GHC.setContext session [] [prel_mod])
908 setContextAfterLoad session ms = do
909 -- load a target if one is available, otherwise load the topmost module.
910 targets <- io (GHC.getTargets session)
911 case [ m | Just m <- map (findTarget ms) targets ] of
913 let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in
914 load_this (last graph')
919 = case filter (`matches` t) ms of
923 summary `matches` Target (TargetModule m) _
924 = GHC.ms_mod_name summary == m
925 summary `matches` Target (TargetFile f _) _
926 | Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
927 summary `matches` target
930 load_this summary | m <- GHC.ms_mod summary = do
931 b <- io (GHC.moduleIsInterpreted session m)
932 if b then io (GHC.setContext session [m] [])
934 prel_mod <- getPrelude
935 io (GHC.setContext session [] [prel_mod,m])
938 modulesLoadedMsg :: SuccessFlag -> [ModuleName] -> GHCi ()
939 modulesLoadedMsg ok mods = do
940 dflags <- getDynFlags
941 when (verbosity dflags > 0) $ do
943 | null mods = text "none."
945 punctuate comma (map ppr mods)) <> text "."
948 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
950 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
953 typeOfExpr :: String -> GHCi ()
955 = do cms <- getSession
956 maybe_ty <- io (GHC.exprType cms str)
959 Just ty -> do ty' <- cleanType ty
960 printForUser $ text str <> text " :: " <> ppr ty'
962 kindOfType :: String -> GHCi ()
964 = do cms <- getSession
965 maybe_ty <- io (GHC.typeKind cms str)
968 Just ty -> printForUser $ text str <> text " :: " <> ppr ty
970 quit :: String -> GHCi Bool
973 shellEscape :: String -> GHCi Bool
974 shellEscape str = io (system str >> return False)
976 -----------------------------------------------------------------------------
977 -- Browsing a module's contents
979 browseCmd :: String -> GHCi ()
982 ['*':m] | looksLikeModuleName m -> browseModule m False
983 [m] | looksLikeModuleName m -> browseModule m True
984 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
986 browseModule m exports_only = do
988 modl <- if exports_only then lookupModule m
989 else wantInterpretedModule m
991 -- Temporarily set the context to the module we're interested in,
992 -- just so we can get an appropriate PrintUnqualified
993 (as,bs) <- io (GHC.getContext s)
994 prel_mod <- getPrelude
995 io (if exports_only then GHC.setContext s [] [prel_mod,modl]
996 else GHC.setContext s [modl] [])
997 unqual <- io (GHC.getPrintUnqual s)
998 io (GHC.setContext s as bs)
1000 mb_mod_info <- io $ GHC.getModuleInfo s modl
1002 Nothing -> throwDyn (CmdLineError ("unknown module: " ++ m))
1005 | exports_only = GHC.modInfoExports mod_info
1006 | otherwise = fromMaybe [] (GHC.modInfoTopLevelScope mod_info)
1008 filtered = filterOutChildren names
1010 things <- io $ mapM (GHC.lookupName s) filtered
1012 dflags <- getDynFlags
1013 let exts = dopt Opt_GlasgowExts dflags
1014 io (putStrLn (showSDocForUser unqual (
1015 vcat (map (pprTyThingInContext exts) (catMaybes things))
1017 -- ToDo: modInfoInstances currently throws an exception for
1018 -- package modules. When it works, we can do this:
1019 -- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
1021 -----------------------------------------------------------------------------
1022 -- Setting the module context
1025 | all sensible mods = fn mods
1026 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
1028 (fn, mods) = case str of
1029 '+':stuff -> (addToContext, words stuff)
1030 '-':stuff -> (removeFromContext, words stuff)
1031 stuff -> (newContext, words stuff)
1033 sensible ('*':m) = looksLikeModuleName m
1034 sensible m = looksLikeModuleName m
1036 separate :: Session -> [String] -> [Module] -> [Module]
1037 -> GHCi ([Module],[Module])
1038 separate session [] as bs = return (as,bs)
1039 separate session (('*':str):ms) as bs = do
1040 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1041 b <- io $ GHC.moduleIsInterpreted session m
1042 if b then separate session ms (m:as) bs
1043 else throwDyn (CmdLineError ("module '"
1044 ++ GHC.moduleNameString (GHC.moduleName m)
1045 ++ "' is not interpreted"))
1046 separate session (str:ms) as bs = do
1047 m <- io $ GHC.findModule session (GHC.mkModuleName str) Nothing
1048 separate session ms as (m:bs)
1050 newContext :: [String] -> GHCi ()
1051 newContext strs = do
1053 (as,bs) <- separate s strs [] []
1054 prel_mod <- getPrelude
1055 let bs' = if null as && prel_mod `notElem` bs then prel_mod:bs else bs
1056 io $ GHC.setContext s as bs'
1059 addToContext :: [String] -> GHCi ()
1060 addToContext strs = do
1062 (as,bs) <- io $ GHC.getContext s
1064 (new_as,new_bs) <- separate s strs [] []
1066 let as_to_add = new_as \\ (as ++ bs)
1067 bs_to_add = new_bs \\ (as ++ bs)
1069 io $ GHC.setContext s (as ++ as_to_add) (bs ++ bs_to_add)
1072 removeFromContext :: [String] -> GHCi ()
1073 removeFromContext strs = do
1075 (as,bs) <- io $ GHC.getContext s
1077 (as_to_remove,bs_to_remove) <- separate s strs [] []
1079 let as' = as \\ (as_to_remove ++ bs_to_remove)
1080 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1082 io $ GHC.setContext s as' bs'
1084 ----------------------------------------------------------------------------
1087 -- set options in the interpreter. Syntax is exactly the same as the
1088 -- ghc command line, except that certain options aren't available (-C,
1091 -- This is pretty fragile: most options won't work as expected. ToDo:
1092 -- figure out which ones & disallow them.
1094 setCmd :: String -> GHCi ()
1096 = do st <- getGHCiState
1097 let opts = options st
1098 io $ putStrLn (showSDoc (
1099 text "options currently set: " <>
1102 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1105 = case toArgs str of
1106 ("args":args) -> setArgs args
1107 ("prog":prog) -> setProg prog
1108 ("prompt":prompt) -> setPrompt (after 6)
1109 ("editor":cmd) -> setEditor (after 6)
1110 ("stop":cmd) -> setStop (after 4)
1111 wds -> setOptions wds
1112 where after n = dropWhile isSpace $ drop n $ dropWhile isSpace str
1116 setGHCiState st{ args = args }
1120 setGHCiState st{ progname = prog }
1122 io (hPutStrLn stderr "syntax: :set prog <progname>")
1126 setGHCiState st{ editor = cmd }
1128 setStop str@(c:_) | isDigit c
1129 = do let (nm_str,rest) = break (not.isDigit) str
1132 let old_breaks = breaks st
1133 if all ((/= nm) . fst) old_breaks
1134 then printForUser (text "Breakpoint" <+> ppr nm <+>
1135 text "does not exist")
1137 let new_breaks = map fn old_breaks
1138 fn (i,loc) | i == nm = (i,loc { onBreakCmd = dropWhile isSpace rest })
1139 | otherwise = (i,loc)
1140 setGHCiState st{ breaks = new_breaks }
1143 setGHCiState st{ stop = cmd }
1145 setPrompt value = do
1148 then io $ hPutStrLn stderr $ "syntax: :set prompt <prompt>, currently \"" ++ prompt st ++ "\""
1149 else setGHCiState st{ prompt = remQuotes value }
1151 remQuotes ('\"':xs) | not (null xs) && last xs == '\"' = init xs
1155 do -- first, deal with the GHCi opts (+s, +t, etc.)
1156 let (plus_opts, minus_opts) = partition isPlus wds
1157 mapM_ setOpt plus_opts
1158 -- then, dynamic flags
1159 newDynFlags minus_opts
1161 newDynFlags minus_opts = do
1162 dflags <- getDynFlags
1163 let pkg_flags = packageFlags dflags
1164 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1166 if (not (null leftovers))
1167 then throwDyn (CmdLineError ("unrecognised flags: " ++
1171 new_pkgs <- setDynFlags dflags'
1173 -- if the package flags changed, we should reset the context
1174 -- and link the new packages.
1175 dflags <- getDynFlags
1176 when (packageFlags dflags /= pkg_flags) $ do
1177 io $ hPutStrLn stderr "package flags have changed, ressetting and loading new packages..."
1178 session <- getSession
1179 io (GHC.setTargets session [])
1180 io (GHC.load session LoadAllTargets)
1181 io (linkPackages dflags new_pkgs)
1182 setContextAfterLoad session []
1186 unsetOptions :: String -> GHCi ()
1188 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1189 let opts = words str
1190 (minus_opts, rest1) = partition isMinus opts
1191 (plus_opts, rest2) = partition isPlus rest1
1193 if (not (null rest2))
1194 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1197 mapM_ unsetOpt plus_opts
1199 let no_flag ('-':'f':rest) = return ("-fno-" ++ rest)
1200 no_flag f = throwDyn (ProgramError ("don't know how to reverse " ++ f))
1202 no_flags <- mapM no_flag minus_opts
1203 newDynFlags no_flags
1205 isMinus ('-':s) = True
1208 isPlus ('+':s) = True
1212 = case strToGHCiOpt str of
1213 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1214 Just o -> setOption o
1217 = case strToGHCiOpt str of
1218 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1219 Just o -> unsetOption o
1221 strToGHCiOpt :: String -> (Maybe GHCiOption)
1222 strToGHCiOpt "s" = Just ShowTiming
1223 strToGHCiOpt "t" = Just ShowType
1224 strToGHCiOpt "r" = Just RevertCAFs
1225 strToGHCiOpt _ = Nothing
1227 optToStr :: GHCiOption -> String
1228 optToStr ShowTiming = "s"
1229 optToStr ShowType = "t"
1230 optToStr RevertCAFs = "r"
1232 -- ---------------------------------------------------------------------------
1238 ["args"] -> io $ putStrLn (show (args st))
1239 ["prog"] -> io $ putStrLn (show (progname st))
1240 ["prompt"] -> io $ putStrLn (show (prompt st))
1241 ["editor"] -> io $ putStrLn (show (editor st))
1242 ["stop"] -> io $ putStrLn (show (stop st))
1243 ["modules" ] -> showModules
1244 ["bindings"] -> showBindings
1245 ["linker"] -> io showLinkerState
1246 ["breaks"] -> showBkptTable
1247 ["context"] -> showContext
1248 _ -> throwDyn (CmdLineError "syntax: :show [args|prog|prompt|editor|stop|modules|bindings|breaks|context]")
1251 session <- getSession
1252 let show_one ms = do m <- io (GHC.showModule session ms)
1254 graph <- io (GHC.getModuleGraph session)
1255 mapM_ show_one graph
1259 unqual <- io (GHC.getPrintUnqual s)
1260 bindings <- io (GHC.getBindings s)
1261 mapM_ printTyThing bindings
1264 printTyThing :: TyThing -> GHCi ()
1265 printTyThing (AnId id) = do
1266 ty' <- cleanType (GHC.idType id)
1267 printForUser $ ppr id <> text " :: " <> ppr ty'
1268 printTyThing _ = return ()
1270 -- if -fglasgow-exts is on we show the foralls, otherwise we don't.
1271 cleanType :: Type -> GHCi Type
1273 dflags <- getDynFlags
1274 if dopt Opt_GlasgowExts dflags
1276 else return $! GHC.dropForAlls ty
1278 showBkptTable :: GHCi ()
1281 printForUser $ prettyLocations (breaks st)
1283 showContext :: GHCi ()
1285 session <- getSession
1286 resumes <- io $ GHC.getResumeContext session
1287 printForUser $ vcat (map pp_resume (reverse resumes))
1290 ptext SLIT("--> ") <> text (GHC.resumeStmt resume)
1291 $$ nest 2 (ptext SLIT("Stopped at") <+> ppr (GHC.resumeSpan resume))
1294 -- -----------------------------------------------------------------------------
1297 completeNone :: String -> IO [String]
1298 completeNone w = return []
1301 completeWord :: String -> Int -> Int -> IO (Maybe (String, [String]))
1302 completeWord w start end = do
1303 line <- Readline.getLineBuffer
1305 ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w
1307 | Just c <- is_cmd line -> do
1308 maybe_cmd <- lookupCommand c
1309 let (n,w') = selectWord (words' 0 line)
1311 Nothing -> return Nothing
1312 Just (_,_,False,complete) -> wrapCompleter complete w
1313 Just (_,_,True,complete) -> let complete' w = do rets <- complete w
1314 return (map (drop n) rets)
1315 in wrapCompleter complete' w'
1317 --printf "complete %s, start = %d, end = %d\n" w start end
1318 wrapCompleter completeIdentifier w
1319 where words' _ [] = []
1320 words' n str = let (w,r) = break isSpace str
1321 (s,r') = span isSpace r
1322 in (n,w):words' (n+length w+length s) r'
1323 -- In a Haskell expression we want to parse 'a-b' as three words
1324 -- where a compiler flag (ie. -fno-monomorphism-restriction) should
1325 -- only be a single word.
1326 selectWord [] = (0,w)
1327 selectWord ((offset,x):xs)
1328 | offset+length x >= start = (start-offset,take (end-offset) x)
1329 | otherwise = selectWord xs
1332 | ((':':w) : _) <- words (dropWhile isSpace line) = Just w
1333 | otherwise = Nothing
1336 cmds <- readIORef commands
1337 return (filter (w `isPrefixOf`) (map (':':) (map cmdName cmds)))
1339 completeMacro w = do
1340 cmds <- readIORef commands
1341 let cmds' = [ cmd | cmd <- map cmdName cmds, cmd `elem` map cmdName builtin_commands ]
1342 return (filter (w `isPrefixOf`) cmds')
1344 completeIdentifier w = do
1346 rdrs <- GHC.getRdrNamesInScope s
1347 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
1349 completeModule w = do
1351 dflags <- GHC.getSessionDynFlags s
1352 let pkg_mods = allExposedModules dflags
1353 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) pkg_mods))
1355 completeHomeModule w = do
1357 g <- GHC.getModuleGraph s
1358 let home_mods = map GHC.ms_mod_name g
1359 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) home_mods))
1361 completeSetOptions w = do
1362 return (filter (w `isPrefixOf`) options)
1363 where options = "args":"prog":allFlags
1365 completeFilename = Readline.filenameCompletionFunction
1367 completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
1369 unionComplete :: (String -> IO [String]) -> (String -> IO [String]) -> String -> IO [String]
1370 unionComplete f1 f2 w = do
1375 wrapCompleter :: (String -> IO [String]) -> String -> IO (Maybe (String,[String]))
1376 wrapCompleter fun w = do
1379 [] -> return Nothing
1380 [x] -> return (Just (x,[]))
1381 xs -> case getCommonPrefix xs of
1382 "" -> return (Just ("",xs))
1383 pref -> return (Just (pref,xs))
1385 getCommonPrefix :: [String] -> String
1386 getCommonPrefix [] = ""
1387 getCommonPrefix (s:ss) = foldl common s ss
1388 where common s "" = ""
1390 common (c:cs) (d:ds)
1391 | c == d = c : common cs ds
1394 allExposedModules :: DynFlags -> [ModuleName]
1395 allExposedModules dflags
1396 = map GHC.mkModuleName (concat (map exposedModules (filter exposed (eltsUFM pkg_db))))
1398 pkg_db = pkgIdMap (pkgState dflags)
1400 completeCmd = completeNone
1401 completeMacro = completeNone
1402 completeIdentifier = completeNone
1403 completeModule = completeNone
1404 completeHomeModule = completeNone
1405 completeSetOptions = completeNone
1406 completeFilename = completeNone
1407 completeHomeModuleOrFile=completeNone
1408 completeBkpt = completeNone
1411 -- ---------------------------------------------------------------------------
1412 -- User code exception handling
1414 -- This is the exception handler for exceptions generated by the
1415 -- user's code and exceptions coming from children sessions;
1416 -- it normally just prints out the exception. The
1417 -- handler must be recursive, in case showing the exception causes
1418 -- more exceptions to be raised.
1420 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
1421 -- raising another exception. We therefore don't put the recursive
1422 -- handler arond the flushing operation, so if stderr is closed
1423 -- GHCi will just die gracefully rather than going into an infinite loop.
1424 handler :: Exception -> GHCi Bool
1426 handler exception = do
1428 io installSignalHandlers
1429 ghciHandle handler (showException exception >> return False)
1431 showException (DynException dyn) =
1432 case fromDynamic dyn of
1433 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
1434 Just Interrupted -> io (putStrLn "Interrupted.")
1435 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
1436 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
1437 Just other_ghc_ex -> io (print other_ghc_ex)
1439 showException other_exception
1440 = io (putStrLn ("*** Exception: " ++ show other_exception))
1442 -----------------------------------------------------------------------------
1443 -- recursive exception handlers
1445 -- Don't forget to unblock async exceptions in the handler, or if we're
1446 -- in an exception loop (eg. let a = error a in a) the ^C exception
1447 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1449 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1450 ghciHandle h (GHCi m) = GHCi $ \s ->
1451 Exception.catch (m s)
1452 (\e -> unGHCi (ghciUnblock (h e)) s)
1454 ghciUnblock :: GHCi a -> GHCi a
1455 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1458 -- ----------------------------------------------------------------------------
1461 expandPath :: String -> GHCi String
1463 case dropWhile isSpace path of
1465 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1466 return (tilde ++ '/':d)
1470 wantInterpretedModule :: String -> GHCi Module
1471 wantInterpretedModule str = do
1472 session <- getSession
1473 modl <- lookupModule str
1474 is_interpreted <- io (GHC.moduleIsInterpreted session modl)
1475 when (not is_interpreted) $
1476 throwDyn (CmdLineError ("module '" ++ str ++ "' is not interpreted"))
1479 wantNameFromInterpretedModule noCanDo str and_then = do
1480 session <- getSession
1481 names <- io $ GHC.parseName session str
1485 let modl = GHC.nameModule n
1486 if not (GHC.isExternalName n)
1487 then noCanDo n $ ppr n <>
1488 text " is not defined in an interpreted module"
1490 is_interpreted <- io (GHC.moduleIsInterpreted session modl)
1491 if not is_interpreted
1492 then noCanDo n $ text "module " <> ppr modl <>
1493 text " is not interpreted"
1496 -- ----------------------------------------------------------------------------
1497 -- Windows console setup
1499 setUpConsole :: IO ()
1501 #ifdef mingw32_HOST_OS
1502 -- On Windows we need to set a known code page, otherwise the characters
1503 -- we read from the console will be be in some strange encoding, and
1504 -- similarly for characters we write to the console.
1506 -- At the moment, GHCi pretends all input is Latin-1. In the
1507 -- future we should support UTF-8, but for now we set the code pages
1510 -- It seems you have to set the font in the console window to
1511 -- a Unicode font in order for output to work properly,
1512 -- otherwise non-ASCII characters are mapped wrongly. sigh.
1513 -- (see MSDN for SetConsoleOutputCP()).
1515 setConsoleCP 28591 -- ISO Latin-1
1516 setConsoleOutputCP 28591 -- ISO Latin-1
1520 -- -----------------------------------------------------------------------------
1521 -- commands for debugger
1523 sprintCmd = pprintCommand False False
1524 printCmd = pprintCommand True False
1525 forceCmd = pprintCommand False True
1527 pprintCommand bind force str = do
1528 session <- getSession
1529 io $ pprintClosureCommand session bind force str
1531 stepCmd :: String -> GHCi ()
1532 stepCmd [] = doContinue GHC.SingleStep
1533 stepCmd expression = do runStmt expression GHC.SingleStep; return ()
1535 traceCmd :: String -> GHCi ()
1536 traceCmd [] = doContinue GHC.RunAndLogSteps
1537 traceCmd expression = do runStmt expression GHC.RunAndLogSteps; return ()
1539 continueCmd :: String -> GHCi ()
1540 continueCmd = noArgs $ doContinue GHC.RunToCompletion
1542 doContinue :: SingleStep -> GHCi ()
1543 doContinue step = do
1544 session <- getSession
1545 runResult <- io $ GHC.resume session step
1546 afterRunStmt runResult
1549 abandonCmd :: String -> GHCi ()
1550 abandonCmd = noArgs $ do
1552 b <- io $ GHC.abandon s -- the prompt will change to indicate the new context
1553 when (not b) $ io $ putStrLn "There is no computation running."
1556 deleteCmd :: String -> GHCi ()
1557 deleteCmd argLine = do
1558 deleteSwitch $ words argLine
1560 deleteSwitch :: [String] -> GHCi ()
1562 io $ putStrLn "The delete command requires at least one argument."
1563 -- delete all break points
1564 deleteSwitch ("*":_rest) = discardActiveBreakPoints
1565 deleteSwitch idents = do
1566 mapM_ deleteOneBreak idents
1568 deleteOneBreak :: String -> GHCi ()
1570 | all isDigit str = deleteBreak (read str)
1571 | otherwise = return ()
1573 historyCmd :: String -> GHCi ()
1575 | null arg = history 20
1576 | all isDigit arg = history (read arg)
1577 | otherwise = io $ putStrLn "Syntax: :history [num]"
1581 resumes <- io $ GHC.getResumeContext s
1583 [] -> io $ putStrLn "Not stopped at a breakpoint"
1585 let hist = GHC.resumeHistory r
1586 (took,rest) = splitAt num hist
1587 spans <- mapM (io . GHC.getHistorySpan s) took
1588 let nums = map (printf "-%-3d:") [(1::Int)..]
1589 printForUser (vcat (zipWith (<+>) (map text nums) (map ppr spans)))
1590 io $ putStrLn $ if null rest then "<end of history>" else "..."
1592 backCmd :: String -> GHCi ()
1593 backCmd = noArgs $ do
1595 (names, ix, span) <- io $ GHC.back s
1596 printForUser $ ptext SLIT("Logged breakpoint at") <+> ppr span
1597 printTypeOfNames s names
1598 -- run the command set with ":set stop <cmd>"
1600 enqueueCommands [stop st]
1602 forwardCmd :: String -> GHCi ()
1603 forwardCmd = noArgs $ do
1605 (names, ix, span) <- io $ GHC.forward s
1606 printForUser $ (if (ix == 0)
1607 then ptext SLIT("Stopped at")
1608 else ptext SLIT("Logged breakpoint at")) <+> ppr span
1609 printTypeOfNames s names
1610 -- run the command set with ":set stop <cmd>"
1612 enqueueCommands [stop st]
1614 -- handle the "break" command
1615 breakCmd :: String -> GHCi ()
1616 breakCmd argLine = do
1617 session <- getSession
1618 breakSwitch session $ words argLine
1620 breakSwitch :: Session -> [String] -> GHCi ()
1621 breakSwitch _session [] = do
1622 io $ putStrLn "The break command requires at least one argument."
1623 breakSwitch session args@(arg1:rest)
1624 | looksLikeModuleName arg1 = do
1625 mod <- wantInterpretedModule arg1
1626 breakByModule session mod rest
1627 | all isDigit arg1 = do
1628 (toplevel, _) <- io $ GHC.getContext session
1630 (mod : _) -> breakByModuleLine mod (read arg1) rest
1632 io $ putStrLn "Cannot find default module for breakpoint."
1633 io $ putStrLn "Perhaps no modules are loaded for debugging?"
1634 | otherwise = do -- try parsing it as an identifier
1635 wantNameFromInterpretedModule noCanDo arg1 $ \name -> do
1636 let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
1637 if GHC.isGoodSrcLoc loc
1638 then findBreakAndSet (GHC.nameModule name) $
1639 findBreakByCoord (Just (GHC.srcLocFile loc))
1640 (GHC.srcLocLine loc,
1642 else noCanDo name $ text "can't find its location: " <> ppr loc
1644 noCanDo n why = printForUser $
1645 text "cannot set breakpoint on " <> ppr n <> text ": " <> why
1647 breakByModule :: Session -> Module -> [String] -> GHCi ()
1648 breakByModule session mod args@(arg1:rest)
1649 | all isDigit arg1 = do -- looks like a line number
1650 breakByModuleLine mod (read arg1) rest
1651 | otherwise = io $ putStrLn "Invalid arguments to :break"
1653 breakByModuleLine :: Module -> Int -> [String] -> GHCi ()
1654 breakByModuleLine mod line args
1655 | [] <- args = findBreakAndSet mod $ findBreakByLine line
1656 | [col] <- args, all isDigit col =
1657 findBreakAndSet mod $ findBreakByCoord Nothing (line, read col)
1658 | otherwise = io $ putStrLn "Invalid arguments to :break"
1660 findBreakAndSet :: Module -> (TickArray -> Maybe (Int, SrcSpan)) -> GHCi ()
1661 findBreakAndSet mod lookupTickTree = do
1662 tickArray <- getTickArray mod
1663 (breakArray, _) <- getModBreak mod
1664 case lookupTickTree tickArray of
1665 Nothing -> io $ putStrLn $ "No breakpoints found at that location."
1666 Just (tick, span) -> do
1667 success <- io $ setBreakFlag True breakArray tick
1668 session <- getSession
1672 recordBreak $ BreakLocation
1679 text "Breakpoint " <> ppr nm <>
1681 then text " was already set at " <> ppr span
1682 else text " activated at " <> ppr span
1684 printForUser $ text "Breakpoint could not be activated at"
1687 -- When a line number is specified, the current policy for choosing
1688 -- the best breakpoint is this:
1689 -- - the leftmost complete subexpression on the specified line, or
1690 -- - the leftmost subexpression starting on the specified line, or
1691 -- - the rightmost subexpression enclosing the specified line
1693 findBreakByLine :: Int -> TickArray -> Maybe (BreakIndex,SrcSpan)
1694 findBreakByLine line arr
1695 | not (inRange (bounds arr) line) = Nothing
1697 listToMaybe (sortBy leftmost_largest complete) `mplus`
1698 listToMaybe (sortBy leftmost_smallest incomplete) `mplus`
1699 listToMaybe (sortBy rightmost ticks)
1703 starts_here = [ tick | tick@(nm,span) <- ticks,
1704 GHC.srcSpanStartLine span == line ]
1706 (complete,incomplete) = partition ends_here starts_here
1707 where ends_here (nm,span) = GHC.srcSpanEndLine span == line
1709 findBreakByCoord :: Maybe FastString -> (Int,Int) -> TickArray
1710 -> Maybe (BreakIndex,SrcSpan)
1711 findBreakByCoord mb_file (line, col) arr
1712 | not (inRange (bounds arr) line) = Nothing
1714 listToMaybe (sortBy rightmost contains) `mplus`
1715 listToMaybe (sortBy leftmost_smallest after_here)
1719 -- the ticks that span this coordinate
1720 contains = [ tick | tick@(nm,span) <- ticks, span `spans` (line,col),
1721 is_correct_file span ]
1723 is_correct_file span
1724 | Just f <- mb_file = GHC.srcSpanFile span == f
1727 after_here = [ tick | tick@(nm,span) <- ticks,
1728 GHC.srcSpanStartLine span == line,
1729 GHC.srcSpanStartCol span >= col ]
1732 leftmost_smallest (_,a) (_,b) = a `compare` b
1733 leftmost_largest (_,a) (_,b) = (GHC.srcSpanStart a `compare` GHC.srcSpanStart b)
1735 (GHC.srcSpanEnd b `compare` GHC.srcSpanEnd a)
1736 rightmost (_,a) (_,b) = b `compare` a
1738 spans :: SrcSpan -> (Int,Int) -> Bool
1739 spans span (l,c) = GHC.srcSpanStart span <= loc && loc <= GHC.srcSpanEnd span
1740 where loc = GHC.mkSrcLoc (GHC.srcSpanFile span) l c
1742 -- for now, use ANSI bold on Unixy systems. On Windows, we add a line
1743 -- of carets under the active expression instead. The Windows console
1744 -- doesn't support ANSI escape sequences, and most Unix terminals
1745 -- (including xterm) do, so this is a reasonable guess until we have a
1746 -- proper termcap/terminfo library.
1747 #if !defined(mingw32_TARGET_OS)
1753 start_bold = BS.pack "\ESC[1m"
1754 end_bold = BS.pack "\ESC[0m"
1756 listCmd :: String -> GHCi ()
1758 mb_span <- getCurrentBreakSpan
1760 Nothing -> printForUser $ text "not stopped at a breakpoint; nothing to list"
1761 Just span | GHC.isGoodSrcSpan span -> io $ listAround span True
1762 | otherwise -> printForUser $ text "unable to list source for" <+> ppr span
1763 listCmd str = list2 (words str)
1765 list2 [arg] | all isDigit arg = do
1766 session <- getSession
1767 (toplevel, _) <- io $ GHC.getContext session
1769 [] -> io $ putStrLn "No module to list"
1770 (mod : _) -> listModuleLine mod (read arg)
1771 list2 [arg1,arg2] | looksLikeModuleName arg1, all isDigit arg2 = do
1772 mod <- wantInterpretedModule arg1
1773 listModuleLine mod (read arg2)
1775 wantNameFromInterpretedModule noCanDo arg $ \name -> do
1776 let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
1777 if GHC.isGoodSrcLoc loc
1779 tickArray <- getTickArray (GHC.nameModule name)
1780 let mb_span = findBreakByCoord (Just (GHC.srcLocFile loc))
1781 (GHC.srcLocLine loc, GHC.srcLocCol loc)
1784 Nothing -> io $ listAround (GHC.srcLocSpan loc) False
1785 Just (_,span) -> io $ listAround span False
1787 noCanDo name $ text "can't find its location: " <>
1790 noCanDo n why = printForUser $
1791 text "cannot list source code for " <> ppr n <> text ": " <> why
1793 io $ putStrLn "syntax: :list [<line> | <module> <line> | <identifier>]"
1795 listModuleLine :: Module -> Int -> GHCi ()
1796 listModuleLine modl line = do
1797 session <- getSession
1798 graph <- io (GHC.getModuleGraph session)
1799 let this = filter ((== modl) . GHC.ms_mod) graph
1801 [] -> panic "listModuleLine"
1803 let filename = fromJust (ml_hs_file (GHC.ms_location summ))
1804 loc = GHC.mkSrcLoc (mkFastString (filename)) line 0
1805 io $ listAround (GHC.srcLocSpan loc) False
1807 -- | list a section of a source file around a particular SrcSpan.
1808 -- If the highlight flag is True, also highlight the span using
1809 -- start_bold/end_bold.
1810 listAround span do_highlight = do
1812 contents <- BS.readFile (pwd `joinFileName` unpackFS file)
1814 lines = BS.split '\n' contents
1815 these_lines = take (line2 - line1 + 1 + pad_before + pad_after) $
1816 drop (line1 - 1 - pad_before) $ lines
1817 fst_line = max 1 (line1 - pad_before)
1818 line_nos = [ fst_line .. ]
1820 highlighted | do_highlight = zipWith highlight line_nos these_lines
1821 | otherwise = these_lines
1823 bs_line_nos = [ BS.pack (show l ++ " ") | l <- line_nos ]
1824 prefixed = zipWith BS.append bs_line_nos highlighted
1826 BS.putStrLn (BS.join (BS.pack "\n") prefixed)
1828 file = GHC.srcSpanFile span
1829 line1 = GHC.srcSpanStartLine span
1830 col1 = GHC.srcSpanStartCol span
1831 line2 = GHC.srcSpanEndLine span
1832 col2 = GHC.srcSpanEndCol span
1834 pad_before | line1 == 1 = 0
1838 highlight | do_bold = highlight_bold
1839 | otherwise = highlight_carets
1841 highlight_bold no line
1842 | no == line1 && no == line2
1843 = let (a,r) = BS.splitAt col1 line
1844 (b,c) = BS.splitAt (col2-col1) r
1846 BS.concat [a,start_bold,b,end_bold,c]
1848 = let (a,b) = BS.splitAt col1 line in
1849 BS.concat [a, start_bold, b]
1851 = let (a,b) = BS.splitAt col2 line in
1852 BS.concat [a, end_bold, b]
1855 highlight_carets no line
1856 | no == line1 && no == line2
1857 = BS.concat [line, nl, indent, BS.replicate col1 ' ',
1858 BS.replicate (col2-col1) '^']
1860 = BS.concat [line, nl, indent, BS.replicate col1 ' ',
1861 BS.replicate (BS.length line-col1) '^']
1863 = BS.concat [line, nl, indent, BS.replicate col2 '^']
1866 indent = BS.pack " "
1867 nl = BS.singleton '\n'
1869 -- --------------------------------------------------------------------------
1872 getTickArray :: Module -> GHCi TickArray
1873 getTickArray modl = do
1875 let arrmap = tickarrays st
1876 case lookupModuleEnv arrmap modl of
1877 Just arr -> return arr
1879 (breakArray, ticks) <- getModBreak modl
1880 let arr = mkTickArray (assocs ticks)
1881 setGHCiState st{tickarrays = extendModuleEnv arrmap modl arr}
1884 discardTickArrays :: GHCi ()
1885 discardTickArrays = do
1887 setGHCiState st{tickarrays = emptyModuleEnv}
1889 mkTickArray :: [(BreakIndex,SrcSpan)] -> TickArray
1891 = accumArray (flip (:)) [] (1, max_line)
1892 [ (line, (nm,span)) | (nm,span) <- ticks,
1893 line <- srcSpanLines span ]
1895 max_line = foldr max 0 (map GHC.srcSpanEndLine (map snd ticks))
1896 srcSpanLines span = [ GHC.srcSpanStartLine span ..
1897 GHC.srcSpanEndLine span ]
1899 lookupModule :: String -> GHCi Module
1900 lookupModule modName
1901 = do session <- getSession
1902 io (GHC.findModule session (GHC.mkModuleName modName) Nothing)
1904 -- don't reset the counter back to zero?
1905 discardActiveBreakPoints :: GHCi ()
1906 discardActiveBreakPoints = do
1908 mapM (turnOffBreak.snd) (breaks st)
1909 setGHCiState $ st { breaks = [] }
1911 deleteBreak :: Int -> GHCi ()
1912 deleteBreak identity = do
1914 let oldLocations = breaks st
1915 (this,rest) = partition (\loc -> fst loc == identity) oldLocations
1917 then printForUser (text "Breakpoint" <+> ppr identity <+>
1918 text "does not exist")
1920 mapM (turnOffBreak.snd) this
1921 setGHCiState $ st { breaks = rest }
1923 turnOffBreak loc = do
1924 (arr, _) <- getModBreak (breakModule loc)
1925 io $ setBreakFlag False arr (breakTick loc)
1927 getModBreak :: Module -> GHCi (GHC.BreakArray, Array Int SrcSpan)
1928 getModBreak mod = do
1929 session <- getSession
1930 Just mod_info <- io $ GHC.getModuleInfo session mod
1931 let modBreaks = GHC.modInfoModBreaks mod_info
1932 let array = GHC.modBreaks_flags modBreaks
1933 let ticks = GHC.modBreaks_locs modBreaks
1934 return (array, ticks)
1936 setBreakFlag :: Bool -> GHC.BreakArray -> Int -> IO Bool
1937 setBreakFlag toggle array index
1938 | toggle = GHC.setBreakOn array index
1939 | otherwise = GHC.setBreakOff array index