summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ghc/GHCi/UI.hs44
-rw-r--r--ghc/GHCi/UI/Monad.hs11
2 files changed, 46 insertions, 9 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs
index e386fe6058..55d06dcc1e 100644
--- a/ghc/GHCi/UI.hs
+++ b/ghc/GHCi/UI.hs
@@ -102,7 +102,7 @@ import Data.Char
import Data.Function
import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef )
import Data.List ( find, group, intercalate, intersperse, isPrefixOf, nub,
- partition, sort, sortBy )
+ partition, sort, sortBy, (\\) )
import qualified Data.Set as S
import Data.Maybe
import Data.Map (Map)
@@ -482,6 +482,7 @@ interactiveUI config srcs maybe_exprs = do
stop = default_stop,
editor = default_editor,
options = [],
+ localConfig = SourceLocalConfig,
-- We initialize line number as 0, not 1, because we use
-- current line number while reporting errors which is
-- incremented after reading a line.
@@ -566,8 +567,6 @@ runGHCi paths maybe_exprs = do
let
ignore_dot_ghci = gopt Opt_IgnoreDotGhci dflags
- current_dir = return (Just ".ghci")
-
app_user_dir = liftIO $ withGhcAppData
(\dir -> return (Just (dir </> "ghci.conf")))
(return Nothing)
@@ -606,17 +605,44 @@ runGHCi paths maybe_exprs = do
setGHCContextFromGHCiState
- dot_cfgs <- if ignore_dot_ghci then return [] else do
- dot_files <- catMaybes <$> sequence [ current_dir, app_user_dir, home_dir ]
- liftIO $ filterM checkFileAndDirPerms dot_files
- mdot_cfgs <- liftIO $ mapM canonicalizePath' dot_cfgs
+ processedCfgs <- if ignore_dot_ghci
+ then pure []
+ else do
+ userCfgs <- do
+ paths <- catMaybes <$> sequence [ app_user_dir, home_dir ]
+ checkedPaths <- liftIO $ filterM checkFileAndDirPerms paths
+ liftIO . fmap (nub . catMaybes) $ mapM canonicalizePath' checkedPaths
+
+ localCfg <- do
+ let path = ".ghci"
+ ok <- liftIO $ checkFileAndDirPerms path
+ if ok then liftIO $ canonicalizePath' path else pure Nothing
+
+ mapM_ sourceConfigFile userCfgs
+ -- Process the global and user .ghci
+ -- (but not $CWD/.ghci or CLI args, yet)
+
+ behaviour <- localConfig <$> getGHCiState
+
+ processedLocalCfg <- case localCfg of
+ Just path | path `notElem` userCfgs ->
+ -- don't read .ghci twice if CWD is $HOME
+ case behaviour of
+ SourceLocalConfig -> localCfg <$ sourceConfigFile path
+ IgnoreLocalConfig -> pure Nothing
+ _ -> pure Nothing
+
+ pure $ maybe id (:) processedLocalCfg userCfgs
let arg_cfgs = reverse $ ghciScripts dflags
-- -ghci-script are collected in reverse order
-- We don't require that a script explicitly added by -ghci-script
-- is owned by the current user. (#6017)
- mapM_ sourceConfigFile $ nub $ (catMaybes mdot_cfgs) ++ arg_cfgs
- -- nub, because we don't want to read .ghci twice if the CWD is $HOME.
+
+ mapM_ sourceConfigFile $ nub arg_cfgs \\ processedCfgs
+ -- Dedup, and remove any configs we already processed.
+ -- Importantly, if $PWD/.ghci was ignored due to configuration,
+ -- explicitly specifying it does cause it to be processed.
-- Perform a :load for files given on the GHCi command line
-- When in -e mode, if the load fails then we want to stop
diff --git a/ghc/GHCi/UI/Monad.hs b/ghc/GHCi/UI/Monad.hs
index 16bcd20ee4..696303b949 100644
--- a/ghc/GHCi/UI/Monad.hs
+++ b/ghc/GHCi/UI/Monad.hs
@@ -15,6 +15,7 @@ module GHCi.UI.Monad (
GHCiState(..), GhciMonad(..),
GHCiOption(..), isOptionSet, setOption, unsetOption,
Command(..), CommandResult(..), cmdSuccess,
+ LocalConfigBehaviour(..),
PromptFunction,
BreakLocation(..),
TickArray,
@@ -79,6 +80,7 @@ data GHCiState = GHCiState
prompt_cont :: PromptFunction,
editor :: String,
stop :: String,
+ localConfig :: LocalConfigBehaviour,
options :: [GHCiOption],
line_number :: !Int, -- ^ input line
break_ctr :: !Int,
@@ -197,6 +199,15 @@ data GHCiOption
-- modules after load
deriving Eq
+-- | Treatment of ./.ghci files. For now we either load or
+-- ignore. But later we could implement a "safe mode" where
+-- only safe operations are performed.
+--
+data LocalConfigBehaviour
+ = SourceLocalConfig
+ | IgnoreLocalConfig
+ deriving (Eq)
+
data BreakLocation
= BreakLocation
{ breakModule :: !GHC.Module