14

I'm tweaking the pager of Git, but I've got some issues with it.

What I want is:

  1. Always colored output
  2. Scrolling by touchpad or mouse
  3. Quit-if-one-screen

And my current configuration is:

$ git config --global core.pager
less -+F -+X -+S

This does everything except the last one.

But, if I remove -+F, there will be no output in case of one-screen. If I remove -+X as well, the output is back but I cannot scroll by touchpad in less.

Is there a workaround which can meet all the requirements above?

1
  • 1
    This is a very interesting question. When I use -F (quit if one screen) I always do it in combination with -X (disable termcap init and de-init), but as you say, that wouldn't allow scrolling with the mouse. (I doubt scrolling is possible at all with -X.) I've modified the question title, but feel free to roll that back if you feel it loses too much meaning. :)
    – Wildcard
    Dec 9, 2016 at 2:43

2 Answers 2

14

UPDATE

tl;dr Solution: upgrade to less 530

From http://www.greenwoodsoftware.com/less/news.530.html:

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

So with this fix we don't even need to bother determining whether to use -X on our own, less -F just takes care of it.

PS. Some other less configs that I use:

export PAGER='less -F -S -R -M -i'
export MANPAGER='less -R -M -i +Gg'
git config --global core.pager 'less -F -S -R -i'
#alias less='less -F -S -R -M -i'

I eventually ended up with writing a wrapper on my own.

#!/usr/local/bin/bash

# BSD/OSX compatibility
[[ $(type -p gsed) ]] && SED=$(type -p gsed) || SED=$(type -p sed)
CONTEXT=$(expand <&0)
[[ ${#CONTEXT} -eq 0 ]] && exit 0
CONTEXT_NONCOLOR=$( $SED -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" <<< "$CONTEXT")
LINE_COUNT=$( (fold -w $(tput cols) | wc -l) <<< "$CONTEXT_NONCOLOR" )

[[ $LINE_COUNT -ge $(tput lines) ]] && less -+X -+S -R <<< "$CONTEXT" || echo "$CONTEXT"

BSD/OSX users should manually install gnu-sed. The amazing regexp, which helps remove color codes, is from https://stackoverflow.com/a/18000433/2487227

I've saved this script to /usr/local/bin/pager and then git config --global core.pager /usr/local/bin/pager

The treatment for OCD patients, hooray!

8
  • It won't work if your file has wrapped lines. Dec 13, 2016 at 1:35
  • @ThomasDickey I deem that fold should handle that... but, yeah, bugs maybe... could you plz kindly provide an example? Dec 13, 2016 at 1:37
  • @ThomasDickey paste.kde.org/ph9vl7es5 this one worked for me Dec 13, 2016 at 1:41
  • fold doesn't really understand tabs. You might be able to repair it using expand. That still won't handle embedded escape sequences (which often is asked-for in the context of git). Dec 13, 2016 at 1:48
  • 2
    tabs will only "work" when your terminal width happens to be a multiple of the tab-stops. When I tested this, I noticed that fold did not adjust wrapped lines using spaces, but merely found the closest point for chopping. So the appearance will be misleading. Dec 13, 2016 at 9:08
0

I use the following wrapper as my pager. It's not as fancy as the other wrapper shown here (because it always uses less -S to truncate long lines), but it's darn simple. Seems to work pretty well with iTerm2.

#!/bin/bash
set -e

text=$(</dev/stdin)
text_lines=$(echo "${text}" | wc -l)
term_lines=$(tput lines)

if [[ $text_lines -lt $term_lines ]]; then
    echo "${text}"
else
    echo "${text}" | less -S -R
fi
1
  • 1
    You can also toggle back and forth between wrap vs. truncate in the middle of reading a file by typing -S <return> in less. May 28, 2021 at 2:03

You must log in to answer this question.

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