1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2005-2006
8 -----------------------------------------------------------------------------
10 module InteractiveUI ( interactiveUI, ghciWelcomeMsg ) where
12 #include "HsVersions.h"
20 import GHC ( Session, LoadHowMuch(..), Target(..), TargetId(..),
21 Module, ModuleName, TyThing(..), Phase,
22 BreakIndex, SrcSpan, Resume, SingleStep )
32 import HscTypes ( implicitTyThings )
33 import qualified RdrName ( getGRE_NameQualifier_maybes ) -- should this come via GHC?
34 import Outputable hiding (printForUser, printForUserPartWay)
35 import Module -- for ModuleEnv
39 -- Other random utilities
41 import BasicTypes hiding (isTopLevel)
42 import Panic hiding (showException)
48 import Maybes ( orElse )
52 #ifndef mingw32_HOST_OS
53 import System.Posix hiding (getEnv)
55 import GHC.ConsoleHandler ( flushConsole )
56 import qualified System.Win32
60 import Control.Concurrent ( yield ) -- Used in readline loop
61 import System.Console.Readline as Readline
66 import Control.Exception as Exception
67 -- import Control.Concurrent
69 import qualified Data.ByteString.Char8 as BS
73 import System.Environment
74 import System.Exit ( exitWith, ExitCode(..) )
75 import System.Directory
77 import System.IO.Error as IO
81 import Control.Monad as Monad
84 import Foreign.C ( withCStringLen )
85 import GHC.Exts ( unsafeCoerce# )
86 import GHC.IOBase ( IOErrorType(InvalidArgument) )
88 import Data.IORef ( IORef, readIORef, writeIORef )
91 import System.Posix.Internals ( setNonBlockingFD )
94 -----------------------------------------------------------------------------
96 ghciWelcomeMsg :: String
97 ghciWelcomeMsg = "GHCi, version " ++ cProjectVersion ++
98 ": http://www.haskell.org/ghc/ :? for help"
100 cmdName :: Command -> String
101 cmdName (n,_,_,_) = n
103 macros_ref :: IORef [Command]
104 GLOBAL_VAR(macros_ref, [], [Command])
106 builtin_commands :: [Command]
108 -- Hugs users are accustomed to :e, so make sure it doesn't overlap
109 ("?", keepGoing help, Nothing, completeNone),
110 ("add", keepGoingPaths addModule, Just filenameWordBreakChars, completeFilename),
111 ("abandon", keepGoing abandonCmd, Nothing, completeNone),
112 ("break", keepGoing breakCmd, Nothing, completeIdentifier),
113 ("back", keepGoing backCmd, Nothing, completeNone),
114 ("browse", keepGoing (browseCmd False), Nothing, completeModule),
115 ("browse!", keepGoing (browseCmd True), Nothing, completeModule),
116 ("cd", keepGoing changeDirectory, Just filenameWordBreakChars, completeFilename),
117 ("check", keepGoing checkModule, Nothing, completeHomeModule),
118 ("continue", keepGoing continueCmd, Nothing, completeNone),
119 ("cmd", keepGoing cmdCmd, Nothing, completeIdentifier),
120 ("ctags", keepGoing createCTagsFileCmd, Just filenameWordBreakChars, completeFilename),
121 ("def", keepGoing (defineMacro False), Nothing, completeIdentifier),
122 ("def!", keepGoing (defineMacro True), Nothing, completeIdentifier),
123 ("delete", keepGoing deleteCmd, Nothing, completeNone),
124 ("e", keepGoing editFile, Just filenameWordBreakChars, completeFilename),
125 ("edit", keepGoing editFile, Just filenameWordBreakChars, completeFilename),
126 ("etags", keepGoing createETagsFileCmd, Just filenameWordBreakChars, completeFilename),
127 ("force", keepGoing forceCmd, Nothing, completeIdentifier),
128 ("forward", keepGoing forwardCmd, Nothing, completeNone),
129 ("help", keepGoing help, Nothing, completeNone),
130 ("history", keepGoing historyCmd, Nothing, completeNone),
131 ("info", keepGoing info, Nothing, completeIdentifier),
132 ("kind", keepGoing kindOfType, Nothing, completeIdentifier),
133 ("load", keepGoingPaths loadModule_, Just filenameWordBreakChars, completeHomeModuleOrFile),
134 ("list", keepGoing listCmd, Nothing, completeNone),
135 ("module", keepGoing setContext, Nothing, completeModule),
136 ("main", keepGoing runMain, Nothing, completeIdentifier),
137 ("print", keepGoing printCmd, Nothing, completeIdentifier),
138 ("quit", quit, Nothing, completeNone),
139 ("reload", keepGoing reloadModule, Nothing, completeNone),
140 ("set", keepGoing setCmd, Just flagWordBreakChars, completeSetOptions),
141 ("show", keepGoing showCmd, Nothing, completeNone),
142 ("sprint", keepGoing sprintCmd, Nothing, completeIdentifier),
143 ("step", keepGoing stepCmd, Nothing, completeIdentifier),
144 ("steplocal", keepGoing stepLocalCmd, Nothing, completeIdentifier),
145 ("stepmodule",keepGoing stepModuleCmd, Nothing, completeIdentifier),
146 ("type", keepGoing typeOfExpr, Nothing, completeIdentifier),
147 ("trace", keepGoing traceCmd, Nothing, completeIdentifier),
148 ("undef", keepGoing undefineMacro, Nothing, completeMacro),
149 ("unset", keepGoing unsetOptions, Just flagWordBreakChars, completeSetOptions)
153 -- We initialize readline (in the interactiveUI function) to use
154 -- word_break_chars as the default set of completion word break characters.
155 -- This can be overridden for a particular command (for example, filename
156 -- expansion shouldn't consider '/' to be a word break) by setting the third
157 -- entry in the Command tuple above.
159 -- NOTE: in order for us to override the default correctly, any custom entry
160 -- must be a SUBSET of word_break_chars.
161 word_break_chars, flagWordBreakChars, filenameWordBreakChars :: String
162 word_break_chars = let symbols = "!#$%&*+/<=>?@\\^|-~"
163 specials = "(),;[]`{}"
165 in spaces ++ specials ++ symbols
166 flagWordBreakChars = " \t\n"
167 filenameWordBreakChars = " \t\n\\`@$><=;|&{(" -- bash defaults
170 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
171 keepGoing a str = a str >> return False
173 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
174 keepGoingPaths a str = a (toArgs str) >> return False
176 shortHelpText :: String
177 shortHelpText = "use :? for help.\n"
181 " Commands available from the prompt:\n" ++
183 " <statement> evaluate/run <statement>\n" ++
184 " : repeat last command\n" ++
185 " :{\\n ..lines.. \\n:}\\n multiline command\n" ++
186 " :add <filename> ... add module(s) to the current target set\n" ++
187 " :browse[!] [[*]<mod>] display the names defined by module <mod>\n" ++
188 " (!: more details; *: all top-level names)\n" ++
189 " :cd <dir> change directory to <dir>\n" ++
190 " :cmd <expr> run the commands returned by <expr>::IO String\n" ++
191 " :ctags [<file>] create tags file for Vi (default: \"tags\")\n" ++
192 " :def <cmd> <expr> define a command :<cmd>\n" ++
193 " :edit <file> edit file\n" ++
194 " :edit edit last module\n" ++
195 " :etags [<file>] create tags file for Emacs (default: \"TAGS\")\n" ++
196 " :help, :? display this list of commands\n" ++
197 " :info [<name> ...] display information about the given names\n" ++
198 " :kind <type> show the kind of <type>\n" ++
199 " :load <filename> ... load module(s) and their dependents\n" ++
200 " :main [<arguments> ...] run the main function with the given arguments\n" ++
201 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
202 " :quit exit GHCi\n" ++
203 " :reload reload the current module set\n" ++
204 " :type <expr> show the type of <expr>\n" ++
205 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
206 " :!<command> run the shell command <command>\n" ++
208 " -- Commands for debugging:\n" ++
210 " :abandon at a breakpoint, abandon current computation\n" ++
211 " :back go back in the history (after :trace)\n" ++
212 " :break [<mod>] <l> [<col>] set a breakpoint at the specified location\n" ++
213 " :break <name> set a breakpoint on the specified function\n" ++
214 " :continue resume after a breakpoint\n" ++
215 " :delete <number> delete the specified breakpoint\n" ++
216 " :delete * delete all breakpoints\n" ++
217 " :force <expr> print <expr>, forcing unevaluated parts\n" ++
218 " :forward go forward in the history (after :back)\n" ++
219 " :history [<n>] show the last <n> items in the history (after :trace)\n" ++
220 " :print [<name> ...] prints a value without forcing its computation\n" ++
221 " :sprint [<name> ...] simplifed version of :print\n" ++
222 " :step single-step after stopping at a breakpoint\n"++
223 " :step <expr> single-step into <expr>\n"++
224 " :steplocal single-step restricted to the current top level decl.\n"++
225 " :stepmodule single-step restricted to the current module\n"++
226 " :trace trace after stopping at a breakpoint\n"++
227 " :trace <expr> trace into <expr> (remembers breakpoints for :history)\n"++
230 " -- Commands for changing settings:\n" ++
232 " :set <option> ... set options\n" ++
233 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
234 " :set prog <progname> set the value returned by System.getProgName\n" ++
235 " :set prompt <prompt> set the prompt used in GHCi\n" ++
236 " :set editor <cmd> set the command used for :edit\n" ++
237 " :set stop <cmd> set the command to run when a breakpoint is hit\n" ++
238 " :unset <option> ... unset options\n" ++
240 " Options for ':set' and ':unset':\n" ++
242 " +r revert top-level expressions after each evaluation\n" ++
243 " +s print timing/memory stats after each evaluation\n" ++
244 " +t print type after evaluation\n" ++
245 " -<flags> most GHC command line flags can also be set here\n" ++
246 " (eg. -v2, -fglasgow-exts, etc.)\n" ++
247 " for GHCi-specific flags, see User's Guide,\n"++
248 " Flag reference, Interactive-mode options\n" ++
250 " -- Commands for displaying information:\n" ++
252 " :show bindings show the current bindings made at the prompt\n" ++
253 " :show breaks show the active breakpoints\n" ++
254 " :show context show the breakpoint context\n" ++
255 " :show modules show the currently loaded modules\n" ++
256 " :show packages show the currently active package flags\n" ++
257 " :show languages show the currently active language flags\n" ++
258 " :show <setting> show anything that can be set with :set (e.g. args)\n" ++
261 findEditor :: IO String
266 win <- System.Win32.getWindowsDirectory
267 return (win `joinFileName` "notepad.exe")
272 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
273 interactiveUI session srcs maybe_expr = do
274 -- HACK! If we happen to get into an infinite loop (eg the user
275 -- types 'let x=x in x' at the prompt), then the thread will block
276 -- on a blackhole, and become unreachable during GC. The GC will
277 -- detect that it is unreachable and send it the NonTermination
278 -- exception. However, since the thread is unreachable, everything
279 -- it refers to might be finalized, including the standard Handles.
280 -- This sounds like a bug, but we don't have a good solution right
286 -- Initialise buffering for the *interpreted* I/O system
287 initInterpBuffering session
289 when (isNothing maybe_expr) $ do
290 -- Only for GHCi (not runghc and ghc -e):
292 -- Turn buffering off for the compiled program's stdout/stderr
294 -- Turn buffering off for GHCi's stdout
296 hSetBuffering stdout NoBuffering
297 -- We don't want the cmd line to buffer any input that might be
298 -- intended for the program, so unbuffer stdin.
299 hSetBuffering stdin NoBuffering
301 -- initial context is just the Prelude
302 prel_mod <- GHC.findModule session (GHC.mkModuleName "Prelude")
304 GHC.setContext session [] [prel_mod]
308 Readline.setAttemptedCompletionFunction (Just completeWord)
309 --Readline.parseAndBind "set show-all-if-ambiguous 1"
311 Readline.setBasicWordBreakCharacters word_break_chars
312 Readline.setCompleterWordBreakCharacters word_break_chars
313 Readline.setCompletionAppendCharacter Nothing
316 default_editor <- findEditor
318 startGHCi (runGHCi srcs maybe_expr)
319 GHCiState{ progname = "<interactive>",
323 editor = default_editor,
329 tickarrays = emptyModuleEnv,
330 last_command = Nothing,
332 remembered_ctx = Nothing
336 Readline.resetTerminal Nothing
341 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
342 runGHCi paths maybe_expr = do
343 let read_dot_files = not opt_IgnoreDotGhci
345 when (read_dot_files) $ do
348 exists <- io (doesFileExist file)
350 dir_ok <- io (checkPerms ".")
351 file_ok <- io (checkPerms file)
352 when (dir_ok && file_ok) $ do
353 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
356 Right hdl -> runCommands (fileLoop hdl False False)
358 when (read_dot_files) $ do
359 -- Read in $HOME/.ghci
360 either_dir <- io (IO.try getHomeDirectory)
364 cwd <- io (getCurrentDirectory)
365 when (dir /= cwd) $ do
366 let file = dir ++ "/.ghci"
367 ok <- io (checkPerms file)
369 either_hdl <- io (IO.try (openFile file ReadMode))
372 Right hdl -> runCommands (fileLoop hdl False False)
374 -- Perform a :load for files given on the GHCi command line
375 -- When in -e mode, if the load fails then we want to stop
376 -- immediately rather than going on to evaluate the expression.
377 when (not (null paths)) $ do
378 ok <- ghciHandle (\e -> do showException e; return Failed) $
380 when (isJust maybe_expr && failed ok) $
381 io (exitWith (ExitFailure 1))
383 -- if verbosity is greater than 0, or we are connected to a
384 -- terminal, display the prompt in the interactive loop.
385 is_tty <- io (hIsTerminalDevice stdin)
386 dflags <- getDynFlags
387 let show_prompt = verbosity dflags > 0 || is_tty
392 #if defined(mingw32_HOST_OS)
393 -- The win32 Console API mutates the first character of
394 -- type-ahead when reading from it in a non-buffered manner. Work
395 -- around this by flushing the input buffer of type-ahead characters,
396 -- but only if stdin is available.
397 flushed <- io (IO.try (GHC.ConsoleHandler.flushConsole stdin))
399 Left err | isDoesNotExistError err -> return ()
400 | otherwise -> io (ioError err)
401 Right () -> return ()
403 -- enter the interactive loop
404 interactiveLoop is_tty show_prompt
406 -- just evaluate the expression we were given
411 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
414 interactiveLoop :: Bool -> Bool -> GHCi ()
415 interactiveLoop is_tty show_prompt =
416 -- Ignore ^C exceptions caught here
417 ghciHandleDyn (\e -> case e of
419 #if defined(mingw32_HOST_OS)
422 interactiveLoop is_tty show_prompt
423 _other -> return ()) $
425 ghciUnblock $ do -- unblock necessary if we recursed from the
426 -- exception handler above.
428 -- read commands from stdin
431 then runCommands readlineLoop
432 else runCommands (fileLoop stdin show_prompt is_tty)
434 runCommands (fileLoop stdin show_prompt is_tty)
438 -- NOTE: We only read .ghci files if they are owned by the current user,
439 -- and aren't world writable. Otherwise, we could be accidentally
440 -- running code planted by a malicious third party.
442 -- Furthermore, We only read ./.ghci if . is owned by the current user
443 -- and isn't writable by anyone else. I think this is sufficient: we
444 -- don't need to check .. and ../.. etc. because "." always refers to
445 -- the same directory while a process is running.
447 checkPerms :: String -> IO Bool
448 #ifdef mingw32_HOST_OS
453 Util.handle (\_ -> return False) $ do
454 st <- getFileStatus name
456 if fileOwner st /= me then do
457 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
460 let mode = fileMode st
461 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
462 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
464 putStrLn $ "*** WARNING: " ++ name ++
465 " is writable by someone else, IGNORING!"
470 fileLoop :: Handle -> Bool -> Bool -> GHCi (Maybe String)
471 fileLoop hdl show_prompt is_tty = do
472 when show_prompt $ do
475 l <- io (IO.try (hGetLine hdl))
477 Left e | isEOFError e -> return Nothing
478 | InvalidArgument <- etype -> return Nothing
479 | otherwise -> io (ioError e)
480 where etype = ioeGetErrorType e
481 -- treat InvalidArgument in the same way as EOF:
482 -- this can happen if the user closed stdin, or
483 -- perhaps did getContents which closes stdin at
486 str <- io $ consoleInputToUnicode is_tty l
489 #ifdef mingw32_HOST_OS
490 -- Convert the console input into Unicode according to the current code page.
491 -- The Windows console stores Unicode characters directly, so this is a
492 -- rather roundabout way of doing things... oh well.
493 -- See #782, #1483, #1649
494 consoleInputToUnicode :: Bool -> String -> IO String
495 consoleInputToUnicode is_tty str
497 cp <- System.Win32.getConsoleCP
498 System.Win32.stringToUnicode cp str
500 decodeStringAsUTF8 str
502 -- for Unix, assume the input is in UTF-8 and decode it to a Unicode String.
504 consoleInputToUnicode :: Bool -> String -> IO String
505 consoleInputToUnicode _is_tty str = decodeStringAsUTF8 str
508 decodeStringAsUTF8 :: String -> IO String
509 decodeStringAsUTF8 str =
510 withCStringLen str $ \(cstr,len) ->
511 utf8DecodeString (castPtr cstr :: Ptr Word8) len
513 mkPrompt :: GHCi String
515 session <- getSession
516 (toplevs,exports) <- io (GHC.getContext session)
517 resumes <- io $ GHC.getResumeContext session
518 -- st <- getGHCiState
524 let ix = GHC.resumeHistoryIx r
526 then return (brackets (ppr (GHC.resumeSpan r)) <> space)
528 let hist = GHC.resumeHistory r !! (ix-1)
529 span <- io$ GHC.getHistorySpan session hist
530 return (brackets (ppr (negate ix) <> char ':'
531 <+> ppr span) <> space)
533 dots | _:rs <- resumes, not (null rs) = text "... "
540 -- let (btoplevs, bexports) = fromMaybe ([],[]) (remembered_ctx st) in
541 -- hsep (map (\m -> text "!*" <> ppr (GHC.moduleName m)) btoplevs) <+>
542 -- hsep (map (\m -> char '!' <> ppr (GHC.moduleName m)) bexports) <+>
543 hsep (map (\m -> char '*' <> ppr (GHC.moduleName m)) toplevs) <+>
544 hsep (map (ppr . GHC.moduleName) exports)
546 deflt_prompt = dots <> context_bit <> modules_bit
548 f ('%':'s':xs) = deflt_prompt <> f xs
549 f ('%':'%':xs) = char '%' <> f xs
550 f (x:xs) = char x <> f xs
554 return (showSDoc (f (prompt st)))
558 readlineLoop :: GHCi (Maybe String)
561 saveSession -- for use by completion
563 l <- io (readline prompt `finally` setNonBlockingFD 0)
564 -- readline sometimes puts stdin into blocking mode,
565 -- so we need to put it back for the IO library
568 Nothing -> return Nothing
571 str <- io $ consoleInputToUnicode True l
575 queryQueue :: GHCi (Maybe String)
580 c:cs -> do setGHCiState st{ cmdqueue = cs }
583 runCommands :: GHCi (Maybe String) -> GHCi ()
584 runCommands getCmd = do
585 mb_cmd <- noSpace queryQueue
586 mb_cmd <- maybe (noSpace getCmd) (return . Just) mb_cmd
590 b <- ghciHandle handler (doCommand c)
591 if b then return () else runCommands getCmd
593 noSpace q = q >>= maybe (return Nothing)
594 (\c->case removeSpaces c of
596 ":{" -> multiLineCmd q
597 c -> return (Just c) )
601 setGHCiState st{ prompt = "%s| " }
602 mb_cmd <- collectCommand q ""
603 getGHCiState >>= \st->setGHCiState st{ prompt = p }
605 -- we can't use removeSpaces for the sublines here, so
606 -- multiline commands are somewhat more brittle against
607 -- fileformat errors (such as \r in dos input on unix),
608 -- we get rid of any extra spaces for the ":}" test;
609 -- we also avoid silent failure if ":}" is not found;
610 -- and since there is no (?) valid occurrence of \r (as
611 -- opposed to its String representation, "\r") inside a
612 -- ghci command, we replace any such with ' ' (argh:-(
613 collectCommand q c = q >>=
614 maybe (io (ioError collectError))
615 (\l->if removeSpaces l == ":}"
616 then return (Just $ removeSpaces c)
617 else collectCommand q (c++map normSpace l))
618 where normSpace '\r' = ' '
620 -- QUESTION: is userError the one to use here?
621 collectError = userError "unterminated multiline command :{ .. :}"
622 doCommand (':' : cmd) = specialCommand cmd
623 doCommand stmt = do timeIt $ runStmt stmt GHC.RunToCompletion
626 enqueueCommands :: [String] -> GHCi ()
627 enqueueCommands cmds = do
629 setGHCiState st{ cmdqueue = cmds ++ cmdqueue st }
632 -- This version is for the GHC command-line option -e. The only difference
633 -- from runCommand is that it catches the ExitException exception and
634 -- exits, rather than printing out the exception.
635 runCommandEval :: String -> GHCi Bool
636 runCommandEval c = ghciHandle handleEval (doCommand c)
638 handleEval (ExitException code) = io (exitWith code)
639 handleEval e = do handler e
640 io (exitWith (ExitFailure 1))
642 doCommand (':' : command) = specialCommand command
644 = do r <- runStmt stmt GHC.RunToCompletion
646 False -> io (exitWith (ExitFailure 1))
647 -- failure to run the command causes exit(1) for ghc -e.
650 runStmt :: String -> SingleStep -> GHCi Bool
652 | null (filter (not.isSpace) stmt) = return False
653 | ["import", mod] <- words stmt = keepGoing setContext ('+':mod)
655 = do st <- getGHCiState
656 session <- getSession
657 result <- io $ withProgName (progname st) $ withArgs (args st) $
658 GHC.runStmt session stmt step
659 afterRunStmt (const True) result
662 --afterRunStmt :: GHC.RunResult -> GHCi Bool
663 -- False <=> the statement failed to compile
664 afterRunStmt :: (SrcSpan -> Bool) -> GHC.RunResult -> GHCi Bool
665 afterRunStmt _ (GHC.RunException e) = throw e
666 afterRunStmt step_here run_result = do
667 session <- getSession
668 resumes <- io $ GHC.getResumeContext session
670 GHC.RunOk names -> do
671 show_types <- isOptionSet ShowType
672 when show_types $ printTypeOfNames session names
673 GHC.RunBreak _ names mb_info
674 | isNothing mb_info ||
675 step_here (GHC.resumeSpan $ head resumes) -> do
676 printForUser $ ptext SLIT("Stopped at") <+>
677 ppr (GHC.resumeSpan $ head resumes)
678 -- printTypeOfNames session names
679 let namesSorted = sortBy compareNames names
680 tythings <- catMaybes `liftM`
681 io (mapM (GHC.lookupName session) namesSorted)
682 docs <- io$ pprTypeAndContents session [id | AnId id <- tythings]
683 printForUserPartWay docs
684 maybe (return ()) runBreakCmd mb_info
685 -- run the command set with ":set stop <cmd>"
687 enqueueCommands [stop st]
689 | otherwise -> io(GHC.resume session GHC.SingleStep) >>=
690 afterRunStmt step_here >> return ()
694 io installSignalHandlers
695 b <- isOptionSet RevertCAFs
696 io (when b revertCAFs)
698 return (case run_result of GHC.RunOk _ -> True; _ -> False)
700 runBreakCmd :: GHC.BreakInfo -> GHCi ()
701 runBreakCmd info = do
702 let mod = GHC.breakInfo_module info
703 nm = GHC.breakInfo_number info
705 case [ loc | (_,loc) <- breaks st,
706 breakModule loc == mod, breakTick loc == nm ] of
708 loc:_ | null cmd -> return ()
709 | otherwise -> do enqueueCommands [cmd]; return ()
710 where cmd = onBreakCmd loc
712 printTypeOfNames :: Session -> [Name] -> GHCi ()
713 printTypeOfNames session names
714 = mapM_ (printTypeOfName session) $ sortBy compareNames names
716 compareNames :: Name -> Name -> Ordering
717 n1 `compareNames` n2 = compareWith n1 `compare` compareWith n2
718 where compareWith n = (getOccString n, getSrcSpan n)
720 printTypeOfName :: Session -> Name -> GHCi ()
721 printTypeOfName session n
722 = do maybe_tything <- io (GHC.lookupName session n)
723 case maybe_tything of
725 Just thing -> printTyThing thing
728 data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand
730 specialCommand :: String -> GHCi Bool
731 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
732 specialCommand str = do
733 let (cmd,rest) = break isSpace str
734 maybe_cmd <- lookupCommand cmd
736 GotCommand (_,f,_,_) -> f (dropWhile isSpace rest)
738 do io $ hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
742 do io $ hPutStr stdout ("there is no last command to perform\n"
746 lookupCommand :: String -> GHCi (MaybeCommand)
747 lookupCommand "" = do
749 case last_command st of
750 Just c -> return $ GotCommand c
751 Nothing -> return NoLastCommand
752 lookupCommand str = do
753 mc <- io $ lookupCommand' str
755 setGHCiState st{ last_command = mc }
757 Just c -> GotCommand c
758 Nothing -> BadCommand
760 lookupCommand' :: String -> IO (Maybe Command)
761 lookupCommand' str = do
762 macros <- readIORef macros_ref
763 let cmds = builtin_commands ++ macros
764 -- look for exact match first, then the first prefix match
765 return $ case [ c | c <- cmds, str == cmdName c ] of
767 [] -> case [ c | c@(s,_,_,_) <- cmds, str `isPrefixOf` s ] of
771 getCurrentBreakSpan :: GHCi (Maybe SrcSpan)
772 getCurrentBreakSpan = do
773 session <- getSession
774 resumes <- io $ GHC.getResumeContext session
778 let ix = GHC.resumeHistoryIx r
780 then return (Just (GHC.resumeSpan r))
782 let hist = GHC.resumeHistory r !! (ix-1)
783 span <- io $ GHC.getHistorySpan session hist
786 getCurrentBreakModule :: GHCi (Maybe Module)
787 getCurrentBreakModule = do
788 session <- getSession
789 resumes <- io $ GHC.getResumeContext session
793 let ix = GHC.resumeHistoryIx r
795 then return (GHC.breakInfo_module `liftM` GHC.resumeBreakInfo r)
797 let hist = GHC.resumeHistory r !! (ix-1)
798 return $ Just $ GHC.getHistoryModule hist
800 -----------------------------------------------------------------------------
803 noArgs :: GHCi () -> String -> GHCi ()
805 noArgs _ _ = io $ putStrLn "This command takes no arguments"
807 help :: String -> GHCi ()
808 help _ = io (putStr helpText)
810 info :: String -> GHCi ()
811 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
812 info s = do { let names = words s
813 ; session <- getSession
814 ; dflags <- getDynFlags
815 ; let pefas = dopt Opt_PrintExplicitForalls dflags
816 ; mapM_ (infoThing pefas session) names }
818 infoThing pefas session str = io $ do
819 names <- GHC.parseName session str
820 mb_stuffs <- mapM (GHC.getInfo session) names
821 let filtered = filterOutChildren (\(t,_f,_i) -> t) (catMaybes mb_stuffs)
822 unqual <- GHC.getPrintUnqual session
823 putStrLn (showSDocForUser unqual $
824 vcat (intersperse (text "") $
825 map (pprInfo pefas) filtered))
827 -- Filter out names whose parent is also there Good
828 -- example is '[]', which is both a type and data
829 -- constructor in the same type
830 filterOutChildren :: (a -> TyThing) -> [a] -> [a]
831 filterOutChildren get_thing xs
832 = [x | x <- xs, not (getName (get_thing x) `elemNameSet` implicits)]
834 implicits = mkNameSet [getName t | x <- xs, t <- implicitTyThings (get_thing x)]
836 pprInfo :: PrintExplicitForalls -> (TyThing, Fixity, [GHC.Instance]) -> SDoc
837 pprInfo pefas (thing, fixity, insts)
838 = pprTyThingInContextLoc pefas thing
839 $$ show_fixity fixity
840 $$ vcat (map GHC.pprInstance insts)
843 | fix == GHC.defaultFixity = empty
844 | otherwise = ppr fix <+> ppr (GHC.getName thing)
846 runMain :: String -> GHCi ()
848 let ss = concat $ intersperse "," (map (\ s -> ('"':s)++"\"") (toArgs args))
849 enqueueCommands ['[': ss ++ "] `System.Environment.withArgs` main"]
851 addModule :: [FilePath] -> GHCi ()
853 io (revertCAFs) -- always revert CAFs on load/add.
854 files <- mapM expandPath files
855 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
856 session <- getSession
857 io (mapM_ (GHC.addTarget session) targets)
858 prev_context <- io $ GHC.getContext session
859 ok <- io (GHC.load session LoadAllTargets)
860 afterLoad ok session False prev_context
862 changeDirectory :: String -> GHCi ()
863 changeDirectory "" = do
864 -- :cd on its own changes to the user's home directory
865 either_dir <- io (IO.try getHomeDirectory)
868 Right dir -> changeDirectory dir
869 changeDirectory dir = do
870 session <- getSession
871 graph <- io (GHC.getModuleGraph session)
872 when (not (null graph)) $
873 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
874 prev_context <- io $ GHC.getContext session
875 io (GHC.setTargets session [])
876 io (GHC.load session LoadAllTargets)
877 setContextAfterLoad session prev_context []
878 io (GHC.workingDirectoryChanged session)
879 dir <- expandPath dir
880 io (setCurrentDirectory dir)
882 editFile :: String -> GHCi ()
884 do file <- if null str then chooseEditFile else return str
888 $ throwDyn (CmdLineError "editor not set, use :set editor")
889 io $ system (cmd ++ ' ':file)
892 -- The user didn't specify a file so we pick one for them.
893 -- Our strategy is to pick the first module that failed to load,
894 -- or otherwise the first target.
896 -- XXX: Can we figure out what happened if the depndecy analysis fails
897 -- (e.g., because the porgrammeer mistyped the name of a module)?
898 -- XXX: Can we figure out the location of an error to pass to the editor?
899 -- XXX: if we could figure out the list of errors that occured during the
900 -- last load/reaload, then we could start the editor focused on the first
902 chooseEditFile :: GHCi String
904 do session <- getSession
905 let hasFailed x = io $ fmap not $ GHC.isLoaded session $ GHC.ms_mod_name x
907 graph <- io (GHC.getModuleGraph session)
908 failed_graph <- filterM hasFailed graph
909 let order g = flattenSCCs $ GHC.topSortModuleGraph True g Nothing
911 x : _ -> GHC.ml_hs_file (GHC.ms_location x)
914 case pick (order failed_graph) of
915 Just file -> return file
917 do targets <- io (GHC.getTargets session)
918 case msum (map fromTarget targets) of
919 Just file -> return file
920 Nothing -> throwDyn (CmdLineError "No files to edit.")
922 where fromTarget (GHC.Target (GHC.TargetFile f _) _) = Just f
923 fromTarget _ = Nothing -- when would we get a module target?
925 defineMacro :: Bool{-overwrite-} -> String -> GHCi ()
926 defineMacro overwrite s = do
927 let (macro_name, definition) = break isSpace s
928 macros <- io (readIORef macros_ref)
929 let defined = map cmdName macros
932 then io $ putStrLn "no macros defined"
933 else io $ putStr ("the following macros are defined:\n" ++
936 if (not overwrite && macro_name `elem` defined)
937 then throwDyn (CmdLineError
938 ("macro '" ++ macro_name ++ "' is already defined"))
941 let filtered = [ cmd | cmd <- macros, cmdName cmd /= macro_name ]
943 -- give the expression a type signature, so we can be sure we're getting
944 -- something of the right type.
945 let new_expr = '(' : definition ++ ") :: String -> IO String"
947 -- compile the expression
949 maybe_hv <- io (GHC.compileExpr cms new_expr)
952 Just hv -> io (writeIORef macros_ref --
953 (filtered ++ [(macro_name, runMacro hv, Nothing, completeNone)]))
955 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi Bool
957 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
958 enqueueCommands (lines str)
961 undefineMacro :: String -> GHCi ()
962 undefineMacro str = mapM_ undef (words str)
963 where undef macro_name = do
964 cmds <- io (readIORef macros_ref)
965 if (macro_name `notElem` map cmdName cmds)
966 then throwDyn (CmdLineError
967 ("macro '" ++ macro_name ++ "' is not defined"))
969 io (writeIORef macros_ref (filter ((/= macro_name) . cmdName) cmds))
971 cmdCmd :: String -> GHCi ()
973 let expr = '(' : str ++ ") :: IO String"
974 session <- getSession
975 maybe_hv <- io (GHC.compileExpr session expr)
979 cmds <- io $ (unsafeCoerce# hv :: IO String)
980 enqueueCommands (lines cmds)
983 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
984 loadModule fs = timeIt (loadModule' fs)
986 loadModule_ :: [FilePath] -> GHCi ()
987 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
989 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
990 loadModule' files = do
991 session <- getSession
992 prev_context <- io $ GHC.getContext session
995 discardActiveBreakPoints
996 io (GHC.setTargets session [])
997 io (GHC.load session LoadAllTargets)
1000 let (filenames, phases) = unzip files
1001 exp_filenames <- mapM expandPath filenames
1002 let files' = zip exp_filenames phases
1003 targets <- io (mapM (uncurry GHC.guessTarget) files')
1005 -- NOTE: we used to do the dependency anal first, so that if it
1006 -- fails we didn't throw away the current set of modules. This would
1007 -- require some re-working of the GHC interface, so we'll leave it
1008 -- as a ToDo for now.
1010 io (GHC.setTargets session targets)
1011 doLoad session False prev_context LoadAllTargets
1013 checkModule :: String -> GHCi ()
1015 let modl = GHC.mkModuleName m
1016 session <- getSession
1017 prev_context <- io $ GHC.getContext session
1018 result <- io (GHC.checkModule session modl False)
1020 Nothing -> io $ putStrLn "Nothing"
1021 Just r -> io $ putStrLn (showSDoc (
1022 case GHC.checkedModuleInfo r of
1023 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
1025 (local,global) = partition ((== modl) . GHC.moduleName . GHC.nameModule) scope
1027 (text "global names: " <+> ppr global) $$
1028 (text "local names: " <+> ppr local)
1030 afterLoad (successIf (isJust result)) session False prev_context
1032 reloadModule :: String -> GHCi ()
1034 session <- getSession
1035 prev_context <- io $ GHC.getContext session
1036 doLoad session True prev_context $
1037 if null m then LoadAllTargets
1038 else LoadUpTo (GHC.mkModuleName m)
1041 doLoad :: Session -> Bool -> ([Module],[Module]) -> LoadHowMuch -> GHCi SuccessFlag
1042 doLoad session retain_context prev_context howmuch = do
1043 -- turn off breakpoints before we load: we can't turn them off later, because
1044 -- the ModBreaks will have gone away.
1045 discardActiveBreakPoints
1046 ok <- io (GHC.load session howmuch)
1047 afterLoad ok session retain_context prev_context
1050 afterLoad :: SuccessFlag -> Session -> Bool -> ([Module],[Module]) -> GHCi ()
1051 afterLoad ok session retain_context prev_context = do
1052 io (revertCAFs) -- always revert CAFs on load.
1054 loaded_mod_summaries <- getLoadedModules session
1055 let loaded_mods = map GHC.ms_mod loaded_mod_summaries
1056 loaded_mod_names = map GHC.moduleName loaded_mods
1057 modulesLoadedMsg ok loaded_mod_names
1060 if not retain_context
1062 setGHCiState st{ remembered_ctx = Nothing }
1063 setContextAfterLoad session prev_context loaded_mod_summaries
1065 -- figure out which modules we can keep in the context, which we
1066 -- have to put back, and which we have to remember because they
1067 -- are (temporarily) unavailable. See ghci.prog009, #1873, #1360
1068 let (as,bs) = prev_context
1069 as1 = filter isHomeModule as -- package modules are kept anyway
1070 bs1 = filter isHomeModule bs
1071 (as_ok, as_bad) = partition (`elem` loaded_mods) as1
1072 (bs_ok, bs_bad) = partition (`elem` loaded_mods) bs1
1073 (rem_as, rem_bs) = fromMaybe ([],[]) (remembered_ctx st)
1074 (rem_as_ok, rem_as_bad) = partition (`elem` loaded_mods) rem_as
1075 (rem_bs_ok, rem_bs_bad) = partition (`elem` loaded_mods) rem_bs
1076 as' = nub (as_ok++rem_as_ok)
1077 bs' = nub (bs_ok++rem_bs_ok)
1078 rem_as' = nub (rem_as_bad ++ as_bad)
1079 rem_bs' = nub (rem_bs_bad ++ bs_bad)
1081 -- Put back into the context any modules that we previously had
1082 -- to drop because they weren't available (rem_as_ok, rem_bs_ok).
1083 setContextKeepingPackageModules session prev_context (as',bs')
1085 -- If compilation failed, remember any modules that we are unable
1086 -- to load, so that we can put them back in the context in the future.
1088 Succeeded -> setGHCiState st{ remembered_ctx = Nothing }
1089 Failed -> setGHCiState st{ remembered_ctx = Just (rem_as',rem_bs') }
1093 setContextAfterLoad :: Session -> ([Module],[Module]) -> [GHC.ModSummary] -> GHCi ()
1094 setContextAfterLoad session prev [] = do
1095 prel_mod <- getPrelude
1096 setContextKeepingPackageModules session prev ([], [prel_mod])
1097 setContextAfterLoad session prev ms = do
1098 -- load a target if one is available, otherwise load the topmost module.
1099 targets <- io (GHC.getTargets session)
1100 case [ m | Just m <- map (findTarget ms) targets ] of
1102 let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in
1103 load_this (last graph')
1108 = case filter (`matches` t) ms of
1112 summary `matches` Target (TargetModule m) _
1113 = GHC.ms_mod_name summary == m
1114 summary `matches` Target (TargetFile f _) _
1115 | Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
1119 load_this summary | m <- GHC.ms_mod summary = do
1120 b <- io (GHC.moduleIsInterpreted session m)
1121 if b then setContextKeepingPackageModules session prev ([m], [])
1123 prel_mod <- getPrelude
1124 setContextKeepingPackageModules session prev ([],[prel_mod,m])
1126 -- | Keep any package modules (except Prelude) when changing the context.
1127 setContextKeepingPackageModules
1129 -> ([Module],[Module]) -- previous context
1130 -> ([Module],[Module]) -- new context
1132 setContextKeepingPackageModules session prev_context (as,bs) = do
1133 let (_,bs0) = prev_context
1134 prel_mod <- getPrelude
1135 let pkg_modules = filter (\p -> not (isHomeModule p) && p /= prel_mod) bs0
1136 let bs1 = if null as then nub (prel_mod : bs) else bs
1137 io $ GHC.setContext session as (nub (bs1 ++ pkg_modules))
1139 isHomeModule :: Module -> Bool
1140 isHomeModule mod = GHC.modulePackageId mod == mainPackageId
1142 modulesLoadedMsg :: SuccessFlag -> [ModuleName] -> GHCi ()
1143 modulesLoadedMsg ok mods = do
1144 dflags <- getDynFlags
1145 when (verbosity dflags > 0) $ do
1147 | null mods = text "none."
1148 | otherwise = hsep (
1149 punctuate comma (map ppr mods)) <> text "."
1152 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
1154 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
1157 typeOfExpr :: String -> GHCi ()
1159 = do cms <- getSession
1160 maybe_ty <- io (GHC.exprType cms str)
1162 Nothing -> return ()
1163 Just ty -> do dflags <- getDynFlags
1164 let pefas = dopt Opt_PrintExplicitForalls dflags
1165 printForUser $ text str <+> dcolon
1166 <+> pprTypeForUser pefas ty
1168 kindOfType :: String -> GHCi ()
1170 = do cms <- getSession
1171 maybe_ty <- io (GHC.typeKind cms str)
1173 Nothing -> return ()
1174 Just ty -> printForUser $ text str <+> dcolon <+> ppr ty
1176 quit :: String -> GHCi Bool
1177 quit _ = return True
1179 shellEscape :: String -> GHCi Bool
1180 shellEscape str = io (system str >> return False)
1182 -----------------------------------------------------------------------------
1183 -- Browsing a module's contents
1185 browseCmd :: Bool -> String -> GHCi ()
1188 ['*':s] | looksLikeModuleName s -> do
1189 m <- wantInterpretedModule s
1190 browseModule bang m False
1191 [s] | looksLikeModuleName s -> do
1193 browseModule bang m True
1196 (as,bs) <- io $ GHC.getContext s
1197 -- Guess which module the user wants to browse. Pick
1198 -- modules that are interpreted first. The most
1199 -- recently-added module occurs last, it seems.
1201 (as@(_:_), _) -> browseModule bang (last as) True
1202 ([], bs@(_:_)) -> browseModule bang (last bs) True
1203 ([], []) -> throwDyn (CmdLineError ":browse: no current module")
1204 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
1206 -- without bang, show items in context of their parents and omit children
1207 -- with bang, show class methods and data constructors separately, and
1208 -- indicate import modules, to aid qualifying unqualified names
1209 -- with sorted, sort items alphabetically
1210 browseModule :: Bool -> Module -> Bool -> GHCi ()
1211 browseModule bang modl exports_only = do
1213 -- :browse! reports qualifiers wrt current context
1214 current_unqual <- io (GHC.getPrintUnqual s)
1215 -- Temporarily set the context to the module we're interested in,
1216 -- just so we can get an appropriate PrintUnqualified
1217 (as,bs) <- io (GHC.getContext s)
1218 prel_mod <- getPrelude
1219 io (if exports_only then GHC.setContext s [] [prel_mod,modl]
1220 else GHC.setContext s [modl] [])
1221 target_unqual <- io (GHC.getPrintUnqual s)
1222 io (GHC.setContext s as bs)
1224 let unqual = if bang then current_unqual else target_unqual
1226 mb_mod_info <- io $ GHC.getModuleInfo s modl
1228 Nothing -> throwDyn (CmdLineError ("unknown module: " ++
1229 GHC.moduleNameString (GHC.moduleName modl)))
1231 dflags <- getDynFlags
1233 | exports_only = GHC.modInfoExports mod_info
1234 | otherwise = GHC.modInfoTopLevelScope mod_info
1237 -- sort alphabetically name, but putting
1238 -- locally-defined identifiers first.
1239 -- We would like to improve this; see #1799.
1240 sorted_names = loc_sort local ++ occ_sort external
1242 (local,external) = partition ((==modl) . nameModule) names
1243 occ_sort = sortBy (compare `on` nameOccName)
1244 -- try to sort by src location. If the first name in
1245 -- our list has a good source location, then they all should.
1247 | n:_ <- names, isGoodSrcSpan (nameSrcSpan n)
1248 = sortBy (compare `on` nameSrcSpan) names
1252 mb_things <- io $ mapM (GHC.lookupName s) sorted_names
1253 let filtered_things = filterOutChildren (\t -> t) (catMaybes mb_things)
1255 rdr_env <- io $ GHC.getGRE s
1257 let pefas = dopt Opt_PrintExplicitForalls dflags
1258 things | bang = catMaybes mb_things
1259 | otherwise = filtered_things
1260 pretty | bang = pprTyThing
1261 | otherwise = pprTyThingInContext
1263 labels [] = text "-- not currently imported"
1264 labels l = text $ intercalate "\n" $ map qualifier l
1265 qualifier = maybe "-- defined locally"
1266 (("-- imported via "++) . intercalate ", "
1267 . map GHC.moduleNameString)
1268 importInfo = RdrName.getGRE_NameQualifier_maybes rdr_env
1269 modNames = map (importInfo . GHC.getName) things
1271 -- annotate groups of imports with their import modules
1272 -- the default ordering is somewhat arbitrary, so we group
1273 -- by header and sort groups; the names themselves should
1274 -- really come in order of source appearance.. (trac #1799)
1275 annotate mts = concatMap (\(m,ts)->labels m:ts)
1276 $ sortBy cmpQualifiers $ group mts
1277 where cmpQualifiers =
1278 compare `on` (map (fmap (map moduleNameFS)) . fst)
1280 group mts@((m,_):_) = (m,map snd g) : group ng
1281 where (g,ng) = partition ((==m).fst) mts
1283 let prettyThings = map (pretty pefas) things
1284 prettyThings' | bang = annotate $ zip modNames prettyThings
1285 | otherwise = prettyThings
1286 io (putStrLn $ showSDocForUser unqual (vcat prettyThings'))
1287 -- ToDo: modInfoInstances currently throws an exception for
1288 -- package modules. When it works, we can do this:
1289 -- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
1291 -----------------------------------------------------------------------------
1292 -- Setting the module context
1294 setContext :: String -> GHCi ()
1296 | all sensible mods = fn mods
1297 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
1299 (fn, mods) = case str of
1300 '+':stuff -> (addToContext, words stuff)
1301 '-':stuff -> (removeFromContext, words stuff)
1302 stuff -> (newContext, words stuff)
1304 sensible ('*':m) = looksLikeModuleName m
1305 sensible m = looksLikeModuleName m
1307 separate :: Session -> [String] -> [Module] -> [Module]
1308 -> GHCi ([Module],[Module])
1309 separate _ [] as bs = return (as,bs)
1310 separate session (('*':str):ms) as bs = do
1311 m <- wantInterpretedModule str
1312 separate session ms (m:as) bs
1313 separate session (str:ms) as bs = do
1314 m <- lookupModule str
1315 separate session ms as (m:bs)
1317 newContext :: [String] -> GHCi ()
1318 newContext strs = do
1320 (as,bs) <- separate s strs [] []
1321 prel_mod <- getPrelude
1322 let bs' = if null as && prel_mod `notElem` bs then prel_mod:bs else bs
1323 io $ GHC.setContext s as bs'
1326 addToContext :: [String] -> GHCi ()
1327 addToContext strs = do
1329 (as,bs) <- io $ GHC.getContext s
1331 (new_as,new_bs) <- separate s strs [] []
1333 let as_to_add = new_as \\ (as ++ bs)
1334 bs_to_add = new_bs \\ (as ++ bs)
1336 io $ GHC.setContext s (as ++ as_to_add) (bs ++ bs_to_add)
1339 removeFromContext :: [String] -> GHCi ()
1340 removeFromContext strs = do
1342 (as,bs) <- io $ GHC.getContext s
1344 (as_to_remove,bs_to_remove) <- separate s strs [] []
1346 let as' = as \\ (as_to_remove ++ bs_to_remove)
1347 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1349 io $ GHC.setContext s as' bs'
1351 ----------------------------------------------------------------------------
1354 -- set options in the interpreter. Syntax is exactly the same as the
1355 -- ghc command line, except that certain options aren't available (-C,
1358 -- This is pretty fragile: most options won't work as expected. ToDo:
1359 -- figure out which ones & disallow them.
1361 setCmd :: String -> GHCi ()
1363 = do st <- getGHCiState
1364 let opts = options st
1365 io $ putStrLn (showSDoc (
1366 text "options currently set: " <>
1369 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1371 dflags <- getDynFlags
1372 io $ putStrLn (showSDoc (
1373 vcat (text "GHCi-specific dynamic flag settings:"
1374 :map (flagSetting dflags) ghciFlags)
1376 io $ putStrLn (showSDoc (
1377 vcat (text "other dynamic, non-language, flag settings:"
1378 :map (flagSetting dflags) nonLanguageDynFlags)
1380 where flagSetting dflags (str,f)
1381 | dopt f dflags = text " " <> text "-f" <> text str
1382 | otherwise = text " " <> text "-fno-" <> text str
1383 (ghciFlags,others) = partition (\(_,f)->f `elem` flags)
1385 nonLanguageDynFlags = filter (\(_,f)->not $ f `elem` map snd xFlags)
1387 flags = [Opt_PrintExplicitForalls
1388 ,Opt_PrintBindResult
1389 ,Opt_BreakOnException
1391 ,Opt_PrintEvldWithShow
1394 = case toArgs str of
1395 ("args":args) -> setArgs args
1396 ("prog":prog) -> setProg prog
1397 ("prompt":_) -> setPrompt (after 6)
1398 ("editor":_) -> setEditor (after 6)
1399 ("stop":_) -> setStop (after 4)
1400 wds -> setOptions wds
1401 where after n = dropWhile isSpace $ drop n $ dropWhile isSpace str
1403 setArgs, setProg, setOptions :: [String] -> GHCi ()
1404 setEditor, setStop, setPrompt :: String -> GHCi ()
1408 setGHCiState st{ args = args }
1412 setGHCiState st{ progname = prog }
1414 io (hPutStrLn stderr "syntax: :set prog <progname>")
1418 setGHCiState st{ editor = cmd }
1420 setStop str@(c:_) | isDigit c
1421 = do let (nm_str,rest) = break (not.isDigit) str
1424 let old_breaks = breaks st
1425 if all ((/= nm) . fst) old_breaks
1426 then printForUser (text "Breakpoint" <+> ppr nm <+>
1427 text "does not exist")
1429 let new_breaks = map fn old_breaks
1430 fn (i,loc) | i == nm = (i,loc { onBreakCmd = dropWhile isSpace rest })
1431 | otherwise = (i,loc)
1432 setGHCiState st{ breaks = new_breaks }
1435 setGHCiState st{ stop = cmd }
1437 setPrompt value = do
1440 then io $ hPutStrLn stderr $ "syntax: :set prompt <prompt>, currently \"" ++ prompt st ++ "\""
1441 else setGHCiState st{ prompt = remQuotes value }
1443 remQuotes ('\"':xs) | not (null xs) && last xs == '\"' = init xs
1447 do -- first, deal with the GHCi opts (+s, +t, etc.)
1448 let (plus_opts, minus_opts) = partitionWith isPlus wds
1449 mapM_ setOpt plus_opts
1450 -- then, dynamic flags
1451 newDynFlags minus_opts
1453 newDynFlags :: [String] -> GHCi ()
1454 newDynFlags minus_opts = do
1455 dflags <- getDynFlags
1456 let pkg_flags = packageFlags dflags
1457 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1459 if (not (null leftovers))
1460 then throwDyn (CmdLineError ("unrecognised flags: " ++
1464 new_pkgs <- setDynFlags dflags'
1466 -- if the package flags changed, we should reset the context
1467 -- and link the new packages.
1468 dflags <- getDynFlags
1469 when (packageFlags dflags /= pkg_flags) $ do
1470 io $ hPutStrLn stderr "package flags have changed, ressetting and loading new packages..."
1471 session <- getSession
1472 io (GHC.setTargets session [])
1473 io (GHC.load session LoadAllTargets)
1474 io (linkPackages dflags new_pkgs)
1475 -- package flags changed, we can't re-use any of the old context
1476 setContextAfterLoad session ([],[]) []
1480 unsetOptions :: String -> GHCi ()
1482 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1483 let opts = words str
1484 (minus_opts, rest1) = partition isMinus opts
1485 (plus_opts, rest2) = partitionWith isPlus rest1
1487 if (not (null rest2))
1488 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1491 mapM_ unsetOpt plus_opts
1493 let no_flag ('-':'f':rest) = return ("-fno-" ++ rest)
1494 no_flag f = throwDyn (ProgramError ("don't know how to reverse " ++ f))
1496 no_flags <- mapM no_flag minus_opts
1497 newDynFlags no_flags
1499 isMinus :: String -> Bool
1500 isMinus ('-':_) = True
1503 isPlus :: String -> Either String String
1504 isPlus ('+':opt) = Left opt
1505 isPlus other = Right other
1507 setOpt, unsetOpt :: String -> GHCi ()
1510 = case strToGHCiOpt str of
1511 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1512 Just o -> setOption o
1515 = case strToGHCiOpt str of
1516 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1517 Just o -> unsetOption o
1519 strToGHCiOpt :: String -> (Maybe GHCiOption)
1520 strToGHCiOpt "s" = Just ShowTiming
1521 strToGHCiOpt "t" = Just ShowType
1522 strToGHCiOpt "r" = Just RevertCAFs
1523 strToGHCiOpt _ = Nothing
1525 optToStr :: GHCiOption -> String
1526 optToStr ShowTiming = "s"
1527 optToStr ShowType = "t"
1528 optToStr RevertCAFs = "r"
1530 -- ---------------------------------------------------------------------------
1533 showCmd :: String -> GHCi ()
1537 ["args"] -> io $ putStrLn (show (args st))
1538 ["prog"] -> io $ putStrLn (show (progname st))
1539 ["prompt"] -> io $ putStrLn (show (prompt st))
1540 ["editor"] -> io $ putStrLn (show (editor st))
1541 ["stop"] -> io $ putStrLn (show (stop st))
1542 ["modules" ] -> showModules
1543 ["bindings"] -> showBindings
1544 ["linker"] -> io showLinkerState
1545 ["breaks"] -> showBkptTable
1546 ["context"] -> showContext
1547 ["packages"] -> showPackages
1548 ["languages"] -> showLanguages
1549 _ -> throwDyn (CmdLineError "syntax: :show [args|prog|prompt|editor|stop|modules|bindings|breaks|context]")
1551 showModules :: GHCi ()
1553 session <- getSession
1554 loaded_mods <- getLoadedModules session
1555 -- we want *loaded* modules only, see #1734
1556 let show_one ms = do m <- io (GHC.showModule session ms); io (putStrLn m)
1557 mapM_ show_one loaded_mods
1559 getLoadedModules :: GHC.Session -> GHCi [GHC.ModSummary]
1560 getLoadedModules session = do
1561 graph <- io (GHC.getModuleGraph session)
1562 filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph
1564 showBindings :: GHCi ()
1567 bindings <- io (GHC.getBindings s)
1568 docs <- io$ pprTypeAndContents s
1569 [ id | AnId id <- sortBy compareTyThings bindings]
1570 printForUserPartWay docs
1572 compareTyThings :: TyThing -> TyThing -> Ordering
1573 t1 `compareTyThings` t2 = getName t1 `compareNames` getName t2
1575 printTyThing :: TyThing -> GHCi ()
1576 printTyThing tyth = do dflags <- getDynFlags
1577 let pefas = dopt Opt_PrintExplicitForalls dflags
1578 printForUser (pprTyThing pefas tyth)
1580 showBkptTable :: GHCi ()
1583 printForUser $ prettyLocations (breaks st)
1585 showContext :: GHCi ()
1587 session <- getSession
1588 resumes <- io $ GHC.getResumeContext session
1589 printForUser $ vcat (map pp_resume (reverse resumes))
1592 ptext SLIT("--> ") <> text (GHC.resumeStmt resume)
1593 $$ nest 2 (ptext SLIT("Stopped at") <+> ppr (GHC.resumeSpan resume))
1595 showPackages :: GHCi ()
1597 pkg_flags <- fmap packageFlags getDynFlags
1598 io $ putStrLn $ showSDoc $ vcat $
1599 text ("active package flags:"++if null pkg_flags then " none" else "")
1600 : map showFlag pkg_flags
1601 pkg_ids <- fmap (preloadPackages . pkgState) getDynFlags
1602 io $ putStrLn $ showSDoc $ vcat $
1603 text "packages currently loaded:"
1604 : map (nest 2 . text . packageIdString) pkg_ids
1605 where showFlag (ExposePackage p) = text $ " -package " ++ p
1606 showFlag (HidePackage p) = text $ " -hide-package " ++ p
1607 showFlag (IgnorePackage p) = text $ " -ignore-package " ++ p
1609 showLanguages :: GHCi ()
1611 dflags <- getDynFlags
1612 io $ putStrLn $ showSDoc $ vcat $
1613 text "active language flags:" :
1614 [text (" -X" ++ str) | (str,f) <- DynFlags.xFlags, dopt f dflags]
1616 -- -----------------------------------------------------------------------------
1619 completeNone :: String -> IO [String]
1620 completeNone _w = return []
1622 completeMacro, completeIdentifier, completeModule,
1623 completeHomeModule, completeSetOptions, completeFilename,
1624 completeHomeModuleOrFile
1625 :: String -> IO [String]
1628 completeWord :: String -> Int -> Int -> IO (Maybe (String, [String]))
1629 completeWord w start end = do
1630 line <- Readline.getLineBuffer
1631 let line_words = words (dropWhile isSpace line)
1633 ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w
1635 | ((':':c) : _) <- line_words -> do
1636 completionVars <- lookupCompletionVars c
1637 case completionVars of
1638 (Nothing,complete) -> wrapCompleter complete w
1639 (Just breakChars,complete)
1640 -> let (n,w') = selectWord
1641 (words' (`elem` breakChars) 0 line)
1642 complete' w = do rets <- complete w
1643 return (map (drop n) rets)
1644 in wrapCompleter complete' w'
1645 | ("import" : _) <- line_words ->
1646 wrapCompleter completeModule w
1648 --printf "complete %s, start = %d, end = %d\n" w start end
1649 wrapCompleter completeIdentifier w
1650 where words' _ _ [] = []
1651 words' isBreak n str = let (w,r) = break isBreak str
1652 (s,r') = span isBreak r
1653 in (n,w):words' isBreak (n+length w+length s) r'
1654 -- In a Haskell expression we want to parse 'a-b' as three words
1655 -- where a compiler flag (ie. -fno-monomorphism-restriction) should
1656 -- only be a single word.
1657 selectWord [] = (0,w)
1658 selectWord ((offset,x):xs)
1659 | offset+length x >= start = (start-offset,take (end-offset) x)
1660 | otherwise = selectWord xs
1662 lookupCompletionVars ('!':_) = return (Just filenameWordBreakChars,
1664 lookupCompletionVars c = do
1665 maybe_cmd <- lookupCommand' c
1667 Just (_,_,ws,f) -> return (ws,f)
1668 Nothing -> return (Just filenameWordBreakChars,
1672 completeCmd :: String -> IO [String]
1674 cmds <- readIORef macros_ref
1675 return (filter (w `isPrefixOf`) (map (':':)
1676 (map cmdName (builtin_commands ++ cmds))))
1678 completeMacro w = do
1679 cmds <- readIORef macros_ref
1680 return (filter (w `isPrefixOf`) (map cmdName cmds))
1682 completeIdentifier w = do
1684 rdrs <- GHC.getRdrNamesInScope s
1685 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
1687 completeModule w = do
1689 dflags <- GHC.getSessionDynFlags s
1690 let pkg_mods = allExposedModules dflags
1691 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) pkg_mods))
1693 completeHomeModule w = do
1695 g <- GHC.getModuleGraph s
1696 let home_mods = map GHC.ms_mod_name g
1697 return (filter (w `isPrefixOf`) (map (showSDoc.ppr) home_mods))
1699 completeSetOptions w = do
1700 return (filter (w `isPrefixOf`) options)
1701 where options = "args":"prog":allFlags
1703 completeFilename w = do
1704 ws <- Readline.filenameCompletionFunction w
1706 -- If we only found one result, and it's a directory,
1707 -- add a trailing slash.
1709 isDir <- expandPathIO file >>= doesDirectoryExist
1710 if isDir && last file /= '/'
1711 then return [file ++ "/"]
1716 completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
1718 unionComplete :: (String -> IO [String]) -> (String -> IO [String]) -> String -> IO [String]
1719 unionComplete f1 f2 w = do
1724 wrapCompleter :: (String -> IO [String]) -> String -> IO (Maybe (String,[String]))
1725 wrapCompleter fun w = do
1728 [] -> Readline.setAttemptedCompletionOver True >> return Nothing
1729 [x] -> -- Add a trailing space, unless it already has an appended slash.
1730 let appended = if last x == '/' then x else x ++ " "
1731 in return (Just (appended,[]))
1732 xs -> case getCommonPrefix xs of
1733 "" -> return (Just ("",xs))
1734 pref -> return (Just (pref,xs))
1736 getCommonPrefix :: [String] -> String
1737 getCommonPrefix [] = ""
1738 getCommonPrefix (s:ss) = foldl common s ss
1739 where common _s "" = ""
1741 common (c:cs) (d:ds)
1742 | c == d = c : common cs ds
1745 allExposedModules :: DynFlags -> [ModuleName]
1746 allExposedModules dflags
1747 = concat (map exposedModules (filter exposed (eltsUFM pkg_db)))
1749 pkg_db = pkgIdMap (pkgState dflags)
1751 completeMacro = completeNone
1752 completeIdentifier = completeNone
1753 completeModule = completeNone
1754 completeHomeModule = completeNone
1755 completeSetOptions = completeNone
1756 completeFilename = completeNone
1757 completeHomeModuleOrFile=completeNone
1760 -- ---------------------------------------------------------------------------
1761 -- User code exception handling
1763 -- This is the exception handler for exceptions generated by the
1764 -- user's code and exceptions coming from children sessions;
1765 -- it normally just prints out the exception. The
1766 -- handler must be recursive, in case showing the exception causes
1767 -- more exceptions to be raised.
1769 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
1770 -- raising another exception. We therefore don't put the recursive
1771 -- handler arond the flushing operation, so if stderr is closed
1772 -- GHCi will just die gracefully rather than going into an infinite loop.
1773 handler :: Exception -> GHCi Bool
1775 handler exception = do
1777 io installSignalHandlers
1778 ghciHandle handler (showException exception >> return False)
1780 showException :: Exception -> GHCi ()
1781 showException (DynException dyn) =
1782 case fromDynamic dyn of
1783 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
1784 Just Interrupted -> io (putStrLn "Interrupted.")
1785 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
1786 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
1787 Just other_ghc_ex -> io (print other_ghc_ex)
1789 showException other_exception
1790 = io (putStrLn ("*** Exception: " ++ show other_exception))
1792 -----------------------------------------------------------------------------
1793 -- recursive exception handlers
1795 -- Don't forget to unblock async exceptions in the handler, or if we're
1796 -- in an exception loop (eg. let a = error a in a) the ^C exception
1797 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1799 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1800 ghciHandle h (GHCi m) = GHCi $ \s ->
1801 Exception.catch (m s)
1802 (\e -> unGHCi (ghciUnblock (h e)) s)
1804 ghciUnblock :: GHCi a -> GHCi a
1805 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1808 -- ----------------------------------------------------------------------------
1811 expandPath :: String -> GHCi String
1812 expandPath path = io (expandPathIO path)
1814 expandPathIO :: String -> IO String
1816 case dropWhile isSpace path of
1818 tilde <- getHomeDirectory -- will fail if HOME not defined
1819 return (tilde ++ '/':d)
1823 wantInterpretedModule :: String -> GHCi Module
1824 wantInterpretedModule str = do
1825 session <- getSession
1826 modl <- lookupModule str
1827 is_interpreted <- io (GHC.moduleIsInterpreted session modl)
1828 when (not is_interpreted) $
1829 throwDyn (CmdLineError ("module '" ++ str ++ "' is not interpreted"))
1832 wantNameFromInterpretedModule :: (Name -> SDoc -> GHCi ()) -> String
1833 -> (Name -> GHCi ())
1835 wantNameFromInterpretedModule noCanDo str and_then = do
1836 session <- getSession
1837 names <- io $ GHC.parseName session str
1841 let modl = GHC.nameModule n
1842 if not (GHC.isExternalName n)
1843 then noCanDo n $ ppr n <>
1844 text " is not defined in an interpreted module"
1846 is_interpreted <- io (GHC.moduleIsInterpreted session modl)
1847 if not is_interpreted
1848 then noCanDo n $ text "module " <> ppr modl <>
1849 text " is not interpreted"
1852 -- -----------------------------------------------------------------------------
1853 -- commands for debugger
1855 sprintCmd, printCmd, forceCmd :: String -> GHCi ()
1856 sprintCmd = pprintCommand False False
1857 printCmd = pprintCommand True False
1858 forceCmd = pprintCommand False True
1860 pprintCommand :: Bool -> Bool -> String -> GHCi ()
1861 pprintCommand bind force str = do
1862 session <- getSession
1863 io $ pprintClosureCommand session bind force str
1865 stepCmd :: String -> GHCi ()
1866 stepCmd [] = doContinue (const True) GHC.SingleStep
1867 stepCmd expression = do runStmt expression GHC.SingleStep; return ()
1869 stepLocalCmd :: String -> GHCi ()
1870 stepLocalCmd [] = do
1871 mb_span <- getCurrentBreakSpan
1873 Nothing -> stepCmd []
1875 Just mod <- getCurrentBreakModule
1876 current_toplevel_decl <- enclosingTickSpan mod loc
1877 doContinue (`isSubspanOf` current_toplevel_decl) GHC.SingleStep
1879 stepLocalCmd expression = stepCmd expression
1881 stepModuleCmd :: String -> GHCi ()
1882 stepModuleCmd [] = do
1883 mb_span <- getCurrentBreakSpan
1885 Nothing -> stepCmd []
1887 Just span <- getCurrentBreakSpan
1888 let f some_span = optSrcSpanFileName span == optSrcSpanFileName some_span
1889 doContinue f GHC.SingleStep
1891 stepModuleCmd expression = stepCmd expression
1893 -- | Returns the span of the largest tick containing the srcspan given
1894 enclosingTickSpan :: Module -> SrcSpan -> GHCi SrcSpan
1895 enclosingTickSpan mod src = do
1896 ticks <- getTickArray mod
1897 let line = srcSpanStartLine src
1898 ASSERT (inRange (bounds ticks) line) do
1899 let enclosing_spans = [ span | (_,span) <- ticks ! line
1900 , srcSpanEnd span >= srcSpanEnd src]
1901 return . head . sortBy leftmost_largest $ enclosing_spans
1903 traceCmd :: String -> GHCi ()
1904 traceCmd [] = doContinue (const True) GHC.RunAndLogSteps
1905 traceCmd expression = do runStmt expression GHC.RunAndLogSteps; return ()
1907 continueCmd :: String -> GHCi ()
1908 continueCmd = noArgs $ doContinue (const True) GHC.RunToCompletion
1910 -- doContinue :: SingleStep -> GHCi ()
1911 doContinue :: (SrcSpan -> Bool) -> SingleStep -> GHCi ()
1912 doContinue pred step = do
1913 session <- getSession
1914 runResult <- io $ GHC.resume session step
1915 afterRunStmt pred runResult
1918 abandonCmd :: String -> GHCi ()
1919 abandonCmd = noArgs $ do
1921 b <- io $ GHC.abandon s -- the prompt will change to indicate the new context
1922 when (not b) $ io $ putStrLn "There is no computation running."
1925 deleteCmd :: String -> GHCi ()
1926 deleteCmd argLine = do
1927 deleteSwitch $ words argLine
1929 deleteSwitch :: [String] -> GHCi ()
1931 io $ putStrLn "The delete command requires at least one argument."
1932 -- delete all break points
1933 deleteSwitch ("*":_rest) = discardActiveBreakPoints
1934 deleteSwitch idents = do
1935 mapM_ deleteOneBreak idents
1937 deleteOneBreak :: String -> GHCi ()
1939 | all isDigit str = deleteBreak (read str)
1940 | otherwise = return ()
1942 historyCmd :: String -> GHCi ()
1944 | null arg = history 20
1945 | all isDigit arg = history (read arg)
1946 | otherwise = io $ putStrLn "Syntax: :history [num]"
1950 resumes <- io $ GHC.getResumeContext s
1952 [] -> io $ putStrLn "Not stopped at a breakpoint"
1954 let hist = GHC.resumeHistory r
1955 (took,rest) = splitAt num hist
1957 [] -> io $ putStrLn $
1958 "Empty history. Perhaps you forgot to use :trace?"
1960 spans <- mapM (io . GHC.getHistorySpan s) took
1961 let nums = map (printf "-%-3d:") [(1::Int)..]
1962 names = map GHC.historyEnclosingDecl took
1963 printForUser (vcat(zipWith3
1964 (\x y z -> x <+> y <+> z)
1966 (map (bold . ppr) names)
1967 (map (parens . ppr) spans)))
1968 io $ putStrLn $ if null rest then "<end of history>" else "..."
1970 bold :: SDoc -> SDoc
1971 bold c | do_bold = text start_bold <> c <> text end_bold
1974 backCmd :: String -> GHCi ()
1975 backCmd = noArgs $ do
1977 (names, _, span) <- io $ GHC.back s
1978 printForUser $ ptext SLIT("Logged breakpoint at") <+> ppr span
1979 printTypeOfNames s names
1980 -- run the command set with ":set stop <cmd>"
1982 enqueueCommands [stop st]
1984 forwardCmd :: String -> GHCi ()
1985 forwardCmd = noArgs $ do
1987 (names, ix, span) <- io $ GHC.forward s
1988 printForUser $ (if (ix == 0)
1989 then ptext SLIT("Stopped at")
1990 else ptext SLIT("Logged breakpoint at")) <+> ppr span
1991 printTypeOfNames s names
1992 -- run the command set with ":set stop <cmd>"
1994 enqueueCommands [stop st]
1996 -- handle the "break" command
1997 breakCmd :: String -> GHCi ()
1998 breakCmd argLine = do
1999 session <- getSession
2000 breakSwitch session $ words argLine
2002 breakSwitch :: Session -> [String] -> GHCi ()
2003 breakSwitch _session [] = do
2004 io $ putStrLn "The break command requires at least one argument."
2005 breakSwitch session (arg1:rest)
2006 | looksLikeModuleName arg1 = do
2007 mod <- wantInterpretedModule arg1
2008 breakByModule mod rest
2009 | all isDigit arg1 = do
2010 (toplevel, _) <- io $ GHC.getContext session
2012 (mod : _) -> breakByModuleLine mod (read arg1) rest
2014 io $ putStrLn "Cannot find default module for breakpoint."
2015 io $ putStrLn "Perhaps no modules are loaded for debugging?"
2016 | otherwise = do -- try parsing it as an identifier
2017 wantNameFromInterpretedModule noCanDo arg1 $ \name -> do
2018 let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
2019 if GHC.isGoodSrcLoc loc
2020 then findBreakAndSet (GHC.nameModule name) $
2021 findBreakByCoord (Just (GHC.srcLocFile loc))
2022 (GHC.srcLocLine loc,
2024 else noCanDo name $ text "can't find its location: " <> ppr loc
2026 noCanDo n why = printForUser $
2027 text "cannot set breakpoint on " <> ppr n <> text ": " <> why
2029 breakByModule :: Module -> [String] -> GHCi ()
2030 breakByModule mod (arg1:rest)
2031 | all isDigit arg1 = do -- looks like a line number
2032 breakByModuleLine mod (read arg1) rest
2036 breakByModuleLine :: Module -> Int -> [String] -> GHCi ()
2037 breakByModuleLine mod line args
2038 | [] <- args = findBreakAndSet mod $ findBreakByLine line
2039 | [col] <- args, all isDigit col =
2040 findBreakAndSet mod $ findBreakByCoord Nothing (line, read col)
2041 | otherwise = breakSyntax
2044 breakSyntax = throwDyn (CmdLineError "Syntax: :break [<mod>] <line> [<column>]")
2046 findBreakAndSet :: Module -> (TickArray -> Maybe (Int, SrcSpan)) -> GHCi ()
2047 findBreakAndSet mod lookupTickTree = do
2048 tickArray <- getTickArray mod
2049 (breakArray, _) <- getModBreak mod
2050 case lookupTickTree tickArray of
2051 Nothing -> io $ putStrLn $ "No breakpoints found at that location."
2052 Just (tick, span) -> do
2053 success <- io $ setBreakFlag True breakArray tick
2057 recordBreak $ BreakLocation
2064 text "Breakpoint " <> ppr nm <>
2066 then text " was already set at " <> ppr span
2067 else text " activated at " <> ppr span
2069 printForUser $ text "Breakpoint could not be activated at"
2072 -- When a line number is specified, the current policy for choosing
2073 -- the best breakpoint is this:
2074 -- - the leftmost complete subexpression on the specified line, or
2075 -- - the leftmost subexpression starting on the specified line, or
2076 -- - the rightmost subexpression enclosing the specified line
2078 findBreakByLine :: Int -> TickArray -> Maybe (BreakIndex,SrcSpan)
2079 findBreakByLine line arr
2080 | not (inRange (bounds arr) line) = Nothing
2082 listToMaybe (sortBy (leftmost_largest `on` snd) complete) `mplus`
2083 listToMaybe (sortBy (leftmost_smallest `on` snd) incomplete) `mplus`
2084 listToMaybe (sortBy (rightmost `on` snd) ticks)
2088 starts_here = [ tick | tick@(_,span) <- ticks,
2089 GHC.srcSpanStartLine span == line ]
2091 (complete,incomplete) = partition ends_here starts_here
2092 where ends_here (_,span) = GHC.srcSpanEndLine span == line
2094 findBreakByCoord :: Maybe FastString -> (Int,Int) -> TickArray
2095 -> Maybe (BreakIndex,SrcSpan)
2096 findBreakByCoord mb_file (line, col) arr
2097 | not (inRange (bounds arr) line) = Nothing
2099 listToMaybe (sortBy (rightmost `on` snd) contains ++
2100 sortBy (leftmost_smallest `on` snd) after_here)
2104 -- the ticks that span this coordinate
2105 contains = [ tick | tick@(_,span) <- ticks, span `spans` (line,col),
2106 is_correct_file span ]
2108 is_correct_file span
2109 | Just f <- mb_file = GHC.srcSpanFile span == f
2112 after_here = [ tick | tick@(_,span) <- ticks,
2113 GHC.srcSpanStartLine span == line,
2114 GHC.srcSpanStartCol span >= col ]
2116 -- For now, use ANSI bold on terminals that we know support it.
2117 -- Otherwise, we add a line of carets under the active expression instead.
2118 -- In particular, on Windows and when running the testsuite (which sets
2119 -- TERM to vt100 for other reasons) we get carets.
2120 -- We really ought to use a proper termcap/terminfo library.
2122 do_bold = (`isPrefixOf` unsafePerformIO mTerm) `any` ["xterm", "linux"]
2123 where mTerm = System.Environment.getEnv "TERM"
2124 `Exception.catch` \_ -> return "TERM not set"
2126 start_bold :: String
2127 start_bold = "\ESC[1m"
2129 end_bold = "\ESC[0m"
2131 listCmd :: String -> GHCi ()
2133 mb_span <- getCurrentBreakSpan
2135 Nothing -> printForUser $ text "not stopped at a breakpoint; nothing to list"
2136 Just span | GHC.isGoodSrcSpan span -> io $ listAround span True
2137 | otherwise -> printForUser $ text "unable to list source for" <+> ppr span
2138 listCmd str = list2 (words str)
2140 list2 :: [String] -> GHCi ()
2141 list2 [arg] | all isDigit arg = do
2142 session <- getSession
2143 (toplevel, _) <- io $ GHC.getContext session
2145 [] -> io $ putStrLn "No module to list"
2146 (mod : _) -> listModuleLine mod (read arg)
2147 list2 [arg1,arg2] | looksLikeModuleName arg1, all isDigit arg2 = do
2148 mod <- wantInterpretedModule arg1
2149 listModuleLine mod (read arg2)
2151 wantNameFromInterpretedModule noCanDo arg $ \name -> do
2152 let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
2153 if GHC.isGoodSrcLoc loc
2155 tickArray <- getTickArray (GHC.nameModule name)
2156 let mb_span = findBreakByCoord (Just (GHC.srcLocFile loc))
2157 (GHC.srcLocLine loc, GHC.srcLocCol loc)
2160 Nothing -> io $ listAround (GHC.srcLocSpan loc) False
2161 Just (_,span) -> io $ listAround span False
2163 noCanDo name $ text "can't find its location: " <>
2166 noCanDo n why = printForUser $
2167 text "cannot list source code for " <> ppr n <> text ": " <> why
2169 io $ putStrLn "syntax: :list [<line> | <module> <line> | <identifier>]"
2171 listModuleLine :: Module -> Int -> GHCi ()
2172 listModuleLine modl line = do
2173 session <- getSession
2174 graph <- io (GHC.getModuleGraph session)
2175 let this = filter ((== modl) . GHC.ms_mod) graph
2177 [] -> panic "listModuleLine"
2179 let filename = fromJust (ml_hs_file (GHC.ms_location summ))
2180 loc = GHC.mkSrcLoc (mkFastString (filename)) line 0
2181 io $ listAround (GHC.srcLocSpan loc) False
2183 -- | list a section of a source file around a particular SrcSpan.
2184 -- If the highlight flag is True, also highlight the span using
2185 -- start_bold/end_bold.
2186 listAround :: SrcSpan -> Bool -> IO ()
2187 listAround span do_highlight = do
2188 contents <- BS.readFile (unpackFS file)
2190 lines = BS.split '\n' contents
2191 these_lines = take (line2 - line1 + 1 + pad_before + pad_after) $
2192 drop (line1 - 1 - pad_before) $ lines
2193 fst_line = max 1 (line1 - pad_before)
2194 line_nos = [ fst_line .. ]
2196 highlighted | do_highlight = zipWith highlight line_nos these_lines
2197 | otherwise = [\p -> BS.concat[p,l] | l <- these_lines]
2199 bs_line_nos = [ BS.pack (show l ++ " ") | l <- line_nos ]
2200 prefixed = zipWith ($) highlighted bs_line_nos
2202 BS.putStrLn (BS.intercalate (BS.pack "\n") prefixed)
2204 file = GHC.srcSpanFile span
2205 line1 = GHC.srcSpanStartLine span
2206 col1 = GHC.srcSpanStartCol span
2207 line2 = GHC.srcSpanEndLine span
2208 col2 = GHC.srcSpanEndCol span
2210 pad_before | line1 == 1 = 0
2214 highlight | do_bold = highlight_bold
2215 | otherwise = highlight_carets
2217 highlight_bold no line prefix
2218 | no == line1 && no == line2
2219 = let (a,r) = BS.splitAt col1 line
2220 (b,c) = BS.splitAt (col2-col1) r
2222 BS.concat [prefix, a,BS.pack start_bold,b,BS.pack end_bold,c]
2224 = let (a,b) = BS.splitAt col1 line in
2225 BS.concat [prefix, a, BS.pack start_bold, b]
2227 = let (a,b) = BS.splitAt col2 line in
2228 BS.concat [prefix, a, BS.pack end_bold, b]
2229 | otherwise = BS.concat [prefix, line]
2231 highlight_carets no line prefix
2232 | no == line1 && no == line2
2233 = BS.concat [prefix, line, nl, indent, BS.replicate col1 ' ',
2234 BS.replicate (col2-col1) '^']
2236 = BS.concat [indent, BS.replicate (col1 - 2) ' ', BS.pack "vv", nl,
2239 = BS.concat [prefix, line, nl, indent, BS.replicate col2 ' ',
2241 | otherwise = BS.concat [prefix, line]
2243 indent = BS.pack (" " ++ replicate (length (show no)) ' ')
2244 nl = BS.singleton '\n'
2246 -- --------------------------------------------------------------------------
2249 getTickArray :: Module -> GHCi TickArray
2250 getTickArray modl = do
2252 let arrmap = tickarrays st
2253 case lookupModuleEnv arrmap modl of
2254 Just arr -> return arr
2256 (_breakArray, ticks) <- getModBreak modl
2257 let arr = mkTickArray (assocs ticks)
2258 setGHCiState st{tickarrays = extendModuleEnv arrmap modl arr}
2261 discardTickArrays :: GHCi ()
2262 discardTickArrays = do
2264 setGHCiState st{tickarrays = emptyModuleEnv}
2266 mkTickArray :: [(BreakIndex,SrcSpan)] -> TickArray
2268 = accumArray (flip (:)) [] (1, max_line)
2269 [ (line, (nm,span)) | (nm,span) <- ticks,
2270 line <- srcSpanLines span ]
2272 max_line = foldr max 0 (map GHC.srcSpanEndLine (map snd ticks))
2273 srcSpanLines span = [ GHC.srcSpanStartLine span ..
2274 GHC.srcSpanEndLine span ]
2276 lookupModule :: String -> GHCi Module
2277 lookupModule modName
2278 = do session <- getSession
2279 io (GHC.findModule session (GHC.mkModuleName modName) Nothing)
2281 -- don't reset the counter back to zero?
2282 discardActiveBreakPoints :: GHCi ()
2283 discardActiveBreakPoints = do
2285 mapM (turnOffBreak.snd) (breaks st)
2286 setGHCiState $ st { breaks = [] }
2288 deleteBreak :: Int -> GHCi ()
2289 deleteBreak identity = do
2291 let oldLocations = breaks st
2292 (this,rest) = partition (\loc -> fst loc == identity) oldLocations
2294 then printForUser (text "Breakpoint" <+> ppr identity <+>
2295 text "does not exist")
2297 mapM (turnOffBreak.snd) this
2298 setGHCiState $ st { breaks = rest }
2300 turnOffBreak :: BreakLocation -> GHCi Bool
2301 turnOffBreak loc = do
2302 (arr, _) <- getModBreak (breakModule loc)
2303 io $ setBreakFlag False arr (breakTick loc)
2305 getModBreak :: Module -> GHCi (GHC.BreakArray, Array Int SrcSpan)
2306 getModBreak mod = do
2307 session <- getSession
2308 Just mod_info <- io $ GHC.getModuleInfo session mod
2309 let modBreaks = GHC.modInfoModBreaks mod_info
2310 let array = GHC.modBreaks_flags modBreaks
2311 let ticks = GHC.modBreaks_locs modBreaks
2312 return (array, ticks)
2314 setBreakFlag :: Bool -> GHC.BreakArray -> Int -> IO Bool
2315 setBreakFlag toggle array index
2316 | toggle = GHC.setBreakOn array index
2317 | otherwise = GHC.setBreakOff array index