How do some tools (e.g. nano , less) manage to leave no content in terminals after exit?

There are two worldviews here:

  • As far as programs using termcap/terminfo are concerned, your terminal potentially has two modes: cursor addressing mode and scrolling mode. The latter is the normal mode, and a program switches to cursor addressing mode when it needs to move the cursor around the screen by row and column addresses, treating the screen as a two-dimensional entity.

    termcap and terminfo handle translating this worldview, which is what programs see, into the worldview as seen by terminals.

  • As far as a terminal (emulated or real) is concerned, there are two screen buffers, only one of which is displayed at any time. There's a primary screen buffer and an alternate screen buffer. Control sequences emitted by programs switch the terminal between the two.
    • For some terminals, usually emulated ones, the alternate screen buffer is tailored to the usage of termcap/terminfo. They are designed with the knowledge that part of switching to cursor addressing mode is switching to the alternate screen buffer and part of switching to scrolling mode is switching to the primary screen buffer. This is how termcap/terminfo translate things. So these terminals don't show scrolling user interface widgets when the alternate screen buffer is being displayed, and simply have no scrollback mechanism for that screen buffer.
    • For other terminals, usually real ones, the alternate screen buffer is pretty much like the primary. Both are largely identical in terms of what they support. A few emulated terminals fall into this class, note. Unicode rxvt, for example, has scrollback for both the primary and alternate screen buffers.

Programs that present full-screen textual user interfaces (such as vim, nano, less, mc, and so forth) use termcap/terminfo to switch to cursor-addressing mode at start-up and back to scrolling mode when they suspend, or shell out, or exit. The ncurses library does this, but so too do non-ncurses-using programs that build more directly on top of termcap/terminfo.

The scrolling within TUIs presented by less or vim is nothing to do with scrollback. That is implemented inside those programs, which are just redrawing their full-screen textual user interface as appropriate as things scroll around.

Note that these programs do not "leave no content" in the alternate screen buffer. The terminal simply is no longer displaying what they leave behind.

  • This is particularly noticable with Unicode rxvt on some platforms, where the termcap/terminfo sequences for switching to cursor addressing mode do not implicitly clear the alternate screen buffer. So using multiple such full-screen TUI programs in succession can end up displaying the old contents of the alternate screen buffer as left there by the last program, at least for a little while until the new program writes its output (most noticable when less is at the end of a pipeline).
  • With xterm, one can switch to displaying the alternate screen buffer from the GUI menu of the terminal emulator, and see the content still there.

The actual control sequences are what the relevant standards call set private mode control sequences. The relevant private mode numbers are 47, 1047, 1048, and 1049. Note the differences in what extra actions are implied by each, on top of switching to/from the alternate screen buffer.

Further reading

  • How to save/restore terminal output
  • Entering/exiting alternate screen buffer
  • OpenSSH, FreeBSD screen overwrite when closing application
  • What exactly is scrollback and scrollback buffer?
  • Building blocks of interactive terminal applications

A library called curses, it knows what terminal type you are using, and sends the correct escape sequences. There terminal is asked to switch to a different vertical buffer, and mode that allows more control.

You can add a no-clear to this a couple of ways. You can resolve less from clearing the screen by calling it with the -X argument.

Note the $ symbol in the command lines below. This is specifying the terminal prompt of a normal user.

$ seq 1 200 | less -X

If that is your desired behavior you can alias less to this default with:

$ alias less='less -X'

There are similar workarounds for other programs.

Alternatively, rather than trying to configure each application individually you can add your own terminal definition. In this case I'll call it xterm-noclear for this example.

Run these steps to create a new xterm definition:

$ infocmp -I xterm > xterm-noclear.src
$ gedit xterm-noclear.src

Now change the second line in your editor from xterm to xterm-noclear.

Remove the instructions that clears the screen by searching rmcup and smcup, and removing these two instructions:




Save the file then add the terminal definition with:

$ tic ~/xterm-noclear.src

You can make this a system-wide available terminal definition with:

$ sudo tic ~/xterm-noclear.src

Now you can use this TERM with:

$ export TERM=xterm-noclear