tty-progressbar 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/CHANGELOG.md +21 -1
- data/README.md +24 -2
- data/appveyor.yml +2 -0
- data/examples/multi/width.rb +13 -0
- data/examples/unicode.rb +7 -0
- data/lib/tty/progressbar.rb +46 -20
- data/lib/tty/progressbar/configuration.rb +16 -2
- data/lib/tty/progressbar/formatter/bar.rb +16 -5
- data/lib/tty/progressbar/multi.rb +10 -4
- data/lib/tty/progressbar/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/custom_token_spec.rb +1 -1
- data/spec/unit/multi/reset_spec.rb +28 -0
- data/spec/unit/multi/width_spec.rb +118 -0
- data/spec/unit/new_spec.rb +10 -0
- data/spec/unit/render_spec.rb +25 -0
- data/spec/unit/resize_spec.rb +1 -1
- data/spec/unit/width_spec.rb +65 -0
- data/tty-progressbar.gemspec +3 -2
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2470861861ae00abd4f276cede9731c712d2508
|
4
|
+
data.tar.gz: 38d29289ddfd613781defa037dc1181654ef7a3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e2e6a01da4dcb082e8e55e1ecfc18841dd42a1cf1a2d622aa6d081d13f112a9f28fa4ef32cec33ffa68f50578a979eb3e4398f28145ac7204114a18a4145eaa
|
7
|
+
data.tar.gz: 5226faf2809e8939088d0d9ab4b91f391c687bc7e92149df9b13d0fbd6a7ea0a7a337863d9c1c54a59a6cbe92088605b0e915f6c7640d4b88d9e32b71fb6111a
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
## [v0.
|
3
|
+
## [v0.15.0] - 2018-06-24
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add #format= for overriding formatting string
|
7
|
+
* Add #display_columns for determining display width of multibyte characters
|
8
|
+
* Add :inset option to bar configuration options
|
9
|
+
* Add ability to configure width for multi bar with top level bar
|
10
|
+
* Add unicode-display_width dependency
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
* Change #update to only set configuration if actually present
|
14
|
+
* Change bar formatter to handle multibyte characters
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
* Fix to stop reseting multibar state when registered bar reset by Eric Hodel(@drbrain)
|
18
|
+
* Fix rendered bar to pad formatted output when it gets shorter by Eric Hodel(@drbrain)
|
19
|
+
* Fix multi bar to advance in steps matching each bar advance progress
|
20
|
+
* Fix multi bar rendering for widths exceeding screen columns count
|
21
|
+
|
22
|
+
## [v0.14.0] - 2018-01-17
|
4
23
|
|
5
24
|
### Changed
|
6
25
|
* Change to only output to a console and stop output to a file, pipe etc...
|
@@ -160,6 +179,7 @@
|
|
160
179
|
|
161
180
|
* Initial implementation and release
|
162
181
|
|
182
|
+
[v0.15.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.14.0...v0.15.0
|
163
183
|
[v0.14.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.13.0...v0.14.0
|
164
184
|
[v0.13.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.2...v0.13.0
|
165
185
|
[v0.12.2]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.1...v0.12.2
|
data/README.md
CHANGED
@@ -26,6 +26,7 @@
|
|
26
26
|
* Includes many predefined tokens to calculate ETA, Bytes ... [tokens](#41-tokens)
|
27
27
|
* Allows to define your [custom tokens](#42-custom-formatters)
|
28
28
|
* Supports parallel multi progress bars [multi](#6-ttyprogressbarmulti-api)
|
29
|
+
* Handles Unicode characters in progress bar [unicode](#44-unicode)
|
29
30
|
* Works on all ECMA-48 compatible terminals
|
30
31
|
|
31
32
|
## Installation
|
@@ -70,6 +71,7 @@ Or install it yourself as:
|
|
70
71
|
* [4.1 Tokens](#41-tokens)
|
71
72
|
* [4.2 Custom Formatters](#42-custom-formatters)
|
72
73
|
* [4.3 Custom Tokens](#43-custom-tokens)
|
74
|
+
* [4.4 Unicode](#44-unicode)
|
73
75
|
* [5. Logging](#5-logging)
|
74
76
|
* [6. TTY::ProgressBar::Multi API](#6-ttyprogressbarmulti-api)
|
75
77
|
* [6.1 new](#61-new)
|
@@ -302,10 +304,10 @@ trap(:WINCH) { bar.resize }
|
|
302
304
|
|
303
305
|
The progress bar fires events when it is progressing, stopped or finished. You can register to listen for events using the `on` message.
|
304
306
|
|
305
|
-
Every time an `advance` is called the `:progress` event gets fired which you can listen for:
|
307
|
+
Every time an `advance` is called the `:progress` event gets fired which you can listen for inside a block which includes the actual amount of progress as a first yielded argument:
|
306
308
|
|
307
309
|
```ruby
|
308
|
-
bar.on(:progress) { ... }
|
310
|
+
bar.on(:progress) { |amount| ... }
|
309
311
|
```
|
310
312
|
|
311
313
|
When the progress bar finishes and completes then the `:done` event is fired. You can listen for this event:
|
@@ -474,6 +476,26 @@ which outputs:
|
|
474
476
|
(4) Bye Piotr!
|
475
477
|
```
|
476
478
|
|
479
|
+
### 4.4 Unicode
|
480
|
+
|
481
|
+
The format string as well as `:complete`, `:head` and `:incompelte` configuration options can contain Unicode characters that aren't monospaced.
|
482
|
+
|
483
|
+
For example, you can specify complete bar progression character to be Unicode non-monospaced:
|
484
|
+
|
485
|
+
```ruby
|
486
|
+
bar = TTY::ProgressBar.new("Unicode [:bar]", total: 30, complete: 'あ')
|
487
|
+
#
|
488
|
+
# => Unicode [あああああああああああああああ]
|
489
|
+
```
|
490
|
+
|
491
|
+
Similarly, the formatted string can include Unicode characters:
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
bar = TTY::ProgressBar.new("あめかんむり[:bar]", total: 20)
|
495
|
+
#
|
496
|
+
# => あめかんむり[== ]
|
497
|
+
```
|
498
|
+
|
477
499
|
## 5. Logging
|
478
500
|
|
479
501
|
If you want to print messages out to terminal along with the progress bar use the `log` method. The messages will appear above the progress bar and will continue scrolling up as more are logged out.
|
data/appveyor.yml
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../../lib/tty-progressbar'
|
2
|
+
|
3
|
+
bars = TTY::ProgressBar::Multi.new("main [:bar] :percent")
|
4
|
+
|
5
|
+
bar1 = bars.register "foo [:bar] :percent", total: 150
|
6
|
+
bar2 = bars.register "bar [:bar] :percent", total: 250
|
7
|
+
bar3 = bars.register "baz [:bar] :percent", total: 100
|
8
|
+
|
9
|
+
th1 = Thread.new { 15.times { sleep(0.1); bar1.advance(10) } }
|
10
|
+
th2 = Thread.new { 50.times { sleep(0.1); bar2.advance(5)} }
|
11
|
+
th3 = Thread.new { 50.times { sleep(0.1); bar3.advance(5) } }
|
12
|
+
|
13
|
+
[th1, th2, th3].each(&:join)
|
data/examples/unicode.rb
ADDED
data/lib/tty/progressbar.rb
CHANGED
@@ -5,6 +5,7 @@ require 'forwardable'
|
|
5
5
|
require 'monitor'
|
6
6
|
require 'tty-cursor'
|
7
7
|
require 'tty-screen'
|
8
|
+
require 'unicode/display_width'
|
8
9
|
|
9
10
|
require_relative 'progressbar/configuration'
|
10
11
|
require_relative 'progressbar/formatter'
|
@@ -23,7 +24,7 @@ module TTY
|
|
23
24
|
|
24
25
|
CURSOR_LOCK = Monitor.new
|
25
26
|
|
26
|
-
|
27
|
+
attr_accessor :format
|
27
28
|
|
28
29
|
attr_reader :current
|
29
30
|
|
@@ -33,12 +34,33 @@ module TTY
|
|
33
34
|
|
34
35
|
def_delegators :@configuration, :total, :width, :no_width,
|
35
36
|
:complete, :incomplete, :head, :hide_cursor, :clear,
|
36
|
-
:output, :frequency, :interval, :width=
|
37
|
+
:output, :frequency, :interval, :inset, :width=
|
37
38
|
|
38
39
|
def_delegators :@meter, :rate, :mean_rate
|
39
40
|
|
40
41
|
def_delegator :@formatter, :use
|
41
42
|
|
43
|
+
# Determine terminal width
|
44
|
+
#
|
45
|
+
# @return [Integer]
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
def self.max_columns
|
49
|
+
TTY::Screen.width
|
50
|
+
end
|
51
|
+
|
52
|
+
# Determine the monospace display width of a string
|
53
|
+
#
|
54
|
+
# @param [String] value
|
55
|
+
# the value to determine width of
|
56
|
+
#
|
57
|
+
# @return [Integer]
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
def self.display_columns(value)
|
61
|
+
Unicode::DisplayWidth.of(value)
|
62
|
+
end
|
63
|
+
|
42
64
|
# Create progress bar
|
43
65
|
#
|
44
66
|
# @param [String] format
|
@@ -80,6 +102,10 @@ module TTY
|
|
80
102
|
|
81
103
|
@formatter.load
|
82
104
|
reset
|
105
|
+
|
106
|
+
@first_render = true
|
107
|
+
@multibar = nil
|
108
|
+
@row = nil
|
83
109
|
end
|
84
110
|
|
85
111
|
# Reset progress to default configuration
|
@@ -96,9 +122,6 @@ module TTY
|
|
96
122
|
@start_at = Time.now
|
97
123
|
@started = false
|
98
124
|
@tokens = {}
|
99
|
-
@multibar = nil
|
100
|
-
@row = nil
|
101
|
-
@first_render = true
|
102
125
|
|
103
126
|
@meter.clear
|
104
127
|
end
|
@@ -135,7 +158,7 @@ module TTY
|
|
135
158
|
return if done?
|
136
159
|
|
137
160
|
synchronize do
|
138
|
-
emit(:progress)
|
161
|
+
emit(:progress, progress)
|
139
162
|
if progress.respond_to?(:to_hash)
|
140
163
|
tokens, progress = progress, 1
|
141
164
|
end
|
@@ -201,7 +224,9 @@ module TTY
|
|
201
224
|
def update(options = {})
|
202
225
|
synchronize do
|
203
226
|
options.each do |name, val|
|
204
|
-
@configuration.
|
227
|
+
if @configuration.respond_to?("#{name}=")
|
228
|
+
@configuration.public_send("#{name}=", val)
|
229
|
+
end
|
205
230
|
end
|
206
231
|
end
|
207
232
|
end
|
@@ -250,14 +275,22 @@ module TTY
|
|
250
275
|
write(TTY::Cursor.hide)
|
251
276
|
end
|
252
277
|
|
278
|
+
if @multibar
|
279
|
+
characters_in = @multibar.line_inset(self)
|
280
|
+
update(inset: self.class.display_columns(characters_in))
|
281
|
+
end
|
282
|
+
|
253
283
|
formatted = @formatter.decorate(self, @format)
|
254
284
|
@tokens.each do |token, val|
|
255
285
|
formatted = formatted.gsub(":#{token}", val)
|
256
286
|
end
|
257
|
-
|
287
|
+
|
288
|
+
padded = padout(formatted)
|
289
|
+
|
290
|
+
write(padded, true)
|
258
291
|
|
259
292
|
@last_render_time = Time.now
|
260
|
-
@last_render_width = formatted
|
293
|
+
@last_render_width = self.class.display_columns(formatted)
|
261
294
|
end
|
262
295
|
|
263
296
|
# Move cursor to a row of the current bar if the bar is rendered
|
@@ -420,15 +453,6 @@ module TTY
|
|
420
453
|
render
|
421
454
|
end
|
422
455
|
|
423
|
-
# Determine terminal width
|
424
|
-
#
|
425
|
-
# @return [Integer]
|
426
|
-
#
|
427
|
-
# @api public
|
428
|
-
def max_columns
|
429
|
-
TTY::Screen.width
|
430
|
-
end
|
431
|
-
|
432
456
|
# Show bar format
|
433
457
|
#
|
434
458
|
# @return [String]
|
@@ -461,8 +485,10 @@ module TTY
|
|
461
485
|
#
|
462
486
|
# @api private
|
463
487
|
def padout(message)
|
464
|
-
|
465
|
-
|
488
|
+
message_length = self.class.display_columns(message)
|
489
|
+
|
490
|
+
if @last_render_width > message_length
|
491
|
+
remaining_width = @last_render_width - message_length
|
466
492
|
message += ' ' * remaining_width
|
467
493
|
end
|
468
494
|
message
|
@@ -5,6 +5,7 @@ module TTY
|
|
5
5
|
attr_reader :total
|
6
6
|
|
7
7
|
attr_accessor :width
|
8
|
+
#attr_reader :width
|
8
9
|
|
9
10
|
attr_accessor :no_width
|
10
11
|
|
@@ -24,9 +25,11 @@ module TTY
|
|
24
25
|
|
25
26
|
attr_accessor :interval
|
26
27
|
|
28
|
+
attr_accessor :inset
|
29
|
+
|
27
30
|
def initialize(options)
|
28
31
|
self.total = options[:total] if options[:total]
|
29
|
-
@width
|
32
|
+
@width = options.fetch(:width) { total }
|
30
33
|
@no_width = options.fetch(:no_width) { false }
|
31
34
|
@incomplete = options.fetch(:incomplete) { ' ' }
|
32
35
|
@complete = options.fetch(:complete) { '=' }
|
@@ -36,12 +39,23 @@ module TTY
|
|
36
39
|
@output = options.fetch(:output) { $stderr }
|
37
40
|
@frequency = options.fetch(:frequency) { 0 } # 0Hz
|
38
41
|
@interval = options.fetch(:interval) { 1 } # 1 sec
|
42
|
+
@inset = options.fetch(:inset) { 0 }
|
39
43
|
end
|
40
44
|
|
45
|
+
# def width=(value)
|
46
|
+
# return if value.nil?
|
47
|
+
|
48
|
+
# if value < ProgressBar.max_columns
|
49
|
+
# @width = value
|
50
|
+
# else
|
51
|
+
# @width = ProgressBar.max_columns
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
41
55
|
def total=(value)
|
42
56
|
fail ArgumentError unless value
|
43
57
|
@total = value
|
44
|
-
|
58
|
+
self.width = value if width.nil?
|
45
59
|
end
|
46
60
|
end # Configuration
|
47
61
|
end # ProgressBar
|
@@ -30,12 +30,23 @@ module TTY
|
|
30
30
|
#
|
31
31
|
# @api public
|
32
32
|
def format(value)
|
33
|
-
|
33
|
+
without_bar = value.gsub(/:bar/, '')
|
34
|
+
available_space = [0, ProgressBar.max_columns -
|
35
|
+
ProgressBar.display_columns(without_bar) -
|
36
|
+
@progress.inset].max
|
34
37
|
width = [@progress.width, available_space].min
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
complete_bar_length = (width * @progress.ratio).round
|
39
|
+
complete_char_length = ProgressBar.display_columns(@progress.complete)
|
40
|
+
incomplete_char_length = ProgressBar.display_columns(@progress.incomplete)
|
41
|
+
|
42
|
+
# decimal number of items only when unicode chars are used
|
43
|
+
# otherwise it has no effect on regular ascii chars
|
44
|
+
complete_items = (complete_bar_length / complete_char_length.to_f).round
|
45
|
+
incomplete_items = (width - complete_items * complete_char_length) / incomplete_char_length
|
46
|
+
|
47
|
+
complete = Array.new(complete_items, @progress.complete)
|
48
|
+
incomplete = Array.new(incomplete_items, @progress.incomplete)
|
49
|
+
complete[-1] = @progress.head if complete_bar_length > 0
|
39
50
|
|
40
51
|
bar = ''
|
41
52
|
bar += complete.join
|
@@ -18,6 +18,8 @@ module TTY
|
|
18
18
|
|
19
19
|
def_delegators :@bars, :each, :empty?, :length, :[]
|
20
20
|
|
21
|
+
def_delegators :@top_bar, :width, :width=
|
22
|
+
|
21
23
|
DEFAULT_INSET = {
|
22
24
|
top: Gem.win_platform? ? '+ ' : "\u250c ",
|
23
25
|
middle: Gem.win_platform? ? '|-- ' : "\u251c\u2500\u2500 ",
|
@@ -51,6 +53,9 @@ module TTY
|
|
51
53
|
@top_bar = nil
|
52
54
|
@top_bar = register(format, observable: false) if format
|
53
55
|
|
56
|
+
@width = @options[:width]
|
57
|
+
@top_bar.update(width: @width) if @width
|
58
|
+
|
54
59
|
@callbacks = {
|
55
60
|
progress: [],
|
56
61
|
stopped: [],
|
@@ -73,7 +78,8 @@ module TTY
|
|
73
78
|
@bars << bar
|
74
79
|
observe(bar) if observable
|
75
80
|
if @top_bar
|
76
|
-
@top_bar.update(total: total
|
81
|
+
@top_bar.update(total: total)
|
82
|
+
@top_bar.update(width: total) unless @width
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
@@ -105,9 +111,9 @@ module TTY
|
|
105
111
|
#
|
106
112
|
# @api private
|
107
113
|
def progress_handler
|
108
|
-
|
109
|
-
@top_bar.advance if @top_bar
|
110
|
-
emit(:progress)
|
114
|
+
-> (progress) do
|
115
|
+
@top_bar.advance(progress) if @top_bar
|
116
|
+
emit(:progress, progress)
|
111
117
|
end
|
112
118
|
end
|
113
119
|
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar::Multi, '#reset' do
|
2
|
+
let(:output) { StringIO.new('', 'w+') }
|
3
|
+
|
4
|
+
it "leaves multibar state alone" do
|
5
|
+
main = TTY::ProgressBar::Multi.new("", output: output, total: 10)
|
6
|
+
progress = main.register("[:bar]")
|
7
|
+
progress.advance(10)
|
8
|
+
expect(progress.complete?).to be(true)
|
9
|
+
progress.reset
|
10
|
+
expect(progress.complete?).to be(false)
|
11
|
+
progress.advance(10)
|
12
|
+
output.rewind
|
13
|
+
|
14
|
+
top = TTY::ProgressBar::Multi::DEFAULT_INSET[:top]
|
15
|
+
bottom = TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom]
|
16
|
+
|
17
|
+
progress_updates =
|
18
|
+
output.read.scan(/#{Regexp.escape top}|#{Regexp.escape bottom}/)
|
19
|
+
expect(progress_updates.shift).to match(top)
|
20
|
+
expect(progress_updates.shift).to match(top)
|
21
|
+
expect(progress_updates.shift).to match(bottom)
|
22
|
+
expect(progress_updates.shift).to match(bottom)
|
23
|
+
expect(progress_updates.shift).to match(bottom)
|
24
|
+
expect(progress_updates.shift).to match(bottom)
|
25
|
+
|
26
|
+
expect(progress_updates).to be_empty
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar::Multi, 'width' do
|
2
|
+
let(:output) { StringIO.new('', 'w+') }
|
3
|
+
let(:save) { TTY::Cursor.save }
|
4
|
+
let(:restore) { TTY::Cursor.restore }
|
5
|
+
let(:top) { TTY::ProgressBar::Multi::DEFAULT_INSET[:top] }
|
6
|
+
let(:middle) { TTY::ProgressBar::Multi::DEFAULT_INSET[:middle] }
|
7
|
+
let(:bottom) { TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom] }
|
8
|
+
|
9
|
+
it "sets top level bar width to maximum columns when exceeds terminal width" do
|
10
|
+
allow(TTY::Screen).to receive(:width).and_return(15)
|
11
|
+
|
12
|
+
bars = TTY::ProgressBar::Multi.new("[:bar] main", output: output)
|
13
|
+
|
14
|
+
bar1 = bars.register("[:bar] one", total: 20)
|
15
|
+
bar2 = bars.register("[:bar] two", total: 20)
|
16
|
+
|
17
|
+
bar1.advance(10)
|
18
|
+
bar2.advance(10)
|
19
|
+
|
20
|
+
output.rewind
|
21
|
+
expect(output.read).to eq([
|
22
|
+
"\e[1G#{top}[== ] main\n",
|
23
|
+
"\e[1G#{bottom}[=== ] one\n",
|
24
|
+
save,
|
25
|
+
"\e[2A", # up 2 lines
|
26
|
+
"\e[1G#{top}[=== ] main",
|
27
|
+
restore,
|
28
|
+
"\e[1G#{bottom}[=== ] two\n"
|
29
|
+
].join)
|
30
|
+
|
31
|
+
bar1.advance(10)
|
32
|
+
|
33
|
+
output.rewind
|
34
|
+
expect(output.read).to eq([
|
35
|
+
"\e[1G#{top}[== ] main\n",
|
36
|
+
"\e[1G#{bottom}[=== ] one\n",
|
37
|
+
save,
|
38
|
+
"\e[2A", # up 2 lines
|
39
|
+
"\e[1G#{top}[=== ] main",
|
40
|
+
restore,
|
41
|
+
"\e[1G#{bottom}[=== ] two\n",
|
42
|
+
save,
|
43
|
+
"\e[3A", # up 3 lines
|
44
|
+
"\e[1G#{top}[===== ] main",
|
45
|
+
restore,
|
46
|
+
save,
|
47
|
+
"\e[2A", # up 2 lines
|
48
|
+
"\e[1G#{middle}[=====] one",
|
49
|
+
restore,
|
50
|
+
save,
|
51
|
+
"\e[2A", # up 2 lines
|
52
|
+
"#{middle}\n", # bar finished
|
53
|
+
restore
|
54
|
+
].join)
|
55
|
+
|
56
|
+
bar2.advance(10)
|
57
|
+
|
58
|
+
output.rewind
|
59
|
+
expect(output.read).to eq([
|
60
|
+
"\e[1G#{top}[== ] main\n",
|
61
|
+
"\e[1G#{bottom}[=== ] one\n",
|
62
|
+
save,
|
63
|
+
"\e[2A", # up 2 lines
|
64
|
+
"\e[1G#{top}[=== ] main",
|
65
|
+
restore,
|
66
|
+
"\e[1G#{bottom}[=== ] two\n",
|
67
|
+
save,
|
68
|
+
"\e[3A", # up 3 lines
|
69
|
+
"\e[1G#{top}[===== ] main",
|
70
|
+
restore,
|
71
|
+
save,
|
72
|
+
"\e[2A", # up 2 lines
|
73
|
+
"\e[1G#{middle}[=====] one",
|
74
|
+
restore,
|
75
|
+
save,
|
76
|
+
"\e[2A", # up 2 lines
|
77
|
+
"#{middle}\n", # bar finished
|
78
|
+
restore,
|
79
|
+
save,
|
80
|
+
"\e[3A", # up 3 lines
|
81
|
+
"\e[1G#{top}[======] main",
|
82
|
+
restore,
|
83
|
+
save,
|
84
|
+
"\e[3A", # up 1 line
|
85
|
+
"#{top}\n",
|
86
|
+
restore,
|
87
|
+
save,
|
88
|
+
"\e[1A", # up 1 line
|
89
|
+
"\e[1G#{bottom}[=====] two",
|
90
|
+
restore,
|
91
|
+
save,
|
92
|
+
"\e[1A", # up 1 line
|
93
|
+
"#{bottom}\n",
|
94
|
+
restore
|
95
|
+
].join)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "sets top level bar width to a custom value" do
|
99
|
+
bars = TTY::ProgressBar::Multi.new("[:bar] main", output: output, width: 20)
|
100
|
+
|
101
|
+
bar1 = bars.register("[:bar] one", total: 20)
|
102
|
+
bar2 = bars.register("[:bar] two", total: 20)
|
103
|
+
|
104
|
+
bar1.advance(10)
|
105
|
+
bar2.advance(10)
|
106
|
+
|
107
|
+
output.rewind
|
108
|
+
expect(output.read).to eq([
|
109
|
+
"\e[1G#{top}[===== ] main\n",
|
110
|
+
"\e[1G#{bottom}[========== ] one\n",
|
111
|
+
save,
|
112
|
+
"\e[2A", # up 2 lines
|
113
|
+
"\e[1G#{top}[========== ] main",
|
114
|
+
restore,
|
115
|
+
"\e[1G#{bottom}[========== ] two\n"
|
116
|
+
].join)
|
117
|
+
end
|
118
|
+
end
|
data/spec/unit/new_spec.rb
CHANGED
@@ -7,6 +7,16 @@ RSpec.describe TTY::ProgressBar, '::new' do
|
|
7
7
|
}.to raise_error(ArgumentError, /Expected bar formatting string, got `{:output=>#{output}}` instead\./)
|
8
8
|
end
|
9
9
|
|
10
|
+
it "allows to change formatting string" do
|
11
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 4)
|
12
|
+
bar.advance(2)
|
13
|
+
bar.format = "(:bar)"
|
14
|
+
bar.advance(2)
|
15
|
+
output.rewind
|
16
|
+
|
17
|
+
expect(output.read).to eq("\e[1G[== ]\e[1G(====)\n")
|
18
|
+
end
|
19
|
+
|
10
20
|
it "displays output where width == total" do
|
11
21
|
progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
|
12
22
|
progress.advance
|
@@ -0,0 +1,25 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar, "#render" do
|
2
|
+
let(:output) { StringIO.new("", "w+") }
|
3
|
+
|
4
|
+
it "pads out longer previous lines" do
|
5
|
+
progress = TTY::ProgressBar.new ":current_byte" do |config|
|
6
|
+
config.no_width = true
|
7
|
+
config.output = output
|
8
|
+
config.total = 1_048_577
|
9
|
+
end
|
10
|
+
|
11
|
+
progress.advance(1)
|
12
|
+
progress.advance(1_048_574)
|
13
|
+
progress.advance(1)
|
14
|
+
progress.advance(1)
|
15
|
+
|
16
|
+
output.rewind
|
17
|
+
|
18
|
+
expect(output.read).to eq([
|
19
|
+
"\e[1G1B",
|
20
|
+
"\e[1G1024.00KB", # must not pad, line is longer
|
21
|
+
"\e[1G1.00MB ", # must pad out "0KB"
|
22
|
+
"\e[1G1.00MB", # must not pad, line is equal
|
23
|
+
].join)
|
24
|
+
end
|
25
|
+
end
|
data/spec/unit/resize_spec.rb
CHANGED
data/spec/unit/width_spec.rb
CHANGED
@@ -8,8 +8,10 @@ RSpec.describe TTY::ProgressBar, '#width' do
|
|
8
8
|
config.width = 1024
|
9
9
|
end
|
10
10
|
allow(TTY::Screen).to receive(:width).and_return(20)
|
11
|
+
|
11
12
|
5.times { progress.advance }
|
12
13
|
output.rewind
|
14
|
+
|
13
15
|
expect(output.read).to eq([
|
14
16
|
"\e[1G[==== ]",
|
15
17
|
"\e[1G[======= ]",
|
@@ -18,4 +20,67 @@ RSpec.describe TTY::ProgressBar, '#width' do
|
|
18
20
|
"\e[1G[==================]\n"
|
19
21
|
].join)
|
20
22
|
end
|
23
|
+
|
24
|
+
it "handles unicode characters width in formatting string" do
|
25
|
+
bar = TTY::ProgressBar.new("あめかんむり[:bar]", output: output, total: 20)
|
26
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
27
|
+
|
28
|
+
4.times { bar.advance(5) }
|
29
|
+
output.rewind
|
30
|
+
|
31
|
+
expect(output.read).to eq([
|
32
|
+
"\e[1Gあめかんむり[== ]",
|
33
|
+
"\e[1Gあめかんむり[=== ]",
|
34
|
+
"\e[1Gあめかんむり[===== ]",
|
35
|
+
"\e[1Gあめかんむり[======]\n"
|
36
|
+
].join)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "handles unicodes characters within bar" do
|
40
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
41
|
+
complete: 'あ', incomplete: 'め')
|
42
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
43
|
+
|
44
|
+
4.times { bar.advance(5) }
|
45
|
+
output.rewind
|
46
|
+
|
47
|
+
expect(output.read).to eq([
|
48
|
+
"\e[1G[あああめめめめめめ]",
|
49
|
+
"\e[1G[あああああめめめめ]",
|
50
|
+
"\e[1G[あああああああめめ]",
|
51
|
+
"\e[1G[あああああああああ]\n"
|
52
|
+
].join)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "handles unicodes characters within bar" do
|
56
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
57
|
+
complete: 'あ', incomplete: ' ')
|
58
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
59
|
+
|
60
|
+
4.times { bar.advance(5) }
|
61
|
+
output.rewind
|
62
|
+
|
63
|
+
expect(output.read).to eq([
|
64
|
+
"\e[1G[あああ ]",
|
65
|
+
"\e[1G[あああああ ]",
|
66
|
+
"\e[1G[あああああああ ]",
|
67
|
+
"\e[1G[あああああああああ]\n"
|
68
|
+
].join)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "handles unicodes characters within bar" do
|
72
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
73
|
+
complete: 'x', incomplete: 'め')
|
74
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
75
|
+
|
76
|
+
4.times { bar.advance(5) }
|
77
|
+
output.rewind
|
78
|
+
|
79
|
+
expect(output.read).to eq([
|
80
|
+
"\e[1G[xxxxxめめめめめめ]",
|
81
|
+
"\e[1G[xxxxxxxxxめめめめ]",
|
82
|
+
"\e[1G[xxxxxxxxxxxxxxめめ]",
|
83
|
+
"\e[1G[xxxxxxxxxxxxxxxxxx]\n"
|
84
|
+
].join)
|
85
|
+
end
|
21
86
|
end
|
data/tty-progressbar.gemspec
CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.required_ruby_version = '>= 2.0.0'
|
22
22
|
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency 'tty-cursor', '~> 0.5.0'
|
24
|
+
spec.add_dependency 'tty-screen', '~> 0.6.4'
|
25
|
+
spec.add_dependency 'unicode-display_width', '~> 1.3'
|
25
26
|
|
26
27
|
spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
|
27
28
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-progressbar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-cursor
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: unicode-display_width
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,11 +138,13 @@ files:
|
|
124
138
|
- examples/lazy.rb
|
125
139
|
- examples/multi/main_bar.rb
|
126
140
|
- examples/multi/simple.rb
|
141
|
+
- examples/multi/width.rb
|
127
142
|
- examples/simple.rb
|
128
143
|
- examples/slow_process.rb
|
129
144
|
- examples/speed.rb
|
130
145
|
- examples/threaded.rb
|
131
146
|
- examples/tokens.rb
|
147
|
+
- examples/unicode.rb
|
132
148
|
- lib/tty-progressbar.rb
|
133
149
|
- lib/tty/progressbar.rb
|
134
150
|
- lib/tty/progressbar/configuration.rb
|
@@ -185,10 +201,13 @@ files:
|
|
185
201
|
- spec/unit/multi/finish_spec.rb
|
186
202
|
- spec/unit/multi/line_inset_spec.rb
|
187
203
|
- spec/unit/multi/register_spec.rb
|
204
|
+
- spec/unit/multi/reset_spec.rb
|
188
205
|
- spec/unit/multi/stop_spec.rb
|
206
|
+
- spec/unit/multi/width_spec.rb
|
189
207
|
- spec/unit/new_spec.rb
|
190
208
|
- spec/unit/pipeline_spec.rb
|
191
209
|
- spec/unit/ratio_spec.rb
|
210
|
+
- spec/unit/render_spec.rb
|
192
211
|
- spec/unit/reset_spec.rb
|
193
212
|
- spec/unit/resize_spec.rb
|
194
213
|
- spec/unit/set_current_spec.rb
|
@@ -260,10 +279,13 @@ test_files:
|
|
260
279
|
- spec/unit/multi/finish_spec.rb
|
261
280
|
- spec/unit/multi/line_inset_spec.rb
|
262
281
|
- spec/unit/multi/register_spec.rb
|
282
|
+
- spec/unit/multi/reset_spec.rb
|
263
283
|
- spec/unit/multi/stop_spec.rb
|
284
|
+
- spec/unit/multi/width_spec.rb
|
264
285
|
- spec/unit/new_spec.rb
|
265
286
|
- spec/unit/pipeline_spec.rb
|
266
287
|
- spec/unit/ratio_spec.rb
|
288
|
+
- spec/unit/render_spec.rb
|
267
289
|
- spec/unit/reset_spec.rb
|
268
290
|
- spec/unit/resize_spec.rb
|
269
291
|
- spec/unit/set_current_spec.rb
|