Not quite working yet. Only the very first rendering succeeds. After
that any keypress triggers a second render which aborts. Image is
getting corrupted in memory somehow.
I'm loading them in uncompressed ASCII format, and all streams and gap
buffers all over the place need to get massively scaled up to 256KB
capacity. But the tests don't yet run out of RAM, so I'll keep going.
This was the whole proximal goal in implementing balanced terminals.
Printing these is still unreliable. It always surrounds in [], which may
not work.
Rename cells containing screens to screen vars because of the ambiguity
that each grapheme in fake screens is represented by a type screen-cell.
While we're at it, we also analogously rename keyboard vars.
Save a single trace to potentially multiple globals just like a gap buffer
(if say we have a single let binding defining multiple functions).
I don't have a strong use for this yet, but it seems cleaner. Maybe it's
redundant or wrong.
Inline a function by patching a few variable names. I don't even have to
worry about `return` statements if there's a single call and it's in tail
position in the caller.
We don't have support for browsing them yet. Just errors for now, which
should only be a line or two. Larger traces might be useful for inspecting
results of macroexpansion.
It turns out there's another problem, and it predates the ability to create
new definitions:
ctrl-s triggers a call to `evaluate`, which inserts a new definition
into globals. which has a null gap buffer.
All this happens long before the new code in this commit, resulting in a
null gap buffer by the time we get to word-at-cursor.
Which in turn happens because we perform a raw `evaluate`, which doesn't
update the gap buffer like `run` does (using `maybe-stash-gap-buffer-to-global`).
And arguably `evaluate` shouldn't mess with the gap buffer. Gap buffers
are a UI concern.
The hardest version of this immediate scenario: It's unclear how to guarantee
that every definition have a gap buffer, when two definitions may share
one (closures sharing a lexical environment).
New plan:
- improve the logic for detecting definitions. Looking at the outermost
layer isn't enough. And a single expression can create multiple definitions.
- extract a helper to attach a single gap buffer to multiple definitions.
- have the UI detect conflicts in gap buffers and prompt the user for
a decision if a different gap buffer already exists for a definition.