Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unite our two control sequence automata #2183

Closed
dankamongmen opened this issue Sep 19, 2021 · 48 comments · Fixed by #2208
Closed

unite our two control sequence automata #2183

dankamongmen opened this issue Sep 19, 2021 · 48 comments · Fixed by #2208
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request input readin' dem bytes
Milestone

Comments

@dankamongmen
Copy link
Owner

We have two automata we traverse to handle control escapes -- the one handled by pump_control_read(), and the special key trie. as a result, we have two distinct control loops, and two distinct states. this last is horrible, as there's no well-defined map of state changes effected by one on the other.

unite these two automata. given that special keys require a dynamic state machine (it's prepared based on terminfo data), a wholly explicit controlflow-based automaton (like that used in pump_control_read()) won't work. we need a dataflow-based one, as used by our trie traversal.

so we'll need add some special node types to our trie, basically the same we have from the other automaton:

  • accumulate a number
  • accumulate a string
  • accumulate a hex-encoded string, which is just a special case of either of the previous 2
    ...and that's it, i think? pretty easy. let's do it up right
@dankamongmen dankamongmen added documentation Improvements or additions to documentation enhancement New feature or request labels Sep 19, 2021
@dankamongmen dankamongmen added this to the 3.0.0 milestone Sep 19, 2021
@dankamongmen dankamongmen self-assigned this Sep 19, 2021
@dankamongmen dankamongmen added the input readin' dem bytes label Sep 19, 2021
@dankamongmen
Copy link
Owner Author

so right now a trienode just has an (optional) Σ-index (there is no index on terminating nodes). we will add a word for an aggregated numeric, string (pointer), an NCKEY, or function pointer to each node. since no sequences end in numerics or strings, this ought be sufficient for all nodes. the function pointer indicates an accepting state, and is invoked upon transition (since there are no valid prefixes, all accepting states are terminal states). we'll need a 4-way type; this can be two bits, but we'll likely just use a full int:

TRIE_NUMERIC
TRIE_STRING
TRIE_SPECIAL
TRIE_FXN

where TRIE_SPECIAL combined with NCKEY_INVALID (0) indicates a transitory node.

state-wise, we'll want an array of trienode pointers, equivalent in length to the longest path in the trie. we can calculate this as we build the trie, and allocate the array upon completion of trie construction. from this path plus the in-trie state, we can recreate any path without keeping the actual characters, meaning we can replay failed escapes as input without keeping external state.

Escape is handled distinctly, and always takes us to the STATE_ESCAPE node. this way we needn't have a Σ-index on terminal nodes, saving memory (each index is about 1K, with 128 ways and 8 bytes per pointer). Escape remains the initial node; we are not going to process standard UTF8 via the control trie. upon an escape while in-trie, we replay the path and return to ESC. upon a standard termination (non-0 TRIE_SPECIAL or any TRIE_FXN), we play in the special or execute on the fxn, and then move to NULL (do not move directly to STATE_ESCAPE).

we'll break apart the control-flow automaton, turning them into functions invoked on TRIE_FXN and (possibly manual) constructions. i don't think it's worth coming up with a little regexy DSL to do algorithmic construction -- there simply aren't enough TRIE_FXNs.

so for instance let's say we need recognize \e[num:num:numu, that would be

NULL Esc-> STATE_ESC [-> STATE_CSI 0-9-> TRIE_NUMERIC
0-9-> loop
:-> TRIE_SPECIAL[0] 0-9-> TRIE_NUMERIC
0-9->loop
:-> TRIE_SPECIAL[0] 0-9-> TRIE_NUMERIC
0-9->loop
u-> TRIE_FXN

where that TRIE_FXN takes the three aggregated numerics, evaluates them, and calls the relevant function. we then move back to NULL. any Escape along the way moves us to STATE_ESC following a replay along the path. any invalid follow moves us to NULL following a replay along the path.

that ought work.

@dankamongmen
Copy link
Owner Author

also, trienodes ought hold an ncinput, not their own weird assemblage of ncinput.

@dankamongmen
Copy link
Owner Author

ok, i've gotta stop tonight, but very good progress. i've gone ahead and done a DSL, with \N as a numeric accumulator, \S as a string accumulator, and literals otherwise. we'll want \H as the hash, and we might need a Kleene closure for drainage purposes. the constaints for numeric transitions are too tight right now--i've had to comment out the special keys for now, but we'll need add them back. that same principle would apply to any Kleene.

i've converted about half of the CF automaton over to DF -- mouse, kitty, cursor location, and geometry.

when using the kitty protocol, we probably ought not try to match old-school alts/ctrls.

so this will be done soon. dankamongmen/unifytries branch.

@dankamongmen
Copy link
Owner Author

well, we have verified that unknown sequences even when interleaved with the initial query responses now get replayed as input, which is good! exactly what we expected.

2021-09-23-233808_910x1057_scrot

@wez
Copy link

wez commented Sep 30, 2021

@dankamongmen
Copy link
Owner Author

5fccc295-1b29-4916-a696-da948c9d80b5.mp4

@dankamongmen
Copy link
Owner Author

wezterm now starts without any bleed, 'twas a bug in our Kleene reduction

@dankamongmen
Copy link
Owner Author

this also fixed the XTerm bleed. i no longer see bleeding with any terminal. =]

@dankamongmen
Copy link
Owner Author

dankamongmen commented Sep 30, 2021

btw @wez while i've got your attention, i added some info to wez/wezterm#1063

@dankamongmen
Copy link
Owner Author

mlterm bleeds with \e[?1;3;0S

@dankamongmen
Copy link
Owner Author

mlterm is handled

@dankamongmen
Copy link
Owner Author

st is fine

@dankamongmen
Copy link
Owner Author

VTE bleed: \e[?1;1S\e[?2;1S\e[?1;1S

@dankamongmen
Copy link
Owner Author

no more bleed for VTE

@dankamongmen
Copy link
Owner Author

hyper is fine

@dankamongmen
Copy link
Owner Author

contour is fine

@dankamongmen
Copy link
Owner Author

so we only have one more problem that i see: in all terminals, the intro banner is printed over, unless we're at the bottom. presumably a missing cursor location lookup in init_banner()?

@dankamongmen
Copy link
Owner Author

hrmmm. when redirected, and we then cat the redirected output, the same thing happens with 2.4.3 (which does not exhibit this behavior when not redirected). maybe this is related to #2114?

@dankamongmen
Copy link
Owner Author

got the last issue resolved. =]

@dankamongmen
Copy link
Owner Author

nope, one more problem: we're getting a stray 'u' in notcurses-demo on kitty only.

@dankamongmen
Copy link
Owner Author

ok, if i throw a sleep() in before the render in notcurses-info, and press ctrl-c, the u is printed following the ctrl-c:

2021-09-30-040208_1453x448_scrot

@dankamongmen
Copy link
Owner Author

hrmmmm it seems to be KKEYBOARD_POP...

@dankamongmen
Copy link
Owner Author

oh this is an old version of kitty (0.19.3). yeah, looks like popping the keyboard protocol results in a u in 0.19.3 (it looks like the keyboard protocol was introduced in 0.20.0):

[schwarzgerat](0) $ echo -e '\e[<u'
u
[schwarzgerat](0) $ 

@dankamongmen
Copy link
Owner Author

we should probably just refrain from emitting a KKEYBOARD_POP unless we got a response to \e[?u. We're currently sending it unconditionally.

@dankamongmen
Copy link
Owner Author

got it, fixed

dankamongmen added a commit that referenced this issue Sep 30, 2021
Unify the dynamic, dataflow special keys automaton and the static, codeflow terminal response automaton, yielding a single automaton. Add kitty keyboard support information to `notcurses-info`. Closes #2183.
@BarryHuffman
Copy link

BarryHuffman commented Oct 6, 2021

Slightly off topic but as a non-dev I enjoyed reading your thoughts on sprixels and your proposals on STEGP.

With RHEL/Canonical's focusing more on desktop, and neglecting console interfaces (removal of the TTY/Console scrollback feature being a major example), issues in KMS/DRM, undocumented lack of legacy VT options or POSIX, ect.

It's great that Notcurses is pushing the envelope, and exposing the cracks in "modern" vterminals/consoles/libraries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request input readin' dem bytes
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants