-
Notifications
You must be signed in to change notification settings - Fork 0
/
Progressbar.rb
74 lines (61 loc) · 1.74 KB
/
Progressbar.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Progressbar
def initialize
@last_length = 0
@title = ""
@progress = 0
end
def show(title, &block)
@title = title
print @title + " "
start_progress
# thanks to http://www.dcmanges.com/blog/ruby-dsls-instance-eval-with-delegation
@self_before_instance_eval = eval "self", block.binding
instance_eval(&block)
finish_progress
end
def interrupt
# TODO: Make some of the strings constants so we don't have to use a magic number here.
progressbar_length = 16 + @last_length + @title.length
move_cursor = "\e[#{progressbar_length}D"
print move_cursor + (" " * progressbar_length) + move_cursor
STDOUT.flush
yield
puts
print @title + " "
render_progress(@progress)
end
def progress(percent)
print "\e[#{15 + @last_length}D"
render_progress(percent)
end
def method_missing(method, *args, &block)
@self_before_instance_eval.send method, *args, &block
end
private
def render_progress(percent)
@progress = percent
print "["
print "*" * [(percent/10).to_i, 10].min
print " " * [10 - (percent/10).to_i, 0].max
if percent.class != Float
printable_percent = "%3s" % percent
else
non_decimal_digits = (Math.log(percent) / Math.log(10)).truncate + 1
printable_percent = (non_decimal_digits < 3 ? " " * (3 - non_decimal_digits) : "") + percent.floor.to_s
end
print "]\e[32m #{printable_percent}\e[0m %"
new_length = printable_percent.length
if @last_length > new_length
print " " * (@last_length - new_length)
print "\e[#{@last_length - new_length}D"
end
@last_length = new_length
STDOUT.flush
end
def start_progress
render_progress(0)
end
def finish_progress
puts
end
end