Module: Console
- Defined in:
- lib/color_console/console.rb,
lib/color_console/table.rb,
lib/color_console/progress.rb,
lib/color_console/log4r_logger.rb,
lib/color_console/platform/ansi.rb,
lib/color_console/java_util_logger.rb,
lib/color_console/platform/windows.rb,
lib/color_console/platform/windows_ffi.rb,
lib/color_console/platform/windows_fiddle.rb
Overview
A module for using our color console for log output with the java.util.logging log framework.
Defined Under Namespace
Modules: JavaUtilLogger, Log4rLogger, Windows
Constant Summary collapse
- FOREGROUND_COLORS =
Constants for foreground and background colors
{ black: 0, blue: BLUE | INTENSITY, dark_blue: BLUE, light_blue: BLUE | INTENSITY, cyan: BLUE | GREEN | INTENSITY, green: GREEN, dark_green: GREEN, light_green: GREEN | INTENSITY, red: RED | INTENSITY, dark_red: RED, light_red: RED | INTENSITY, magenta: RED | BLUE, dark_magenta: RED | BLUE, light_magenta: RED | BLUE | INTENSITY, yellow: GREEN | RED | INTENSITY, gray: BLUE | GREEN | RED, dark_gray: INTENSITY, light_gray: BLUE | GREEN | RED, white: BLUE | GREEN | RED | INTENSITY }
- BACKGROUND_COLORS =
{}
- BLUE =
Constants for colour components
0x1
- GREEN =
0x2
- RED =
0x4
- INTENSITY =
0x8
Class Method Summary collapse
-
._calculate_widths(rows, col_count, avail_width) ⇒ Object
Calculates the widths to use to display a table of data.
-
._clear_line(lines = 1) ⇒ Object
Clears the current line.
-
._display_row(row, widths, opts = {}) ⇒ Object
Displays a single
row
of data within columns ofwidths
width. -
._output_row_sep(widths, opts) ⇒ Object
Outputs a row separator line.
-
._puts(text = nil, fg = nil, bg = nil) ⇒ Object
Send a line of text to the screen, terminating with a new-line.
-
._window_size ⇒ Array?
Get the current console window size.
-
._write(text, fg = nil, bg = nil) ⇒ Object
Write a line of text to the console, with optional foreground and background colors.
-
.clear_progress ⇒ Object
Clears any currently displayed progress bar or status message.
-
.clear_status ⇒ Object
Clears any currently displayed progress bar or status message.
-
.display_row(row, widths, opts = {}) ⇒ Object
Displays a single
row
of data within columns ofwidths
width. -
.display_table(rows, opts = {}) ⇒ Object
Displays an array of arrays as a table of data.
-
.height ⇒ Object
Returns the height of the console window.
-
.puts(text = nil, fg = nil, bg = nil) ⇒ Object
Send a line of text to the screen, terminating with a new-line.
-
.replace_console_logger(options = {}) ⇒ Object
Removes any existing console handler, and adds a ColorConsoleHandler.
-
.show_progress(label, complete, opts = {}) ⇒ Object
Displays a progress bar as the current status line.
-
.status(msg, opts = {}) ⇒ Object
Sets text to be displayed temporarily on the current line.
-
.title=(text) ⇒ Object
Sets the title bar text of the console window.
-
.width ⇒ Object
Returns the width of the console window.
-
.wrap_text(text, width) ⇒ Array
Utility method for wrapping lines of
text
atwidth
characters. -
.write(text, fg = nil, bg = nil) ⇒ Object
Writes a partital line of text to the console, with optional foreground and background colors.
Class Method Details
._calculate_widths(rows, col_count, avail_width) ⇒ Object
Calculates the widths to use to display a table of data.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/color_console/table.rb', line 73 def _calculate_widths(rows, col_count, avail_width) max_widths = Array.new(col_count) rows.each do |row| row.each_with_index do |col, i| max_widths[i] = col.to_s.length if !max_widths[i] || col.to_s.length > max_widths[i] end end max_width = max_widths.reduce(0, &:+) while avail_width < max_width # Reduce longest width(s) to next longest longest = max_widths.max num_longest = max_widths.count{ |w| w == longest } next_longest = max_widths.select{ |w| w < longest }.max if !next_longest || (num_longest * (longest - next_longest) > max_width - avail_width) reduction = (max_width - avail_width) / num_longest reduction = 1 if reduction <= 0 if !next_longest max_widths.map!{ |w| w - reduction } else max_widths.map!{ |w| w > next_longest ? w - reduction : w } end else max_widths.map!{ |w| w > next_longest ? next_longest : w } end max_width = max_widths.reduce(0, &:+) end max_widths end |
._clear_line(lines = 1) ⇒ Object
Clears the current line
129 130 131 132 133 134 135 136 |
# File 'lib/color_console/platform/ansi.rb', line 129 def _clear_line(lines = 1) raise ArgumentError, "Number of lines to clear (#{lines}) must be > 0" if lines < 1 while lines > 0 STDOUT.write "\r\e[2K" lines -= 1 STDOUT.write "\e[A" if lines > 0 end end |
._display_row(row, widths, opts = {}) ⇒ Object
Displays a single row
of data within columns of widths
width. If the contents of a cell exceeds the available width, it is wrapped, and the row is displayed over multiple lines.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/color_console/table.rb', line 107 def _display_row(row, widths, opts = {}) fg = opts.fetch(:text_color, opts.fetch(:color, :cyan)) bg = opts[:background_color] indent = opts.fetch(:indent, 0) col_sep = opts[:col_sep] row_sep = opts[:row_sep] line_count = 0 lines = row.each_with_index.map do |col, i| cell_lines = wrap_text(col, widths[i]) line_count = cell_lines.size if cell_lines.size > line_count cell_lines end (0...line_count).each do |i| _write(' ' * indent) _write("#{col_sep} ", fg, bg) if col_sep line = (0...widths.size).map do |col| "%#{row[col].is_a?(Numeric) ? '' : '-'}#{widths[col]}s" % (lines[col] && lines[col][i]) end.join(" #{col_sep} ") _write(line, fg, bg) _write(" #{col_sep}", fg, bg) if col_sep _puts end _output_row_sep(widths, opts) if row_sep end |
._output_row_sep(widths, opts) ⇒ Object
Outputs a row separator line
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/color_console/table.rb', line 137 def _output_row_sep(widths, opts) fg = opts.fetch(:text_color, opts.fetch(:color, :cyan)) bg = opts[:background_color] indent = opts.fetch(:indent, 0) col_sep = opts[:col_sep] row_sep = opts[:row_sep] corner = opts.fetch(:corner, col_sep ? '+' * col_sep.length : '') sep_row = widths.map{ |width| row_sep * (width + 2) } _write(' ' * indent) _write(corner, fg, bg) _write(sep_row.join(corner), fg, bg) _write(corner, fg, bg) _puts end |
._puts(text = nil, fg = nil, bg = nil) ⇒ Object
Send a line of text to the screen, terminating with a new-line.
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/color_console/platform/ansi.rb', line 111 def _puts(text = nil, fg = nil, bg = nil) if @status_displayed _clear_line((@status.length / self.width) + 1) @status_displayed = false end _write("#{text}", fg, bg) STDOUT.write "\n" if @status _write @status, @status_fg, @status_bg @status_displayed = true end end |
._window_size ⇒ Array?
Get the current console window size.
62 63 64 65 66 67 68 69 |
# File 'lib/color_console/platform/ansi.rb', line 62 def _window_size unless @window_size rows = `tput lines` cols = `tput cols` @window_size = [cols.chomp.to_i, rows.chomp.to_i] end @window_size end |
._write(text, fg = nil, bg = nil) ⇒ Object
Write a line of text to the console, with optional foreground and background colors.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/color_console/platform/ansi.rb', line 79 def _write(text, fg = nil, bg = nil) if @status_displayed _clear_line((@status.length / self.width) + 1) @status_displayed = false end if fg || bg reset = true if fg fg_code = FOREGROUND_COLORS[fg] || fg STDOUT.write "\e[#{fg_code}m" end if bg bg_code = BACKGROUND_COLORS[bg] || bg STDOUT.write "\e[#{bg_code}m" end end STDOUT.write text if reset STDOUT.write "\e[0m" end end |
.clear_progress ⇒ Object
Clears any currently displayed progress bar or status message.
66 67 68 |
# File 'lib/color_console/progress.rb', line 66 def clear_progress self.status nil end |
.clear_status ⇒ Object
Clears any currently displayed progress bar or status message.
69 70 71 |
# File 'lib/color_console/progress.rb', line 69 def clear_progress self.status nil end |
.display_row(row, widths, opts = {}) ⇒ Object
Displays a single row
of data within columns of widths
width. If the contents of a cell exceeds the available width, it is wrapped, and the row is displayed over multiple lines.
60 61 62 63 64 65 |
# File 'lib/color_console/table.rb', line 60 def display_row(row, widths, opts = {}) return unless row && row.size > 0 @lock.synchronize do _display_row(row, widths, opts) end end |
.display_table(rows, opts = {}) ⇒ Object
Displays an array of arrays as a table of data. The content of each row is aligned and wrapped if necessary to fit the column widths.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/color_console/table.rb', line 30 def display_table(rows, opts = {}) return unless rows && rows.size > 0 && rows.first.size > 0 col_widths = opts[:col_widths] unless col_widths col_count = rows.first.size avail_width = (opts[:width] || ((width || 10000) - opts.fetch(:indent, 0))) - (" #{opts[:col_sep]} ".length * col_count) col_widths = _calculate_widths(rows, col_count, avail_width - 1) end @lock.synchronize do _output_row_sep(col_widths, opts) if opts[:row_sep] rows.each do |row| _display_row(row, col_widths, opts) end end end |
.height ⇒ Object
Returns the height of the console window
40 41 42 43 |
# File 'lib/color_console/console.rb', line 40 def height sz = _window_size sz && sz.last end |
.puts(text = nil, fg = nil, bg = nil) ⇒ Object
Send a line of text to the screen, terminating with a new-line.
70 71 72 73 74 |
# File 'lib/color_console/console.rb', line 70 def puts(text = nil, fg = nil, bg = nil) @lock.synchronize do _puts(text, fg, bg) end end |
.replace_console_logger(options = {}) ⇒ Object
Removes any existing console handler, and adds a ColorConsoleHandler.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/color_console/log4r_logger.rb', line 88 def replace_console_logger( = {}) logger = [:logger] name = .fetch(:outputter, 'color-console') level = case .delete(:level) when String, Symbol then Log4r::LNAMES.index([:level].to_s.upcase) end STDOUT.puts level # Remove any existing console handler log = logger ? Log4r::Logger[logger] : Log4r::Logger.root log = Log4r::Logger.new(logger) unless log log.outputters.each do |o| log.remove(o.name) if h.is_a?(Log4r::StdoutOutputter) end # Add a ColorConsoleHandler out = Log4rLogger::ColorConsoleOutputter.new(name, ) log.add out # Set the log level log.level = level if level end |
.show_progress(label, complete, opts = {}) ⇒ Object
Displays a progress bar as the current status line. The status line is a partial line of text printed at the current scroll location, and which can be updated or cleared.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/color_console/progress.rb', line 46 def show_progress(label, complete, opts = {}) if self.width opts = {total: opts} if opts.is_a?(Fixnum) total = opts.fetch(:total, 100) complete = total if complete > total = opts.fetch(:bar_length, 40) completion = complete * / total pct = "#{complete * 100 / total}%" = "#{'=' * completion}#{' ' * ( - completion)}" [( - pct.length) / 2, pct.length] = pct if @completed.nil? || pct != @completed self.status("[#{}] #{label}", opts) @completed = pct end end end |
.status(msg, opts = {}) ⇒ Object
Sets text to be displayed temporarily on the current line. Status text can be updated or cleared.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/color_console/progress.rb', line 13 def status(msg, opts = {}) if self.width @lock.synchronize do if @status_displayed # Clear existing status _clear_line((@status.length / self.width) + 1) @status_displayed = false end @completed = nil @status = msg if @status @status_fg = opts.fetch(:text_color, opts.fetch(:color, :cyan)) @status_bg = opts[:background_color] _write @status, @status_fg, @status_bg @status_displayed = true end end end end |
.title=(text) ⇒ Object
Sets the title bar text of the console window.
49 50 51 |
# File 'lib/color_console/platform/ansi.rb', line 49 def title=(text) STDOUT.write "\e]0;#{text}\007" end |
.width ⇒ Object
Returns the width of the console window
30 31 32 33 |
# File 'lib/color_console/console.rb', line 30 def width sz = _window_size sz && sz.first end |
.wrap_text(text, width) ⇒ Array
Utility method for wrapping lines of text
at width
characters.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/color_console/console.rb', line 86 def wrap_text(text, width) text = text.to_s if width > 0 && (text.length > width || text.index("\n")) lines = [] start, nl_pos, ws_pos, wb_pos, end_pos = 0, 0, 0, 0, text.rindex(/[^\s]/) while start < end_pos last_start = start nl_pos = text.index("\n", start) ws_pos = text.rindex(/ +/, start + width) wb_pos = text.rindex(/[\-,.;#)}\]\/\\]/, start + width - 1) ### Debug code ### #STDERR.puts self #ind = ' ' * end_pos #ind[start] = '(' #ind[start+width < end_pos ? start+width : end_pos] = ']' #ind[nl_pos] = 'n' if nl_pos #ind[wb_pos] = 'b' if wb_pos #ind[ws_pos] = 's' if ws_pos #STDERR.puts ind ### End debug code ### if nl_pos && nl_pos <= start + width lines << text[start...nl_pos].strip start = nl_pos + 1 elsif end_pos < start + width lines << text[start..end_pos] start = end_pos elsif ws_pos && ws_pos > start && ((wb_pos.nil? || ws_pos > wb_pos) || (wb_pos && wb_pos > 5 && wb_pos - 5 < ws_pos)) lines << text[start...ws_pos] start = text.index(/[^\s]/, ws_pos + 1) elsif wb_pos && wb_pos > start lines << text[start..wb_pos] start = wb_pos + 1 else lines << text[start...(start+width)] start += width end if start <= last_start # Detect an infinite loop, and just return the original text STDERR.puts "Inifinite loop detected at #{__FILE__}:#{__LINE__}" STDERR.puts " width: #{width}, start: #{start}, nl_pos: #{nl_pos}, " + "ws_pos: #{ws_pos}, wb_pos: #{wb_pos}" return [text] end end lines else [text] end end |
.write(text, fg = nil, bg = nil) ⇒ Object
Writes a partital line of text to the console, with optional foreground and background colors. No line-feed is output.
55 56 57 58 59 |
# File 'lib/color_console/console.rb', line 55 def write(text, fg = nil, bg = nil) @lock.synchronize do _write(text, fg, bg) end end |