Goodbye, Vim

When I was in high school and I was first exposed to the world of Linux customization, I decided to follow the hype train I saw online and started using vim as my text editor. I barely scratched the surface of learning it (I was a filthy arrow key peasant…) but I continued to tinker with it on and off for well over a decade. As time as gone on, vim has become a second language for me, and working without it makes me feel inefficient and shackled. I can cut through massive code-bases, perform single file refactors quickly, and I love any opportunity I can get for a little bit of ! shell magic. Simply put, vim has been the text editor for me, and no matter where I’ve tried to go – Emacs, Joe, VS Code, Sublime Text – I always find myself crawling back.

There’s a schism in the vim world right now, however. The project has begun accepting LLM-based changes into the core, and they’ve even boasted about how “AI-ready” vim9 script can be. While maybe a few contributions and a poorly-received changelog entry is the extent of it, I worry that the writing is on the wall, and maybe my venerable text editor is now succumbing to market forces… I don’t want to use an editor that is slopped together. I don’t want an IDE. I chose to stick with vim over neovim because vim represented the old-school UNIX ideologies that I really resonated with. It does one thing well, it has a slow and steady development model, and I can always count on it working whether I’m shelled into a $5 microcontroller or a $5,000 development machine. The configuration is terse and obtuse, sure, and the scripting sucks, but in this I think we find restraint. It’s likely an overreaction, but bringing AI into this development life-cycle (which was slow, but better for it!) and not recognizing how out of place the words “AI Integration” sound inside of the release notes signals to me that the hacker spirit I once resonated with has left the project.

In reflecting on how vim is starting to diverge from my own values and expectations, it occurred to me that I don’t even know what new features vim has added in the past ten years that have had a material impact on me. I’ve kept a very slim .vimrc over the years (again, I don’t want an IDE), and almost all functionality I depend on is either built-in or easily replaced with a shell utility. It has me wondering, if that’s the case, is there another member of the vi family tree that would satisfy me? I’ve started my search for a replacement.

What Do I Actually Use?

Reviewing my .vimrc and my usage over the past six or so months, I think the subset of features I need is as follows:

And some things that would be nice to have:

me writing this post
vim as I type this post (yo dawg…)

There are other features I rely on constantly, e.g. fugitive and vim-go, but I’m certain that I will have to sacrifice this functionality since I’m leaving the mainstream.

What Are My Options?

I won’t regale you with the history, but vim as we know it is the result of twenty-plus years of feature additions to a basic vi clone. As such, starting with the vi family tree is a great place to begin looking for alternative. Better yet, someone recently wrote a fantastic blog post that puts together a basic catalog of the history of vi clones. Starting there, we have effectively two paths to walk: do we want to stick with the direct UNIX/BSD lineage, or do we want to try a clone from the personal computing era?

nvi

Let’s start with nvi, which is a descendant of elvis, but is trimmed down significantly to be bug-for-bug compatible with the original BSD vi. It’s worth noting that the fork between these two code-bases occurred well over twenty years ago at this point, so there is almost no resemblance. Opening nvi for the first time is almost oppressive in how minimal it is, even compared to the venerable vim. The keybindings are mostly familiar, though backspace in insert mode does not function as one might expect in the year 202X.

I was also a bit lost in regards to how some functionality worked, such as file name completion. That was, until I stumbled onto a very thorough blog by Matt Widmann that details how to configure the damn thing so that it feels more like vim!. I also found another post of his that covers “implementing” some modern functionality that I rely on, such as fuzzy-finding and paragraph wrapping. Honestly, this blog took me from “eh” to “this is genuinely a viable alternative” in a matter of an hour. Given the things he’s documented, a couple of other features I’ve found (vertical splits and ctags!), and the packaging situation, this is a very good option. The biggest downside is the lack of proper UTF-8 support2 and some slightly different keybinds, but neither is a deal-breaker for my needs.

nvi in action
nvi in action once I got things configured

elvis

Since nvi is largely treated as a buttoned-up Real vi ImplementationTM, I wanted to make sure I tried out some of the weirder examples that exist independent of the Cathedral development style. elvis caught my attention because it is charmingly strange. It also has a largely stalled development cycle at this point, but unlike nvi, elvis is almost a bizarro-world vim. For over twenty years, elvis has slowly been growing in features rather than sticking with the strict UNIX legacy (much like vim), to the point that calling it a “vi clone” is really underselling it. Perhaps there’s a world where elvis won the vi clone wars! For instance, elvis proudly renders HTML in-editor, and it even supports web browsing if you want to use the world’s most obscure user agent. I frickin love it. Unfortunately, elvis is niche enough these days that it does not have a presence on most package managers, including Debian and Homebrew3. I gave building a shot on Debian, and I had to hack up the configure script to get it to compile, which is not the best sign. Debian isn’t exactly exotic.

elvis in action
elvis in action, look at the syntax highlighting!

Once I got elvis up and running, I was very overwhelmed. While I initially considered it a point in its favor, the “different timeline” aspect made it very hard to get started, and the documentation sprawled for pages and page and pages. I’ll keep this in my back pocket, but between the failing build, the lack of packaging, and generally what seems to be a total absence of mind-share about this one, I’m likely going to rule it out. There are also some other issues at play, such as the default theme effectively hiding line numbers, that would require a lot of tweaking to sort out.

vile

vile is almost as weird as elvis, albeit in a more controversial way: it is a mishmash of emacs and vi in a single editor. In fact, it was forked from a stripped down emacs named uemacs, which is famously what Linus Torvalds used to develop the Linux kernel. I try to keep an open mind, but this editor felt just a little bit too divergent from what I expected/wanted, though it does seem powerful. vile is slightly less sprawling when compared to elvis, but there are effectively two sets of keybinds operating at once. Most operations are done in a standard modal vi style, but a surprising amount use the emacs key chord setup, prefixing sequences of keys with ^X. Not my cup of tea. That said, I do admire that this editor is still passionately maintained after all these years. It has an undeniable charm.

vile in action
vi user mystified by keychords (colorized, 2026)

As an aside, I couldn’t get the syntax highlighting to work (neither set hl=on or set ac=10 seemed to do anything), which would require more investigation to sort out. The weirdest thing I found was that :q does not quit the current buffer, it quits the entire editor, which was a rake I stepped on repeatedly while testing it out.

Viper Mode (emacs)

If vile wasn’t off-putting enough, I figured it was worth at least mentioning viper-mode (and evil) if only to discuss why I won’t really consider them. It’s almost too easy to poke fun at emacs, but it is truly a marvel of software. It almost transcends the lines between “editor” and “operating system,” which I say not as a jape, but with a fearful reverence… It’s no shock then, that there are two different vi compatibility layers available. viper-mode is built in, and emulates vi throughout the editor. evil-mode does the same, but also replicates the extended set of vim keybinds and behaviors. These emulators are disgustingly thorough, and truly are second-to-none in terms of accuracy.

However, I personally find emacs too expansive and all-encompassing for my needs. I’ve gone down this rabbit hole before (I think I used emacs as my main text editor for work for six or so months) and the problem is that there is almost no bottom to the abyss of flexibility offered by emacs. At some point, when you use these emulation layers, you have to interact with the core of the editor. Unfortunately, that usually means writing a lot of configuration. It’s super powerful, but it goes back to my original point about vim being better off having a limited configuration language. Sure, I can do all sorts of Lisp magic in a configuration file, lazy-load my dependencies, etc. etc. but for my money (or lack thereof, given this is free software), I just want some sane defaults and a terse way to flip settings on and off.

Maybe I’ll revisit emacs at a later point, but I can’t stomach the wormhole of configuration for now.

joe

Joe’s Own Editor (joe) is a text editor with a very long history, but it has nothing to do with vi, nor does it support vi keybinds. It was inspired by Wordstar, which is a little unusual, and I’d pin its origins closer to MS-DOS than I would UNIX. Why am I talking about it? It’s simply another portable text editor with a steady development history, and while the keybindings aren’t my favorite, I did want to give it another shot since I remember liking it a long time ago.

Joe’s Own Editor
There’s some clutter, but almost everything can be easily toggled on/off

Stepping back into joe today, I still found the experience quite comfy, even with strange keybinds. There is a jmacs frontend that switches to a more familiar set of emacs bindings if that’s your cup of tea. What surprised me the most (though maybe it shouldn’t since this was inspired by a word processor) is the pleasant behavior for writing prose! The indentation functionality worked exactly like textwidth, and a keybinding re-flowed the text just like gq. The syntax highlighting also worked well enough, and the visual menu for tweaking settings was very easy to use. The lack of vertical splits is a bummer, but I may want to use joe in the future for all of my non-programming needs given the nice paragraph facilities.

vim Forks

There are two hard forks of vim that have surfaced for the same reasons I am looking to jump ship: vim-classic and evi. vim-classic chose a version of vim 8 that predates the new scripting system, and evi simply chose the last commit of vim 9 that was not coauthored by an LLM. It would be great if either of these gained some traction, but in practice I am not holding my breath, and I am not interested in testing them at this time. Besides literally just being vim already, which wouldn’t be that interesting to explore, I want to wait and see if they can survive. Forks – especially forks done for philosophical reasons and not technical changes – are always a gamble, and it will take years before we can understand whether these are just a flash in the pan. Barely anything feature-wise differentiates them at this moment, and they are already competing for the slimmer subset of die-hards that did not jump ship to the shinier fork, neovim, when that drama was brewing several years ago.

Neither project has shipped a release yet, nor has any package manager started offering them as far as I can tell. If either of these forks calcifies into a real community with any amount of long term support, I may jump back in. But cynically, I really doubt that there’s a long or happy life for either of these editors.

The Saga Continues

I was actually ready to adopt nvi and started typing out a conclusion to this piece, but as I began to work on a couple of map macros, I stumbled upon a segfault… Uh oh. For my own sanity since I recently updated my MacOS version, I decided to force a brew reinstall. Still segfaults. Worse than that, I noticed something in the brew logs: nvi was officially deprecated by brew as I was writing this, and will stop being shipped in a year. I suppose this makes sense, given the lack of upstream maintenance, but they specifically mention wanting to “reduce BDB formula usage.” What is that about? I thought BDB was a pretty standard component…

Berkeley DB (BDB) is a historic in-process database format originating from the olden days of BSD dominance. A lot of BSDs provided their own drop-in compatible db.h as part of their core OS, but on Linux (and the prison that is MacOS), it’s been necessary to pull in a library dependency instead. A tragedy befell the project in 2006, however: Oracle purchased the company that was maintaining Berkeley DB, Sleepycat software. The original license for the upstream BDB project was a relatively lenient OSI-approved license, but in 2013, for some unknown reason, Oracle decided to move it to the AGPL. Now, I’m not opposed to the AGPL in general – it makes a lot of sense for server software when you don’t want a mega corp to repackage your system as a Cloud ServiceTM – but choosing to use this license for a software library that requires linking is absolute fucking insanity. Most projects have had to choose between replacing BDB, using an old pre-AGPL version (which gets harder all the time), changing their own license (which is rarely practical), or YOLO it and see if Oracle notices. I personally would not try my luck against a corporation notorious for suing its own customers with regularity. For package managers like Homebrew, this is a nightmare situation, and I can’t blame them for wanting to completely remove the package and its dependents.

I guess I’m going back to the list…

nvi2

nvi2 is a fork of nvi that adds a number of useful features, including passable UTF-8 support. It’s got a lot of active contributors, I believe it ships with some BSDs, and it generally seems like a much healthier project than plain nvi. Besides not being packaged in a lot of places, I was disappointed to learn that nvi2 is also dependent on BDB, and getting it to build portably seems to require pulling in ancient BDB versions. If this fork ends up becoming popular for replacing nvi itself, I’d be happy to give it a shot, but the lack of portability is a no-go for me at this time.

xvi

Usually when a software project advertises itself as the “smallest,” I’m bracing for a sub-par experience. Despite putting its small size front-and-center on its (spartan) homepage, xvi totally surpassed my expectations, and in some regards, its experience puts other vi implementations to shame. Building it was super easy and only required curses as a dependency. The real magic is the editing experience itself: unlike almost every other vi, backspace is handled in a sane way. I also found the “UI” to be very clean, with little clutter. Compared to other examples I’ve looked at, such as vile, this is very easy on the eyes. My only complaint is that :q quits the entire editor instead of the active window, which is some very hard muscle memory to lose.

xvi editor
Poking through source code with xvi

Unfortunately, xvi follows the familiar tale of waning maintenance. The project has not seen activity in several years, and worse, one of the last things that happened in the repository was a confusing move from using issues to using text files in the repo… Do I open a pull request instead of filing a bug? This editor also has a rather unfortunate name that just so happens to share a common prefix with a popular adult video website. xvi is simply too niche to win any SEO war, and I almost instantly regretted the DuckDuckGo search I made to try and find the project.

I briefly pondered about forking this project, though I think any proper fork will need a full rename that has a bit less baggage.

OpenVi

If I’m not mistaken, this was added to The Vi Family blog post at some point after I had started writing this piece, and I’m not disappointed that I checked again. OpenVi forked from the vi used in OpenBSD, which was originally forked from nvi. It feels very similar to nvi, of course, though there are some minor user-facing changes that have occurred. OpenVi also adds its own set of features (such as sane backspace behavior) rather than trying to maintain the original 4.4BSD behavior perfectly.

Given that I dropped nvi and skipped nvi2, you might wonder why I’m bothering with OpenVi at all. The answer is portability: under the hood, OpenVi packages its own db.h implementation and the only dependency it needs is curses. This lets me have my cake and eat it too. It’s trivial to build this project on MacOS, Linux, and any BSD, and it still shares the same familiar core of nvi. In fact, I was able to fire this up with the same .nexrc file and try out the macro that was segfaulting in nvi. Sure enough, no segfault, and I get to be smug that my incantation was indeed correct, even if I couldn’t test it.

My only complaint is that there are only horizontal splits. Given that most monitors are wider than they are tall, this is unfortunate, but it’s a small price to pay.

Moving Forward

I had a lot of fun poking around these editors, and it gave me nostalgia for my early days tinkering with Linux and exploring the world of Free Software. It will be very challenging to break my habits, but I think OpenVi is the clear winner to replace vim for me, especially since it seems to have some amount of activity and mind-share. I will need to get used to the missing motions and features, and it may even be worth reading the code-base to get a slightly better grasp of what’s on offer. Mercifully, the scale of most of these code-bases pale in comparison to what vim eventually ballooned into, so I could meaningfully interact with their code-bases.

One additional thing I learned (and I might do further writing to evangelize a bit) is that for plain vi, most of the configuration is POSIX-defined and can easily be transferred between the different variants. Once you learn how to escape escape codes for a map, you’re most of the way to being able to recreate most vim creature comforts. After the more complex mappings and tricks clicked for me after reading Matt Widmann’s blog, I wrote a number of facilities myself, and if I ever go back to vim I’ll likely implement some of the plugins I depended on using shell utilities and macro shenanigans. The fundamentals of dynamism in vi via registers are simultaneously simple and clever, and figuring out how I could use old-fashioned UNIX utilities to replace some built-in behavior I had grown accustomed to was very satisfying.

I will surely miss vim – the colors, the help facilities, the cozy configuration, the obscure plugins – but the world is changing and it has taken vim along for the ride. I am still experiencing a lot of grief from the seismic shifts that LLMs have inflicted on software, and maybe this is yet another step backwards for me. If anything, I think shedding some of the functionality I rely on for a while will hopefully give me more discipline and unshackle me when/if I start using something a bit more powerful in the future. When I look back, removing “crutches” from my editing life-cycle and eschewing IDEs is ultimately what built up a lot of my muscle memory and instinct as a software developer, and this may be an opportunity in that regard.

vim is dead! Long live vim!


  1. I discovered while working on this that, historically, fmt(1) was an external tool you would shell out to in ex for this behavior. I also realized I could do something even more obvious – just filter lines through pandoc.

  2. It’s a bit unclear, but as far as I can tell, the original nvi is what package managers are shipping, not nvi2 which extends the code-base with UTF-8 support.

  3. Confusingly, there is a package named elvis in Homebrew, but it’s simply a name collision.