Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Colorized output breaks linewrapping with readline

Tags:

ruby

readline

I'm working with colorizing some output using readline in Ruby, but I am not having any luck getting line wrapping to work properly. For example:

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

The desired result would be:

This prompt is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

What I actually get is:

aaaaaaaaaaa is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

If I remove the color codes, line wrapping works correctly. I know with bash, this can happen if the color codes are incorrectly terminated, but I have tried everything I can think of, including a few different gems, and the behavior is the same. It also occurs on multiple systems with different versions of Readline. This particular project is using rb-readline as opposed to C readline.

like image 350
Eugene Avatar asked Jan 10 '12 16:01

Eugene


1 Answers

Ok, sunkencity gets the check mark because I ended up using most of his solution, but I had to modify it as follows:

# 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

Each sequence needs to be wrapped in \001..\002 so that Readline knows to ignore non printing characters.

like image 110
Eugene Avatar answered Sep 23 '22 03:09

Eugene