ruby - significado - terminal dpd
Salida de progreso en el lugar en el terminal o consola (5)
Cuando ejecuta git clone
, actualiza el progreso en su lugar. Por ejemplo, el porcentaje de los objetos recibidos cambia en su lugar.
user@athena:~/cloj/src$ git clone git://git.boinkor.net/slime.git
Initialized empty Git repository in /home/user/cloj/src/slime/.git/
remote: Counting objects: 15936, done.
remote: Compressing objects: 100% (5500/5500), done.
Receiving objects: 28% (4547/15936), 3.16 MiB | 165 KiB/s
¿Cómo se logra esto? ¿Utiliza ncurses o algo aún más simple, como alguna combinación de caracteres de retroceso y salida de caracteres regulares?
Estoy especialmente interesado en cómo se podría lograr este tipo de salida de consola de Ruby.
EDITAR
Mi pregunta original fue respondida. Pero aquí hay un apéndice. Cuando utiliza MPlayer, por ejemplo, no solo actualiza una línea para mostrar el progreso actual, sino también la línea anterior (por ejemplo, cuando presiona pausa).
===== PAUSE =====
A: 79.9 (01:19.9) of 4718.0 ( 1:18:38.0) 0.3%
¿Cómo actualizarías dos líneas de salida en el lugar?
Hay una serie de librbaries de maldiciones para Ruby. Creo que rbbcurse es el más mantenido.
Use el retorno de carro. ''/ r'' generalmente debería funcionar.
...
eol = done ? done : " /r";
...
fprintf(stderr, "...%s", ..., eol);
fflush(stderr);
Git simplemente emite un retorno de carro y sin alimentación de línea, que el terminal interpreta como "mover a la primera columna".
Escribí una pequeña clase para la actualización de salida multilínea:
class ConsoleReset
# Unix
# Contains a string to clear the line in the shell
CLR = "/e[0K"
# ANSI escape sequence for hiding terminal cursor
ESC_CURS_INVIS = "/e[?25l"
# ANSI escape sequence for showing terminal cursor
ESC_CURS_VIS = "/e[?25h"
# ANSI escape sequence for clearing line in terminal
ESC_R_AND_CLR = "/r#{CLR}"
# ANSI escape sequence for going up a line in terminal
ESC_UP_A_LINE = "/e[1A"
def initialize
@first_call = true
end
def reset_line(text = '''')
# Initialise ANSI escape string
escape = ""
# The number of lines the previous message spanned
lines = text.strip.lines.count - 1
# Clear and go up a line
lines.times { escape += "#{ESC_R_AND_CLR}#{ESC_UP_A_LINE}" }
# Clear the line that is to be printed on
# escape += "#{ESC_R_AND_CLR}"
# Console is clear, we can print!
STDOUT.print escape if !@first_call
@first_call = false
print text
end
def hide_cursor
STDOUT.print(ESC_CURS_INVIS)
end
def show_cursor
STDOUT.print(ESC_CURS_VIS)
end
def test
hide_cursor
5.times do |i|
line = [''==========================================='']
(1..10).each do |num|
line << ["#{num}:/t#{rand_num}"]
end
line << [''==========================================='']
line = line.join("/n")
reset_line(line)
sleep 1
end
show_cursor
puts ''''
end
private
def rand_num
rand(10 ** rand(10))
end
end
Inspirado por prydonius/spinning_cursor
. Ver el método de test
, por ejemplo, el uso.
Tendrás que usar otro método (como Curses) para actualizar dos líneas en el lugar.
ablogaboutcode.com | web.archive.org
...y...
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html