Linux – how to make less pager respond to scroll wheel and not clear the screen

bashlinuxmousescrollingterminal

I know about answers like how-to-make-mouse-wheel-scroll-the-less-pager-using-bash-and-gnome-terminal, which is to remove the -X flag from the $LESS environment variable. But I would like to do both of these:

  1. use the mouse wheel to scroll the pager (as opposed to scrolling the terminal window's scrollbar) (which you get by removing -X from $LESS)
  2. have the content from the pager remain on the screen after quitting (which is normally accomplished by adding -X to $LESS).

Is there any way I can have my cake and eat it as well?

Best Answer

Not without hacking less's source code. A bit of background story:

Less cannot handle mouse (including scroll events) at all.

Terminal emulators support a so-called alternate screen. This is which most fullscreen apps switch to for their duration (and switch back to the normal screen when they quit, causing the previous contents to "restore"), and it doesn't have a scrollback buffer. Less also switches to this alternate screen, unless -X is given in which case it doesn't.

Many terminal emulators figured out that when it's in alternate screen mode and the application running inside is not interested in mouse events, it makes sense to convert scrolling into Up or Down keypress events. It's a hack, and it'd be harmful either on normal screen (imagine what would happen e.g. at your shell prompt), or when the application wishes to handle mouse (sure, they have to see the actual mouse events then). But since by default neither of these two hold when you're running less, this hack kicks in (subject to the terminal emulator supporting it, and being enabled via \e[?1007h vs. \e[?1007l). Your scroll events are converted by the terminal emulator to Up and Down keypresses, and less can't distinguish them from actual keypresses. It doesn't receive mouse scroll events: it sees Up and Down keypresses.

So there you are: Either you switch to alternate screen and the terminal's hack converts scroll events into keypresses for less, and the normal screen is restored when you quit; or you don't, and then there can't be any magic converting scroll events to keypresses and less doesn't understand the scroll events.

So what could be done? Well, either implement mouse support in less and let it handle scroll events itself (and live with a nondefault click or copy-paste behavior), or implement another weird hack: upon quitting, after reverting to the normal screen, less could for the last time print a screenful of content, repeating whatever was displayed before you quit.

In practice, it basically boils down to: sorry, forget it.

Related Question