How does "less" switch to the text, then back to the prompt?
When I run less
on some file, the prompt goes away, and I get the contents of the file on screen. Then when I press q, it goes back to the prompt. I think less
does this by saving the current terminal buffer, opening a new buffer, outputting the file into the new one, then when closed, discarding the new buffer, and restoring the old, but I don't know what this process is called or how it does this.
I looked in man less
but didn't find anything. I tried googling it, but couldn't find anything useful, except that the screen
command can do the same thing with shell sessions.
Ultimately, I'm asking because I want git diff
to use a new buffer instead of printing inline. I've already set GIT_PAGER=less
and git --paginate diff
, but they didn't change anything. And I have a workaround, but it's a bit long: git diff --color=always | less -R
Update: After some research, it looks like tput smcup
and tput rmcup
are high-level commands to do the same thing, probably using the termcap
package.
All of less
’s screen management functions are in its screen.c
module. At startup, unless it’s in “no init” (-X
or --no-init
) mode, it outputs its sc_init
string, which is termcap
’s ti
string (“terminal initialisation”, which gets the terminal ready for full-screen, cursor-controlling operation). At exit, it outputs its sc_deinit
string, which is termcap
’s te
string.
The behaviour you’re seeing is the default behaviour with git
, if less
isn’t configured (i.e. the LESS
variable is unset); when that’s the case, git
runs less
with the FRX
options, which cause less
to respectively quit if the content fits on a single screen, display colours, and skip initialising the terminal.
To get the behaviour you’re after, set LESS
to -R
, or set the core.pager
git
setting to something like less -+X
(see man git-config
for details).