From: Ian Lynagh Date: Sun, 25 Nov 2007 12:20:20 +0000 (+0000) Subject: MERGED: Make ":" in GHCi repeat the last command X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=d2b3daa3cc474e6ab010fb6af5c21ddb852b8b5b MERGED: Make ":" in GHCi repeat the last command Ian Lynagh **20071124231857 It used to be a synonym for ":r" in 6.6.1, but this wasn't documented or known about by the developers. In 6.8.1 it was accidentally broken. This patch brings it back, but as "repeat the last command", similar to pressing enter in gdb. This is almost as good for people who want it to reload, and means that it can also be used to repeat commands like :step. --- diff --git a/compiler/ghci/GhciMonad.hs b/compiler/ghci/GhciMonad.hs index 2ccde55..4e8e65f 100644 --- a/compiler/ghci/GhciMonad.hs +++ b/compiler/ghci/GhciMonad.hs @@ -46,6 +46,8 @@ import GHC.Exts ----------------------------------------------------------------------------- -- GHCi monad +type Command = (String, String -> GHCi Bool, Bool, String -> IO [String]) + data GHCiState = GHCiState { progname :: String, @@ -62,6 +64,9 @@ data GHCiState = GHCiState -- tickarrays caches the TickArray for loaded modules, -- so that we don't rebuild it each time the user sets -- a breakpoint. + -- ":" at the GHCi prompt repeats the last command, so we + -- remember is here: + last_command :: Maybe Command, cmdqueue :: [String], remembered_ctx :: Maybe ([Module],[Module]) -- modules we want to add to the context, but can't diff --git a/compiler/ghci/InteractiveUI.hs b/compiler/ghci/InteractiveUI.hs index e5c6813..3ae37f5 100644 --- a/compiler/ghci/InteractiveUI.hs +++ b/compiler/ghci/InteractiveUI.hs @@ -97,8 +97,6 @@ ghciWelcomeMsg :: String ghciWelcomeMsg = "GHCi, version " ++ cProjectVersion ++ ": http://www.haskell.org/ghc/ :? for help" -type Command = (String, String -> GHCi Bool, Bool, String -> IO [String]) - cmdName :: Command -> String cmdName (n,_,_,_) = n @@ -165,6 +163,7 @@ helpText = " Commands available from the prompt:\n" ++ "\n" ++ " evaluate/run \n" ++ + " : repeat last command\n" ++ " :{\\n ..lines.. \\n:}\\n multiline command\n" ++ " :add ... add module(s) to the current target set\n" ++ " :browse[!] [[*]] display the names defined by module \n" ++ @@ -314,6 +313,7 @@ interactiveUI session srcs maybe_expr = do break_ctr = 0, breaks = [], tickarrays = emptyModuleEnv, + last_command = Nothing, cmdqueue = [], remembered_ctx = Nothing } @@ -711,29 +711,48 @@ printTypeOfName session n Just thing -> printTyThing thing - +data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand specialCommand :: String -> GHCi Bool specialCommand ('!':str) = shellEscape (dropWhile isSpace str) specialCommand str = do let (cmd,rest) = break isSpace str - maybe_cmd <- io (lookupCommand cmd) + maybe_cmd <- lookupCommand cmd case maybe_cmd of - Nothing -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n" - ++ shortHelpText) >> return False) - Just (_,f,_,_) -> f (dropWhile isSpace rest) - -lookupCommand :: String -> IO (Maybe Command) + GotCommand (_,f,_,_) -> f (dropWhile isSpace rest) + BadCommand -> + do io $ hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n" + ++ shortHelpText) + return False + NoLastCommand -> + do io $ hPutStr stdout ("there is no last command to perform\n" + ++ shortHelpText) + return False + +lookupCommand :: String -> GHCi (MaybeCommand) +lookupCommand "" = do + st <- getGHCiState + case last_command st of + Just c -> return $ GotCommand c + Nothing -> return NoLastCommand lookupCommand str = do + mc <- io $ lookupCommand' str + st <- getGHCiState + setGHCiState st{ last_command = mc } + return $ case mc of + Just c -> GotCommand c + Nothing -> BadCommand + +lookupCommand' :: String -> IO (Maybe Command) +lookupCommand' str = do macros <- readIORef macros_ref let cmds = builtin_commands ++ macros -- look for exact match first, then the first prefix match - case [ c | c <- cmds, str == cmdName c ] of - c:_ -> return (Just c) - [] -> case [ c | c@(s,_,_,_) <- cmds, str `isPrefixOf` s ] of - [] -> return Nothing - c:_ -> return (Just c) - + return $ case [ c | c <- cmds, str == cmdName c ] of + c:_ -> Just c + [] -> case [ c | c@(s,_,_,_) <- cmds, str `isPrefixOf` s ] of + [] -> Nothing + c:_ -> Just c getCurrentBreakSpan :: GHCi (Maybe SrcSpan) getCurrentBreakSpan = do @@ -1594,7 +1613,7 @@ completeWord w start end = do ':':_ | all isSpace (take (start-1) line) -> wrapCompleter completeCmd w _other | ((':':c) : _) <- line_words -> do - maybe_cmd <- lookupCommand c + maybe_cmd <- lookupCommand' c let (n,w') = selectWord (words' 0 line) case maybe_cmd of Nothing -> return Nothing diff --git a/docs/users_guide/ghci.xml b/docs/users_guide/ghci.xml index 98496d7..528a652 100644 --- a/docs/users_guide/ghci.xml +++ b/docs/users_guide/ghci.xml @@ -1991,6 +1991,17 @@ Prelude> :. cmds.ghci + + : + : + + + Repeat the previous command. + + + + + :history [num] :history