Skip to content

Instantly share code, notes, and snippets.

@bitmand
Last active December 21, 2025 10:35
Show Gist options
  • Select an option

  • Save bitmand/bedac6c5091af5e8ccb68ca23b72f6e1 to your computer and use it in GitHub Desktop.

Select an option

Save bitmand/bedac6c5091af5e8ccb68ca23b72f6e1 to your computer and use it in GitHub Desktop.
Terminal size and resize in Crystal
# Crystal forum thread about terminal size
# https://forum.crystal-lang.org/t/how-to-get-the-width-of-the-terminal/5621/6
#
# Prints the terminal size at startup and again if terminal is resized
#
# $ crystal run term-size.cr
# LibC::TTYSize(@lines=25, @cols=222, @xpixel=3552, @ypixel=1000)
# LibC::TTYSize(@lines=24, @cols=222, @xpixel=3552, @ypixel=960)
# LibC::TTYSize(@lines=22, @cols=222, @xpixel=3552, @ypixel=880)
# LibC::TTYSize(@lines=21, @cols=222, @xpixel=3552, @ypixel=840)
# LibC::TTYSize(@lines=19, @cols=222, @xpixel=3552, @ypixel=760)
# LibC::TTYSize(@lines=22, @cols=222, @xpixel=3552, @ypixel=880)
#
lib LibC
{% if flag?(:linux) %}
TIOCGWINSZ = 0x5413u32 # Linux
{% elsif flag?(:darwin) || flag?(:bsd) %}
TIOCGWINSZ = 0x40087468u32 # BSDs and MacOS
{% else %}
TIOCGWINSZ = 0x5468 # Solaris
{% end %}
fun ioctl(fd : LibC::Int, request : LibC::ULong, ...) : LibC::Int
struct TTYSize
lines : UInt16
cols : UInt16
xpixel : UInt16
ypixel : UInt16
end
end
def tty_size
size = LibC::TTYSize.new
LibC.ioctl(STDERR.fd, LibC::TIOCGWINSZ, pointerof(size)).zero? || raise "ioctl failed"
size
end
# print terminal size
puts tty_size.inspect
# catch WINCH signal and print new terminal size
Signal::WINCH.trap do
puts tty_size.inspect
end
sleep 15.seconds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment