summaryrefslogtreecommitdiff
path: root/compiler/ghci
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-09-28 13:51:56 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-09-28 13:51:56 +0000
commit939ce676b146713bbe0de42dec6c30da2c948049 (patch)
tree24678a63fdef3df9c8c89980bf7abde213858ae4 /compiler/ghci
parentc838103b0636d8209d9d910db0a0328ee1682a39 (diff)
downloadhaskell-939ce676b146713bbe0de42dec6c30da2c948049.tar.gz
Add basic :edit support
Without jumping to line numbers or %-expansion, we could add that later.
Diffstat (limited to 'compiler/ghci')
-rw-r--r--compiler/ghci/InteractiveUI.hs52
1 files changed, 50 insertions, 2 deletions
diff --git a/compiler/ghci/InteractiveUI.hs b/compiler/ghci/InteractiveUI.hs
index 485e329d39..c38b37634d 100644
--- a/compiler/ghci/InteractiveUI.hs
+++ b/compiler/ghci/InteractiveUI.hs
@@ -123,6 +123,9 @@ builtin_commands = [
("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),
@@ -159,6 +162,8 @@ helpText =
" :browse [*]<module> display the names defined by <module>\n" ++
" :cd <dir> change directory to <dir>\n" ++
" :def <cmd> <expr> define a command :<cmd>\n" ++
+ " :edit <file> edit file\n" ++
+ " :edit edit last module\n" ++
" :help, :? display this list of commands\n" ++
" :info [<name> ...] display information about the given names\n" ++
" :load <filename> ... load module(s) and their dependents\n" ++
@@ -170,6 +175,7 @@ helpText =
" :set args <arg> ... set the arguments returned by System.getArgs\n" ++
" :set prog <progname> set the value returned by System.getProgName\n" ++
" :set prompt <prompt> set the prompt used in GHCi\n" ++
+ " :set editor <cmd> set the comand used for :edit\n" ++
"\n" ++
" :show modules show the currently loaded modules\n" ++
" :show bindings show the current bindings made at the prompt\n" ++
@@ -242,11 +248,13 @@ jumpFunction session@(Session ref) (I# idsPtr) hValues location b
writeIORef ref (hsc_env { hsc_IC = new_ic })
is_tty <- hIsTerminalDevice stdin
prel_mod <- GHC.findModule session prel_name Nothing
+ default_editor <- findEditor
withExtendedLinkEnv (zip names hValues) $
startGHCi (interactiveLoop is_tty True)
GHCiState{ progname = "<interactive>",
args = [],
prompt = location++"> ",
+ editor = default_editor,
session = session,
options = [],
prelude = prel_mod }
@@ -255,6 +263,15 @@ jumpFunction session@(Session ref) (I# idsPtr) hValues location b
return b
#endif
+findEditor = do
+ getEnv "EDITOR"
+ `IO.catch` \_ -> do
+#ifdef mingw32_HOST_OS
+ GetWindowsDirectory ++ "\\notepad.exe", or something
+#else
+ return ""
+#endif
+
interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
interactiveUI session srcs maybe_expr = do
#if defined(GHCI) && defined(BREAKPOINT)
@@ -306,10 +323,13 @@ interactiveUI session srcs maybe_expr = do
Readline.setCompleterWordBreakCharacters word_break_chars
#endif
+ default_editor <- findEditor
+
startGHCi (runGHCi srcs maybe_expr)
GHCiState{ progname = "<interactive>",
args = [],
prompt = "%s> ",
+ editor = default_editor,
session = session,
options = [],
prelude = prel_mod }
@@ -739,6 +759,27 @@ changeDirectory dir = do
dir <- expandPath dir
io (setCurrentDirectory dir)
+editFile :: String -> GHCi ()
+editFile str
+ | null str = do
+ -- find the name of the "topmost" file loaded
+ session <- getSession
+ graph0 <- io (GHC.getModuleGraph session)
+ graph1 <- filterM (io . GHC.isLoaded session . GHC.ms_mod_name) graph0
+ let graph2 = flattenSCCs (GHC.topSortModuleGraph True graph1 Nothing)
+ case GHC.ml_hs_file (GHC.ms_location (last graph2)) of
+ Just file -> do_edit file
+ Nothing -> throwDyn (CmdLineError "unknown file name")
+ | otherwise = do_edit str
+ where
+ do_edit file = do
+ st <- getGHCiState
+ let cmd = editor st
+ when (null cmd) $
+ throwDyn (CmdLineError "editor not set, use :set editor")
+ io $ system (cmd ++ ' ':file)
+ return ()
+
defineMacro :: String -> GHCi ()
defineMacro s = do
let (macro_name, definition) = break isSpace s
@@ -1169,11 +1210,13 @@ setCmd ""
else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
))
setCmd str
- = case words str of
+ = case toArgs str of
("args":args) -> setArgs args
("prog":prog) -> setProg prog
- ("prompt":prompt) -> setPrompt (dropWhile isSpace $ drop 6 $ dropWhile isSpace str)
+ ("prompt":prompt) -> setPrompt (after 6)
+ ("editor":cmd) -> setEditor (after 6)
wds -> setOptions wds
+ where after n = dropWhile isSpace $ drop n $ dropWhile isSpace str
setArgs args = do
st <- getGHCiState
@@ -1185,6 +1228,10 @@ setProg [prog] = do
setProg _ = do
io (hPutStrLn stderr "syntax: :set prog <progname>")
+setEditor cmd = do
+ st <- getGHCiState
+ setGHCiState st{ editor = cmd }
+
setPrompt value = do
st <- getGHCiState
if null value
@@ -1431,6 +1478,7 @@ data GHCiState = GHCiState
progname :: String,
args :: [String],
prompt :: String,
+ editor :: String,
session :: GHC.Session,
options :: [GHCiOption],
prelude :: Module