Random Tech Thoughts

The title above is not random

Prevent Applications Like Vim and Less Clearing Screen on Exit

TL;DR

The content clearing behavior is caused by the smcup/rmcup capability. Here’s the methods to preserve screen content depends on what terminal you use:

  • For tmux, the alternate-screen option defaults to on. Add the following in .tmux.conf to disable it:

    set-window-option -g alternate-screen off
    
  • screen does not enable the annoying terminal capability by default. If you encounter this, add the following to .screenrc:

    alterscreen off
    
  • If you don’t use screen or tmux, I suggest you invest some time in these tools and I assure you they worth it. If you can’t use these tools, then follow the directions in smcup/rmcup: hate. This removes the declaration of the annoying capabilities in the terminfo database, so the application will not use them.

Update: If you find ssh “clears” screen after logout, check if .bash_logout on the server contains clear command.

Why?

When working on terminal, I prefer applications such as less and vim preserve their content on exit. This is quite handy to me. For example I often look up some commands’ man page for some options and then started typing on the terminal. With the man page preserved on the screen, I can still look it up when typing. (Note that man send its output to $PAGER, which is less for me.)

I’ve noticed that the content preserving behavior is different on different machines, and it also varies if you use screen or tmux. After arguing with one member in my lab which behavior is better, I finally decided to figure out what caused the difference.

Behind the scene

So let’s first figure out how is the clear screen behavior implemented. (More actually, restore to what the screen looks like before calling the command.) tmux’s man page explains what the alternate-screen option does:

This option configures whether programs running inside tmux may use the terminal alternate screen feature, which allows the smcup and rmcup terminfo(5) capabilities.

If we set this option on, less and vim will first store the content on the screen and restore the content after exit. (You can disable this for less with the -X option.)

The man page of terminfo is not very clear on what smcup/rmcup does. Here’s an example of using smcup/rmcup to save and restore screen, copied and modified from bash-hackers. I’m using git log as an example here (you can also try more the file itself, but the effect is not that obvious):

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
# save screen
tput smcup

# This will always preserve content regardless of terminal and terminfo.
# But as we surround it with smcup and rmcup, we will see the screen being
# cleared when exits.
git log

# restore
tput rmcup

How the solution works

For application to save and restore screen, 2 conditions must be met:

  • The terminal supports smcup/rmcup capability (such as iTerm2 on OS X)
  • The terminfo set by $TERM declares these capability (xterm declares, vt100 does not. But the above example still works even if $TERM is set to vt100. I guess tput still sends out the correct control code even though the vt100 terminfo set by $TERM does not declare it. But applications should first check the capability of terminal. and only send control-code if that capability exists.)

Breaking either of the conditions can preserve the screen content. That’s how the solution in the TL;DR section works.

References

Comments