getEnv "EDITOR"
`IO.catch` \_ -> do
#if mingw32_HOST_OS
- win <- System.Win32.getWindowsDirectory
- return (win `joinFileName` "notepad.exe")
+ win <- System.Win32.getWindowsDirectory
+ return (win </> "notepad.exe")
#else
- return ""
+ return ""
#endif
interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
-- intended for the program, so unbuffer stdin.
hSetBuffering stdin NoBuffering
- -- initial context is just the Prelude
- prel_mod <- GHC.findModule session (GHC.mkModuleName "Prelude")
- (Just basePackageId)
- GHC.setContext session [] [prel_mod]
-
#ifdef USE_READLINE
- Readline.initialize
- Readline.setAttemptedCompletionFunction (Just completeWord)
- --Readline.parseAndBind "set show-all-if-ambiguous 1"
+ Readline.initialize
+ Readline.setAttemptedCompletionFunction (Just completeWord)
+ --Readline.parseAndBind "set show-all-if-ambiguous 1"
- Readline.setBasicWordBreakCharacters word_break_chars
- Readline.setCompleterWordBreakCharacters word_break_chars
+ Readline.setBasicWordBreakCharacters word_break_chars
+ Readline.setCompleterWordBreakCharacters word_break_chars
+ Readline.setCompletionAppendCharacter Nothing
#endif
+ -- initial context is just the Prelude
+ prel_mod <- GHC.findModule session (GHC.mkModuleName "Prelude")
+ (Just basePackageId)
+ GHC.setContext session [] [prel_mod]
+
default_editor <- findEditor
startGHCi (runGHCi srcs maybe_expr)
- GHCiState{ progname = "<interactive>",
- args = [],
+ GHCiState{ progname = "<interactive>",
+ args = [],
prompt = "%s> ",
stop = "",
- editor = default_editor,
- session = session,
- options = [],
+ editor = default_editor,
+ session = session,
+ options = [],
prelude = prel_mod,
break_ctr = 0,
breaks = [],
dir_ok <- io (checkPerms ".")
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 "./.ghci" ReadMode))
+ case either_hdl of
+ Left _e -> return ()
+ Right hdl -> runCommands (fileLoop hdl False False)
+
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)
+ 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)
-- Perform a :load for files given on the GHCi command line
-- When in -e mode, if the load fails then we want to stop
-- immediately rather than going on to evaluate the expression.
when (not (null paths)) $ do
- ok <- ghciHandle (\e -> do showException e; return Failed) $
- loadModule paths
+ ok <- ghciHandle (\e -> do showException e; return Failed) $
+ loadModule paths
when (isJust maybe_expr && failed ok) $
- io (exitWith (ExitFailure 1))
+ io (exitWith (ExitFailure 1))
-- if verbosity is greater than 0, or we are connected to a
-- terminal, display the prompt in the interactive loop.
return (filter (w `isPrefixOf`) options)
where options = "args":"prog":allFlags
-completeFilename = Readline.filenameCompletionFunction
+completeFilename w = do
+ ws <- Readline.filenameCompletionFunction w
+ case ws of
+ -- If we only found one result, and it's a directory,
+ -- add a trailing slash.
+ [file] -> do
+ isDir <- expandPathIO file >>= doesDirectoryExist
+ if isDir && last file /= '/'
+ then return [file ++ "/"]
+ else return [file]
+ _ -> return ws
+
completeHomeModuleOrFile = unionComplete completeHomeModule completeFilename
wrapCompleter fun w = do
strs <- fun w
case strs of
- [] -> return Nothing
- [x] -> return (Just (x,[]))
+ [] -> Readline.setAttemptedCompletionOver True >> return Nothing
+ [x] -> -- Add a trailing space, unless it already has an appended slash.
+ let appended = if last x == '/' then x else x ++ " "
+ in return (Just (appended,[]))
xs -> case getCommonPrefix xs of
"" -> return (Just ("",xs))
pref -> return (Just (pref,xs))
-- Utils
expandPath :: String -> GHCi String
-expandPath path =
+expandPath path = io (expandPathIO path)
+
+expandPathIO :: String -> IO String
+expandPathIO path =
case dropWhile isSpace path of
('~':d) -> do
- tilde <- io getHomeDirectory -- will fail if HOME not defined
+ tilde <- getHomeDirectory -- will fail if HOME not defined
return (tilde ++ '/':d)
other ->
return other