UPDATED: Added how to use colour themes / "styles" (more important than it sounds). This was first posted 2020-06-25.
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.)
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).
First, make sure the
$LESS environment variable includes "R". I recommend you put a line in one of your shell start-up files (
~/.zshrc, like that) that says
export LESS=MR but the "M" isn't necessary for this. Check by typing
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!):
export PYGMENTIZE_STYLE='monokai' case "$1" in *.hpml) pygmentize -O style=$PYGMENTIZE_STYLE -l html "$1";; *) pygmentize -O style=$PYGMENTIZE_STYLE -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.
I loved this whole idea (syntax highlighting in my pager!) but was finding that under a lot of circumstances the default colour theme was showing me a lot of dark blue text on my black terminal background. That wasn't going well for me. I finally figured out how to change what
pygmentize calls its "style." It is, like so many Linuxy things, simple - once you know how. At the command line, run
pygmentize -L styles to see a list of available styles. "monokai" and "solarized-light" work best for me, but you should experiment to find out what works best for you.
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.
This is mostly 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.