Revisiting Focus: Fixing the Jai Text Editor
- https://www.youtube.com/watch?v=VBNmDvTg260
- Original title: I was wrong about this Text Editor
- github :: focus-editor/focus: A simple and fast text editor
- Increase MAX_FONT_SIZE limit · focus#661
Tsoding returns to the Focus editor — a text editor written 100% in the Jai language — years after claiming it would "replace VS Code," opening the stream by admitting that claim was clickbait. The bulk of this two-hour live session is a deep code-reading and hacking expedition through Focus's font-rendering internals: building it in 4 seconds, swapping FreeType for a raylib-based font atlas so zooming works, and wrestling with the editor's font-page allocation to fix crashes. Along the way it's a tour of Jai's allocators, struct-scope quirks, and Jon Blow's coding patterns.
Around 1:30h mark, Tsoding finds memory leak in glyph allocation that (presumably) Jon Blow written and screams out loud. Later he realised that authors of Focus ported font-rendering incorrectly, using bare structs instead of pointers.
The retraction
- Opens by walking back his earlier "this will replace VS Code" video: "I lied for clicks on the internet." Sets the tone — this is an honest revisit, not a hype piece.
- Focus is implemented 100% in Jai. Not very actively developed (last commit ~2 weeks prior); the authors are busy with life.
Building and first impressions
- Clones and builds the whole editor with
build.jaiin ~4 seconds — the recurring flex of the stream ("Can your text editor do that?"). - Resulting binary is a chunky ~18 MB, mostly statically linked, with minimal dynamic dependencies.
Font rendering and the zoom problem
- Focus's font handling is tied to FreeType, which is why smooth zooming was problematic. Tsoding leans on raylib (Raylib), which bakes font atlases, so zooming is a non-issue in his setup.
- Detour into font-atlas trust: atlas pipelines assume trusted fonts baked at build time. Rendering untrusted fonts (e.g. a web browser downloading arbitrary fonts) is a security concern. Riffs on Ken Thompson's "Reflections on Trusting Trust" — you can't fully trust any software, compiler included.
Reading the codebase
- Explores Focus's custom allocators: flat pool, pool, and an "unmapping allocator" that actually munmap's freed memory; pools take an internal block allocator so other code can pull blocks from them.
- Jai language quirks: assigning struct fields inside a struct scope, what is/isn't allowed in a data scope (no non-static
if), and the classic Jai pain — three hours lost to a single missing semicolon. - Notes a Jon-Blow signature pattern: storing per-resource "should I free/deinit this" booleans/flags set at allocation time — a style he sees constantly in Blow's code and nowhere else.
Hacking the font-page allocation
- Chases crashes through the font/glyph code (
make_font_page,font_pagesdynamic array, temporary-glyph allocator), wanting bounds checks that pinpoint buffer overflows instead of bare segfaults. - Figures out glyph atlases are pre-warmed by drawing the common characters once so the font pages land in GPU memory.
- Ends up reworking
font_pagestoward a dynamic array of pointers (heap-allocated pages) to fix the allocation/crash behavior, second- guessing the original arena-style design as he goes.
Aside
- On game-dev language choice: just pick whatever — "if you haven't got a language picked yet, you don't know enough to evaluate performance yet." You can even make a game in the terminal.