#How to get remaining bytes in a stream
1 messages · Page 1 of 1 (latest)
Hi, how do I get the remaining bytes from a stream? I have a reader which I setup like so:
reader = std.Io.File.stdin().reader(io, readerBuffer)
The issue is I'm operating the terminal in raw mode and when I use arrow keys it sends it in multiple bytes using control sequences.
It doesn't have a delimiter, so is there a way to just read any bytes in that buffer and flush immediately?
I already tried using allocRemaining but that seems to just infinitely ask for input until the user actually types till the limit.
I just need something to get and clear out the multiple bytes that come from control sequence characters like \x1b[A and what not
when not piping into stdin, then it has not end, hence why it loops forever.
the control sequences are well defined, so you should be able to tell when you are at the end and therefore when to stop reading.
you probably want to read as much as available into a buffer large enough to hold a whole sequence or multiple, to minimise the actual syscalls.
that could either be the interfaces buffer via take/peek/fill family of functions, or a seperate one via readVec (unfortunately no other read* function will read less than the buffer length, excluding end of stream ofc)
Thanks. I'll just manually check then if I'm parsing an escape code
I'm doing a TUI, so I want to be able to get character by character
instead of deleting it, react to it with ✅ to mark it as answered
I should have said that instead of grumbling
What about ESC? If I just press ESC and nothing else, the peek will wait for input instead. How do I get around this?
Are you sure your terminal is in raw mode?
And also, are you sure that the terminal "app" you are using is sending the ESC to your program?
unless something else is grabbing /handling the esc key you should be seeing the code for esc. it's 127 or something similar i think. i had a project from last year where i was parsing the keycodes
Not all terminals handle "special" keys the same way. It really depends on operating system and env settings.
Sorry for the late response
@charred girder @covert cosmos the issue is that yes, escape gets pressed, but escape is also the first byte when pressing certain keys such as the arrow keys, f1-12 etc.
I try to peek at the next byte when ESC is seen and that works for special keys because there's extra bytes after that, but if the user presses the actual ESC key then there are no extra bytes after it and doing a peek makes it wait for user input
The buffer in Zig's reader has nothing else either. It only seems to hold one byte at a time when using takeByte() with stdout
Have you tried a different terminal? For me ghostty and iterm send different codes for some keys. (Im not saying I know the answer, its just the first thing I would try)
Yes, I tried alacritty and xterm and the same behaviour occurs on both. I'm unsure if they're the same keys, but it's the same mechanism by first sending a ESC byte and then extra stuff after
If you work out out, please let us know. I don't use 'esc' in my terminal code, but it sounds like sometihing one day I'd want to do.
I try to peek at the next byte when ESC is seen and that works for special keys because there's extra bytes after that, but if the user presses the actual ESC key then there are no extra bytes after it and doing a peek makes it wait for user input
Thats a major problem with the default encoding schemes there are cases where you can't even distinguish for example tab and ctrl+i send the exact same sequence to the application
its why protocols like fixterms and kitty keyboard protocol exist, which change how these conflicts work
A library like vaxis or other tui libraries will likely help you, parsing terminal input is not the easiest thing to get right.
https://github.com/rockorager/libvaxis/blob/main/src/Key.zig
https://github.com/rockorager/libvaxis/blob/main/src/tty.zig#L118-L120