My ambivalent view on Vim superintelligence, contrasted with GNU Emacs

August 15, 2016

I have historically had an extremely ambivalent attitude on vim as a superintelligent editor; my standard remark is that if I want such an editor, that's what I have GNU Emacs for. Part of this is just that I often want vim to not get in the way, and part of this is that I'm used to vi being vi. But a good part of this comes down to what I see as a fundamental philosophical difference between the editors.

To put it simply, vi has a powerful conceptual model at its heart, while GNU Emacs already starts out being basically a big random ball of stuff. Sure, GNU Emacs has a certain amount of concepts, but at its core it's a mechanism for wiring keystrokes to Lisp functions. It's nice when the collection of keystrokes have some conceptual unity behind them (it makes them easier to remember), but there is no fundamental model of 'how GNU Emacs edits text' that makes that necessary in the way that it does for vi. You can have commands in vi(m) that really feel like they are breaking the rules; in GNU Emacs, the rules are just conventions and may be freely violated without pain.

(However much I love it, magit clearly breaks the 'rules' of GNU Emacs in a flagrant way by binding ordinary alphabetical characters to all sorts of special actions in its status buffer. In GNU Emacs, of course, this is perfectly fine and has a long history.)

The consequence of this is that because GNU Emacs is fundamentally relatively arbitrary, it's much easier to make it do random superintelligent things without damaging what conceptual integrity it has. And you have a clear hook in the core of the editor for doing those superintelligent things, because 'running Lisp code in response to keystrokes' is what GNU Emacs is all about.

The other advantage that GNU Emacs has is that, to put it one way, it's Lisp all the way down (even if some of the Lisp is in C). At a conceptual level and often at a practical level, GNU Emacs is written in the same language as your superintelligent extensions to it, and your extensions do the same kind of things as everything except the very lowest level code (often through exactly the same interfaces). There is no privileged (language) core to GNU Emacs.

Neither of these are true for Vim. Instead, vim has a hard core of both a conceptual model and an implementation environment, and then it has a plugin model that is attached on the side instead of being a fundamental component. In Emacs, auto-indentation is conceptually simple; you rebind newline to run your Lisp code that analyzes the state of the text buffer and then inserts the right number of spaces (and maybe tabs) as well as that newline. The only difference from plain newline processing is that you're running a lot more Lisp code and you're not inserting just a single character. In vim, well, you need an entirely new conceptual model of hooking into keystrokes, and then what happens is a completely different path from if you didn't have smart auto-indentation active. And this change raises other relatively deep questions; for example, you can normally repeat insertions with .. What happens if you . an insertion with a newline in an environment with auto-indent? Does it insert the actual end result text, or does it basically re-run the user's typing and thus re-trigger auto-indentation in the new context?

You can answer these questions (and you have to), and presumably vim has. But that these questions get raised when you start adding various forms of superintelligence to vim is why I feel ambivalent about the whole endeavour. On the one hand, I see the appeal and the necessity. On the other hand, it feels messy in a way that base vi(m) doesn't.

(I sort of touched on this in Where vi runs into its limits, but the whole issue is on my mind again for reasons beyond the scope of this entry.)

(I optimistically think it might be possible to create a vi-like 'composable operations' editor with a strong conceptual model that gracefully allowed for extensions, auto-indentation intelligence, and so on. But I have no idea what the result would look like, and it might not look entirely like vi. Perhaps it shouldn't permit arbitrary extensions to its functionality and instead have a clear model for, say, parsing buffer contents and expressing auto-indentation rules based on the parse state.)

Comments on this page:

For what it's worth I think some of the best plugins (usually written by Tim Pope, like Fugitive or Surround, try to keep the model the same while still being super intelligent. It makes them compose well with the hard core and not impossible to remember how to use.

Written on 15 August 2016.
« Some options for reindenting (some of) my existing Python code
How you tell what signals a Linux process is ignoring »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Aug 15 22:42:50 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.