Repository: pwndbg/pwndbg

Issue:
Clear screen before printing context
### Discussed in https://github.com/pwndbg/pwndbg/discussions/1164

As discussed (see below), can the screen be cleared before the next instruction or printing context so that each element of the output stays in a consistent location?

<div type='discussions-op-text'>

<sup>Originally posted by **JesseAusten** September 25, 2022</sup>
I've noticed pwndbg doesn't refresh the screen each time I step an instruction like gef does, as in the register context isn't lined up with the top of the screen, it just keeps whatever fits. Is there a way to clear the screen each time I step through a program?</div>


Discussion:
`set context-clear-screen on` should do this.
That worked, thank you! Should that be something that's on by default rather than adding it to an init script?
I personally like having the history over alignment. Not sure how others feel.
Oh that doesn't actually keep the history so there's no way to scroll up and see output or previous commands?
I also like having history so I am not sure if we should change the default. We can add a https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/lib/tips.py about it.
I use `tmux`, so it keeps the history for me. But it would good if it kept the history regardless. `gef`s implmentation probably does this since they're just using control characters, we can probably do something similar.
It seems that `gdb> shell clear -x` keeps history while clearing the screen, similar to `^L` in the shell. It seems that's also what gef uses.
Oh, that's nice. Maybe we could have: `set context-clear-mode` with three values?:
1. One that would clear the screen but keep the history
2. Second that would clear the screen but not keep history (our current `set context-clear-screen on`)
3. Third that would not clear the screen and not keep history (out current default)

Wdyt? Not sure how to name those values though :)

Or just... use 1) and do not support 2) or 3)?
I don't think 2 is necessary, not sure that anyone would prefer that over 1. I think keeping the current default, option 3, around (but not enabled by default) would still be good to have.
> Oh that doesn't actually keep the history so there's no way to scroll up and see output or previous commands?

Wait, I just checked locally and I can scroll up myshell to get the previous output after setting `set context-clear-screen on` in Pwndbg.

We are currently using this for clearing the screen:
```py
def clear_screen(out=sys.stdout):
    """
    Clear the screen by moving the cursor to top-left corner and
    clear the content
    """
    out.write("\x1b[H\x1b[J")
```

And this is also what GEF may fallback to if there is a `tty` included. Why may it clear history for you?
Okay, that is interesting. The behavior depends on the used terminal; here, on Ubuntu 22.04 with `set context-clear-screen on` I get this behavior:
* gnome-terminal - does not save history
* gnome-terminal + screen session - does save history
* terminator - does save history
Also, I'd prefer to not rely on the `clear` binary if possible.

Interesting: https://askubuntu.com/a/997893

So we are doing:
```py
out.write("\x1b[H\x1b[J")
```
And that askubuntu thread suggests doing:
```
out.write("\x1b[H\x1b[2J")
```

And... that seems to work for me - it does not remove the scrollback buffer when clearing the screen.


Resolving patch:
diff --git a/pwndbg/commands/context.py b/pwndbg/commands/context.py
--- a/pwndbg/commands/context.py
+++ b/pwndbg/commands/context.py
@@ -33,9 +33,24 @@
 def clear_screen(out=sys.stdout):
     """
     Clear the screen by moving the cursor to top-left corner and
-    clear the content
+    clearing the content. Different terminals may act differently
     """
-    out.write("\x1b[H\x1b[J")
+    ## The ANSI escape codes we use here are described e.g. on:
+    # https://en.wikipedia.org/wiki/ANSI_escape_code#CSIsection
+    #
+    ## To sum up the escape codes used below:
+    # \x1b - Escape | Starts all the escape sequences
+    # [ - Control Sequence Introducer | Starts most of the useful sequences
+    # H - Cursor Position | Moves the cursor to row n, column m (default=1)
+    # \x1b - Escape | Starts all the escape sequences
+    # <n> J - Erase in Display | Clears part of the screen.
+    # If n is 0 (or missing), clear from cursor to end of screen.
+    # If n is 1, clear from cursor to beginning of the screen.
+    # If n is 2, clear entire screen (and moves cursor to upper left on DOS ANSI.SYS).
+    # If n is 3, clear entire screen and delete all lines saved in the
+    # scrollback buffer (this feature was added for xterm and is supported
+    # by other terminal applications
+    out.write("\x1b[H\x1b[2J")
 
 
 config_clear_screen = pwndbg.config.Parameter(
diff --git a/pwndbg/lib/tips.py b/pwndbg/lib/tips.py
--- a/pwndbg/lib/tips.py
+++ b/pwndbg/lib/tips.py
@@ -9,6 +9,7 @@
     "Use GDB's `pi` command to run an interactive Python console where you can use Pwndbg APIs like `pwndbg.gdblib.memory.read(addr, len)`, `pwndbg.gdblib.memory.write(addr, data)`, `pwndbg.gdb.vmmap.get()` and so on!",
     "GDB's `set directories <path>` parameter can be used to debug e.g. glibc sources like the malloc/free functions!",
     # Pwndbg hints
+    "If you want Pwndbg to clear screen on each command (but still save previous output in history) use `set context-clear-screen on`.",
     "GDB and Pwndbg parameters can be shown or set with `show <param>` and `set <param> <value>` GDB commands",
     "Use Pwndbg's `config` and `theme` commands to tune its configuration and theme colors!",
     "Pwndbg mirrors some of Windbg commands like `eq`, `ew`, `ed`, `eb`, `es`, `dq`, `dw`, `dd`, `db`, `ds` for writing and reading memory",


Test patch: