Can ‘less -F’ be usefully combined with termcap initialization

less

less -F closes less if the contents fit on one screen. However, if I use termcap initialization, i.e., I don't use -X and the file fits on the screen, nothing is printed because less displays the contents, notices that they fit on the screen, exits and clears the screen during deinitialization.

This can be demonstrated as follows (assumes empty LESS variable):

$ echo foo > new_file
$ cat new_file
foo
$ less -X -F new_file
foo
$ less -F new_file
$

I like termcap features, it allows scrolling with the mouse wheel among other things so I definitely don't want to use -X. Is there still a way to have less quit if the content fits on the screen (and basically behave like cat)?

Best Answer

Here's a relevant excerpt from less' FAQ:

Can less leave the screen alone when it quits?

When less starts, it sends the "ti" termcap string to the terminal, and when it quits, it sends the "te" string. Exactly what the "te" string does depends on the system you are using, the type of terminal, and your version of termcap. On some systems, it does nothing; on others it restores the screen to the state it was in when less started, thus erasing from the screen the last page of the file which less was viewing.

If you don't like the behavior of "te" on your system, you can disable the sending of the "ti" and "te" strings by invoking less with the -X option. Unfortunately, this sometimes has other side effects, because the "ti"/"te" strings might do other things that are required. For example, on some terminals, disabling "ti" and "te" causes arrow keys to cease to function.

If you want "te" to do something different (for example, restore the screen if it's not doing that already), you'll have to figure out how to change the termcap or terminfo for your terminal on your system. Unfortunately, this is done differently on different systems, so you'll have to check the documentation for your system.

Research leads to "ti" and "te" termcap capabilities being named "smcup" and "rmcup" in terminfo, which is a more modern termcap equivalent.

You can see how your terminal ($TERM, likely xterm) is configured with:

infocmp -1  # which will print out capabilites one per line

You can decipher the meaning of sequences with the help of a VT100 control characters reference.

If you strip the "smcup" and "rmcup" capabilities from your terminal:

infocmp -1 | sed -r '/[sr]mcup.*/d' > new-terminfo-for-$TERM

and then let the terminfo library know this is the new, preferred capability spec for $TERM,

tic new-terminfo-for-$TERM
# you reverse this with `rm -ri ~/.terminfo`

you will notice the less' alternative screen is not cleared anymore (because it had never been entered). But so does the mouse not work anymore.

If you fiddle with "rmcup" control character sequences and figure it out, please let me know!

Update:

A working alternative is to wrap less as a function that runs cat when the file fits the terminal height (put this in your .bashrc):

less () {
    # When single file argument, and file small enough, cat it
    if [ $# = 1 ] && [ -f "$1" ] && [ $(wc -l "$1" | cut -d' ' -f1) -le $((${LINES:-0} - 3)) ]; then
        cat "$@"
    else
        command less "$@"
    fi
}
Related Question