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

Terminal dimensions #6

Open
rchog opened this issue Mar 24, 2024 · 3 comments
Open

Terminal dimensions #6

rchog opened this issue Mar 24, 2024 · 3 comments

Comments

@rchog
Copy link

rchog commented Mar 24, 2024

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 message ESC[n;mR to be 'printed' to STDIN. I got this kind of working1, 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 of2, but I could not figure out a way to access libc constants in OCaml, so I had to hardcode the value of TIOCGWINSZ, 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.

Footnotes

  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

Copy link

linear bot commented Mar 24, 2024

@kovidgoyal
Copy link

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.

@rchog
Copy link
Author

rchog commented Mar 26, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants