Getting the size of the terminal in a portable way

G

Greg Hurrell

I'd like to be able to determine the width of the terminal in which my
command-line tool is running.

I made a quick program to find out the value of TIOCGWINSZ on my
system (Mac OS X 10.4.8, running on Intel):

#include <sys/ioctl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
printf("%d\n", TIOCGWINSZ);
return 0;
}

The value is 1074295912 (0x40087468). Then I used the following Ruby
code based on something I found in the archives:

TIOCGWINSZ = 0x40087468
str = [0, 0, 0, 0].pack('SSSS')
if STDIN.ioctl(TIOCGWINSZ, str) >= 0
rows, cols, xpixels, ypixels = str.unpack("SSSS")
p rows, cols, xpixels, ypixels
else
puts "Unable to get window size"
end

This returns the correct values:

[55, 132, 792, 770]

That is, 55 rows, 132 columns. I'd like to know if there's a more
portable way of doing this... About the only semi-portable way I can
think of is wrapping this up in a C extension; at least that way
(most) people can compile it locally. Suggestions?

Cheers,
Greg
 
J

James Edward Gray II

I'd like to be able to determine the width of the terminal in which my
command-line tool is running.

I made a quick program to find out the value of TIOCGWINSZ on my
system (Mac OS X 10.4.8, running on Intel):

#include <sys/ioctl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
printf("%d\n", TIOCGWINSZ);
return 0;
}

The value is 1074295912 (0x40087468). Then I used the following Ruby
code based on something I found in the archives:

TIOCGWINSZ = 0x40087468
str = [0, 0, 0, 0].pack('SSSS')
if STDIN.ioctl(TIOCGWINSZ, str) >= 0
rows, cols, xpixels, ypixels = str.unpack("SSSS")
p rows, cols, xpixels, ypixels
else
puts "Unable to get window size"
end

This returns the correct values:

[55, 132, 792, 770]

That is, 55 rows, 132 columns. I'd like to know if there's a more
portable way of doing this... About the only semi-portable way I can
think of is wrapping this up in a C extension; at least that way
(most) people can compile it locally. Suggestions?

HighLine can do this:

require "highline/system_extensions.rb"
cols, rows = HighLine::SystemExtensions.terminal_size

Hope that helps.

James Edward Gray II
 
G

Greg Hurrell

HighLine can do this:

require "highline/system_extensions.rb"
cols, rows = HighLine::SystemExtensions.terminal_size

Thanks, James. That seems to cover just about all platforms, although
it introduces another dependency or two (HighLine itself, plus
HighLine's own dependencies). I guess that's the way it is though...

Cheers,
Greg
 
E

Ezra Zygmuntowicz

Thanks, James. That seems to cover just about all platforms, although
it introduces another dependency or two (HighLine itself, plus
HighLine's own dependencies). I guess that's the way it is though...

Cheers,
Greg

I use highline in a bunch of internal projects for CLI gui's, it
totally rocks(thx JEGII&Gregory!). But I want these to be standalone
gems with no dependencies so I embed highline in my own gems. Its
only a few files and easy to embed so it makes sense to ship it with
the gem that needs it.


Cheers-

-- Ezra Zygmuntowicz
-- Lead Rails Evangelist
-- (e-mail address removed)
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top