loom
Luce LuciaOS

The editor

Shell
$ loom edit notes.txt

A 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:

Shell
$ LOOM_EDITOR=~/my-editor.luc loom edit notes.txt

swaps 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

KeyDoes
ArrowsMove by one character or one line — left and right step character boundaries, not bytes
Home / EndStart and end of the line
Page Up / Page DownMove by one screen of visible lines
Backspace / DeleteErase before and at the cursor
EnterSplit the line
TabFour spaces
Ctrl-SSave; the status bar says so, or says why not
Ctrl-QQuit — 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.