How to chain multiple LESSOPEN scripts

lesssyntax highlighting

Linux distributions nowadays have a default LESSOPEN set to /usr/bin/lesspipe which allows one to easily inspect e.g. zipped files or PDF files.

Now I wanted to see whether I can add syntax highlighting to less. This is easily accomplished with source-highlight. I used LESSOPEN="| /usr/bin/source-highlight -i %s -q -f esc" and it works fine.

But now the problem becomes: How do I get the behavior of both lesspipe and source-highlight? Simply appending one after the other doesn't work:

$ export LESSOPEN="| /usr/bin/lesspipe %s | /usr/bin/source-highlight -i %s -q -f esc"
$ less foo
Invalid LESSOPEN variable

It also doesn't make sense so this is not really surprising.

Is it possible to set this up without writing elaborate scripts? The best case would be to have chaining, i.e., provide syntax highlight for a zipped file as well.

Best Answer

The command in the LESSOPEN variable after the initial pipe is executed by the shell indicated by the SHELL environment variable and must produce the desired content on its standard output.

You can pass the output of lesspipe as input to another command that reads from standard input and writes to standard output. However, in order for source-highlight to read from its standard input, it needs to be told what language to highlight for, so source-highlight doesn't work this way.

When lesspipe doesn't recognized a file format, it prints nothing, which less interprets as an indication to read the original file. If you have ifne from Joey Hess's moreutils, you can use it to detect this case and try source-highlight instead. You'll need to save the original file name in a variable so that you can use it twice.

LESSOPEN='|file=%s; /usr/bin/lesspipe "$file" | /usr/bin/ifne -n /usr/bin/source-highlight -i "$file" -o STDOUT 2>/dev/null'

Note that you'll need to include -r or -R in $LESS or type -r or -R after starting less in order for less to render the colors.