PLEASE SEE THE UPDATED VERSION: 2020-10-22
I use less
heavily. It's what's known as a "pager," a program that lets you look at the contents of a file and page through it. For a long time I've wished that less
would syntax-highlight the files I was looking at, but I haven't done anything about it because I assumed it wasn't possible (I was wrong). Today I started thinking about how nice it would be if my SVN logs (yeah, yeah, move to git
... I hear you, we're working on it) were colourized. That's the subject of a different blog entry, but it led me to this discovery as well. And, I'm happy to say, this is surprisingly easy to set up.
First you need to understand that less
is a classic Unix tool: "do one thing and do it well." It displays text, and it lets you search text, not much else (but within that purview it's pretty much the best there is). And "display text" includes an edge case: it can display colour codes. So if you were to use another program to parse your file and insert colour codes, then less
would show it colourized. And that program is pygmentize
(there are probably other options, but this seems to be the leading choice these days). Pygments is another Unix tool: it colourizes files. Really, that's what it does, that's all it does.
(I should also point out that Pygments is the group of programs that my blog software uses to colourize code samples in this blog.)
Installation
less
is installed on every Linux system in the known universe. pygmentize
is far less common, but it's well known enough to be available through most package managers. Search for the term "pygment" and you'll almost certainly find it. On Fedora: dnf install python3-pygments
. On Mac, brew install pygments
. If your package manager doesn't have it available, there's another package manager that probably does: pip3 install Pygments
(I prefer to use OS-level packages, if you're a heavy Python user you may prefer this method).
Set Up
First, make sure the $LESS
environment variable includes "R". I recommend you put a line in one of your shell start-up files ( ~/.bashrc
, ~/.profile
, /etc/bashrc
, ~/.zshrc
, like that) that says export LESS=MR
but the "M" isn't necessary for this. Check by typing echo $LESS
.
There are two ways to set this up (I'm sure there are more, but let's go with two). First, test whether or not you have a filter for less
in place by running echo $LESSOPEN
. On Fedora, the response is ||/usr/bin/lesspipe.sh %s - that's a system default, I didn't set it up. The main point being that something is already handling the (pre-)parsing of less
files. On Mac, I got an empty response. Either of the following methods will work with either OS, but I have the preferences expressed below based on the existing set-up.
Of these two, the Mac is slightly simpler to set up: in one of your shell start-up files, you need to add the line export LESSOPEN='|pygmentize -g %s'
. The -g
parameter to pygmentize
means essentially "guess the filetype." And honestly, it's damn good at guessing so I prefer this method to what I've set up on Fedora ... but the other method has advantages too.
If you find that the $LESSOPEN
environment variable is set, then less
will probably use a file called ~/.lessfilter
to determine how you want to treat files before they're passed to less
. Let's create that file (make it executable as well!):
case "$1" in
*.hpml)
pygmentize -l html "$1";;
*)
pygmentize -g "$1";;
esac
exit 0
The point of that weird file extension is that this is where you can filter and change pygmentize
's behaviour based on file extension. Some years ago I decided that "HPML" was a good renaming of "HTML" with the "P" standing for "Partial:" several of these files would be assembled into one HTML file. Since that filetype is an invention of mine, I tell pygmentize
to treat it as HTML. And then I tell pygmentize
to make a guess on everything else.
On Fedora, installing this file was all that was needed to get less
doing syntax highlighting on pretty much every kind of file there is. If this doesn't immediately work for you, you may need to reset the $LESSOPEN
environment variable as mentioned above.
Testing
I don't think you'll need this, but if for some reason you want to see pygmentize
in action without your less
setup working, use something like pygmentize -g ~/.bashrc
as a test (you can of course pipe it to less -R
). Use man pygmentize
(no man page on Mac, you'll have to settle for the shorter pygmentize -h
) to get a handle on the options and try them out.
Bibliography
This is almost entirely based on https://superuser.com/questions/117841/when-reading-a-file-with-less-or-more-how-can-i-get-the-content-in-colors . After spending a couple hours tinkering, I concluded that the ~/.lessfilter
file in the main answer is too complex to no good end ... and may be unnecessary. If you have the patience to do so, I would recommend reading that whole page as well so you can come to your own conclusion.