Why a text editor?
In March I started a new project to keep experimenting with Claude Code. I wanted something real, not a toy: something I would actually use, and something hard enough to show me how far (and how well) you can go writing software with an AI agent.
The answer was easy. The tool I spend most of my day in is my editor. I've used Vim and then Neovim for many years, to the point where I just can't use anything that isn't modal. I'd also been curious for a long time about the Kakoune and Helix approach, where you select first and then act.
So I decided to be bold and write my own modal editor. I called it HUME, as in "HUME's Unfinished Modal Editor" (because who doesn't like recursive acronyms?).
It was a chance to build my dream editor, and it also turned out to be a great benchmark, because under the hood an editor is full of hard problems: UTF-8 everywhere, undo trees, rendering, terminal quirks, LSP, plugins.
The irony: I stopped using my editor
About a month in, I realized something: all the code I was producing was written by an agent. I was building a text editor, and I was basically no longer using one.
That could have been the end of the project. Why build the perfect tool for a job you no longer do? I have two reasons:
The first one: checking the diff, reviewing the code and doing small edits here and there are definitely better with a full-featured editor (HUME has a live inline diff and LSP-backed navigation and diagnostics for precisely this reason).
The second one took me a few months to figure out. I understand HUME well at a high level, but reviewing code means catching the small, hard details, and that skill fades if you don’t practice it. Writing code myself is how I keep it sharp, so I plan to keep doing it, even if only on a small side project. And for that, I still want a good editor.
So I kept going, and today HUME is my daily editor.
What HUME is today
HUME is a pragmatic, extensible modal editor. It has all the bells and whistles a modern editor should have, it reuses what I think works well in Vim, Kakoune and Helix, and adds a few ideas of its own:
- Scheme as the embedded scripting language (I've always been fascinated by Lisp...).
- Most of the big features are written as plugins, so you can turn them on or off, customize them, or replace them with your own.
- A "smart" paste that does what you most likely meant, with multiple registers and a kill ring.
Oh, and it supports the Helix theme format: why reinvent the wheel?
Lesson 1: how do you review code you can't read?
One thing I find exhilarating about agentic coding is that it lets you write a program in a language you don't know. I've worked for many years with Ruby, JavaScript and then TypeScript, plus SQL, bash and so on. But Rust? Never.
I know what a struct or an array is, and what an if or a for loop does. I think I get the idea behind the borrow checker (traits, less so). But I think that's not enough to properly review the code Claude writes.
So how do you review code you don't understand? You can ask the agent to review it, but then you're trusting the same LLM that wrote it in the first place. It's almost a philosophical problem.
Learning some Rust along the way certainly helps, and so does pushing back on the agent every time something doesn’t fully convince me. But that alone isn’t enough: I also want a workflow that works, and rules that are enforced automatically. I don’t have a perfect answer, but I found a few things that help.
The basic workflow
The first thing you learn is the basic workflow: plan, implement, review. These are the basics for a reason: they work.
The real lesson here is that asking the LLM to review the code it just wrote works better than trying to get it perfect on the first pass. And since the LLM is fast at writing code, iterating is the way to go.
Let the machine check what I can't
If I can't reliably judge the code by reading it, I want as many rules as possible enforced mechanically. In Rust, one way is to use newtypes everywhere a plain integer could be confused with another (a byte offset is not a char offset is not a line number). On top of that, I added strict clippy rules and architecture lints that stop modules from reaching where they shouldn't. Last but not least, CI runs on macOS, Windows and Linux.
Review only works when it's grounded
This lesson took me longer to learn: agent code review works well only when the agent can see the real thing it's reviewing against.
An example: say you build a generic API meant to serve two different kinds of consumers, but you only write one of them. Ask the agent to review that API and it will keep finding "bugs" for the second consumer. It doesn't know what that consumer looks like, so it guesses, and every guess produces a new hypothetical problem. You end up chasing ghosts.
The fix is boring: don't build for consumers that don't exist yet. Write the real second consumer, or drop the generality until you need it. Once the code is grounded in concrete use, the reviews get much shorter and much more useful.
Lesson 2: notice the pattern, fix it once
The most valuable habit I built wasn't about prompting. It was about watching.
Agents have tendencies, and the same bad move shows up again and again. For example, I noticed Claude widening the visibility of a method, or relaxing a restriction, just to get a test to green faster. The test passed, but the design got a little worse every time.
Correcting it in the moment fixes one diff. Writing it down fixes every future one. So every time I spot a pattern like this, I add a rule to my global CLAUDE.md so it doesn't happen again.
Another example: Claude would skip an architectural fix because it was "not worth the churn". So I tried to teach it that correct code (or a correct algorithm) is always worth the churn, even when it doesn't seem to buy you anything.
**Cost is not a verdict on correctness.** "One call site", "not worth the churn", "non-trivial for now" never license a known-wrong design. Either fix it, or measure the cost and report the number — never assert it. A wrong pattern at N=1 is the template for N=2, and the site may itself grow before anyone revisits it. I've caught and fixed many other patterns this way. If you're curious, my dotfiles repo is here.
The rest of the journey
HUME is already usable (and, dare I say, powerful), but there are still many features I plan to add, and probably a few bugs to fix (what software doesn't have bugs?).
In the next post I’ll dig into what makes HUME different: select-then-act, smart paste, and writing a plugin in Scheme.
If you're curious to try it, here are a few links to get started. Feedback and contributions will be highly appreciated!
Prebuilt binaries
Currently available for macOS (Apple Silicon), Windows and x86_64 Linux:
It works best in a terminal that supports the kitty keyboard protocol (such as iTerm2, WezTerm, Ghostty, foot, etc.).

