tty
tty copied to clipboard
Terminal dimensions
I've been trying to figure out a way to get the dimensions of the current terminal in a sensible (somewhat) cross-platform way. I thought it'd be a fairly easy thing to do and I could try submitting a PR once I have something working, but it's proving to be beyond my skill/knowledge level with OCaml and terminals in general.
However, it seems like a very common thing that people would expect to see in a library like this, so I figured it could merit some discussion at the very least?
AFAIK there's a bunch of ways it could be done, but they all have downsides:
-
CSI DSR (
\x1b[6n
) should cause a status messageESC[n;mR
to be 'printed' to STDIN. I got this kind of working[^1], but this only seems to work for certain terminals. Foot, Alacritty, URXVT and the linux console worked for me while Kitty, Wezterm, xfce-terminal and, surprisingly, xterm didnt. -
ioctl() through Ctypes works, kind of[^2], but I could not figure out a way to access
libc
constants in OCaml, so I had to hardcode the value ofTIOCGWINSZ
, so it's the furthest thing from cross platform. - A separate mini-library that just exposes a couple functions to get the terminal size. Probably the most cross-platform and easiest method, but I didn't try it because submitting a PR with a bunch of C seemed like it might not be welcome. If I'd gone with this method, I'd be tempted to do some of the terminal setup/cleanup through C as well, just because IIRC dealing with things like SIGWINCH, SIGINT etc. in OCaml is much harder(?)
- tputs and/or stty - shelling out to these seems like an easy 'cheat' but I doubt these are available on all platforms.
[^1]: with this hacky monstrosity. I had Base and Stdio opened in these experiments, in case some functions look odd. [^2]: https://gist.github.com/rchog/ac9303c0d6b4d0deb74b006534749722
CSI 6n is CPR aka Report cursor position. If you want to use an escape code to get terminal size you use CSI 14, 16 and 18 t. See https://sw.kovidgoyal.net/kitty/graphics-protocol/#getting-the-window-size and https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI--ordered-by-the-final-character_s for details.
CSI 6n is CPR aka Report cursor position. If you want to use an escape code to get terminal size you use CSI 14, 16 and 18 t. See https://sw.kovidgoyal.net/kitty/graphics-protocol/#getting-the-window-size and https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI--ordered-by-the-final-character_s for details.
Fair, I should've tried that too, though I was under the (apparently false) assumption that moving the cursor to the bottom right and using CSI 6n was the more widely supported method. But after some more experiments just now, it turns out most of the terminals I mentioned as "not working" do give the expected sequences to STDIN with either one - I just had to wait much longer for them. I may be able to hack something together after all nearer the weekend.