Why I Chose Emacs as My New Text Editor

Hint: I Took the Time to Build What I Needed

By on ::    

About , I was changing jobs. I was leaving the walled garden of an IDE for a proprietary language that deployed to an AS/400 . We wrote in IBM RPG and Cool Plex, which looked a lot of meta-code and what I now know to be RDF Triples

At my new job, I was writing web-facing applications using open source technology and deploying to Linux. I needed to find an editor to help me with the task.

I spent a bit of time exploring my options. During that exploration, I learned of Emacs from Carl Meyer. Carl is a friend of mine from high school, and has contributed a lot to the world.

At the time I had three young children, I had just changed jobs, changed programming languages, and couldn’t wrap my head around Emacs. I wanted my editor to behave like other GUI applications.

I didn’t take the time to walk through the Emacs tutorial, and left Emacs behind.

A few months into my new job, I switched languages and paradigms again. In , my company hopped in a van and drove to Chicago to learn about Django and Ruby on Rails . Within a week, our organization adopted Ruby on Rails.

At that time, I adopted Textmate as my editor. It had a beautiful user-interface and required little effort to learn. I wasn’t aware of how useful a shell environment could be; In the years I’d learn more. I had, during my professional life, often relied on GUI views into files, systems, and processes. So I didn’t have a mental model that would have further nudged me towards an integrated text editor. And in my hubris, I didn’t step through the Emacs tutorial.

At the time Textmate was closed source. I used it and loved it, but it began to lag. The search a project function started misbehaving and gridning projects to a halt. I found Sublime Text and switched. At the time, Sublime was positioning as a Textmate replacement.

Then, as I engaged more and more in open source projects, I started wanting an open source text editor. I learned about Atom in 2015. It was open source and acted enough like Sublime, that I switched. During this time, I dabbled with vim . However, the modal nature of editing felt foreign. At times, I’d try out a tutorial, but it never stuck. I also thought about revising Textmate as the owner later released it as open source.

Forward to . I had begun noticing more and more bugs and breaks in Atom. Not one to fear changing editors, I started looking.

I also gave VS Code a spin, and found it disconcerting. First, it felt constraining and off-putting. The configuration ecosystem felt clunky. The plugins felt like an App Store. Everything felt like VS Code was trying to obfuscate it’s underlying systems.

Years ago, I started aspiring to write most of my commit messages following Tim Pope’s guidance on commit messages. To this day, I try to write meaningful commit messages, knowing that these commit messages will most often be close to the code.

Some may put that information in a pull request message on Github or Gitlab, but that information does not remain close to the code. However, that information is now inextricably tied to the details of Github. When I want to spelunk through my code, I don’t want to have to go to Github to get a view into what happened. I want my git annotate and git log to carry as much meaning as possible.

The proverbial last straw was the git prompt for commit messages. The prompt was a small input box; It didn’t encourage meaningful commit messages. Instead it encouraged terse commits. That feature alone told me that people using it will be encouraged to write bad commit messages. I didn’t want to be that guy with my text editor.

So, I spent a bit of time again testing vim and Emacs.

I again tried vim but it felt off. I use Vim when I shell out to a server. I haven’t done it much recently, because I’d likely use Emacs’s Tramp mode.

I tried Emacs, and worked my way through the Tutorial. It was the strong commitment to the Tutorial and honestly the writing of that tutorial that nudged me to dive further in. I spent some time fiddling with Doom or Spacemacs, but in the end settled on bare metal Emacs.

This proved crucial. As someone that’s used text editors for 15+ years, I know the features I’ve used. What I chose to do in Emacs was to complete the tutorial and start coding.

If I found myself wanting a feature, I took note of it. Then, I went and found the package or packages that implemented the feature. I spent quite a bit of time reading through Melpa, looking for a package. What happened is that I have built up my own editor that meets my needs.

Now, 5 months or so in, I’m fully loving the experience. The community of Emacs developers seem to have a higher commitment to writing documentation. Many Emacs developers write their configuration files using the paradigm of Literate Programming. In other words, they first write down their intentions for the software, then write the software.

Org Mode

Org Mode is the missing piece for my past text editors. Carstin Dominik took the time to build out functionality for organizing the non-coding tasks of software development, research, and writing. Were I to begin my blog anew, I’d leverage org-mode and ox-hugo for blogging.

Org Mode layers meaningful tools on top of plain text files; The syntax is close to Markdown, but different enough. The simplicity of structure makes the world of difference. With the plain text, I can run low-level Unix commands (e.g. grep, sed, etc.) but also have higher level programmatic access to the data.

Magit

Prior to magit, I almost always used command line tools for git . My previous workflow would be to use Terminal to state my git commits, and then my text editor to write commit messages. Atom’s slowness to open as a commit message editor was another reason I left Atom. I don’t want to wait multiple seconds to start writing a commit message.

Except for reading git logs, I now do most all git tasks with Magit. That includes an amazing interactive git rebase environment.

Fill Paragraph

I must mention this lowly command.

When Carl introduced me to Emacs, he showed me fill-paragraph. That functionality stuck with me. It’s nothing fancy, but it shows that Emacs treats column-width as a first class citizen.

And why is column width important? First, re-read the note about commit message.

Conforming to that structure helps ensure that your git log excursions are not unduly messy. It also helps if you’re going to interact with the command-line. In other words, automatic word-wrapping is nice, but its not universal, nor does it work in all contexts.

I have used this command to quickly wrap documentation so as to not have it flow off the screen. For coding buffers, I disable word wrapping. I also aspire to 120 character line width for code and 80 character line width for comments. Why the variance? Comments should read more like prose, and long running lines make the paragraphs harder to read.

It ain’t much of a command, but I’ve held a candle for it since I learned about Emacs.

Swiper

I never knew I wanted Swiper until I stumbled onto it. I now use it all of the time; It’s even replaced my default Find behavior in Emacs.

What does it do? I type Control+S In Emacs parlance, that’s C-s and start typing a word. In a mini-buffer at the bottom of the current buffer, I see the lines that include that word. It’s a bit like a find with context. Importantly, this doesn’t move my cursor in the main buffer.

So I end up quickly referencing something and get back to typing. Or, I can navigate through the mini-buffer and jump to that location in the main buffer. Quite slick.

WGrep-Ag

The wgrep-ag package sort of blew my mind. It allows you to use ag with wgrep to edit search results

Follow along carefully:

In Emacs, I search a project using ag. Emacs renders the search results in a mini-buffer. In this case, the mini-buffer is a small set of rows at the bottom of Emacs that show a subset of the results.

With the mini-buffer active (e.g. I’ve been typing results there), I invoke ivy-occur. That function opens all of the search results in a read-only buffer. While I was writing this example, I thought to myself “I wonder if I can use ivy-occur from Swiper results? Yes I can. So I learned something while explaining something.

With this new buffer, I invoke the function wgrep-change-to-wgrep-mode. This toggles ivy-occur buffer into an edit mode. I begin editing the search results as though it were it’s own file.

Then I save the edits, and wgrep-ag writes all of those changes back to the found results.

Another way to think of it, wgrep-ag loads a semi-structured buffer. Each row has three fields: file name, line number, and line text. I can use wgrep-ag to write those changes back to the originating file.

Seriously, this functionality amazes me.

Multiple Cursors

Textmate first introduced me to this powerful concept. Since then, this functionality has been a mandatory feature of my editors.

Two packages help deliver on this:

  1. iedit - by default, if I type Control+; (e.g. C-;), the iedit package highlights each occurence of the word. I can now type and iedit updates all occurrences.
  2. multiple-cursors - this package provides finer grain control, and allows me to set a cursor on ten contiguous lines and start typing.

Expand Region

I didn’t know what I was missing until I installed expand-region. Now with Control+= (e.g. C-=) my cursor expands to the smallest logical region (e.g. highlighting a word), typing it again expands that region (e.g. highlighting the sentence), etc. And Control+Shift+= (e.g. C-+) contracts the region.

Org Roam

Building on org-mode, org roam incorporates note taking paradigms inspired by Zettelkasten.

I’ve used this to write up campaign notes for my New Vistas in the Thel Sector campaign. The bi-directional link and quick note capture tools make for a dream in information management.

In a way, it creates a Wiki that I can use Emacs to edit and navigate.

update:

YASnippet

I forgot to mention YASnippets. Back in the day, I wrote a few snippets in Textmate, ported them to Sublime, and reworked them in Atom. With YASnippets, I've found an easy to use snippet manager.

The documentation is easy to follow. I wrote up a handful of snippets to help with blogging. The following snippet provides guidance for making a custom Hugo Shortcode:

{{< update date="`(format-time-string "%Y-%m-%d")`"
  mode="${2:$$(yas-choose-value '(
    "inline"
    "marginnote"
    "paragraph"
    "sidenote"
    "section"))}"
>}}
  $0
{{< /update >}}

This snippet builds the parameters for my update shorcode. It sets today's date and provides a list of valid modes for the shortcode.

update:

Modus Themes

The Modus Themes by Protesilaos Stavrou have become my go to themes.

It’s been a bit of a circuitous path to get to this point, but it’s been worth it. Protesilaos is developing the Modus themes with the following guiding principle:

Accessible themes for GNU Emacs , conforming with the highest accessibility standard for colour contrast between background and foreground values (WCAG AAA).

In past editors, I’ve often used a dark theme. I made a Vibrant Ink Ruby Atom theme that works with Hugo . This also involved a few tweaks to a language-markdown plugin for Atom. In my current office setup, I often need a light theme. In my current setup, a dark theme often truns my glossy monitor into a mirror. But sometimes, I want a dark theme. And I don’t want the shift between dark and light to highlight the code via a different scheme.

Enter the Modus Themes:

  • modus operandi for light
  • modus vivendi for dark

I’ve grown quite fond of the color palette. I also appreciate the work Protesilaos is doing on visually conforming to WCAG . I’m going to look at leveraging that work to refresh the color palette of my website. But that’s an adventure for another day.

Conclusion

This year, Emacs drew me in. As I’ve entered my 3rd decade of software development, I’ve grown to appreciate tutorials, documentation, and owning my tools. Emacs delivers on all of that. It’s even as old as I am.

What I’ve found is I spend more and more time in Emacs, as it does more and more of what I want, all building from the basis of text files and directories.