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 "
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: "
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 ...
... 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 "
Which is why I have mapped in those Emacs keys into the Vi-mode Python shell above, as well as in my "
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?