class Terminal class Size; VERSION = '0.0.6'.freeze end class << self def size size_via_low_level_ioctl or size_via_stty or nil end def size! size or _height_width_hash_from 25, 80 end # These are experimental def resize(direction, magnitude) tmux 'resize-pane', "-#{direction}", magnitude end def tmux *cmd system 'tmux', *cmd.map(&:to_s) end IOCTL_INPUT_BUF = "\x00" * 8 def size_via_low_level_ioctl # Thanks to runpaint for the general approach to this return unless $stdin.respond_to? :ioctl code = tiocgwinsz_value_for RUBY_PLATFORM return unless code buf = IOCTL_INPUT_BUF.dup return if $stdout.ioctl(code, buf) != 0 return if buf == IOCTL_INPUT_BUF got = buf.unpack('S4')[0..1] _height_width_hash_from(*got) rescue StandardError nil end def tiocgwinsz_value_for(platform) # This is as reported by # Hard-coding because it seems like overkll to acutally involve C for this. { /linux/ => 0x5413, /darwin/ => 0x40087468 # thanks to brandon@brandon.io for the lookup! }.find { |k, _v| platform[k] } end def size_via_stty ints = `stty size`.scan(/\d+/).map(&:to_i) _height_width_hash_from(*ints) rescue StandardError nil end private def _height_width_hash_from *dimensions { height: dimensions[0], width: dimensions[1] } end end end