The editor
$ loom edit notes.txtA full-screen editor opens: line numbers down the left, the file in the middle, a status bar at the bottom saying the path, whether it is modified, and where the cursor is. Ctrl-S saves. Ctrl-Q quits, and twice if there are unsaved changes.
None of that is unusual. What is unusual is where it comes from.
It is written in Luce
The editor is not part of loom. It is programs/editor.luc, an
ordinary Luce program using the ordinary terminal builtins, with no privilege and
no back door. It does its own text handling, its own vertical scrolling, its own
character-boundary arithmetic and its own syntax
highlighting — the host owns raw mode and every escape byte, and this
program owns every editing decision.
It is the proof that the language is enough. An editor is a program that exercises almost everything at once: strings that are edited a character at a time, a cursor that has to land on character boundaries in UTF-8, a whole screen redrawn on every keystroke, a file read and written, a key loop that must not miss a keystroke, and a memory story that must not leak across thousands of edits. When the editor works, the language works.
It travels inside the binary
The editor's source is embedded in the loom binary, so loom edit
needs no path, no install step, and no file on disk to find. Because it has no
file of its own, its compiled artifact cannot go beside its source; it goes to
the private artifact directory under its content hash instead, which is the
same cache with a different address. The first
loom edit on a machine compiles it once; every one after that opens
it.
Nothing about that makes it special. loom run editor.lc FILE runs
a compiled one exactly like any other program, and:
$ LOOM_EDITOR=~/my-editor.luc loom edit notes.txtswaps in a different editor without rebuilding anything. The editor is a default, not a fixture. A test in the repository compiles the embedded source on every build so it can never rot silently.
Keys
| Key | Does |
|---|---|
| Arrows | Move by one character or one line — left and right step character boundaries, not bytes |
| Home / End | Start and end of the line |
| Page Up / Page Down | Move by one screen of visible lines |
| Backspace / Delete | Erase before and at the cursor |
| Enter | Split the line |
| Tab | Four spaces |
| Ctrl-S | Save; the status bar says so, or says why not |
| Ctrl-Q | Quit — twice, when there are unsaved changes |
Those names are the host's stable key names, the same ones any Luce program
sees from key_read(). The editor is reading exactly what
your program can read.
Syntax highlighting
Per line, as it draws: keywords, capitalized type names, builtins, string
literals, numbers, and comments. It is Luce highlighting written in Luce — a
small scanner over the line being drawn, deciding a colour per run of characters
and calling term_style before term_write.
The status bar carries the path, a + when the buffer is modified,
the line and column, any message the last action produced, and the two key hints
on the right.
What it does not do
Honestly and currently: no search, no replace, no undo, no selection, no copy and paste, no multiple buffers, no mouse, no configuration file, and no line-wrapping — a long line scrolls off the right edge. Saving writes the whole file.
Some of that is waiting on the terminal growing (mouse and bracketed paste are named as future work on the host side); the rest is waiting on somebody wanting it enough to write it. It is a Luce program in a repository: changing it is editing one file and running it.