{-# OPTIONS -#include "Linker.h" #-} ----------------------------------------------------------------------------- -- -- GHC Interactive User Interface -- -- (c) The GHC Team 2005-2006 -- ----------------------------------------------------------------------------- module InteractiveUI ( interactiveUI, ghciWelcomeMsg ) where #include "HsVersions.h" import GhciMonad -- The GHC interface import qualified GHC import GHC ( Session, LoadHowMuch(..), Target(..), TargetId(..), Type, Module, ModuleName, TyThing(..), Phase ) import DynFlags import Packages import PackageConfig import UniqFM import PprTyThing import Outputable -- for createtags import Name import OccName import SrcLoc -- Other random utilities import Digraph import BasicTypes hiding (isTopLevel) import Panic hiding (showException) import Config import StaticFlags import Linker import Util -- The debugger import Breakpoints import Debugger hiding ( addModule ) import HscTypes import Id import Var ( globaliseId ) import IdInfo import NameEnv import RdrName import Module import Type import TcType #ifndef mingw32_HOST_OS import System.Posix #if __GLASGOW_HASKELL__ > 504 hiding (getEnv) #endif #else import GHC.ConsoleHandler ( flushConsole ) import System.Win32 ( setConsoleCP, setConsoleOutputCP ) import qualified System.Win32 #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 Control.Concurrent import Numeric import Data.List import Data.Int ( Int64 ) import Data.Maybe ( isJust, isNothing, fromMaybe, catMaybes ) import System.Cmd 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", tlC$ keepGoingPaths addModule, False, completeFilename), ("browse", keepGoing browseCmd, False, completeModule), ("cd", keepGoing changeDirectory, False, completeFilename), ("def", keepGoing defineMacro, False, completeIdentifier), ("e", keepGoing editFile, False, completeFilename), -- Hugs users are accustomed to :e, so make sure it doesn't overlap ("edit", keepGoing editFile, False, completeFilename), ("help", keepGoing help, False, completeNone), ("?", keepGoing help, False, completeNone), ("info", keepGoing info, False, completeIdentifier), ("load", tlC$ keepGoingPaths loadModule_,False, completeHomeModuleOrFile), ("module", keepGoing setContext, False, completeModule), ("main", tlC$ keepGoing runMain, False, completeIdentifier), ("reload", tlC$ 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), #if defined(DEBUGGER) ("print", keepGoing (pprintClosureCommand True False), False, completeIdentifier), ("sprint", keepGoing (pprintClosureCommand False False),False, completeIdentifier), ("force", keepGoing (pprintClosureCommand False True), False, completeIdentifier), ("breakpoint",keepGoing bkptOptions, False, completeBkpt), #endif ("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 -- tlC: Top Level Command tlC :: (String -> GHCi Bool) -> (String -> GHCi Bool) tlC a str = do top_level <- isTopLevel if not top_level then throwDyn (CmdLineError "Command only allowed at Top Level") else a str 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" ++ " :breakpoint