How to Get the Width of Terminal Window in Ruby

How to get the width of terminal window in Ruby

I've found that on Ubuntu, none of the other methods specified here (ENV['COLUMNS'], tput columns or hirb) give the correct result if the terminal is resized while the Ruby application is running. This is not an issue for scripts, but it is an issue for interactive consoles, such as irb.

The ruby-terminfo gem is the best solution I've find so far to give the correct dimensions after a resize, but it requires that you install an additional gem, and is unix-specific.

The gem's usage is simple:

require 'terminfo'
p TermInfo.screen_size # [lines, columns]

TermInfo internally uses TIOCGWINSZ ioctl for the screen size.

Alternatively, as mentioned by user83510, highline's system_extensions also works:

require 'highline'
HighLine::SystemExtensions.terminal_size # [columns, lines]

Interally, highline uses stty size on Unix, and other implementations for ncurses and Windows.

To listen for changes to the terminal size (instead of polling), we can trap the SIGWINCH signal:

require 'terminfo'
Signal.trap('SIGWINCH', proc { puts TermInfo.screen_size.inspect })

This is specifically useful for applications using Readline, such as irb:

Signal.trap('SIGWINCH', proc { Readline.set_screen_size(TermInfo.screen_size[0], TermInfo.screen_size[1]) })

How do I find the width & height of a terminal window?

  • tput cols tells you the number of columns.
  • tput lines tells you the number of rows.

How does one determine console character width from ruby program?

The HighLine gem uses this function to find the dimensions of a terminal:

  # A Windows savvy method to fetch the console columns, and rows.
def terminal_size
stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE)

bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy =
GetConsoleScreenBufferInfo(stdout_handle)
return right - left + 1, bottom - top + 1
end

This method should work also on Windows, if you use Linux (or something similar) only then you can use stty size to find the dimensions more easily using something like:

def terminal_size
`stty size`.split.map { |x| x.to_i }.reverse
end

How can I increase the size of the console inside the code

Assuming you're targeting Windows:

  • Use GetLargestConsoleWindowSize to retrieve the largest possible console size depending on the console font and display settings,

  • Use SetConsoleScreenBufferSize to set the console screen buffer to the largest possible size,

  • Use SetConsoleWindowInfo to set the size and position of the console's window, so that no scrollbars would be visible by default etc..

At this point the console's window should be positioned as you've set. With my tests, however, while the window complies with the sizing request, the position is ignored.

In that case use any API function to move the window, the below examples uses SetWindowPos. I had to declare GetConsoleWindow as it was not declared in Lazarus 1.6.


program Project1;

{$APPTYPE CONSOLE}

uses
windows;

function GetConsoleWindow: HWND; stdcall external 'kernel32';

var
Con: THandle;
Size: TCoord;
Rect: TSmallRect;
Wnd: HWND;
begin
Con := GetStdHandle(STD_OUTPUT_HANDLE);
Size := GetLargestConsoleWindowSize(Con);

SetConsoleScreenBufferSize(Con, Size);

Rect.Left := -10;
Rect.Top := -10;
Rect.Right := Size.X - 11;
Rect.Bottom := Size.Y - 11;
SetConsoleWindowInfo(Con, True, Rect);

Wnd := GetConsoleWindow;
SetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);

Readln;
end.


And don't forget to add error checking.

How might the usable width and height of a tty terminal be set to less than the display dimensions?

The numbers of rows and columns used can be set using a command like the following:

stty cols 72 rows 25


Related Topics



Leave a reply



Submit