2012-01-10 9 views
6

estoy trabajando con algunos colorear salida usando readline en Ruby, pero no estoy teniendo suerte conseguir el ajuste de línea funcione correctamente. Por ejemplo:rompe la salida colorizada linewrapping con readline

"\e[01;32mThis prompt is green and bold\e[00m > " 

El resultado deseado sería:

This prompt is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 

Lo que en realidad me da es:

aaaaaaaaaaa is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 

Si quito los códigos de color, ajuste de línea funciona correctamente. Sé con bash, esto puede suceder si los códigos de color están incorrectamente terminados, pero he intentado todo lo que puedo pensar, incluidas algunas gemas diferentes, y el comportamiento es el mismo. También ocurre en múltiples sistemas con diferentes versiones de Readline. Este proyecto en particular está usando rb-readline en comparación con C readline.

+1

¿Ha intentado utilizar https://rubygems.org/gems/colored el color de su salida? – Maher4Ever

+0

Sí, lo intenté y coloreé. La salida funciona bien, pero cuando se usa con un indicador de lectura, se rompe el ajuste de línea. – Eugene

Respuesta

5

siempre que lanzo esta extensión de cadena en cuando necesito para colorear cadenas para la consola. El problema en su código parece ser el terminador, debería haber solo un cero "\ e [0m".

# encoding: utf-8 
class String 
    def console_red;   colorize(self, "\e[1m\e[31m"); end 
    def console_dark_red;  colorize(self, "\e[31m");  end 
    def console_green;  colorize(self, "\e[1m\e[32m"); end 
    def console_dark_green; colorize(self, "\e[32m");  end 
    def console_yellow;  colorize(self, "\e[1m\e[33m"); end 
    def console_dark_yellow; colorize(self, "\e[33m");  end 
    def console_blue;   colorize(self, "\e[1m\e[34m"); end 
    def console_dark_blue; colorize(self, "\e[34m");  end 
    def console_purple;  colorize(self, "\e[1m\e[35m"); end 

    def console_def;   colorize(self, "\e[1m"); end 
    def console_bold;   colorize(self, "\e[1m"); end 
    def console_blink;  colorize(self, "\e[5m"); end 

    def colorize(text, color_code) "#{color_code}#{text}\e[0m" end 
end 

puts "foo\nbar".console_dark_red 
+0

Gracias. 2 0s o 1, no importa, hace lo mismo. Esto parece un error en readline para mí. – Eugene

+0

Hm, tiene "\ e [01; 32m" al principio Tengo "\ e [1m \ e [32m". – sunkencity

+0

Pedido esto: http://hintsforums.macworld.com/showthread.php?t=17068 Aparentemente se puede añadir escapa extra para conseguir la cáscara de ignorar los códigos de color para el cálculo de la longitud de línea. – sunkencity

3

Este problema no es específico de ruby: también ocurre en bash. Si coloca un shell bash

PS1="\e[01;32mThis prompt is green and bold\e[00m > " 

verá el mismo resultado que el anterior. Pero si pone en

PS1="\[\e[01;32m\]This prompt is green and bold\[\e[00m\] > " 

obtendrá el resultado que deseaba.

+0

Por cierto, si usted es curioso en cuanto a cómo funciona esto: Parece que \\ [bla \\] le dice a bash/readline/lo que sea que, a los efectos de estimar el número de caracteres en la línea, usted debe ignorar cualquier cosa entre \\ [y \\]. Para un terminal dado, la cantidad de caracteres en una línea es adivinada/calculada/estimada, y solo se desplaza a la siguiente línea una vez que se han llenado todos los caracteres no ignorados. – user208769

+0

Acepto que esta debería ser la solución, pero cuando hago esto, mi salida se convierte en esto: "[] Este mensaje es verde y negrita []>" y el ajuste de línea sigue siendo un problema. Esto se puede probar con el script de prueba simple aquí: https: //gist.github.com/1622119 – Eugene

+4

"Los bash-specific \ [y \] de hecho se traducen a \ 001 y \ 002 ..." - [respuesta de SuperUser] (http://superuser.com/questions/301353/escape- non-printing-characters-in-a-function-for-a-bash-prompt). –

18

Ok, sunkencity obtiene la marca de verificación, ya que terminé usando la mayor parte de su solución, pero tuve que modificarlo de la siguiente manera:

# encoding: utf-8 
class String 
    def console_red;   colorize(self, "\001\e[1m\e[31m\002"); end 
    def console_dark_red;  colorize(self, "\001\e[31m\002");  end 
    def console_green;  colorize(self, "\001\e[1m\e[32m\002"); end 
    def console_dark_green; colorize(self, "\001\e[32m\002");  end 
    def console_yellow;  colorize(self, "\001\e[1m\e[33m\002"); end 
    def console_dark_yellow; colorize(self, "\001\e[33m\002");  end 
    def console_blue;   colorize(self, "\001\e[1m\e[34m\002"); end 
    def console_dark_blue; colorize(self, "\001\e[34m\002");  end 
    def console_purple;  colorize(self, "\001\e[1m\e[35m\002"); end 

    def console_def;   colorize(self, "\001\e[1m\002"); end 
    def console_bold;   colorize(self, "\001\e[1m\002"); end 
    def console_blink;  colorize(self, "\001\e[5m\002"); end 

    def colorize(text, color_code) "#{color_code}#{text}\001\e[0m\002" end 
end 

Cada secuencia tiene que ser envuelto en \ 001 .. \ 002 para que Readline sepa ignorar los caracteres que no se imprimen.

+0

Excelente, gracias! Se corrigió un problema con el prompt de Pry a través de https://github.com/pry/pry/issues/493#issuecomment-8799007 –

Cuestiones relacionadas