Цветной вывод прерывает перерисовку строк с помощью readline - PullRequest
7 голосов
/ 10 января 2012

Я работаю с раскрашиванием некоторого вывода, используя readline в Ruby, но мне не повезло, что для правильной работы переноса строк. Например:

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

Желаемый результат будет:

This prompt is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Что я на самом деле получаю:

aaaaaaaaaaa is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Если я уберу цветовые коды, перенос строк будет работать правильно. Я знаю, что с bash это может произойти, если цветовые коды некорректно завершены, но я перепробовал все, что мог придумать, включая несколько разных драгоценных камней, и поведение такое же. Это также происходит в нескольких системах с разными версиями Readline. Этот конкретный проект использует rb-readline в отличие от C readline.

Ответы [ 3 ]

20 голосов
/ 18 января 2012

Хорошо, sunkencity получает галочку, потому что я использовал большую часть его решения, но мне пришлось изменить его следующим образом:

# 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

Каждая последовательность должна быть заключена в \ 001 .. \002, чтобы Readline мог игнорировать непечатаемые символы.

6 голосов
/ 15 января 2012

Я всегда добавляю это расширение строки, когда мне нужно раскрасить строки для консоли.Кажется, проблема в вашем коде заключается в ограничителе, должен быть только один ноль "\ 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
4 голосов
/ 16 января 2012

Эта проблема не относится к ruby ​​- она ​​также возникает в bash. Если вы положили в оболочку bash

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

вы увидите тот же результат, что и выше. Но если вы введете

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

вы получите желаемый результат.

...