Strange Strands

23 May 2006

Toucan Play at That Game

In the search for a better editing environment I've written toucan.el, which contains toucan-mode, an emacs Minor Mode that emulates certain vi features.

Now, why on earth would someone implement bits of vi in emacs? I'm not the first to believe that emacs and vi are "complementary, rather than antogonistic", and I suppose it's on that note that emacs already contains several vi emulation packages. There's vi-mode, vip-mode, and viper-mode at least, but they each suffer from some interesting mindset problems. For example, viper-mode compartmentalises separate spaces for emacs and vi-emulation instead of integrating the two properly. So you end up with Normal Mode, Visual Mode, Insert Mode, and Emacs Mode! It seems very strange to me to what to have more modes when, as Alan Kay notes, "modes are evil". You should try to get away with the minimum that you need; though the rationale for viper-mode is to give vi users a gradual introduction into the wonders of emacs, or perhaps emacs users a way out into vi.

Anyway, that's not what I want. I want the best of both worlds without necessarily being bound by the eccentricities of either. In deciding whether to use vi or emacs as my regular editor to start with, it was clear that moded editing was not conducive to my working swiftly, but I noticed that practiced vi users could be very effective indeed if they learned all of the shortcuts. With emacs on the other hand there is a greater flexibility, and a lower entry barrier. But the three greatest features in emacs for me are a) nxml-mode, which is indispensible if you write as much HTML as anally as I do, b) configurability of the mode line, and c) the ability to extend in emacs lisp.

When I was learning vi, I found that I wanted to script various things into it, including a command for grepping out lines in a file that could then be selected to take you back to the corresponding line in the original file (based on a feature that I had implemented in emano). It was possible in vim, but quite hard to do. On the other hand, when learning emacs I found that it was already implemented: occur-mode.

My .emacs file is replete with customisations, but one general principle that I hold to is to try to make sure that customisations stay as close as possible to the defaults. For example, where C-x C-b was bound to list-buffers I rebound it to the far superior buffer-menu, but the functionality is basically the same. This makes it easier on me should I be in an environment where emacs customisation isn't possible: either because I can't download my .emacs or because the emacs version is lower than required for various features I need in my setup.

So what is the minimally invasive way to add vi features to emacs? There are two problems with using the normal Esc: 1) it sends Meta in emacs, harking back to terminals that were unable to send Meta properly I think, 2) Esc to change modes is possibly the worst choice of key ever given its keyboard placement. It makes me wonder why "hjkl" were chosen as movement keys for homerow speed when you're always having to go up to Esc. This problem is even covered in vim tips, as tip #285 "Don't use the escape key!". One of the solutions in there is to use C-[ since that's the control sequence for Esc, but that doesn't help in emacs since the problem is that we can't use Esc in any form. There's also C-c in vim, but that's just going from bad to worse.

In any case, I figured that an optimal solution wouldn't even involve a modifier key. I got some inspiration from MatchParenthesis on the emacs wiki, which explains how to use "%" to switch between parens contextually: so that "%" only does that when it's over a parenthesis. Eventually I settled on the idea that since I don't use \ usually for anything except entering \t, \r, and \n in programs, I could use that as the mode switcher—and so I am. I have the "t", "r", and "n" commands set to enter "\t", "\r", and "\n". I currently also have "\" set up to input "\" so that I can double type "\" to insert a reverse solidus, but I'm thinking of changing that because I like to use reverse solidus to quit the mode too instead of "i", being vi's usual insert command.

That would be a departure from the vi norm, but I'm not as unhappy about moving away from vi norms as I have moving away from emacs norms. For example, I've already bound "p" to "move the section between the last two marks on the stack to point" instead of the usual paste, and I'm using "c" for change word instead of "cw". That's the beauty of it: I can huffman encode it to my own needs.

I'm still finding the switching of modes kinda difficult, the usual vi barrier, but the nice thing is that I always have emacs available and only need to switch into Toucan Mode when I remember there's something nifty in there that I can use. And even when I'm in Toucan Mode, it's minimally invasive so keybindings such as C-x C-s still work (to save). For now I've made it so that the mode line contains "TOUCAN!" when I'm in Toucan Mode so that I don't go pressing a series of wacky commands; and even if I do I can just press "u" to get rid of them, which is certainly nicer than Ctrl+Shift+- (i.e. C-_) that one has to use in emacs normally.

Strange Strands, Toucan Play at That Game, by Sean B. Palmer
Archival URI: http://inamidst.com/strands/toucan

Feedback?

Your email address:
inamidst.com