Friday, March 25, 2011

Filters in Emacs

In the early 80's, i wrote a filter in C called 'onespc' (V7 Unix had 14 char filenames, i tended to omit vowels). 'onespc' by default would read stdin, compress groups of blank lines (with optional white space) to a single blank line, and write to stdout. I'd use it from the command line, sometimes in scripts that changed many files. I'd use it from Emacs on the whole buffer or regions. 'onespc' has a bunch of options to do similar things, like remove all blank lines.

Emacs was sluggish starting up until the 386/33 or 486/25. This may be ancient history, but it was more than a decade for me. I haven't come up with a good way to use Emacs to edit hundreds of files. My current plan is to learn elisp. That should fix everything. Lisp isn't easy to learn. But i've used Lisp and Sheme in the past.

In the late 80's, i wanted something easier in scripts than

for i in *.txt; do
 onespc $i > x
 mv x $i
done


It's not a good solution, since x might exist as a file. So, i wrote a version of 'into'. The syntax is

for i in *.txt; do
 onespc $i | into $i
done

So, 'into' copies stdin to a temp named file, which it determines does not exist in advance. On EOF, it renames it to the argument, deleting the existing file if it can.

I was about to publish all these utilities, but then someone publish the 'getopt' functions for command line. I liked my least ambigous command line parser better. I never liked the '--' standard. I stalled.

Who knows? Maybe Emacs has a simple file mapper. I'd like to be able to do this easily:

for i in `find . $HOME/some/other/place -type f -name \*.txt`; do
 onespc $i | into $i
done

But 'find' and my filter set (including all of the *ix filters, including 'sed' and 'perl') is a pretty powerful set of flexibility to allow.

Despite emacs's internal docs, 'info', 'man', and google, i can't always find docs for what i want to do just at this moment. One learns by putting in effort. One can always learn more.

No comments: