Grokking the Zen of the Vim Wu-Wei

I love text editors.Which is a good thing, because I spend the overwhelming majority of my computing time (and, hence, sadly, most of my conscious life) in one text editor or another.
For years I have been an Emacs user, only relatively recently moving to BBEdit with my adoption/inheritance of a Mac as a personal machine.
Using and often administrating Linux-based systems has necessitated that I use Vi now and then, but I have long held the opinion that the only Vi command one needs to know is: ":q!", perhaps to be followed by "emacs".

This attitude was born out of some unpleasant experiences really early on in my computing history.
I distinctly remember a few occassions when I was trapped in an apparently psychotic terminal session that would not accept my typing despite dozens of increasingly-frenzied keystrokes, and then suddenly and inexplicably it started accepting my typing but refused to let me stop typing and exit. This was my introduction to the Vi editor.
After once or twice resorting to disconnecting and relogging-in as the only way break out of the grip of this insane editor, I learned how to properly quit it: ":q!".
For many years after that, those three keystrokes probably summed up 90-99% of my Vi usage: whenever I inadvertently triggered an editing session with it, I would quit it with alacrity and get on with life.
It was a long while before I stopped getting a flash of a "Arrgh! Not again!" semi-panicky feeling whenever I saw a screen with all those tildes running down the left hand side.
As far as I was concerned, a Vi session was synonymous with an operating system glitch or failure.

All that has recently radically changed …

For a couple of years now, since getting a Mac, I have been using BBEdit as my primary local editor, and my Emacs usage has been limited to systems administration tasks as well as patching, viewing, editing etc. program and data files on remote clusters/hosts.
Many times in a day, I find that I need to quickly open up a file, check or tweak a couple of lines, and retry running something.
I was getting a little irritated with having to wait one to several seconds for Emacs to fire up each time I need to do this.
Also, I was secretly a little ashamed and tired of lugging around my bloated monstrosity (>1.5K SLOC) of a "~/.emacs" configuration file, without which I was practically helpless.

So I decided to give Vim — the golden child of the Vi family — a try.
It took me a couple of hours of forced usage to get used to the modal paradigm and basic navigation.
But I was impressed enough with its speed and responsiveness (loading in micro-seconds as opposed to the several of Emacs) to stick with it.
As I did, I began to appreciate the efficiency, elegance, and, for lack of a better word, sheer poetry of its movement and editing commands.
It seemed that, without my hands leaving the keyboard, just a few strokes here and a few taps there, I was capable of dancing all over the document, and perform everything from extremely precise targetted micro-surgery to massive document-wide renovations.
I felt like I was working with a well-designed artificial intelligence that smartly and smoothly executed my commands on the document, while other (modeless) text editors began more and more to seem like dumb keystroke-sucking-and-storing buckets in contrast.

I was hooked.

But what I want to share in this post is not (just) a confession or declaration of leaving the "Church of Emacs" for the "Editor-of-the-Beast".
Rather I would like to link to another post that I believe is the most succint yet intuitive description of how to think when using Vim that I have yet read.
While I had grasped in a semi-epiphany (if an epiphany can occur over a couple of decades as opposed to an instant) the compelling sublimity that is the Vim way of doing things, I did not truly begin to grok the Vim way till I read this post:

The beginning of understanding the Zen of Vi comes when you realize that you are not memorizing key-bindings, but rather, you are learning a language.

What a beautiful concept! You are not memorizing that "d$" means "delete from here to the end of the line". You are instead learning how to tell Vi that you want to delete ("d") from here to the end of the line ("$"). The operation command, "d", can be seen as a verb, while the target of the operation, the end of the line, "$", can be seen as the object. Carrying out the same operation with different parts of the document is just learning how to refer to different "object" (in the grammatical sense) in Vi-speak: to delete to the beginning of the line means learning how to say "beginning of the line" in Vi ("0") with the same verb ("d0"), while to delete to the end of the sentence means learning how to say "to the end of the sentence" in Vi (")") with the same verb ("d)"). On the other hand, learning how to carry out different operations is just a matter of learning new "verbs" (e.g., "y" for "yank/copy", "g" for "go to"), and applying them to the same "objects" ("end of line", "beginning of line", etc.). Seen like this, coding with Vi becomes like programming a program, or, alternatively, a better analogy that more accurately captures the sense of using Vi would the one I used previously: coding with VI is like communicating with an AI. Either is bound to appeal to any programmer!

I am still digesting all this, learning the language, along with the rest of the Vim knowledge base.
Or, rather: absorbing the Zen of Vim while I (try to) act without doing with it.
I realize that I am at a bottom of a steep learning curve

emacs_learning_curves

… but I am amazed at not only how much I can get done with what little I already do know, but how elegantly I can get it done as well.

So, bottom of the learning curve or not, I am now a Vim-er.
This has geekoriously been made official by my "~/.bashrc" file exporting "EDITOR='vi'" instead of "EDITOR='emacs'", followed by a (relatively sparse) "~/.vimrc" file being committed to my personal environmental repository.

I have also set up my "~/.inputrc" so that readline uses Vi-mode by default:


# Be 8 bit clean.
set meta-flag on
set input-meta on
set output-meta on
set convert-meta off

# mode in everything that uses readline
set editing-mode vi
set keymap vi

As well as modifying my "~/.pythonstartup" file so that my Python shell does the same:

#! /usr/bin/env python

try:
    import readline, rlcompleter, os, atexit
    def savehist():
        try:
            import os, readline
            histfile_path = os.path.join(os.environ['HOME'], '.pythonhistory')
            readline.write_history_file(histfile_path)
            del os, readline, histfile_path
        except:
            pass
    readline.parse_and_bind('tab: tab-insert')
    readline.parse_and_bind('"\eOP": complete') # 
    readline.parse_and_bind("set editing-mode vi")
    readline.parse_and_bind("set show-all-if-ambiguous on")
    readline.parse_and_bind("set meta-flag on")
    readline.parse_and_bind("set input-meta on")
    readline.parse_and_bind("set output-meta on")
    readline.parse_and_bind("set convert-meta off")
    readline.parse_and_bind('"\C-a": beginning-of-line')
    readline.parse_and_bind('"\C-e": end-of-line')
    histfile_path = os.path.join(os.environ['HOME'], '.pythonhistory')
    atexit.register(savehist)
    readline.read_history_file(histfile_path)
    del os, histfile_path, readline, rlcompleter, atexit
except IOError:
    pass
except ImportError:
    pass

Interesting side note: dozens if not hundreds of Emacs key chords that I thought were buried in muscle memory vanished without a trace within a week of using BBEdit. For future cognitive science/interface design researchers out there: the only ones that remained were “Ctrl-A” and “Ctrl-E“.
Which is why I have mapped in those Emacs keys into the Vi-mode Python shell above, as well as in my "~/.bashrc".

So what does Vi-mode readline get you in the Python and Bash shells, apart from the obvious? Here is what clinched the deal for me: in normal mode (Esc), hit "v", and a Vim session opens up with the current line for editing. Saving and exiting results in the buffer being executed, while ":cq" results in the command being canceled. How awesome is that?

2 thoughts on “Grokking the Zen of the Vim Wu-Wei

  1. Hi Jeet.

    Thanks for your interesting article which I found while googling for “zen of vim”. Editing with vim, I’m pleased again and again about the elgance and efficiency of “the vim language”.

    But where vim is great in editing and navigation capabilities, emacs is great for its versatility. (“Emacs is a great operating system, if only it had a good text editor.” ;-) So why not combine the best of both of them by running emacs by an appropriate vim mode extension, perhaps like extensible vi layer for Emacs. This vim extension comes prebuilt in emacs24, so you probably already now of it. Nevertheless I think, a look at Emacs as My Leader – Vim Survival Guide, where this concept is discussed, is worth the effort.

    Personally, I’m not familiar enough yet with the vim language to apply it to emacs as I don’t have sufficient experience with emacs too, but I thought the blog mentioned above could be interesting for you too, as you obviously are working with text editors a lot. So, I wish you happy hacking with which editor and mode ever…
    Best regards, Andi
    (You would be sorry about my “English”, as I’m a Swiss Citizen ;-)

    1. I *have* been considering going (back) to Emacs with Evil … I like the power of the ecosystem, and yes, it is a *great* ecosystem except for the text editor! :). But I have collected a lot of plugins and tweaks for Vim over time (many of them my own), so it will be a while before I find equivalents I like.

Leave a Reply

Your email address will not be published. Required fields are marked *