2010-01-15 16 views
40

¿Alguna vez ha notado que si ejecuta el rake -T en rieles, la lista de descripciones de rake se trunca por el ancho de la ventana del terminal. Entonces debería haber una forma de obtenerlo en Ruby y usarlo.Cómo obtener el ancho de la ventana de terminal en Ruby

Estoy imprimiendo Ascii-art en la pantalla y no quiero que se rompa. por lo tanto, necesito averiguar el ancho de la terminal en tiempo de ejecución de alguna manera.

¿Alguna idea de cómo hacer eso?

Respuesta

43

he encontrado que en Ubuntu, ninguno de los otros métodos especificados aquí (ENV['COLUMNS'], tput columns o hirb) dan el resultado correcto si el terminal se redimensiona mientras se está ejecutando la aplicación Ruby. Esto no es un problema para los scripts, pero es un problema para las consolas interactivas, como irb.

La ruby-terminfo gem es la mejor solución que he encontrado hasta ahora para dar las dimensiones correctas después de un cambio de tamaño, pero requiere que instale una gema adicional, y es específica para unix.

el uso de la gema es simple:

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

TERMINFO utiliza internamente TIOCGWINSZ ioctl para el tamaño de la pantalla.

Por otra parte, como se ha mencionado por user83510, system_extensions de highline también funciona:

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

Interally, highline utiliza stty size en Unix, y otras implementaciones para ncurses y de Windows.

para escuchar los cambios en el tamaño del terminal (en lugar de sondeo), que pueden atrapar la señal SIGWINCH:

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

Esto es especialmente útil para aplicaciones que utilizan Readline, tales como IRB:

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

Debajo del capó ruby-terminfo está haciendo una llamada a 'ioctl' con' TIOCGWINSZ' y una estructura de 4 cortos sin firmar. Estas son las columnas, filas y x, y en píxeles. Aquí hay una esencia de esto directamente https://gist.github.com/nixpulvis/6025433. –

+0

Para cualquiera que todavía esté llegando a esta página, otra gema más liviana que hace eso es https://github.com/rking/terminal-size – DannyB

3

ENV ['COLUMNS'] le dará la cantidad de columnas en la terminal.

+0

Lo he probado en IRB e inspeccionó el hash de ENV, pero no pudo encontrar la clave de columnas –

+0

Este truco debe ser específico para algunos shells o sistemas operativos. Tampoco funcionó bajo Bash en Debian. –

+0

Interesante, funciona en OSX al menos. –

38

hay un comando común de Unix:

tput cols 

Esto devuelve el ancho de la terminal.

+0

Gracias, este está funcionando. –

+0

\ '/ usr/bin/env tput cols \' .to_i funciona muy bien para mí. – donatJ

4

Estoy un poco tarde, pero en las tareas de rake hago lo siguiente: Rake.application.terminal_width

+0

¡Gran respuesta, muchas gracias! Lo necesitaba específicamente dentro de una tarea de Rake. –

5

Ruby en realidad viene con una clase incorporada llamada "Curses", que le Usted hace todo tipo de cosas con la ventana del terminal.

Por ejemplo, se puede hacer esto:

require 'curses' 

Curses.init_screen() 

puts Curses.lines # Gives you the height of terminal window 
puts Curses.cols # Gives you the width of terminal window 

Para más información: http://ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses/Window.html

+4

Actualización: A partir de ruby ​​2.1+, las maldiciones ya no forman parte de la biblioteca estándar. Ahora se ha movido a su propia joya. Ver: https://bugs.ruby-lang.org/issues/8584 –

22
def winsize 
#Ruby 1.9.3 added 'io/console' to the standard library. 
require 'io/console' 
IO.console.winsize 
rescue LoadError 
# This works with older Ruby, but only with systems 
# that have a tput(1) command, such as Unix clones. 
[Integer(`tput li`), Integer(`tput co`)] 
end 

rows, cols = winsize 
printf "%d rows by %d columns\n", rows, cols 

Link

Cuestiones relacionadas