April 5, 2020

A well-honed tool

I took a few minutes last night to add a small feature to Emacs, saving me from some repetitive steps when I'm starting a blog post (like this one). It was a tiny bit of code and nothing exceptional in itself, but it reminded me of why I choose to use an editor that's nearly as old as I am. It is designed for this kind of organic, incremental growth.

I often find it difficult to explain to my younger colleagues why you would use Emacs or Vim (another vintage editor) over modern tools such as VS Code or Intellij. The old editors are harder to learn. You can't just sit down at one and be productive in minutes. It takes some effort, and usually at least a several weeks of it, to get the hang of them.

But Emacs and Vim have been shaped, balanced, sharpened and smoothed over by decades of usage by hundreds of thousands of programmers, each trying to get through their day as efficiently and fuss-free as possible. In the right hands, they move lines, shift paragraphs and fling code better and faster than anything out there.

They've evolved so much because it is trivial to extend them, to change even the most fundamental features. You just do it as a matter of course, to save a few keystrokes here and there. And many of these incremental modifications have been shared, one programmer to another, almost as long as there have been programmers.

Today's bit of magic took a lot less time to write than this blog post, but it turns a half-dozen steps into one. It opens this site's Github project, creates a new branch (using a plugin called Magit), creates a new file and inserts some boilerplate configuration. With one keystroke, my cursor is blinking, in the right file, in a new branch, configured and ready for me to start typing the post.

(defun eds/insert-skeleton-blog-post ()
  "Insert a basic skeleton for a blog post."
  (goto-char (point-min))
  (insert
   "{:title \"new post\"\n :layout :post\n :tags []}\n\n"))

(require 'init-git) ;; for magit
(defun eds/start-blog-post ()
  "Create a new post with today's date and a new branch"
  (interactive)
  (let* ((branch (format-time-string "%Y-%m-%d"))
         (filename (concat "~/git/eamonnsullivan.co.uk/content/md/posts/" branch "-new-post.md")))
    (find-file filename)
    (eds/insert-skeleton-blog-post)
    (save-buffer)
    (magit-branch-create branch "master")
    (magit-checkout branch)))

It's not great code. There's no error handling (it'll just blow up if there's already a branch with the same name) and the file names, title and configuration are hard-coded, but it's good enough to start with. It'll continue to evolved, as my needs change. I might prompt for the title or tags, for example.

Of course, you can extend Intellij and VS Code, too (VS Code has a good API, for example). Users don't focus on tinkering as much, mostly because these tools probably already have the features they want. I tried Intellij for a long time when I first started at my current job a few years ago, because I was new to the Java Virtual Machine world (this was for Scala) and absolutely everyone else used it. It has just about every feature you would want, and it mostly just works.

What drew me back and motivated me to put effort into adding Scala features to Emacs is that I didn't like all the black-box magic in Intellij. By adding the features I needed to Emacs, I was learning how the language and the build tools work, from the ground up. By shaping Emacs to fit my workflow, I believe I was becoming a better Scala programmer.

My Emacs configuration is nearing its third decade. I started using it to write HTML and, once I got the hang of it, started using it for my day job as a journalist. I found myself enjoying its sparse, no-nonsense, no-distractions interface. And piece by piece, one tiny snippet at a time, it has become almost an extension of my brain. I wouldn't trade it for anything.

Tags: emacs elisp