I'm still thinking we should expose below these fancy procedures the system calls, struct, and flags primitives they use to get and set line disciplines.
I'm not convinced, but I'm willing to discuss it.
Perhaps your Scheme's dynamic-wind isn't so magic, or doesn't exist.
If so, the Scheme is not even R5RS-compliant. Systems that lack R5RS nowadays are toys or written for a special purpose: Scheme 9 as an illustration of how easy it is to write a cleanly coded Scheme interpreter in C, for example.
Your POSIX changing line discipline loses characters when switching from canonical mode, I don't think we can demand all implementations of POSIX a Scheme runs on to be perfect. The scenario I conceive of here is that between invocations of e.g. with-rare-mode a character gets in the canonical mode domain and then is "flushed" in POSIX terms, that is discarded, when we return to raw mode, despite using the NOW option for that.
All the more reason to make changes in between modes rare. A pure TUI editor would start in raw mode and stay there until it shuts down. A bimodal editor like vi switches only at well-defined points. Switching from ex to vi mode takes some time anyway, and it wouldn't occur to me to try typing ahead then.
Your POSIX line discipline doesn't allow setting everything we assume it can. For historical reasons you're actually required to get, set, which will return 0 if any of the changes are accepted, then get again to make sure all or "enough" of the changes were made. Which also brings up the question about what we should do with these procedures if that happens.
In the before-thunk, the terminal should be restored and the whole thing aborted. In the after-thunk, it's unclear; there shouldn't be any reason why restoration should fail. That's why we have exceptions.
According to ... Wikipedia, rare/cbreak mode, which I've not actually used, is for character at a time input. Does that mean with-rare-mode should hang until it gets a character, or should it (can it?) use the timeout line discipline feature that with-rare-mode uses.
Rare mode is basically raw mode except that the normal signal characters (^C, ^\, ^Z) send signals instead of being passed through.
Note that in both rare and raw mode it's actual calls to read-char that hang, just as in cooked mode, and *not* the with-*-mode wrapper.
Ugh, that sounds like a horrible "feature". But I think we should allow for "magic echo", a dot per typed character, and rubout deleting the last dot. Maybe ^U the whole set of characters typed.
That can be done with a higher-level routine using with-rare-mode with a timeout of 0, so it processes characters as it gets them, doing its own echoing and interpretation of rubout-like characters. (It doesn't make sense to turn off signaling in this context, which is why it should be rare and not raw.) But it doesn't need anything special beyond that IIUC.
John Cowan http://vrici.lojban.org/~cowan email@example.com
The native charset of SMS messages supports English, French, mainland
Scandinavian languages, German, Italian, Spanish with no accents, and
GREEK SHOUTING. Everything else has to be Unicode, which means you get
only 70 16-bit characters in a text instead of 160 7-bit characters.