Adding more to less
Posted by ushimitsudoki on January 8, 2009
Ubuntu uses a script to pre-process certain file types before passing them to less. By default, this already handles quite a few types of files, but you might like to tweak it to get some fancier results.
/usr/bin/lesspipe
This is the “main” file the system uses to pre-process files. Take a look and see if it doesn’t make sense.
~/.lessfilter
This is the file we will create and edit to add whatever pre-processing we desire!
Example 1: Source highlighting
Say you want to view some Python source code. Here is the normal output:
That’s not bad or anything, but how about this instead:
To get a result like this, we need to do two things:
1. Set up ~/.lessfilter:
#!/bin/sh case "$1" in *.py) pygmentize "$1" ;; *) # We don't handle this format. exit 1 esac exit 0
This is a very simple “skeleton” – make sure you make it executeable (chmod +x ~/.lessfilter). Check the man page of lesspipe for more details. You probably already have pygmentize installed.
2. Set up the LESS options
You might want to try the new less *.py now, but you will probably see a bunch of funky escape codes. We need to set up an environment that handles the escape codes correctly.
It’s easy. In ~/.bashrc, just add:
# Fix up less for syntax coloring export LESS="--RAW-CONTROL-CHARS"
And boo-ya! There it is! (Check the man page for less more details.)
Don’t forget if you make environmental variable changes like this, you’ll have to open a fresh terminal to see the effect.
Optional stuff
If you want a little more flexibility you could install source-highlight, which I prefer. I think it is more flexible and better documented:
1. sudo apt-get install source-highlight
2. ~/.lessfilter
#!/bin/sh case "$1" in *.py) if [ -x "`which source-highlight`" ]; then source-highlight -n -f esc -i "$1" else pygmentize "$1"; fi ;; *) # We don't handle this format. exit 1 esac exit 0
In this example, note that we check for the existence of source-highlight, and use it if present. Else, we fall back to the pygmentize method – you can use this idea of checking for a program’s existence if you want to have a more robust script.
And, here is the output – not so great in my color scheme, but you can change that up from source-highlight config files (see info source-highlight):
All other source code types
Now that we’ve got our source coloring set-up, it’s simple to add all sorts of extensions. What’s great is that both pygmentize and source-highlight will handle the extensions appropriately, so we don’t have to do much. Here’s an example, then, that covers a whole lot of source types. We will also just be using source-highlight, but you should be able to figure out how to use pygmentize or some other program easily enough by now:
#!/bin/sh case "$1" in *.C|*.H|*.ac|*.am|*.autoconf|*.bib|*.bison|*.c|*.caml|*.cc|*.changelog|\ *.cls|*.cpp|*.cs|*.csh|*.csharp|*.css|*.desktop|*.diff|*.docbook|*.dtx|\ *.eps|*.fixed-fortran|*.flex|*.fortran|*.free-fortran|*.glsl|*.h|*.haxe|\ *.hh|*.hpp|*.htm|*.html|*.hx|*.in|*.ini|*.java|*.javascript|*.js|*.kcfg|\ *.kdevelop|*.kidl|*.ksh|*.l|*.lang|*.langdef|*.latex|*.ldap|*.ldif|*.lex|\ *.lgt|*.ll|*.log|*.logtalk|*.lsm|*.lua|*.m4|*.makefile|*.ml|*.mli|*.moc|\ *.outlang|*.pas|*.pascal|*.patch|*.perl|*.php|*.php3|*.php4|*.php5|*.pl|\ *.pm|*.postscript|*.prolog|*.properties|*.ps|*.py|*.python|*.rb|*.rc|\ *.ruby|*.sh|*.shell|*.sig|*.sl|*.slang|*.slsh|*.sml|*.spec|*.sql|*.sty|\ *.style|*.syslog|*.tcl|*.tcsh|*.tex|*.tk|*.txt|*.ui|*.xhtml|*.xml|*.y|\ *.yacc|*.yy) if [ -x "`which source-highlight`" ];then source-highlight -n -f esc -i "$1" else cat "$1"; fi;; *) #We don't handle this format. exit 1 esac exit 0
You can get the list of languages that source-highlight supports through:
jason@apollo:~/Projects/euler$ source-highlight --lang-list
If you don’t like line numbers in the output, remove the “-n” switch. As always, check the man pages for more details.
Example 2: Adding non-text file types
Another cool thing we can do is pre-process non-text file types and get some kind of output. If you check /usr/bin/lesspipe, you’ll see handlers for things like *.deb and *.doc and so on.
Let’s add a handler or two of our own! It seems strange to have a *.doc handler, and not a *.odt, so lets try that.
Here is the intial result:
jason@apollo:~$ less test.odt "test.odt" may be a binary file. See it anyway? jason@apollo:~$
You probably don’t want to “see it anyway”, because it will be all garbledy-goo. What we want is this:
This is a very similar procedure to what we have already seen: install an appropriate command — in this case odt2txt — and then set up ~/.lessfilter to call it.
1. sudo apt-get install odt2txt
2. ~/.lessfilter now looks like this:
#!/bin/sh case "$1" in *.C|*.H|*.ac|*.am|*.autoconf|*.bib|*.bison|*.c|*.caml|*.cc|*.changelog|\ *.cls|*.cpp|*.cs|*.csh|*.csharp|*.css|*.desktop|*.diff|*.docbook|*.dtx|\ *.eps|*.fixed-fortran|*.flex|*.fortran|*.free-fortran|*.glsl|*.h|*.haxe|\ *.hh|*.hpp|*.htm|*.html|*.hx|*.in|*.ini|*.java|*.javascript|*.js|*.kcfg|\ *.kdevelop|*.kidl|*.ksh|*.l|*.lang|*.langdef|*.latex|*.ldap|*.ldif|*.lex|\ *.lgt|*.ll|*.log|*.logtalk|*.lsm|*.lua|*.m4|*.makefile|*.ml|*.mli|*.moc|\ *.outlang|*.pas|*.pascal|*.patch|*.perl|*.php|*.php3|*.php4|*.php5|*.pl|\ *.pm|*.postscript|*.prolog|*.properties|*.ps|*.py|*.python|*.rb|*.rc|\ *.ruby|*.sh|*.shell|*.sig|*.sl|*.slang|*.slsh|*.sml|*.spec|*.sql|*.sty|\ *.style|*.syslog|*.tcl|*.tcsh|*.tex|*.tk|*.txt|*.ui|*.xhtml|*.xml|*.y|\ *.yacc|*.yy) if [ -x "`which source-highlight`" ];then source-highlight -n -f esc -i "$1" else cat "$1"; fi;; *.odt) if [ -x "`which odt2txt`" ]; then odt2txt "$1" else exit 1; fi;; *) #We don't handle this format. exit 1 esac exit 0
One thing to note in this example, if that if the specific handler we are looking for is not found, we in effect “pass control” back to the system handler (by using “exit 1″).
Summary
And there you have it. I’d like to give credit to this Ubuntu brainstorm idea, which encouraged this post, and to this blog entry and the comments from which I also drew ideas.





Christopher Olah said
I posted my comment at Brainstorm before I realized I could here. Here it is:
Thanks a lot! It looks great!
Now I didn’t test it, but I did notice some things.
1) Makefiles are just called `Makefile’ and not `*.makefile’ (or at least, I’ve never seen them that way). This actually creates a minor problem: source-highlight won’t identify them (at least not the version I’m using)… Since I don’t really use them, I hadn’t got around to fixing this in the one I posted.
2) Consider testing if pygemtize is installed.
3) Consider suggesting a list of programs that you could use with this?
Thanks again!
I also posted a short tutorial on Ubuntuforums (in case you weren’t going to), but it hasn’t shown up yet…
ushimitsudoki said
Christopher,
I agree with your point on makefiles – but that *.makefile is pulled straight from the source-highlight dump, so I included anyway. Files with no extensions is one area where pygmentize does a better job than source-highlight. I might re-do my actual file with pygmentize once I have a better chance to read its documentation.
Christopher Olah said
How about something like this?
Makefile)
if [ -x "`which source-highlight`" ];then source-highlight -n -f esc -s makefile -i "$1"
else cat "$1"; fi;;
Additionally, what do you think of the idea of using framebuffers where possible? Fore example, one might use fbi.
christopherolah said
Your blog has inspired me to set up one of my own. But how do I do the nice syntax-highlighted code?
Christopher Olah said
It occurs to me that I should’ve left a link.
Modernizing the Command Line « Christopherolah’s Blog said
[...] One interesting thing to do is use lesspipe. There is a detailed entry about this on another blog. [...]
Adding more to less | Madbuda said
[...] Adding more to less Ubuntu uses a script to pre-process certain file types before passing them to less. By default, this already handles quite a few types of files, but you might like to tweak it to get some fancier results.via Adding more to less « Me and U(buntu). [...]