This file provides guidance to LLMs when working with code in this repository.
Emacs-like extensible text editor built with SDL3, Clay (immediate-mode UI), and Chibi Scheme for scripting/configuration. Targets desktop (Linux/Mac/Windows) and WebAssembly (browser via Emscripten).
# Desktop build (CMake)
cmake -S . -B build-desktop
cmake --build build-desktop
# WebAssembly build
emcmake cmake -S . -B build-wasm
cmake --build build-wasm
# Quick build with Makefile (GCC, includes debug options)
make compile # Build and run
make build-debug # With AddressSanitizer
make vg # Run with Valgrind
# Run
./out/sev # Makefile build
./build-desktop/app # CMake buildThe app uses SDL3's main callbacks pattern (no main() function):
SDL_AppInit()insrc/init.c— window, fonts, Clay UI, buffers, Scheme initSDL_AppIterate()insrc/iterate.c— main loop with 60 FPS cap for animationsSDL_AppEvent()insrc/event.c— event dispatch (keyboard, mouse, window)SDL_AppQuit()insrc/quit.c— cleanup
AppState struct holds all application state, passed through SDL3 callbacks via void *appstate. Key sub-structs:
Chibi— Scheme context (ctx), global environment (env), cachedcall_interactivelyUIState— current theme symbol, role/paletteVarTables, pre-internedCachedRoles, globalscale_factorInputState— active keymaps, last key event, mouse click/drag callbacks,FocusTarget(PANE / WELCOME / MINIBUFFER), which-key intercept stateMinibuf— active buffer, prompt, submit/cancel Scheme callbacks, push/pop frame stack (depth 8)WhichKeyState— active flag, enabled flag, intercept keymap, accumulated prefix string- Macro recording fields —
macro_recording,macro_buf,macro_buf_len,macro_target_reg
Buffers, marks, logical lines, registers, undo, jump list, buffer-local variables.
- See
src/text/README.mdfor subsystem details.
Input handling, command execution, mode registry, macro recording, Scheme interpreter init.
- See
src/command/README.mdfor subsystem details.
Chibi Scheme provides extensibility and user scripting.
- See
scheme/README.mdfor subsystem details.
Clay immediate-mode UI with SDL3 renderer backend. Layout defined in layout.c:
-
Global header (app icon strip)
-
Pane tree: binary tree of splits and
PANE_DISPLAYleaves; each leaf owns its own tab list and renders its own tab bar above the buffer view -
Welcome screen when no panes are open
-
Global status bar (mode icon + mode name pill; macro indicator dot + "REC" when recording)
-
Which-key popup overlay when active
-
Bottom strip: minibuffer (prompt + editable text + cursor) when active, echo area otherwise
-
See
src/display/README.mdfor display subsystem details. -
See
src/clay/README.mdfor Clay library and renderer backend details.
- Dirty flag:
state->needs_redrawcontrols when to re-render - Key parsing:
parse_key_sequence()handles Emacs-style notation ("C-x","M-f","SPC","RET") - Color resolution:
ui_resolve_color(state, role_symbol)— two-level role → palette →Clay_Color - Buffer-local vars from C:
vartable_get(buffer_get_locals(buf), sexp_intern(ctx, "name", -1), default) - Scheme global vars from C:
sexp_env_ref(ctx, state->chibi.env, sym, default)
-
The Unity testing library (by throwtheswitch.org) is included in
/test/unity/ -
See
test/README.mdfor info about testing and common flows to add tests.
Vendored as git submodules in vendored/:
- SDL3 — windowing and input
- SDL_ttf — font rendering
- chibi-scheme — Scheme interpreter
Clone with --recursive or run git submodule update --init --recursive.
- Make the plan extremely concise. Sacrifice grammar for the sake of concision.
- At the end of each plan, give me a list of unresolved questions to answer, if any.