A reckoner seed: vt100, escape sequences as strings — machines/seeds/seedvt100.shoddy
seedvt100 brings vt100’s
whole surface to a prompt. An escape sequence is a short string of invisible
characters that tells a terminal what to do — move the cursor, clear
the screen. The seed registers ninety-odd of them as string constants, plus
the cursor and scrolling-region words that take numbers, and
VTEVALKEY for reading a keystroke sequence back.
This seed exists because a note was wrong.
halifax listed
vt100 among the machines a prompt could not
reach, under “the terminal, which this shell already owns. Two
things driving one screen is one thing driving it wrongly.” That
sentence is true of a machine that drives a terminal, and
vt100 is not one. Its own header says so:
“Pure — nothing here writes to the screen.”
Every word below EvalKey builds and returns a
string. The program does the printing, or does not.
So the note confused building an escape sequence with emitting one. There was never a rule in the way. Nothing here needs the resource table, a guarded builtin or a capability. This is the most ordinary kind of seed there is: a machine of pure functions — words that only compute, and touch nothing outside — over strings and numbers.
What a session does with the string is its own
business, and there are two honest answers. It can join sequences with
+ and WRITEFILE the result, which is how you
build a banner, a terminal script or a test fixture. And halifax
prints what a line answers, so a string of escapes will reach the
terminal and take effect.
That second one is worth saying plainly. A session can
scramble its own display this way, and VTCLEARSCREEN will do
exactly what it says. That is not a leak and not a rule broken. It is the
operator’s own terminal doing what the operator asked, exactly as if
they had typed the escape by hand. The stack, the dictionary and the tape
are untouched, and CLEAR or a redraw puts the screen back.
The constants are registered from a table, not one registration line apiece. Eighty-nine words that differ only in a name, a string and a sentence are data. Writing them as data lets the list be read down and checked against the VT100 reference in one pass. The eight that take numbers and the one that reads a key are registered by hand, because each has a guard of its own.
VTESC and VTCSI are bridged too,
deliberately. They are the building blocks the rest is made of. With them a
session can assemble a sequence this machine never named. That is better
than a bridge that only reaches the ones somebody thought of.
A VT100 counts from 1. A real terminal accepts a zero row, column or move count and then does something other than what the caller meant. So a zero is refused here rather than built. The scrolling region is the one pair that is a range rather than a point. That makes it the one with an ordering to get wrong, and it is checked.
> VTCLEARSCREEN VTCURSORHOME +
x: "…"
> 3 5 VTCURSORPOS VTBOLD + "HELLO" + VTATTRSOFF +
x: "…"
> VTESC "OP" + VTEVALKEY
x: "pf1"
> "banner.txt" VTCLEARSCREEN VTBOLD + "SHODDY" + WRITEFILE
x: True
The last is the use that needs no terminal at all: a file of escape
sequences, built at a prompt, to be cat-ed later.
The constants all have the effect ( -- str ):
each takes nothing and leaves one string. They are listed by the section of
the VT100 reference they come from. The seed's own table is in the same
order.
| Group | Words |
|---|---|
| Building blocks | VTESC VTCSI |
| Modes | VTNEWLINEMODE VTLINEFEEDMODE VTCURSORKEYAPP VTCURSORKEYNORMAL VT132COLS VT80COLS VTSMOOTHSCROLL VTJUMPSCROLL VTREVERSESCREEN VTNORMALSCREEN VTORIGINRELATIVE VTORIGINABSOLUTE VTAUTOWRAP VTNOAUTOWRAP VTAUTOREPEAT VTNOAUTOREPEAT VTINTERLACE VTNOINTERLACE VTVT52MODE VTANSIMODE |
| Keypad | VTALTKEYPAD VTNUMKEYPAD |
| Character sets | VTUKG0 VTUKG1 VTUSG0 VTUSG1 VTSPECIALG0 VTSPECIALG1 VTALTROMG0 VTALTROMG1 VTALTROMSPECIALG0 VTALTROMSPECIALG1 VTSHIFT2 VTSHIFT3 |
| Attributes | VTATTRSOFF VTBOLD VTLOWINTENSITY VTUNDERLINE VTBLINK VTREVERSEVIDEO VTINVISIBLE |
| Cursor | VTCURSORHOME VTHVHOME VTINDEXDOWN VTREVERSEINDEX VTNEXTLINE VTSAVECURSOR VTRESTORECURSOR |
| Tabs | VTTABSET VTTABCLEAR VTTABCLEARALL |
| Line size | VTDOUBLEHEIGHTTOP VTDOUBLEHEIGHTBOTTOM VTSINGLEWIDTHHEIGHT VTDOUBLEWIDTHHEIGHT |
| Erasing | VTCLEAREOL VTCLEARBOL VTCLEARLINE VTCLEAREOS VTCLEARBOS VTCLEARSCREEN |
| Status | VTREQUESTSTATUS VTREQUESTCURSORPOS VTREQUESTTERMINALTYPE VTRESETTERMINAL |
| Tests & LEDs | VTSCREENALIGNMENTTEST VTTESTPOWERUP VTTESTLOOPBACK VTTESTPOWERUPREPEAT VTTESTLOOPBACKREPEAT VTLEDSOFF VTLED1ON VTLED2ON VTLED3ON VTLED4ON |
| VT52 mode | VTVT52GRAPHICS VTVT52NOGRAPHICS VTVT52UP VTVT52DOWN VTVT52RIGHT VTVT52LEFT VTVT52HOME VTVT52REVERSEINDEX VTVT52CLEAREOL VTVT52CLEAREOS VTVT52IDENT VTVT52IDENTRESPONSE |
The words that take arguments
| Word | Description |
|---|---|
| VTCURSORUP ( n -- str ) | Move the cursor up n lines. Also VTCURSORDOWN, VTCURSORRIGHT, VTCURSORLEFT. Refuses a count below 1. |
| VTCURSORPOS ( row col -- str ) | Put the cursor at row, col. Both count from 1. |
| VTHVPOS ( row col -- str ) | The same position, by the horizontal-and-vertical sequence. |
| VTVT52POS ( row col -- str ) | VT52 mode: the same. |
| VTSCROLLREGION ( top bottom -- str ) | Confine scrolling to those lines. Refuses unless top is above bottom. |
| VTEVALKEY ( raw -- str ) | What escape sequence raw is, as a name: "up", "down", "left", "right", "pf1"–"pf4", "enter", the character itself for a keypad key, or "unknown". Both the application-mode and normal-mode forms are recognised. |
| User | How | |
|---|---|---|
| halifax | The calculator's terminal-control words — escape sequences built at the prompt, to be written to a file or printed. |
A mill — a complete Shoddy program — claims this seed by
folding RckSeedVt100 over its reckoner state. That is all
halifax does.
| Machine | Why | |
|---|---|---|
| cuttle | The Cell type the sequences answer as. | |
| reckoner | RckReg and the argument readers every registered word is built from. | |
| seq | Concat and the fold that registers the constant table. | |
| vt100 | The domain this seed bridges: every escape-sequence builder, and EvalKey for the other direction. |