DEV Community

Cover image for I found a text editor written in pure assembly, and I couldn't leave without contributing
Akash Pattnaik
Akash Pattnaik

Posted on AI-assisted

I found a text editor written in pure assembly, and I couldn't leave without contributing

I wasn't looking for a new side quest. I was just wandering GitHub when I stumbled on rhun — a blazing-fast code editor written entirely in x86-64 assembly. No libc, no toolkit, no Electron. It speaks Wayland and X11 wire protocols directly, draws its own widgets into a pixel buffer, and the whole thing fits in a binary smaller than most favicons.

I opened it, hovered over the row of cryptic little icons in the top-right corner… and nothing happened. No tooltip. I had to click each one to learn what it did. Same story in the Explorer panel — a + and a refresh arrow with zero explanation.

And that was it. I couldn't not fix that.

The rabbit hole

Here's the thing about contributing to an assembly codebase: there's no framework to hide behind. The "UI toolkit" is src/ui/ui.s — immediate-mode hit testing against g_mx/g_my, hover flags in UB_HOVER, a g_hot id per frame. Tooltips didn't exist anywhere in the app, so I got to design the whole mechanism:

  • Collect: every icon button reports hover via a tiny tip_note helper (id + anchor rect) during its draw.
  • Debounce: tip_commit folds the frame's candidate into global state — a new button restarts a 500ms timer (TIP_DELAY), steady hover keeps it, moving away or pressing clears instantly.
  • Wake up: tip_timeout feeds the remaining delay into the event loop's timeout, and tip_tick sets g_dirty exactly once when it expires — so the tooltip appears without further mouse movement and never causes a redraw loop.
  • Draw: a ui_card + centered text popup anchored below the button, clamped to the window, rendered last in app_render so it floats above everything.

One wrinkle worth mentioning: the candidate reset had to move from titlebar_draw to the top of app_render, because the Explorer draws before the title bar in the same frame and would otherwise get its hover candidate wiped before commit. The kind of bug you only find by reading the render order, not the widget code.

What shipped

Seven tooltips across two files (src/app/app.s, src/app/explorer.s, ~310 lines):

  • Title bar: Git history, Terminal, Agents, Settings, File explorer
  • Explorer header: New file, Refresh explorer

Built with the project's pinned LLVM toolchain, ran the full Windows test suite — green except two ConPTY PowerShell timing tests that also fail on unmodified main (environment flakiness, verified via git stash + rebuild). The PR has now been merged here.

The actual lesson

The intimidating part of contributing was never the assembly — it was the unknown layout of someone else's brain in code form. The fix was the oldest trick in the book: read docs/guide.md, follow the render order top-down, and make the smallest change that fits the existing patterns. Immediate-mode UI turns out to be a lovely architecture for tooltips — every frame already knows exactly what's hovered.

If you've been waiting for permission to contribute to that weird, fascinating project in your bookmarks: this is it. The maintainers of small projects are usually delighted. And you'll learn more in one weekend of reading assembly than in a month of tutorials.

Top comments (0)