Tweaking Emacs: Snippets

Using snippets with Emacs has dramatically increased my productivity. I’m using YASnippet, and am thoroughly impressed by it.

Setup is easy, so I won’t repeat that here.

I put my own snippets in ~/.emacs.d/lisp/yasnippets/snippets/java-mode and …/ruby-mode, and you can see them here.

The obvious benefit with snippets is their brevity, usually replacing unnecessary or redundant boilerplate code, such as this one for creating a list in Java:

# name : List<String> list = new ArrayList<String>();
# key: list
# --
List<${1:String}> ${2:list} = new ArrayList<$1>();$0

So creating a list of Integers, named “numbers” is done with “listIntegernumbers”.

Naturally, since this is Emacs, there is a real programming language available for use, so snippets can call Emacs Lisp code, such as this for creating a constructor in Java, which assumes the constructor name is the basename of the current file:

# name: constructor
# contributor: jpace317@gmail.com
# key: init
# --
public `(file-name-nondirectory
         (file-name-sans-extension
	  (or (buffer-file-name)
	   (buffer-name (current-buffer)))))`($1) {
        $0
    }

This is simply applying the principle of automating work as much as possible. In the words of Larry Wall: “The computer should be doing the hard work. That’s what it’s paid to do, after all.”

There are two other aspects about using snippets that I think are overlooked. At least I hadn’t expected them when I began using snippets.

The first is that snippets can essentially provide their own documentation. That is, the syntax ${1:String} above means that the default text “String” will be displayed, until and unless the programmer overwrites it with the different variable type. This is especially beneficial for what often confuses me, the order of the iterated variable, and the accumulator variable (injection below, and I’ve also seen it called memo).

With snippets, the default text describes the variable functionality. Voila and viola, no more confusion:

# name: inject(...) { |...| ... }
# key: inject
# --
inject(${1:0}) { |${2:injection}, ${3:element}| $0 }

The third benefit of snippets is that they add consistency across programming languages. My two primary languages are Java and Ruby (day job, night job), and I’ve added snippets to Java and Ruby mode for common functionality. For example, the Java snippet “constructor” above has the shortcut “init”, as does my snippet for Ruby mode:

# name : initialize
# key: init
# --
def initialize $1
  $0
end

Thus when I’m writing a constructor in either language, all I need to type is “init”. I’ve done the same for initializing instance variables with the same name as a constructor parameter, these two “svar” snippets (“svar” == “set variable”):

# name : set_variable
# key: svar
# --
@$1 = $1
# name : set instance variable
# key: svar
# --
this.$1 = $1;

What drove me somewhat crazy when editing snippets was that Emacs defaults to adding a final newline at the end of a buffer when saving it. Thus when I used one of my snippets, an extra line would be added. (For some snippets, I do want a newline, such as shortcuts for adding methods and constructors, which should be separated from other methods by a blank line.)

I knew of one solution, changing mode-require-final-newline to nil, but I didn’t want to change the global settings. I figured that YASnippet might have its own mode for editing snippets, and indeed it does, and even better, in that mode, a final newline isn’t written.

I set snippet-mode for my snippets with this:

(add-to-list 'auto-mode-alist '("\\.emacs.d/lisp/yasnippet/snippets" . snippet-mode))

Please do yourself a favor and check out YASnippet.

Sharpening the Emacs Saw

Emacs has been my primary/only editor for around 20 years, and I’ve become more aware of how little of its power I actually use. Emacs Rocks has been very inspirational in motivating me to further explore the functionality of Emacs. Lately I’ve been applying the DRY principle to Emacs itself, where if I find myself repeating a sequence of commands (including characters) in Emacs, I’ll write a macro or snippet (using YASnippet, which I highly recommend).

Integrating this approach with the Pomodoro and/or Getting Things Done principles, whenever I find myself repeating, er, myself, I’ll stop and add that sequence as appropriate, usually as a change to either my Emacs environment or my shell (Z shell) setup. It might be a bit of a distraction, diverting my attention for a minute or two, but the benefit is that I can begin using the new shortcut immediately. In fact, to enforce the new shortcut, if I accidentally use the equivalent long sequence, I’ll back up (such as deleting the just-typed characters) and use the new shortcut instead. This helps to erase the old muscle memory and enforce good, new habits.

YASnippet is especially valuable in automatically generating the boilerplate so much required by programming languages, especially Java. Even Ruby has its own overhead, and I recently heard (I’m about eight months behind) on a Ruby Rogues podcast that essentially if a Ruby programmer is actually typing “end”, then their environment is not adequately customized. I’d add that the same would apply to curly braces in Java and other C-derived languages.

A rule of thumb I’ve read is to add one script per day, and I’d advise the same for one’s editor, whether it be Emacs or any other powerful editor that can be customized, as virtually of them can be now. PragProg now has a new Vim book, Practical Vim. I don’t know of an equivalent book for Emacs, but it seems that there would be a market for it.