Thursday, December 27, 2007

Emacs TIp #6: advice

This is an advanced tip, but it has simple applications.

Don't you wish you could change some of the built-in routines? You
like the way they work, but would tweak it just a little bit.

For example, 'ispell' does a great service: it provides suggestions
for the correct spelling of a misspelled word. Wonderful, I use it
all the time. However, it often has the order of choices exactly
opposite of what I'd expect.

e.g. `waht' - the correct option 'what' is #7!

`sopporting' - the correction option 'supporting' is #2!

It's much easier if the choice I usually pick is the first one.
So, it'd be great if I could just tell 'ispell' to reverse the order
of the choices provided.

You can!

Advice is a mechanism that lets you get code to run before, after, or
"around" existing elisp routines. You can modify the arguments going
in, you can modify the result, you can call the existing routing
multiple times. And this advice can be nested too.

Why use advice as opposed to re-writing the routine?

Because (especially in this example) - you don't want to muck with
having your own copy of the code. It's messy, and you might miss
upgrades to that routine with new versions of Emacs.

So, with this case in hand, I spent a minute tracking down the routine
that could be advised. I spent a minute writing the advice:

(defadvice ispell-command-loop (before ispell-reverse-miss-list activate)
"reverse the first argument to ispell-command-loop"
(ad-set-arg 0 (reverse (ad-get-arg 0))))


And now my spelling choices are in the right order! yay.

For more information on advice:
C-h i m advice RET

3 comments:

hober said...

FYI, I've added you to Planet Emacsen.

fimblo said...

Thanks for this... advice :) Good tip. Could you expand on this a bit more? Reading the manual is a little difficult at times, say another one or two concrete examples?

a said...

I used advice just today to answer a question on stackoverflow.com, check out the example here:

diff-save-or-kill-when-killing-buffers-in-emacs

It was needed to customize the desired behavior when killing a buffer.

Another example is to advise the 'yank routine such that when you're yanking in a programming language, the yanked text is automatically indented.