Over the last couple of weeks, I’ve found myself working much more in vim and emacs. I’m not quite sure what started it off, but I think I wanted to figure out, for myself, how efficient I would be using only lexical completion (in vim; vim doesn’t have intelligent omnicomplete for C#, that I know of) vs. using Visual Studio’s intellisense for C#.
A quick aside on this – my old manager, Doug, has a very interesting (and I think correct) view on intellisense (any interspersed comments about vim come from me – he is purely a SlickEdit guy and wouldn’t be caught dead with vim or emacs):
95% of the time, what you really need is just simple lexical completion. If I type in “int fooBarBazYahoo” at the beginning of my function, and then two lines down type “f”, I should be able to easily complete it to the whole variable. Most of the times you use intellisense (in VS) you are either completing local/class variable names (for which I find lexical completion much faster, especially when the order of completions is relative to the “closeness” of a possible completion) or method names, for which you are (likely) writing it more than once in the same file. In vim, tags files and completing from header files (available for C++/C) keeps you typing the minimum amount possible.
The other 5% of the time, what you are really trying to do is search for a specific method, and intellisense isn’t very good at that. Searching for a method is basically searching over a tree that can be very deep (many namespaces + interface/class) and very wide (many class/methods in a given namespace/class), and having to effectively do a depth first search can be a real pain.
Ok, back to the rest of this.
Notes about vim
Like I already mentioned, after using vim fairly regularly for about 2 days (I’ve always used it at least “lightly”, for opening up and searching through lots of source files quickly and doing small edits), I find myself much, much faster at writing code. It may just be that it feels much faster, but that’s still a win for me. In a sense, I feel like vim never gets in my way. My brain very quickly gets back into the habit of typing keystrokes, so I don’t even have to think about the keys I’m hitting. In fact, sometimes I stop after typing some series of commands and find it difficult to remember just which key I hit to do that command in the middle. My fingers and brain have just memorized that some high level concept = some combination of muscle twitches. It really is quite enjoyable.
Other than that, I don’t have many new thoughts about vim. I’m going to say some nice things about emacs in the next section, but I just want to reiterate that I have two rather strong beliefs about vim:
- Moded editors will always require fewer keystrokes to complete any non-trivial task than modeless editors. Some people just don’t like moded editors, which is well and good, but I find that the initial difficulty in getting used to an editor like vim pays itself off immensely when you become good at it. And it really doesn’t take that long, either – it took me about 2 weeks of solid use of vim before I felt really comfortable; during those 2 weeks, I wasn’t significantly less productive than using, say, emacs. Also, for most basic editing tasks (e.g. things short of complicated word processing), vim users will always be more efficient than emacs users.
- The manner in which vim has structured commands is genius. It may seem difficult, complicated, and possibly idiotic at first (“what do you mean I have to type ggVG to select the whole buffer?!”), but once it “clicks”, it is immensely powerful.
If you are an emacs user and #1 made you angry or sad, keep reading below.
Emacs time!
Now it is time for the emacs-ing.
First off, I’m typing in emacs right now. That’s right – I’m writing a blog post using a silly text editor (that’s relatively close to something one of my coworkers said to me earlier in the week about
something slightly different).
One of the things that emacs offers that vim only wishes it had the capability to do (cleanly) is the incredible extensibility of the platform. Some of the common emacs jokes (from vim users) goes something like:
“Have you seen the vim coffee mug? If they had an emacs version, it would be a dinner set” – Linus, the RIT CS admin
“Emacs is a great operating system; too bad it doesn’t have a decent editor” – I’ve seen this various places
And I do agree with the general sentiment – emacs, purely as a text editor, feels miles less effective than vim. What it lacks as a text editor, however, it makes up in powerful extensibility (and thus a rather thriving community of emacs lisp coders) and a much broader set of features.
Muse
Right now, I’m writing in something called Muse, which is an emacs mode for publishing rich text to various formats.
The benefits for using this to write a blog article seem pretty clear to me – even though I’m not as efficient using Emacs, I’m miles more efficient than in a notepad-equivalent editor. Plus, I get the one feature I’ve been aiming for for years – free syntax highlighting!
Muse let’s you define code blocks in any language that emacs supports, and it uses those language modes to color the text. It then transforms your posts (including the highlighted source code) into many formats, among them html, LaTeX, docbook, and pdf. I’m going to use it for html only, but I adore the idea of writing something in a single, canonical format (extra points if it is basically plain text and I can read/write it in any editor) and publishing it to many others.
So, here’s a quick sample. A week back, I read a post on a guy’s blog where he was trying to solve the following: Write a function that takes 3 parameters and returns the sum of the squares of the two largest parameters.
I expanded this a bit (takes any number of parameters), and came up with two solutions – one that uses loop and one that does not. For the non-lisp folk, loop is kinda like list/generator comprehensions in python (and haskell and other languages), and is basically its own mini-language inside of lisp. Lots of lisp hackers tell people to steer away from loop because, as you’ll see, it is a whole different language.
First, the one that uses loop:
(defun sum-max2-squares-loop (&rest values) (loop for x in (subseq (sort values #'>) 0 2) sum (* x x)))
And then the one without:
(defun sum-max2-squares-noloop (&rest values) (reduce #'+ (mapcar (lambda (x) (* x x)) (subseq (sort values #'>) 0 2))))
I prefer the first (I like list/generator comprehensions very much as well), as I feel like loop is exactly the reason to use a language like lisp – you can build your solution on lisp, as the title of the Paul Graham book. Think of loop as a domain specific language for describing iteration.
Org Mode
Sweet jesus do I love org mode. I’ve seen posts about it on my blog roll increasing in the last couple of months, and I decided to sit down and see what all the fuss is about.
I’ve started using it for storing information about my various changes and todo lists for my current work (and due dates for tasks). Yes, I have Outlook and OneNote, but no, I find both of them much less efficient than using org mode. I don’t need to get very fancy, and org mode offers me everything I’m looking for (organize hierarchical lists, tables, todo lists, and relate them to dates if desired) in a nice, textual format (I can read my org mode notes in any editor, even vim :) ).
I don’t really have much to write here, except you should probably try it out yourself, if you have emacs handy. I just installed it on my second work box from EmacsW32, which provides an installer. You can opt out of the “EmacsW32″ part in the installer and just install Emacs. Even if you do opt out of the special W32 patches, I’d keep the emacsclient integration (adds start menu, quick launch, and context menu links, which is handy. I use the vim context menu link all the time).
So there :) I’m going to save this (C-x C-s), publish this page (C-c C-t), and then ship this off to my blog. Yay emacs!
Oh, and if it wasn’t perfectly clear – I use both emacs and vim, and I think both are wonderful. Each has strengths and weaknesses, and I think everyone should spend some time learning both, if only since vi(m) is installed on every unix machine everywhere and emacs keybindings are used in text entry fields in linux (gnome/kde) and OS X (I think, about the mac part).