7

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)?

3 Answers 3

6

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
}
2
  • I've been doing this for several years and can completely recommend it as a solution. Why I'm writing to is seek clarification of your last sentence. Is this a "let me know if this worked for you" to @musiKk or is it related to some other subtle issue with smcup and rmcup that you haven't yet resolved?
    – roaima
    May 23, 2015 at 19:15
  • @roaima, the problem is that the mouse wheel stops working. I like the mouse wheel scrolling, and so does the OP, as he says.
    – K3---rnc
    May 23, 2015 at 20:14
1

For slow inputs, like git log -Gregex, do you want:

A) lines to appear on the main screen as they come in, then switch to the alternate screen once scrolling is needed (so the first $LINES of output will always appear in your scrollback); if so, go with the 2nd of Gilles's answers to a similar question.

B) lines to appear on the alternate screen, but quit the alternate screen and print the lines to the main screen if scrolling turns out to be unnecessary (so no output will appear in your scrollback if scrolling was required); if so, look at my answer to a similar question.

0

The behaviour reported in the question was fixed in less version 530 from Feb '18:

  • Don't output terminal init sequence if using -F and file fits on one screen.

Which means that the output is left on screen with or without -X.

Additionally, less version 598 from Dec '21 introduced option --redraw-on-quit to leave the last view on screen even if there's more than one screenful and the alternate screen is used:

--redraw-on-quit
       When quitting, after sending the terminal deinitialization string, redraws
       the entire last screen.   On  terminals  whose  terminal  deinitialization
       string  causes the terminal to switch from an alternate screen, this makes
       the last screenful of the current file remain visible after less has quit.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .