-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Stabilize IParser API #2607
Comments
@Tyriar Sounds good to me, also using About loose ends - well I dont like the fact that we have a hard limit on OSC/DCS, but thats not really a concern atm. If we have to support arbitrary length sequences in the future, we could always expose the chunked interfaces as well. All in all I think the API works great so far. |
Can you elaborate a little on what the limit is? @sdegutis I'm interested if you had any more feedback after playing with the API. |
@Tyriar The limit is a simple hard limit of max payload length of 10 MB. Any sequence beyond that will be silently swallowed. |
Oh hey @Tyriar and @jerch how's it goin. So my use-case was that I just wanted to create an onScreenChanged callback capture Right now I have to do this: term.parser.addCsiHandler({ prefix: '?', final: 'h' }, (params) => {
if (params.includes(1049)) {
altScreen = true;
toggledAltScreen();
}
return false;
});
term.parser.addCsiHandler({ prefix: '?', final: 'l' }, (params) => {
if (params.includes(1049)) {
altScreen = false;
toggledAltScreen();
}
return false;
}); That's fine enough I guess, but there's a couple ways it could maybe be improved:
|
This is the nicest version I can think of, for my highly specific use-case: // not sure the \? is right, forgot how JS regex works, but ignore that
term.parser.addCsiHandler({ regex: /\?1049(h|l)/ }, (match) => {
altScreen = match[1] === 'h';
toggledAltScreen();
return false;
}); |
@Tyriar VS Code's single usage would also work well with the regex approach, using |
@sdegutis Thx for the feedback. A few notes from my side:
Yes thats currently the only way to hook up something like a state change listener. But keep in mind that DECSET can freely stack param values, thus you will miss 1049 if its not the first param, e.g. About regexp: A more general note on regexp and ANSI sequences - its almost impossible to get this right. There are simply too many ifs and elses in the parsing state that you would have to pull into the regexp itself. I think all regexp based packages trying to strip sequences from data get this wrong. To correctly grab DECSET 1049 by a regexp it would look more like: /(([\x1b][\[])|[\x9b])[?][0-9;]*?1049((h|l)|(;[0-9;]+?)(h|l))/ (This is still slightly wrong but who cares, guess you get my point...) So imho regexp doesnt work here for those two reasons. |
Makes sense, thanks for the info. What about allowing params to be arbitrary number of bytes, e.g. |
Well the parser does not slice into sequences, it acts on sequences as a whole (pretty much again for perf reasons). So the parser would trigger you handler for all of these:
Ofc it would be possible to do a slicing into single params with a next step, but its simply not worth it (as I wrote above): most sequences are position aware for their params, thus cannot be sliced at all. Other like DECSET can combine the params freely and are still valid, only those could be sliced, but are simply not worth the overhead atm. Some background on this: a sequence can be seen as function provided by the terminal, where params translate into function arguments, thus
We only provide the function interface, thus you get all arguments. |
I think @sdegutis's problem could be solved with a proper example in xterm.d.ts, what he ended up landing on was how to use it correctly (though a return true might be better in the if?). |
@Tyriar Well also that the |
@Tyriar Also a return true in the if would stop xterm.js from switching buffers for me, I wanted it to still switch buffers like normal, I just wanted to capture that event and do extra stuff on top of it. |
@sdegutis oh ok, you're using it exactly the same as me then. Just listening, not touching/canceling anything 🙂 |
Yepp, could be part of the hooks cleanup and experimental remove.
Deleted (already answered 😄). |
Yep! Really everything I've been talking about in any of these threads is all working towards an "add arbitrary DOM widgets to the terminal" feature. In this thread, it's that when you start vim, then a DOM element on the main buffer needs to be hidden, and shown again when you quit vim, so I needed a hook for that. |
Personally I think |
@sdegutis sounds like buffer decorations should be bound to a particular buffer so you don't need to juggle it like that. |
@Tyriar Yeah if it were a built-in feature then that would be pretty much needed. Imagine switching to vim while any decoration is on screen. It'd have to hide until vim quits or ctrl-z (SIGTSTP), right? |
👍 moved discussion to #1852 (comment) |
Oh one thing to consider for this API: say you get |
@sdegutis Ah good catch, thats indeed a limitation currently and not possible by API means. Only way to get this behavior is to call the befault handler from the hook with just the params you want to have default actions. Hmm. |
Or why not dispatch at the moment you'd normally call a handler? Why deal with the array of codes as a whole? For example if |
Well it simply was no issue so far. Just checked xterm docs - out of 90 listed CSI commands only 14 can be stacked with no positional meaning. Currently we only implement 5 of those (and 50 in total). All others either cannot be split (due to positional meaning) or have zero/one params.
Because that would not work for commands that must not be split, thus we would have to maintain a list that separates splitables from the others, even if we dont implement that command ourselves (just in case someone wants to hook into that one). This seems rather unmaintainable to me (and the param descent would be rather ugly). To get something close to that imho an altered params list as return value is easier to go with (just drop params that you already handled, keep others for the next handler). |
Got it, thanks for the info. I'll stop with the dumb questions now :) The existing API works fine enough for me. |
There are no dumb ..., whatever - I admit the hooks interface should get better docs, its not obvious how to use it atm. |
@Tyriar To sum this up here - from my side this looks ready to get "official". Gonna address the documentation issue separately with an article about sequences and hooks on the website. |
It's currently flagged experimental:
xterm.js/typings/xterm.d.ts
Lines 418 to 422 in bd0d267
@jerch any concerns about calling this stable? Any more tweaks in mind?
Not sure how many users there are but here's VS Code's single usage which seems to work well:
https://github.com/microsoft/vscode/blob/1beea2f864c1f403ab225dbadfdc398d76faef94/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts#L499-L505
My only thought is we should think about the verb (add, register, etc.) and figure out where we want to go. I think
add
feels a little strange without aremove
, VS Code usesregister
for providers/handlers/factories:The text was updated successfully, but these errors were encountered: