Skip to content

Blog Zero

14 Mar 2022

Paging

Note: there is a public repository containing the source code and formal documentation for the programs that this post is about.

I used the venerable less as my pager for a long time, but I wanted something more Emacs-like. And what could be more Emacs-like than Emacs? Fortunately I found Kaushal Modi's excellent eless shell script, which runs an instance of Emacs that's been adapted to make it work like a pager.

But that was almost 5 years ago, and while much of the core functionality from eless remains in my version — which I've not very imaginatively named empager — I've made a lot of changes to it, both to add functionality and so that it works as much as possible like Emacs does when I use it as an editor. It doesn't work exactly the same because I want it to function in as many environments and situations as possible (such as on newly-installed systems), so empager

The added functionality includes:

If you end up trying out empager you may notice that there are some "idiosyncratic" keybindings. They almost always correspond to custom keybindings that I use in my main Emacs editor, and may not be to everyone's tastes. In which case you can edit your copy of the script to create a custom Emacs-based pager of your very own.

But Wait: There's More!

I use empager all the time, so I've given it the much shorter one-letter name p. I could have defined p as an alias, but sometimes I find that I want to pass it as an argument to a command like xargs. For example, this

find . -name '*.txt' | xargs p

(or just sde txt -- p using searchdown) will fail if p is an alias. I could have also created a symbolic link to empager named p, but the tiny p script included in the repository is a little more flexible, in that it runs whichever pager program is specified by the PAGER environment variable.

And speaking of environment variables, empager also takes options from the EMPAGER environment variable just like less takes them from the LESS environment variable. (I set it to -FR.) You can also have the man command use empager as its man page viewer/pager by setting and exporting the MANPAGER environment variable to empager like so:

MANPAGER=empager
export MANPAGER

However, in a few circumstances empager will display some unsightly raw escape codes. The only place that this happens consistently for me is in the help displayed when using the help() function in an interactive Python shell, so I start interactive Python 2 and 3 sessions using the following aliases:

alias py2='PAGER=bempager python2'
alias py3='MANPAGER=bempager python3'

where bempager is included in the repository and is a simple wrapper script that removes any and all backspaces before passing data along to empager. (Apparently Python 2 uses the PAGER environment variable while Python 3 uses the MANPAGER environment variable.) I also define the alias

alias lman='MANPAGER=less man'

so that if I do encounter a man page that doesn't play well with empager (or bempager) then I can quickly switch to using less for that page.

One final pager-related tweak that I'll share here is a readline macro that I've added to my ~/.inputrc file:

"\C-p": " 2>&1 | p"

This allows me to very quickly redirect a command's regular and error output to an instance of my default pager program by just typing C-p (a.k.a. Ctrl+p) at the end of the command. (Emacs users that use C-p "properly" will of course want to choose a different keybinding.) For example, if I've typed the command

curl wttr.in/:help

and then I type C-p the command becomes

curl wttr.in/:help 2>&1 | p

and the site's help information is displayed in my default pager instead of potentially scrolling off the screen. (Remember that you need to type C-x C-r in the terminal to have any changes you've made to your ~/.inputrc file take effect there.)

If you'd like to support this site then check out my web app InEveryNook.com and see if it's of interest to you, pass it along to anyone you think might be interested in it, or both. Thanks!

Tags: emacs shell software