-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
add Json serializable API for Buffer.ts and BufferLine.ts #2213
Conversation
Hi @JavaCS3, FYI the issue for this is #595. I had a chat with @jerch about this and we see these problems with the current approach of including it into core:
Given this, we think the best way to approach this feature is to use an addon (example /**
* Serializes terminal rows into a string that can be written back to the terminal
* to restore the state. The cursor will also be positioned to the correct cell.
* When restoring a terminal it is best to do before `Terminal.open` is called
* to avoid wasting CPU cycles rendering incomplete frames.
* @param rows The number of rows to serialize, starting from the bottom of the
* terminal. This defaults to the number of rows in the viewport.
*/
serialize(rows?: number): string; If you're unfamiliar with terminals the resulting string would look something like this This has a bunch of benefits:
Note that this would not be able to support color or other styles until we expose attributes in the API but that's something we want to do and could improve upon it at a later time. |
@JavaCS3 Many thanks for this well coded PR and your efforts ❤️. We still kinda have to disappoint you, as it does not suit our philosophy to cleanup the codebase from rarely used parts with v4 - many things will move into addons to keep the terminal core slim. Nevertheless feel free to come up with an addon as Tyriar already sketched up. |
@Tyriar Thanks for your advice. Let me try another PR. |
@Tyriar Is there anywhere I can find TTY control char table? I only know a little like: |
@JavaCS3 This is what I use https://invisible-island.net/xterm/ctlseqs/ctlseqs.html I suggest at least to start with that you assume it's the first thing done in the terminal and just print lines like normal, and just using the default color for now (if this all works we can talk about how we expose colors in the API) so you would only end up using
|
@Tyriar Sounds good |
@Tyriar How to run unittest in addons folder? I have trouble doing that. API test seems working but I don't need that currently. Please check JavaCS3@36d0354 If you have time. I add a Many thanks |
It looks like you actually want to use an integration test which are named |
Coming back to the original request of recording and replaying a terminal recording like asciinema - I've implemented something like that a couple of years ago using a technique similar to how asciinema does it. Back in that time, I've been recording the data events on the pty stream, and giving them a timestamp: // this runs in node.js
const records = [];
pty.on('data', (data) => {
records.push({ time: Date.now(), data: data.toString() })
}); Once the pty session ends, you can serialize the records, e.g.: fs.writeFileSync('/path/to/recording.js', JSON.stringify(records)); You will end up with a file very similar to what the asciinema recorder uses Once you have that file, all you need to do is to parse the records, and then write the data back to xterm.js based on the recorded time: // this code runs in the browser
// intialize xterm
const terminal = new Terminal();
// load the records from the file
const records = await fetch('/path/to/recording.js').then((res) => res.json());
// helper function to wait x ms
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// holds the last timestamp we've processed
let time;
// write records based on timing
for (let i=0; i < records.length; i++) {
let record = records[i];
if (!time) time = record.time;
await wait(record.time - time);
terminal.write(record.data);
time = record.time;
} The code above is untested and incomplete, but I hope it shows you a rough direction. |
Btw there is a very old command in linux that already does that: #> script It tees the whole pty output into a file, that can later be replayed. |
@jerch omg, that is unbelievably useful, why are you just telling me this now 😛 |
Lol its unix land, there is a handy tool for everything (well almost, cloning your grandma does not yet work). |
Your approach is mostly right. But when you need to
The performance of the first approach is not that good when you directly jump to almost the end of a terminal "video". Because you need to flush a lot of intermediate data. So my approach is the 2nd one. And I need an API to make a snapshot of a terminal. Maybe there's another solution. Besides that, maybe serialize API can serialize to HTML snapshot as well if needed. |
Yeah, the I think a better approach here would be like this:
|
@JavaCS3
Now your player only needs draw the content at a certain time with correct dimension. How it draws the content does not matter (let it be a gif, a html box, or even an mpeg). I know I asked/said this several times already - imho you need to get your goals straight, to know what you want to support and what not. E.g. if you want to be able to fully replay stuff - do as @mofux pointed out - save the pty stream with timestamps and replay everything in a full xterm.js instance. |
Hello there, I'm working on a kind of terminal recording playback tool (similar to https://github.com/asciinema/asciinema-player) with xterm.js.
I think it would be better for xterm.js to have ability to create something like a snapshot of current buffer state. And restore to any snapshot of a state. So I create this PR.
I'm glad if we can discuss about this PR.