Writing my own text editor, and daily-driving it

63 points by Aks 17 hours ago on lobsters | 7 comments

ciprian_craciun | 11 hours ago

Lovely side-project!

It especially resonated with me because I've also written (and daily driven) my own text editor sce since 2008 (thinking about it, it's almost 20 years now). (In fact, just like the author, I've also ended up customizing Howl to match my expected behavior for when I've needed a GUI editor for quick copy-paste snippets between Xorg primary buffer.)


Reading through the article, I think the author didn't actually needed a text editor, but actually something more closer to an IDE, because having a terminal emulator is a bit out-of-scope of a normal text editor. But this is no critique, to each its-own.

In contrast I think one could have extracted the three orthogonal features as separate tools / libraries (perhaps part of the same code-base) for easier reuse in other projects:

  • buffer editor -- just editing a file;
  • file-browsing -- I know there is fzf, but unfortunately it's not available as a library (and it's written in Go); having a file-browser TUI available as a library is an invaluable reusable component;
  • project-wide search -- which reminds me of rg which could have been wrapped in a library (if it's not already available?);

Then, by putting together these independent building blocks one could achieve a very custom IDE.

patryk | 9 hours ago

You can use skim as a library instead of FZF. It's quite similar, but not 100% drop-in replacement

ciprian_craciun | 7 hours ago

I've took a quick look at skim, however it seems a bit too much for what I had in mind...

What I see as "perfect" for the role of a fzf replacement, is actually a dmenu-like tool that just:

  • reads from stdin a list of items; (perhaps accept more than \n / \0 terminated lines, like for example some minimal JSON items with "label" and "value" fields;)
  • take via arguments the acceptance policy; (i.e. at least one, many, etc.;)
  • present the user with the TUI;
  • write to stdout the item (or the list of items) that the user has selected; (as with input, perhaps as an option permit some minimal JSON item;)

(And I know that fzf does a lot more than what I've described above.)

The issue with tools like fzf, skim and many other clones, is that they try to be an IDE into themselves, by allowing the user to both search, preview, issue commands, etc.

zesterer | 9 hours ago

It's great to hear that you've been able to maintain your own editor since 2008, that's quite a time. I think I wrote my first line of code in late 2009. I imagine the codebase feels very homely now. That you last felt the need to make a change 2 years ago is even more impressive!

I think the author didn't actually needed a text editor, but actually something more closer to an IDE

I think you're probably right on some level, but I think the desire for a terminal window falls out of the fact that I'm not an IDE user: I prefer to have the compiler output be separate to the editing experience, which somewhat necessitates an easily accessible terminal.

I think one could have extracted the three orthogonal features

I did consider doing some level of feature extraction at first as you suggest, but quickly realised I'd end up expanding the project's scope beyond what I had the capacity to manage among my other commitments: even if only psychologically, library-ifying a component encourages thinking about generalities and versatility and it's easy to get bogged down pondering the API over actually creating the thing you want to create.

which reminds me of rg which could have been wrapped in a library

Unmentioned in the post: I did start off by simply wrapping ripgrep. I think it's probably a viable approach, but I had a yearning to learn more about what implementing a regex engine looks like in practice and I couldn't resist. After I realised that I could build something that more than fulfils my performance needs, the desire to reuse ripgrep vanished. My engine is still slower than ripgrep, but only by about 30-50% in most of the informal tests I ran on my own machine: that's close enough that I don't really care to close the gap since most queries return results faster than I can blink anyway.

ciprian_craciun | 8 hours ago

I imagine the codebase feels very homely now. That you last felt the need to make a change 2 years ago is even more impressive!

My editor is quite feature-complete (for my needs at least), thus I didn't feel like I needed to constantly improve it. (Actually there is one fixup and one improvement from late 2025 that I didn't yet push to GitHub).

On the other side, it's also very bare bones, it doesn't even have syntax highlighting (because I don't use it), and undo/redo is on the TODO since that 2008. :)

telemachus | 4 hours ago

For anyone interested in this sort of thing but at a more beginner level, I recommend reading the source for Kilo—a roughly 1000 line editor in the style of Nano or Pico—and then working through this more in-depth tutorial about the same editor. (There is also a Rust version of the tutorial, though I haven't tried it.) Since I prefer vi-like editors, I wrote a (still private) version of kilo as vilo, a minimal modal editor. I used it for a few weeks to write email and Markdown, but it's a long way from good enough to use for everything.

Mostly, the experiment made me thankful again for the people behind Vim and Neovim.

Fits like a glove: my editor does exactly what I want it to do; no more, no less.

Not necessarily disagreeing but I find myself configuring my editor(s) quite differently based on task, file type, machine, or whatever.

Might be an outlier here, and maybe this is included in "I have several distinct hardcoded configs" but while my dotfiles don't seem to change that much over the years, especially the IDE and my "notes/temp" text editors have a lot more churn than my vim config.