#else
import GHC.ConsoleHandler ( flushConsole )
import qualified System.Win32
-import System.FilePath
#endif
#ifdef USE_READLINE
import Control.Exception as Exception
-- import Control.Concurrent
+import System.FilePath
import qualified Data.ByteString.Char8 as BS
import Data.List
import Data.Maybe
" :delete * delete all breakpoints\n" ++
" :force <expr> print <expr>, forcing unevaluated parts\n" ++
" :forward go forward in the history (after :back)\n" ++
- " :history [<n>] show the last <n> items in the history (after :trace)\n" ++
+ " :history [<n>] after :trace, show the execution history\n" ++
" :print [<name> ...] prints a value without forcing its computation\n" ++
" :sprint [<name> ...] simplifed version of :print\n" ++
" :step single-step after stopping at a breakpoint\n"++
" :step <expr> single-step into <expr>\n"++
- " :steplocal single-step restricted to the current top level decl.\n"++
+ " :steplocal single-step within the current top-level binding\n"++
" :stepmodule single-step restricted to the current module\n"++
" :trace trace after stopping at a breakpoint\n"++
- " :trace <expr> trace into <expr> (remembers breakpoints for :history)\n"++
+ " :trace <expr> evaluate <expr> with tracing on (see :history)\n"++
"\n" ++
" -- Commands for changing settings:\n" ++
" :show modules show the currently loaded modules\n" ++
" :show packages show the currently active package flags\n" ++
" :show languages show the currently active language flags\n" ++
- " :show <setting> show anything that can be set with :set (e.g. args)\n" ++
+ " :show <setting> show value of <setting>, which is one of\n" ++
+ " [args, prog, prompt, editor, stop]\n" ++
"\n"
findEditor :: IO String
runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi ()
runGHCi paths maybe_exprs = do
- let read_dot_files = not opt_IgnoreDotGhci
+ let
+ read_dot_files = not opt_IgnoreDotGhci
- when (read_dot_files) $ do
- -- Read in ./.ghci.
- let file = "./.ghci"
- exists <- io (doesFileExist file)
- when exists $ do
- dir_ok <- io (checkPerms ".")
- file_ok <- io (checkPerms file)
+ current_dir = return (Just ".ghci")
+
+ app_user_dir = do
+ either_dir <- io $ IO.try (getAppUserDataDirectory "ghc")
+ case either_dir of
+ Right dir -> return (Just (dir </> "ghci.conf"))
+ _ -> return Nothing
+
+ home_dir = do
+ either_dir <- io $ IO.try (getEnv "HOME")
+ case either_dir of
+ Right home -> return (Just (home </> ".ghci"))
+ _ -> return Nothing
+
+ sourceConfigFile :: FilePath -> GHCi ()
+ sourceConfigFile file = do
+ exists <- io $ doesFileExist file
+ when exists $ do
+ dir_ok <- io $ checkPerms (getDirectory file)
+ file_ok <- io $ checkPerms file
when (dir_ok && file_ok) $ do
- either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
- case either_hdl of
- Left _e -> return ()
- Right hdl -> runCommands (fileLoop hdl False False)
+ either_hdl <- io $ IO.try (openFile file ReadMode)
+ case either_hdl of
+ Left _e -> return ()
+ Right hdl -> runCommands (fileLoop hdl False False)
+ where
+ getDirectory f = case takeDirectory f of "" -> "."; d -> d
when (read_dot_files) $ do
- -- Read in $HOME/.ghci
- either_dir <- io (IO.try getHomeDirectory)
- case either_dir of
- Left _e -> return ()
- Right dir -> do
- cwd <- io (getCurrentDirectory)
- when (dir /= cwd) $ do
- let file = dir ++ "/.ghci"
- ok <- io (checkPerms file)
- when ok $ do
- either_hdl <- io (IO.try (openFile file ReadMode))
- case either_hdl of
- Left _e -> return ()
- Right hdl -> runCommands (fileLoop hdl False False)
+ cfgs0 <- sequence [ current_dir, app_user_dir, home_dir ]
+ cfgs <- io $ mapM canonicalizePath (catMaybes cfgs0)
+ mapM_ sourceConfigFile (nub cfgs)
+ -- nub, because we don't want to read .ghci twice if the
+ -- CWD is $HOME.
-- Perform a :load for files given on the GHCi command line
-- When in -e mode, if the load fails then we want to stop