Retrying Emacs

Written By: Matthew Tolman
Published: Sep. 17, 2025
Estimated Reading Time: 6 min

Lately I've been retrying Emacs. I've been enjoying NeoVim, and I got a pretty good tmux + NeoVim workflow going. However, there were some things that I just missed. Not every key combination is possible in the terminal, which has been frustrating when I want to get a specific mapping done. Also, there isn't a great way to manage builds from inside of NeoVim. Having builds inside an IDE is really nice when something goes wrong since you can click the link to the file/row to jump to the problematic line of code.

I didn't want to switch back to a more resource heavy IDE like JetBrains or an Electron-based IDE like VSCode. I've been really enjoying the lightweight nature of NeoVim. I also want an IDE that can adapt to many languages easily, similar to NeoVim. So, I turned to an old IDE I used to use, Emacs.

Coding Experience

Emacs has a very different feel. First off, I do run Emacs in GUI mode, so I'm not bounded by the limitations of the terminal. However, this also means I can't use tmux with Emacs. So, I need to be able to do everything in Emacs, rather than having a terminal that does everything else.

This does simplify the flow for compiled languages quite a bit. I can have a shortcut to compile my program without leaving my editor, or even switching my window.

Additionally, since compilation is part of the editor, I can simply click on an error message to go to where it's at. I also found that getting some languages setup was a lot easier in Emacs, while other languages were incredibly hard to setup. Lisp-based languages were the easiest to setup. C/C++ was extremely hard.

Shortcut Keys

Shortcuts are also different. Emacs has a huge focus on combinator keys and using control characters (e.g. Control, Meta/Alt/Option, etc.) with some characters designed as a prefix (e.g. C-c is used for almost all custom bindings). This does mean that you don't have to leave different modes to do things, like move the cursor. This does allow Emacs to give a much more "direct" experience where it's just you and the input. No mode switching, you just enter a flow state much quicker since you just start typing.

The downside to this approach isn't that shotcut sequences can be long (in NeoVim having to switch to the right mode and then do a shortcut sequence ends up being similar in length). Rather, it's that it's much harder to setup a collision-free shortcut key, especially since Emacs comes with a lot of shortcut sequences. For instance, I would love to have C-u for a visual undo tree, but C-u is used for shortcut repeating. And so many keys are already bound to trigger |C-u automatically, so I'd have to rebind all of those. So, I instead bound it to C-i. However, C-i is tied to indenting, to the point that the default TAB key uses C-i. So, when I rebound it I broke my indenting and unindenting using TAB.

This really messed things up.

NeoVim's modes, while annoying to learn at first, do provide a very clean separation between setting shortcut keys. This is something I really miss. But, I guess I'll get used to it.

Structural Editing

Lisp developers may be familiar with structural editing. For those who haven't used it, here's how it works. Instead of separating your code into characters, words, or lines, your editor will instead split it up into semantic groups. For instance, consider the following Lisp code:

        (defun abc [param1 param2]
            (+ (* param1 param2) 10))
    

A traditional editor with line editing would allow you to manipulate the code line by line, as follows:

        (defun abc [param1 param2]
        
        (+ (* param1 param2) 10))
    

If your editor allows editing word by word, you would get the following edit sequence:

        ( defun abc [ param1 param2 ] ( + ( * param1 param2 ) 10 ) )
    

However, with structual editing we get the following edit sequence instead

    (defun abc
        [param1 param2]
        (+
            (* param1 param2)
            10
        )
    )
   

Here, we can edit every structural expression by itself. This means with a shortcut key we can select the plus sequence. It also means, we can move each sequence in and out. For instance, we can "eject" 10 from the add expression. Or we can delete the entire multiplication expression at once.

There are some plugins for NeoVim which do try to bring in structural editing, but they're not that great (at least not compared to Emacs). They also have a lot of difficulty when applied to languages other than Lisp.

Emacs support for structural editing is just fantastic. It also works really well for other languages. This is since it will treat different statements and expressions as a single unit (i.e. an "if" statement and it's body is one structural element, a for loop and it's body is another, etc). This allows deleting and moving statements to be really fast and easy. It's one of the things I really missed about Emacs.

Lots of Functionality

Emacs has a lot of functionality. It can run a browser, display images, play games, read XKCD comics, and more. This is both an advantage and downside. It means you can do almost everything you'd want, but it also makes it much harder to get started. Plus, just because emacs can do everything doesn't mean it should. Emacs is single-threaded, so doing too much will bring things to a crawl (any "threading" is cooperative).

Also, to get the most out of Emacs GUI mode is needed, and GUI mode startup is slower than NeoVim startup times. Plus, you can't tmux with a GUI, or use SSH, which does limit where you can use it. Emacs does have a lot of remote debugging capabilities, but sometimes you just need to use a terminal, especially when dealing with headless servers.

The other issue I found with the large amount of functionality is it makes creating (and keeping track of) keybindings a lot harder.

In other words, Emac's power is a double edged sword. It has a lot of capabilities, but they also bring limitations.

ELisp

ELisp is just way better than the proprietary Vim language, and I do prefer it over Lua. Of course, I've written Lisp professionally before, and a lot of Lispers do like Lisp. And, ELisp really makes Emacs ideal for Lisp. Not because of anything inherent in ELisp, but simply because Emacs developers have put so much effort into making Lisp editing good that there just aren't as many other places with comparable tooling. The only other comparable tools I've found is the Cursive plugin for IntelliJ, and even then, there is something magical about using Emacs tools and plugins. They just do what you want.

Final Thoughts

My final thoughts: I need more time with Emacs. I can feel myself really wanting to go back to NeoVim for batch editing (I love vim macros and the . repeat command). Also, I do like the vim yank registries better than the emacs kill ring (yes, emacs has really brutal names). Also, I haven't found as good of a file editor/manager in emacs as I have in NeoVim.

I'm also very used to Git from the terminal, so trying to use any sort of interface for Git (even a TUI-like interface) is just not something I'm comftorable with. And not being able to tmux Emacs (while maintaining functionality) has really caused some pain points.

That said, all of those pain points are simply workflow and familiarity issues. Given enough time, they would be non-issues. It's not that Emacs is "better" or "worse" than NeoVim, it's just that it's different.

I'm not giving up on NeoVim yet either. I use it a lot when I'm editing over SSH or on headless machines. I also use it heavily on Mac since I can simply ignore all of the "Command vs Control" shortcut changes and just use Vim keybindings instead. Plus, vim motions can be added to almost every editor, which makes using any editor on Mac a lot nicer.