Since we mostly work with the command-line, we need our output to be more elegant. Here are the main colors you may need to do so. You can always add to this set.
class Stringdef red; colorize(self, "\e[1m\e[31m"); enddef green; colorize(self, "\e[1m\e[32m"); enddef dark_green; colorize(self, "\e[32m"); enddef yellow; colorize(self, "\e[1m\e[33m"); enddef blue; colorize(self, "\e[1m\e[34m"); enddef dark_blue; colorize(self, "\e[34m"); enddef purple; colorize(self, "\e[35m"); enddef dark_purple; colorize(self, "\e[1;35m"); enddef cyan; colorize(self, "\e[1;36m"); enddef dark_cyan; colorize(self, "\e[36m"); enddef pure; colorize(self, "\e[0m\e[28m"); enddef bold; colorize(self, "\e[1m"); enddef colorize(text, color_code) "#{color_code}#{text}\e[0m" endend
All you need is to call the color when you puts
it
puts "RubyFu".redputs "RubyFu".greenputs "RubyFu".yellow.bold
To understand this code, let's explain it with a diagram
\033 [0; 31m^ ^ ^| | || | |--------------------------------------- [The color number]| |-------------------- [The modifier] (ends with "m")|-- [Escaped character] | 0 - normal(you can use "\e") | 1 - bold| 2 - normal again| 3 - background color| 4 - underline| 5 - blinking
Or you can use an external gem called [colorized] for fancier options
gem install colorize
Then just require it in your script
require 'colorize'
It's awesome to have more flexibility in your terminal, and sometimes we need to do more with our scripts.
Overwriting console output makes our applications elegant and less noisy for repeated outputs like counting and loading progress bars.
I've read a how-to about bash Prompt cursor movement and I found it is convenient to have in our scripts. Here's what I've found so far
- Position the Cursor:\033[<L>;<C>HOr\033[<L>;<C>fputs the cursor at line L and column C.- Move the cursor up N lines:\033[<N>A- Move the cursor down N lines:\033[<N>B- Move the cursor forward N columns:\033[<N>C- Move the cursor backward N columns:\033[<N>D- Clear the screen, move to (0,0):\033[2J- Erase to end of line:\033[K- Save cursor position:\033[s- Restore cursor position:\033[u
So to test these I created the following PoC
#!/usr/bin/env ruby# KING SABRI | @KINGSABRI(1..3).map do |num|print "\rNumber: #{num}"sleep 0.5print ("\033[1B") # Move cursor down 1 line​('a'..'c').map do |char|print "\rCharacter: #{char}"print ("\e[K")sleep 0.5print ("\033[1B") # Move cursor down 1 lines​('A'..'C').map do |char1|print "\rCapital letters: #{char1}"print ("\e[K")sleep 0.3endprint ("\033[1A") # Move curse up 1 line​end​print ("\033[1A") # Move curse up 1 lineend​print ("\033[2B") # Move cursor down 2 lines​puts ""
So far so good, but why don't we make these as Ruby methods for more elegant usage? So I came up with the following
# KING SABRI | @KINGSABRIclass Stringdef mv_up(n=1)cursor(self, "\033[#{n}A")end​def mv_down(n=1)cursor(self, "\033[#{n}B")end​def mv_fw(n=1)cursor(self, "\033[#{n}C")end​def mv_bw(n=1)cursor(self, "\033[#{n}D")end​def cls_uplinecursor(self, "\e[K")end​def cls# cursor(self, "\033[2J")cursor(self, "\e[H\e[2J")end​def save_positioncursor(self, "\033[s")end​def restore_positioncursor(self, "\033[u")end​def cursor(text, position)"\r#{position}#{text}"endend
Then as a PoC, I've used the same previous PoC code (after updating String class on-the-fly in the same script)
#!/usr/bin/env ruby# KING SABRI | @KINGSABRI# Level 1(1..3).map do |num|print "\rNumber: #{num}"sleep 0.7# Level 2('a'..'c').map do |char|print "Characters: #{char}".mv_downsleep 0.5# Level 3('A'..'C').map do |char1|print "Capital: #{char1}".mv_downsleep 0.2print "".mv_upendprint "".mv_upendsleep 0.7endprint "".mv_down 3
It's much more elegant, isn't it? Say yes plz
Some application...
(1..10).each do |percent|print "#{percent*10}% complete\r"sleep(0.5)print ("\e[K") # Delete current lineendputs "Done!"
Another example
(1..5).to_a.reverse.each do |c|print "\rI'll exit after #{c} second(s)"print "\e[K"sleep 1end
Using our elegant way (after updating String class on-the-fly)
(1..5).to_a.reverse.each do |c|print "I'll exit after #{c} second".cls_uplinesleep 1endputs