Class: TTY::ProgressBar
- Inherits:
-
Object
- Object
- TTY::ProgressBar
- Extended by:
- Forwardable
- Includes:
- MonitorMixin
- Defined in:
- lib/tty/progressbar.rb,
lib/tty/progressbar/meter.rb,
lib/tty/progressbar/multi.rb,
lib/tty/progressbar/version.rb,
lib/tty/progressbar/pipeline.rb,
lib/tty/progressbar/converter.rb,
lib/tty/progressbar/formatter.rb,
lib/tty/progressbar/configuration.rb,
lib/tty/progressbar/formatter/bar.rb,
lib/tty/progressbar/formatter/rate.rb,
lib/tty/progressbar/formatter/total.rb,
lib/tty/progressbar/formatter/current.rb,
lib/tty/progressbar/formatter/elapsed.rb,
lib/tty/progressbar/formatter/percent.rb,
lib/tty/progressbar/formatter/byte_rate.rb,
lib/tty/progressbar/formatter/estimated.rb,
lib/tty/progressbar/formatter/mean_byte.rb,
lib/tty/progressbar/formatter/mean_rate.rb,
lib/tty/progressbar/formatter/total_byte.rb,
lib/tty/progressbar/formatter/current_byte.rb
Overview
Used for creating terminal progress bar
Defined Under Namespace
Modules: Converter Classes: BarFormatter, ByteFormatter, ByteRateFormatter, Configuration, CurrentFormatter, ElapsedFormatter, EstimatedFormatter, Formatter, MeanByteFormatter, MeanRateFormatter, Meter, Multi, PercentFormatter, Pipeline, RateFormatter, TotalByteFormatter, TotalFormatter
Constant Summary collapse
- ECMA_CSI =
"\e[".freeze
- CURSOR_LOCK =
Monitor.new
- VERSION =
'0.14.0'.freeze
Instance Attribute Summary collapse
- #current ⇒ Object
- #format ⇒ Object readonly
- #row ⇒ Object readonly
- #start_at ⇒ Object readonly
Instance Method Summary collapse
-
#advance(progress = 1, tokens = {}) ⇒ Object
Advance the progress bar.
-
#attach_to(multibar) ⇒ Object
private
Attach this bar to multi bar.
-
#clear_line ⇒ Object
Clear current line.
-
#complete? ⇒ Boolean
Check if progress is finised.
-
#done? ⇒ Boolean
Check if progress is finished or stopped.
-
#finish ⇒ Object
End the progress.
-
#initialize(format, options = {}) {|@configuration| ... } ⇒ ProgressBar
constructor
Create progress bar.
-
#inspect ⇒ String
Inspect bar properties.
-
#iterate(collection, progress = 1, &block) ⇒ Enumerator
Iterate over collection either yielding computation to block or provided Enumerator.
-
#log(message) ⇒ Object
Log message above the current progress bar.
-
#max_columns ⇒ Integer
Determine terminal width.
-
#move_to_row ⇒ Object
private
Move cursor to a row of the current bar if the bar is rendered under a multibar.
-
#on(name, &callback) ⇒ self
Register callback with this bar.
-
#ratio ⇒ Float
Ratio of completed over total steps.
-
#ratio=(value) ⇒ Object
Advance the progress bar to an exact ratio.
-
#render ⇒ Object
private
Render progress to the output.
-
#reset ⇒ Object
Reset progress to default configuration.
-
#resize(new_width = nil) ⇒ Object
Resize progress bar with new configuration.
-
#start ⇒ Object
Start progression by drawing bar and setting time.
-
#stop ⇒ Object
Stop and cancel the progress at the current position.
-
#stopped? ⇒ Boolean
Check if progress is stopped.
-
#to_s ⇒ String
Show bar format.
-
#update(options = {}) ⇒ Object
Update configuration options for this bar.
-
#write(data, clear_first = false) ⇒ Object
private
Write out to the output.
Constructor Details
#initialize(format, options = {}) {|@configuration| ... } ⇒ ProgressBar
Create progress bar
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/tty/progressbar.rb', line 67 def initialize(format, = {}) super() @format = format if format.is_a?(Hash) raise ArgumentError, "Expected bar formatting string, " \ "got `#{format}` instead." end @configuration = TTY::ProgressBar::Configuration.new() yield @configuration if block_given? @formatter = TTY::ProgressBar::Formatter.new @meter = TTY::ProgressBar::Meter.new(interval) @callbacks = Hash.new { |h, k| h[k] = [] } @formatter.load reset end |
Instance Attribute Details
#current ⇒ Object
28 29 30 |
# File 'lib/tty/progressbar.rb', line 28 def current @current end |
#format ⇒ Object (readonly)
26 27 28 |
# File 'lib/tty/progressbar.rb', line 26 def format @format end |
#row ⇒ Object (readonly)
32 33 34 |
# File 'lib/tty/progressbar.rb', line 32 def row @row end |
#start_at ⇒ Object (readonly)
30 31 32 |
# File 'lib/tty/progressbar.rb', line 30 def start_at @start_at end |
Instance Method Details
#advance(progress = 1, tokens = {}) ⇒ Object
Advance the progress bar
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/tty/progressbar.rb', line 134 def advance(progress = 1, tokens = {}) return if done? synchronize do emit(:progress) if progress.respond_to?(:to_hash) tokens, progress = progress, 1 end @start_at = Time.now if @current.zero? && !@started @current += progress @tokens = tokens @meter.sample(Time.now, progress) if !no_width && @current >= total finish && return end now = Time.now return if (now - @last_render_time) < @render_period render end end |
#attach_to(multibar) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Attach this bar to multi bar
112 113 114 |
# File 'lib/tty/progressbar.rb', line 112 def attach_to() @multibar = end |
#clear_line ⇒ Object
Clear current line
358 359 360 |
# File 'lib/tty/progressbar.rb', line 358 def clear_line output.print(ECMA_CSI + '0m' + TTY::Cursor.clear_line) end |
#complete? ⇒ Boolean
Check if progress is finised
368 369 370 |
# File 'lib/tty/progressbar.rb', line 368 def complete? @done end |
#done? ⇒ Boolean
Check if progress is finished or stopped
386 387 388 |
# File 'lib/tty/progressbar.rb', line 386 def done? @done || @stopped end |
#finish ⇒ Object
End the progress
323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/tty/progressbar.rb', line 323 def finish # reenable cursor if it is turned off if hide_cursor && @last_render_width != 0 write(TTY::Cursor.show, false) end return if done? @current = total unless no_width render clear ? clear_line : write("\n", false) ensure @meter.clear @done = true emit(:done) end |
#inspect ⇒ String
Inspect bar properties
446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/tty/progressbar.rb', line 446 def inspect "#<#{self.class.name} " \ "@format=\"#{format}\", " \ "@current=\"#{@current}\", " \ "@total=\"#{total}\", " \ "@width=\"#{width}\", " \ "@complete=\"#{complete}\", " \ "@head=\"#{head}\", " \ "@incomplete=\"#{incomplete}\", " \ "@interval=\"#{interval}\">" end |
#iterate(collection, progress = 1, &block) ⇒ Enumerator
If ‘total` is set, iteration will NOT stop after this number of iterations, only when provided Enumerable is finished. It may be convenient in “unsure number of iterations” situations (like downloading in chunks, when server may eventually send more chunks than predicted), but be careful to not pass infinite enumerators without previosly doing `.take(some_finite_number)` on them.
Iterate over collection either yielding computation to block or provided Enumerator. If the bar’s ‘total` was not set, it would be taken from `collection.count`, otherwise previously set `total` would be used. This allows using the progressbar with infinite, lazy, or slowly-calculated enumerators.
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/tty/progressbar.rb', line 184 def iterate(collection, progress = 1, &block) update(total: collection.count * progress) unless total progress_enum = Enumerator.new do |iter| collection.each do |elem| advance(progress) iter.yield(elem) end end block_given? ? progress_enum.each(&block) : progress_enum end |
#log(message) ⇒ Object
Log message above the current progress bar
411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/tty/progressbar.rb', line 411 def log() = .gsub(/\r|\n/, ' ') if done? write( + "\n", false) return end = padout() write( + "\n", true) render end |
#max_columns ⇒ Integer
Determine terminal width
428 429 430 |
# File 'lib/tty/progressbar.rb', line 428 def max_columns TTY::Screen.width end |
#move_to_row ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Move cursor to a row of the current bar if the bar is rendered under a multibar. Otherwise, do not move and yield on current row.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/tty/progressbar.rb', line 267 def move_to_row if @multibar CURSOR_LOCK.synchronize do if @first_render @row = @multibar.next_row yield if block_given? output.print "\n" @first_render = false else lines_up = (@multibar.rows + 1) - @row output.print TTY::Cursor.save output.print TTY::Cursor.up(lines_up) yield if block_given? output.print TTY::Cursor.restore end end else yield if block_given? end end |
#on(name, &callback) ⇒ self
Register callback with this bar
398 399 400 401 402 403 |
# File 'lib/tty/progressbar.rb', line 398 def on(name, &callback) synchronize do @callbacks[name] << callback end self end |
#ratio ⇒ Float
Ratio of completed over total steps
237 238 239 240 241 242 |
# File 'lib/tty/progressbar.rb', line 237 def ratio synchronize do proportion = total > 0 ? (@current.to_f / total) : 0 [[proportion, 0].max, 1].min end end |
#ratio=(value) ⇒ Object
Advance the progress bar to an exact ratio. The target value is set to the closest available value.
227 228 229 230 |
# File 'lib/tty/progressbar.rb', line 227 def ratio=(value) target = (value * total).floor advance(target - @current) end |
#render ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Render progress to the output
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/tty/progressbar.rb', line 247 def render return if done? if hide_cursor && @last_render_width == 0 && !(@current >= total) write(TTY::Cursor.hide) end formatted = @formatter.decorate(self, @format) @tokens.each do |token, val| formatted = formatted.gsub(":#{token}", val) end write(formatted, true) @last_render_time = Time.now @last_render_width = formatted.length end |
#reset ⇒ Object
Reset progress to default configuration
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/tty/progressbar.rb', line 88 def reset @width = 0 if no_width @render_period = frequency == 0 ? 0 : 1.0 / frequency @current = 0 @last_render_time = Time.now @last_render_width = 0 @done = false @stopped = false @start_at = Time.now @started = false @tokens = {} @multibar = nil @row = nil @first_render = true @meter.clear end |
#resize(new_width = nil) ⇒ Object
Resize progress bar with new configuration
310 311 312 313 314 315 316 317 318 |
# File 'lib/tty/progressbar.rb', line 310 def resize(new_width = nil) return if done? synchronize do clear_line if new_width self.width = new_width end end end |
#start ⇒ Object
Start progression by drawing bar and setting time
119 120 121 122 123 124 125 126 127 |
# File 'lib/tty/progressbar.rb', line 119 def start synchronize do @started = true @start_at = Time.now @meter.start end advance(0) end |
#stop ⇒ Object
Stop and cancel the progress at the current position
341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/tty/progressbar.rb', line 341 def stop # reenable cursor if it is turned off if hide_cursor && @last_render_width != 0 write(TTY::Cursor.show, false) end return if done? render clear ? clear_line : write("\n", false) ensure @meter.clear @stopped = true emit(:stopped) end |
#stopped? ⇒ Boolean
Check if progress is stopped
377 378 379 |
# File 'lib/tty/progressbar.rb', line 377 def stopped? @stopped end |
#to_s ⇒ String
Show bar format
437 438 439 |
# File 'lib/tty/progressbar.rb', line 437 def to_s @format.to_s end |
#update(options = {}) ⇒ Object
Update configuration options for this bar
201 202 203 204 205 206 207 |
# File 'lib/tty/progressbar.rb', line 201 def update( = {}) synchronize do .each do |name, val| @configuration.public_send("#{name}=", val) end end end |
#write(data, clear_first = false) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Write out to the output
293 294 295 296 297 298 299 300 301 302 |
# File 'lib/tty/progressbar.rb', line 293 def write(data, clear_first = false) return unless tty? # write only to terminal move_to_row do output.print(TTY::Cursor.column(1)) if clear_first characters_in = @multibar.line_inset(self) if @multibar output.print("#{characters_in}#{data}") output.flush end end |