3

Whenever I run clear in my terminal, it deletes the scrollback buffer from the top of the screen to the current line. I have tried it in xterm, st, and urxvt, and the problem remains. Is there any way I can change the behavior of clear so it does not touch the scrollback buffer?

Kusalananda
  • 333,661
Alvo
  • 33
  • I think that is specific to terminal and not clear command... I use Gnome terminal 3.18.3 and it retains the scrollback buffer.. I also enable an option that rewraps lines on resizing the terminal... – Sundeep Oct 23 '16 at 04:07

5 Answers5

5

The comment "from the top of the screen to the current line" is ambiguous. If you meant from the top of the visible part of the screen, that is not the scrollback. The scrollback of a terminal is the part that you can see only by using the scrollbar (or suitable keys such as shift pageup).

XTerm Control Sequences documents the relevant escape sequence:

CSI Ps J  Erase in Display (ED).
            Ps = 0  -> Erase Below (default).
            Ps = 1  -> Erase Above.
            Ps = 2  -> Erase All.
            Ps = 3  -> Erase Saved Lines (xterm).

The terminal description capability clear uses the next-to-last one, e.g.,

clear=\E[H\E[2J

to position the cursor to the upper left and then clear the whole (visible) screen. You could use the Erase Below, but that is not used in the terminal description.

Referring to clearing the scrollback: That's a terminal-specific feature, originally an escape sequence in xterm (1999, documented in ctlseqs.ms but not mentioned in changes) and later (2011) implemented as an extension for Linux console and the corresponding terminal description. The terminal database lists it as a "miscellaneous extension".

Currently, these terminal descriptions have the feature:

Whether it is supported in xterm look-alikes such as VTE would have to be answered by testing (there is no useful documentation for VTE or Konsole).

If you prefer to not use the extension, you could remove the E3 capability from the terminal description which you use, e.g.,

infocmp -1x >foo
edit foo, removing the line with "E3="
tic -x foo

I suggested using the options -1 and -x to simplify the formatting and to show the feature to change. The example given in https://ghostbin.com/paste/kfsbj is consistent with that advice:

  • the pathname /home/flowerpick/.terminfo/x/xterm would be used by ncurses
  • the capabilities AX and XT are extended capabilities (like E3), shown with the -x option.

If you are using more than one terminal type, you would have to do this for each (value of $TERM), and the change only applies to the machine where you run clear. The first couple of lines of the infocmp output show which one you are working on:

#   Reconstructed via infocmp from file: /home/flowerpick/.terminfo/x/xterm
xterm|xterm terminal emulator (X Window System),

For instance, uxrvt sets $TERM to something like rxvt-unicode, producing lines like this in infocmp:

#       Reconstructed via infocmp from file: /lib/terminfo/r/rxvt-unicode       
rxvt-unicode|rxvt-unicode terminal (X Window System),

The st program uses xterm (or possibly xterm-256color), though it's been a while since I saw a copy of that which worked well enough to comment upon.

By the way, you could have an alias for clear which is sending the given escape sequence (ignoring the terminal description), but I haven't seen this reported by anyone.

If you wanted to "clear above", that is not as straightforward as typing "clear". The escape \033[1J erases from the upper-left to the current cursor position. You could make a script which does this, to clear only the lines above your current cursor:

  • use the cursor position report to find the row/column on which the cursor currently is, and
  • if the cursor is not on the first line, (saving that position), move the cursor up one line and then (with the hpa sequence) move right a large number,
  • issue the "clear above", and
  • return to the original position using cup (cursor addressing).

That part with the cursor position report doesn't seem as if it would work in (for example) a readline binding, so I suggested a script. You could make a binding that used the save/restore cursor capabilities if there were not the problem of being on the first line.

Thomas Dickey
  • 76,765
  • I followed your instruction, but the problem remains. – Alvo Oct 24 '16 at 11:51
  • What does infocmp -x show? (It shouldn't show the E3 capability). – Thomas Dickey Oct 24 '16 at 20:44
  • Thank you for the detailed answer. When I mention "from the top of the screen to the current line", I meant from the top of the visible part of the screen. Since my question is no longer related to the scroll back buffer, I'm wondering how I could preserve the top of the visible part of the screen to the current line whenever I clear the screen. I had tried perl -e'print "\33[H\33[1J"'(changing the numbers according to the list you given above), but all of them deletes the visible part of the screen to the line where I issued the command. – Alvo Oct 26 '16 at 04:54
  • I tried all four values with the clear sequence e.g. clear=\E[H\E[0J, but I couln't change the behavior of clear. I tried the same in xterm but it didn't work either. But clear and ctrl-l did stop working if I remove the line with clear. – Alvo Dec 13 '18 at 01:49
  • The "\033[H" moves the cursor to the upper-left corner of the screen. If you omit that, clear-below (0) should not affect the "above" portion (except for Windows console....). – Thomas Dickey Dec 13 '18 at 01:55
  • Sorry I don't quite understand what you mean. I get my desired outcome when I run $ print "\033[H". How should i set the value of clear to have the same effect? I thought setting clear=\E[H\E[0J is the equivalent of "\033[H". – Alvo Dec 13 '18 at 02:03
  • no: the H code moves the cursor, the J code clears the display. – Thomas Dickey Dec 13 '18 at 02:27
  • If I omit "\E[H" then clear doesn't clear the screen. Playing with different value for J code doesn't yield my desired outcome. And I made sure the E3 extension is not in the output of infocmp. I just want the content that was cleared out on the screen to show up again when I scroll back with shift-PgUp. – Alvo Dec 13 '18 at 23:44
  • @Alvo I'm having the same issue, have you found a solution? – Razor Nov 27 '20 at 05:08
3

I had the same problem and adding an alias in .bashrc helped:

alias clear='printf "\E[H\E[2J"'

Reminder: The changes in .bashrc take effect after you open new terminal!

Paulo Tomé
  • 3,782
1

I routinely use clear to get my command prompt to move to the top of the screen and inadvertently erase the scrollback buffer, often with important content such as useful error messages from previous operations.

Checking the man page, it clearly states:

clear clears your screen if this is possible, including its scrollback buffer (if the extended “E3” capability is defined).

There is also an option there:

-x do not attempt to clear the terminal's scrollback buffer using the extended “E3” capability.

Since then, I have added this to my list of aliases in ~/.bashrc:

alias clear='clear -x'

I still get the prompt to move to the top when I run clear, but now I can scroll back further up if I want.

Nagev
  • 439
0

For me, I do not have an issue with locally run clear, but if I ssh into another host, and a clear is run there, it trashes my scroll history, which I consider to be very bad. I ended editing konsole source (21.12.1), file src/Vt102Emulation.cpp, with this: (see https://github.com/KDE/konsole/blob/release/21.12/src/Vt102Emulation.cpp)

--- Vt102Emulation.cpp  2022-08-07 22:21:16.570790929 +0100
+++ Vt102Emulation.cpp  2022-08-07 22:22:52.170787056 +0100
@@ -684,7 +684,7 @@
     case token_csi_ps('J',   0) : _currentScreen->clearToEndOfScreen   (          ); break;
     case token_csi_ps('J',   1) : _currentScreen->clearToBeginOfScreen (          ); break;
     case token_csi_ps('J',   2) : _currentScreen->clearEntireScreen    (          ); break;
-    case token_csi_ps('J',   3) : clearHistory();                                 break;
+    case token_csi_ps('J',   3) :  /* IGNORE clearHistory(); */                   break;
     case token_csi_ps('g',   0) : _currentScreen->changeTabStop        (false     ); break; //VT100
     case token_csi_ps('g',   3) : _currentScreen->clearTabStops        (          ); break; //VT100
     case token_csi_ps('h',   4) : _currentScreen->    setMode      (MODE_Insert   ); break;

This makes konsole do nothing if it sees the \E[3J string that fubars the scroll history.

0

My solution for this is to add the following alias to my .bashrc

alias clear='tput reset'

In case one wants to use the original behaviour, e.g. to clear sensitive information from the scrollback buffer, the un-aliased version can easily be invoked by prepending a backslash \ as explained here or here. That would look like this

\clear