Commit b03f074f authored by Ben Gamari's avatar Ben Gamari 🐢 Committed by Austin Seipp

ghci: Allow :back and :forward to take counts

These behave like the count arguments of the gdb `up` and `down`
commands, allowing the user to quickly jump around in history.

Reviewed By: austin

Differential Revision: https://phabricator.haskell.org/D853
parent 578d2bad
......@@ -564,11 +564,11 @@ resumeExec canLogSpan step
handleRunStatus step expr bindings final_ids
breakMVar statusMVar status hist'
back :: GhcMonad m => m ([Name], Int, SrcSpan)
back = moveHist (+1)
back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
back n = moveHist (+n)
forward :: GhcMonad m => m ([Name], Int, SrcSpan)
forward = moveHist (subtract 1)
forward :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
forward n = moveHist (subtract n)
moveHist :: GhcMonad m => (Int -> Int) -> m ([Name], Int, SrcSpan)
moveHist fn = do
......
......@@ -96,6 +96,11 @@
<literal>Main</literal> with an explicit module header but
without <literal>main</literal> is now an error (#7765).
</para>
<para>
The <literal>:back</literal> and <literal>:forward</literal>
commands now take an optional count allowing the user to move forward or
backward in history several steps at a time.
</para>
</listitem>
</itemizedlist>
</sect3>
......
......@@ -2096,12 +2096,14 @@ $ ghci -lm
<varlistentry>
<term>
<literal>:back</literal>
<literal>:back <optional><replaceable>n</replaceable></optional></literal>
<indexterm><primary><literal>:back</literal></primary></indexterm>
</term>
<listitem>
<para>Travel back one step in the history. See <xref
linkend="tracing" />. See also:
<para>Travel back <replaceable>n</replaceable> steps in the
history. <replaceable>n</replaceable> is one if omitted.
See <xref linkend="tracing" /> for more about GHCi's debugging
facilities. See also:
<literal>:trace</literal>, <literal>:history</literal>,
<literal>:forward</literal>.</para>
</listitem>
......@@ -2474,12 +2476,14 @@ Prelude> :. cmds.ghci
<varlistentry>
<term>
<literal>:forward</literal>
<literal>:forward <optional><replaceable>n</replaceable></optional></literal>
<indexterm><primary><literal>:forward</literal></primary></indexterm>
</term>
<listitem>
<para>Move forward in the history. See <xref
linkend="tracing" />. See also:
<para>Move forward <replaceable>n</replaceable> steps in the
history. <replaceable>n</replaceable> is one if omitted.
See <xref linkend="tracing" /> for more about GHCi's debugging
facilities. See also:
<literal>:trace</literal>, <literal>:history</literal>,
<literal>:back</literal>.</para>
</listitem>
......
......@@ -268,14 +268,14 @@ defFullHelpText =
" -- Commands for debugging:\n" ++
"\n" ++
" :abandon at a breakpoint, abandon current computation\n" ++
" :back go back in the history (after :trace)\n" ++
" :back [<n>] go back in the history N steps (after :trace)\n" ++
" :break [<mod>] <l> [<col>] set a breakpoint at the specified location\n" ++
" :break <name> set a breakpoint on the specified function\n" ++
" :continue resume after a breakpoint\n" ++
" :delete <number> delete the specified breakpoint\n" ++
" :delete * delete all breakpoints\n" ++
" :force <expr> print <expr>, forcing unevaluated parts\n" ++
" :forward go forward in the history (after :back)\n" ++
" :forward [<n>] go forward in the history N step s(after :back)\n" ++
" :history [<n>] after :trace, show the execution history\n" ++
" :list show the source code around current breakpoint\n" ++
" :list <identifier> show the source code for <identifier>\n" ++
......@@ -2747,24 +2747,34 @@ bold c | do_bold = text start_bold <> c <> text end_bold
| otherwise = c
backCmd :: String -> GHCi ()
backCmd = noArgs $ withSandboxOnly ":back" $ do
(names, _, pan) <- GHC.back
printForUser $ ptext (sLit "Logged breakpoint at") <+> ppr pan
printTypeOfNames names
-- run the command set with ":set stop <cmd>"
st <- getGHCiState
enqueueCommands [stop st]
backCmd arg
| null arg = back 1
| all isDigit arg = back (read arg)
| otherwise = liftIO $ putStrLn "Syntax: :back [num]"
where
back num = withSandboxOnly ":back" $ do
(names, _, pan) <- GHC.back num
printForUser $ ptext (sLit "Logged breakpoint at") <+> ppr pan
printTypeOfNames names
-- run the command set with ":set stop <cmd>"
st <- getGHCiState
enqueueCommands [stop st]
forwardCmd :: String -> GHCi ()
forwardCmd = noArgs $ withSandboxOnly ":forward" $ do
(names, ix, pan) <- GHC.forward
printForUser $ (if (ix == 0)
then ptext (sLit "Stopped at")
else ptext (sLit "Logged breakpoint at")) <+> ppr pan
printTypeOfNames names
-- run the command set with ":set stop <cmd>"
st <- getGHCiState
enqueueCommands [stop st]
forwardCmd arg
| null arg = forward 1
| all isDigit arg = forward (read arg)
| otherwise = liftIO $ putStrLn "Syntax: :back [num]"
where
forward num = withSandboxOnly ":forward" $ do
(names, ix, pan) <- GHC.forward num
printForUser $ (if (ix == 0)
then ptext (sLit "Stopped at")
else ptext (sLit "Logged breakpoint at")) <+> ppr pan
printTypeOfNames names
-- run the command set with ":set stop <cmd>"
st <- getGHCiState
enqueueCommands [stop st]
-- handle the "break" command
breakCmd :: String -> GHCi ()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment