{-# OPTIONS -#include "Linker.h" #-} ----------------------------------------------------------------------------- -- -- GHC Interactive User Interface -- -- (c) The GHC Team 2005 -- ----------------------------------------------------------------------------- module InteractiveUI ( interactiveUI, ghciWelcomeMsg ) where #include "HsVersions.h" #if defined(GHCI) && defined(BREAKPOINT) import GHC.Exts ( Int(..), Ptr(..), int2Addr# ) import Foreign.StablePtr ( deRefStablePtr, castPtrToStablePtr ) import System.IO.Unsafe ( unsafePerformIO ) import Var ( Id, globaliseId, idName, idType ) import HscTypes ( Session(..), InteractiveContext(..), HscEnv(..) , extendTypeEnvWithIds ) import RdrName ( extendLocalRdrEnv, mkRdrUnqual, lookupLocalRdrEnv ) import NameEnv ( delListFromNameEnv ) import TcType ( tidyTopType ) import qualified Id ( setIdType ) import IdInfo ( GlobalIdDetails(..) ) import Linker ( HValue, extendLinkEnv, withExtendedLinkEnv,initDynLinker ) import PrelNames ( breakpointJumpName, breakpointCondJumpName ) #endif -- The GHC interface import qualified GHC import GHC ( Session, dopt, DynFlag(..), Target(..), TargetId(..), DynFlags(..), pprModule, Type, Module, ModuleName, SuccessFlag(..), TyThing(..), Name, LoadHowMuch(..), Phase, GhcException(..), showGhcException, CheckedModule(..), SrcLoc ) import DynFlags ( allFlags ) import Packages ( PackageState(..) ) import PackageConfig ( InstalledPackageInfo(..) ) import UniqFM ( eltsUFM ) import PprTyThing import Outputable -- for createtags (should these come via GHC?) import Name ( nameSrcLoc, nameModule, nameOccName ) import OccName ( pprOccName ) import SrcLoc ( isGoodSrcLoc, srcLocFile, srcLocLine, srcLocCol ) -- Other random utilities import Digraph ( flattenSCCs ) import BasicTypes ( failed, successIf ) import Panic ( panic, installSignalHandlers ) import Config import StaticFlags ( opt_IgnoreDotGhci ) import Linker ( showLinkerState ) import Util ( removeSpaces, handle, global, toArgs, looksLikeModuleName, prefixMatch, sortLe ) #ifndef mingw32_HOST_OS import System.Posix #if __GLASGOW_HASKELL__ > 504 hiding (getEnv) #endif #else import GHC.ConsoleHandler ( flushConsole ) import System.Win32 ( setConsoleCP, setConsoleOutputCP ) #endif #ifdef USE_READLINE import Control.Concurrent ( yield ) -- Used in readline loop import System.Console.Readline as Readline #endif --import SystemExts import Control.Exception as Exception import Data.Dynamic -- import Control.Concurrent import Numeric import Data.List import Data.Int ( Int64 ) import Data.Maybe ( isJust, fromMaybe, catMaybes ) import System.Cmd import System.CPUTime import System.Environment import System.Exit ( exitWith, ExitCode(..) ) import System.Directory import System.IO import System.IO.Error as IO import Data.Char import Control.Monad as Monad import Foreign.StablePtr ( newStablePtr ) import GHC.Exts ( unsafeCoerce# ) import GHC.IOBase ( IOErrorType(InvalidArgument) ) import Data.IORef ( IORef, newIORef, readIORef, writeIORef ) import System.Posix.Internals ( setNonBlockingFD ) ----------------------------------------------------------------------------- ghciWelcomeMsg = " ___ ___ _\n"++ " / _ \\ /\\ /\\/ __(_)\n"++ " / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n"++ "/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n"++ "\\____/\\/ /_/\\____/|_| Type :? for help.\n" type Command = (String, String -> GHCi Bool, Bool, String -> IO [String]) cmdName (n,_,_,_) = n GLOBAL_VAR(commands, builtin_commands, [Command]) builtin_commands :: [Command] builtin_commands = [ ("add", keepGoingPaths addModule, False, completeFilename), ("browse", keepGoing browseCmd, False, completeModule), ("cd", keepGoing changeDirectory, False, completeFilename), ("def", keepGoing defineMacro, False, completeIdentifier), ("help", keepGoing help, False, completeNone), ("?", keepGoing help, False, completeNone), ("info", keepGoing info, False, completeIdentifier), ("load", keepGoingPaths loadModule_, False, completeHomeModuleOrFile), ("module", keepGoing setContext, False, completeModule), ("main", keepGoing runMain, False, completeIdentifier), ("reload", keepGoing reloadModule, False, completeNone), ("check", keepGoing checkModule, False, completeHomeModule), ("set", keepGoing setCmd, True, completeSetOptions), ("show", keepGoing showCmd, False, completeNone), ("etags", keepGoing createETagsFileCmd, False, completeFilename), ("ctags", keepGoing createCTagsFileCmd, False, completeFilename), ("type", keepGoing typeOfExpr, False, completeIdentifier), ("kind", keepGoing kindOfType, False, completeIdentifier), ("unset", keepGoing unsetOptions, True, completeSetOptions), ("undef", keepGoing undefineMacro, False, completeMacro), ("quit", quit, False, completeNone) ] keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool) keepGoing a str = a str >> return False keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool) keepGoingPaths a str = a (toArgs str) >> return False shortHelpText = "use :? for help.\n" -- NOTE: spaces at the end of each line to workaround CPP/string gap bug. helpText = " Commands available from the prompt:\n" ++ "\n" ++ " evaluate/run \n" ++ " :add ... add module(s) to the current target set\n" ++ " :browse [*] display the names defined by \n" ++ " :cd change directory to \n" ++ " :def define a command :\n" ++ " :help, :? display this list of commands\n" ++ " :info [ ...] display information about the given names\n" ++ " :load ... load module(s) and their dependents\n" ++ " :module [+/-] [*] ... set the context for expression evaluation\n" ++ " :main [ ...] run the main function with the given arguments\n" ++ " :reload reload the current module set\n" ++ "\n" ++ " :set