Class: TTY::Spinner
- Inherits:
-
Object
- Object
- TTY::Spinner
- Includes:
- Formats
- Defined in:
- lib/tty/spinner.rb,
lib/tty/spinner/multi.rb,
lib/tty/spinner/version.rb
Overview
Used for creating terminal spinner
Defined Under Namespace
Classes: Multi
Constant Summary collapse
- NotSpinningError =
Class.new(StandardError)
- ECMA_CSI =
"\x1b[".freeze
- MATCHER =
/:spinner/
- TICK =
'✔'.freeze
- CROSS =
'✖'.freeze
- CURSOR_USAGE_LOCK =
Monitor.new
- VERSION =
"0.5.0"
Constants included from Formats
Instance Attribute Summary collapse
-
#format ⇒ String
readonly
The current format type.
-
#hide_cursor ⇒ Boolean
readonly
Whether to show or hide cursor.
-
#message ⇒ String
readonly
The message to print before the spinner.
-
#output ⇒ Object
readonly
The object that responds to print call defaulting to stderr.
-
#tokens ⇒ Hash[Symbol, Object]
readonly
Tokens for the message.
Instance Method Summary collapse
-
#add_multispinner(multispinner, index) ⇒ Object
private
Notifies the TTY::Spinner that it is running under a multispinner.
-
#auto_spin ⇒ Object
Start automatic spinning animation.
-
#clear_line ⇒ Object
Clear current line.
-
#done? ⇒ Boolean
Whether the spinner has completed spinning.
-
#duration ⇒ Numeric
Duration of the spinning animation.
-
#error(stop_message = '') ⇒ Object
Finish spinning and set state to :error.
-
#error? ⇒ Boolean
Whether the spinner is in the error state.
-
#initialize(*args) ⇒ Spinner
constructor
Initialize a spinner.
-
#job(&work) ⇒ Object
Add job to this spinner.
-
#job? ⇒ Boolean
Check if this spinner has a scheduled job.
-
#join(timeout = nil) ⇒ Object
Join running spinner.
-
#kill ⇒ Object
Kill running spinner.
-
#next_char ⇒ String
private
Retrieve next character.
-
#on(name, &block) ⇒ Object
Register callback.
-
#pause ⇒ Object
Pause spinner automatic animation.
-
#paused? ⇒ Boolean
Checked if current spinner is paused.
-
#redraw_indent ⇒ Object
private
Redraw the indent for this spinner, if it exists.
-
#reset ⇒ Object
Reset the spinner to initial frame.
-
#resume ⇒ Object
Resume spinner automatic animation.
-
#run(stop_message = '') { ... } ⇒ Object
Run spinner while executing job.
-
#spin ⇒ String
Perform a spin.
-
#spinning? ⇒ Boolean
Whether the spinner is spinning.
-
#start ⇒ Object
Start timer and unlock spinner.
-
#stop(stop_message = '') ⇒ Object
Finish spining.
-
#success(stop_message = '') ⇒ Object
Finish spinning and set state to :success.
-
#success? ⇒ Boolean
Whether the spinner is in the success state.
-
#update(tokens) ⇒ Object
Update string formatting tokens.
Constructor Details
#initialize(*args) ⇒ Spinner
Initialize a spinner
83 84 85 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 |
# File 'lib/tty/spinner.rb', line 83 def initialize(*args) = args.last.is_a?(::Hash) ? args.pop : {} @message = args.empty? ? ':spinner' : args.pop @tokens = {} @format = .fetch(:format) { :classic } @output = .fetch(:output) { $stderr } @hide_cursor = .fetch(:hide_cursor) { false } @frames = .fetch(:frames) do fetch_format(@format.to_sym, :frames) end @clear = .fetch(:clear) { false } @success_mark= .fetch(:success_mark) { TICK } @error_mark = .fetch(:error_mark) { CROSS } @interval = .fetch(:interval) do fetch_format(@format.to_sym, :interval) end @callbacks = Hash.new { |h, k| h[k] = [] } @length = @frames.length @current = 0 @done = false @state = :stopped @thread = nil @job = nil @multispinner= nil @index = nil @succeeded = false @first_run = true end |
Instance Attribute Details
#format ⇒ String (readonly)
The current format type
37 38 39 |
# File 'lib/tty/spinner.rb', line 37 def format @format end |
#hide_cursor ⇒ Boolean (readonly)
Whether to show or hide cursor
44 45 46 |
# File 'lib/tty/spinner.rb', line 44 def hide_cursor @hide_cursor end |
#message ⇒ String (readonly)
The message to print before the spinner
52 53 54 |
# File 'lib/tty/spinner.rb', line 52 def @message end |
#output ⇒ Object (readonly)
The object that responds to print call defaulting to stderr
30 31 32 |
# File 'lib/tty/spinner.rb', line 30 def output @output end |
#tokens ⇒ Hash[Symbol, Object] (readonly)
Tokens for the message
60 61 62 |
# File 'lib/tty/spinner.rb', line 60 def tokens @tokens end |
Instance Method Details
#add_multispinner(multispinner, index) ⇒ 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.
Notifies the TTY::Spinner that it is running under a multispinner
120 121 122 123 |
# File 'lib/tty/spinner.rb', line 120 def add_multispinner(multispinner, index) @multispinner = multispinner @index = index end |
#auto_spin ⇒ Object
Start automatic spinning animation
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/tty/spinner.rb', line 203 def auto_spin CURSOR_USAGE_LOCK.synchronize do start sleep_time = 1.0 / @interval spin @thread = Thread.new do sleep(sleep_time) while @started_at if Thread.current['pause'] Thread.stop Thread.current['pause'] = false end spin sleep(sleep_time) end end end end |
#clear_line ⇒ Object
Clear current line
404 405 406 |
# File 'lib/tty/spinner.rb', line 404 def clear_line write(ECMA_CSI + '0m' + TTY::Cursor.clear_line) end |
#done? ⇒ Boolean
Whether the spinner has completed spinning
130 131 132 |
# File 'lib/tty/spinner.rb', line 130 def done? @done end |
#duration ⇒ Numeric
Duration of the spinning animation
277 278 279 |
# File 'lib/tty/spinner.rb', line 277 def duration @started_at ? Time.now - @started_at : nil end |
#error(stop_message = '') ⇒ Object
Finish spinning and set state to :error
393 394 395 396 397 398 399 |
# File 'lib/tty/spinner.rb', line 393 def error( = '') return if done? @succeeded = :error stop() emit(:error) end |
#error? ⇒ Boolean
Whether the spinner is in the error state. This is only true temporarily while it is being marked with a failure mark.
159 160 161 |
# File 'lib/tty/spinner.rb', line 159 def error? @succeeded == :error end |
#job(&work) ⇒ Object
Add job to this spinner
183 184 185 186 187 188 189 |
# File 'lib/tty/spinner.rb', line 183 def job(&work) if block_given? @job = work else @job end end |
#job? ⇒ Boolean
Check if this spinner has a scheduled job
196 197 198 |
# File 'lib/tty/spinner.rb', line 196 def job? !@job.nil? end |
#join(timeout = nil) ⇒ Object
Join running spinner
287 288 289 290 291 292 293 |
# File 'lib/tty/spinner.rb', line 287 def join(timeout = nil) unless @thread raise(NotSpinningError, 'Cannot join spinner that is not running') end timeout ? @thread.join(timeout) : @thread.join end |
#kill ⇒ Object
Kill running spinner
298 299 300 |
# File 'lib/tty/spinner.rb', line 298 def kill @thread.kill if @thread end |
#next_char ⇒ String
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.
Retrieve next character
369 370 371 372 373 374 375 376 377 |
# File 'lib/tty/spinner.rb', line 369 def next_char if success? @success_mark elsif error? @error_mark else @frames[@current - 1] end end |
#on(name, &block) ⇒ Object
Register callback
166 167 168 169 |
# File 'lib/tty/spinner.rb', line 166 def on(name, &block) @callbacks[name] << block self end |
#pause ⇒ Object
Pause spinner automatic animation
235 236 237 238 239 |
# File 'lib/tty/spinner.rb', line 235 def pause return if paused? @thread['pause'] = true if @thread end |
#paused? ⇒ Boolean
Checked if current spinner is paused
228 229 230 |
# File 'lib/tty/spinner.rb', line 228 def paused? !!(@thread && @thread['pause']) end |
#redraw_indent ⇒ 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.
Redraw the indent for this spinner, if it exists
326 327 328 329 330 331 332 |
# File 'lib/tty/spinner.rb', line 326 def redraw_indent if @hide_cursor && !spinning? write(ECMA_CSI + DEC_TCEM + DEC_RST) end write("", false) end |
#reset ⇒ Object
Reset the spinner to initial frame
422 423 424 425 |
# File 'lib/tty/spinner.rb', line 422 def reset @current = 0 @first_run = true end |
#resume ⇒ Object
Resume spinner automatic animation
244 245 246 247 248 |
# File 'lib/tty/spinner.rb', line 244 def resume return unless paused? @thread.wakeup if @thread end |
#run(stop_message = '') { ... } ⇒ Object
Run spinner while executing job
261 262 263 264 265 266 267 268 269 270 |
# File 'lib/tty/spinner.rb', line 261 def run( = '', &block) auto_spin @work = Thread.new { instance_eval(&block) } @work.join ensure stop() end |
#spin ⇒ String
Perform a spin
308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/tty/spinner.rb', line 308 def spin return if @done if @hide_cursor && !spinning? write(TTY::Cursor.hide) end data = .gsub(MATCHER, @frames[@current]) data = replace_tokens(data) write(data, true) @current = (@current + 1) % @length @state = :spinning data end |
#spinning? ⇒ Boolean
Whether the spinner is spinning
139 140 141 |
# File 'lib/tty/spinner.rb', line 139 def spinning? @state == :spinning end |
#start ⇒ Object
Start timer and unlock spinner
174 175 176 177 178 |
# File 'lib/tty/spinner.rb', line 174 def start @started_at = Time.now @done = false reset end |
#stop(stop_message = '') ⇒ Object
Finish spining
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/tty/spinner.rb', line 340 def stop( = '') return if done? if @hide_cursor write(TTY::Cursor.show, false) end return clear_line if @clear data = .gsub(MATCHER, next_char) data = replace_tokens(data) if !.empty? data << ' ' + end write(data, true) write("\n", false) unless @clear || @multispinner ensure @state = :stopped @done = true @started_at = nil emit(:done) kill end |
#success(stop_message = '') ⇒ Object
Finish spinning and set state to :success
382 383 384 385 386 387 388 |
# File 'lib/tty/spinner.rb', line 382 def success( = '') return if done? @succeeded = :success stop() emit(:success) end |
#success? ⇒ Boolean
Whether the spinner is in the success state. When true the spinner is marked with a success mark.
149 150 151 |
# File 'lib/tty/spinner.rb', line 149 def success? @succeeded == :success end |
#update(tokens) ⇒ Object
Update string formatting tokens
414 415 416 417 |
# File 'lib/tty/spinner.rb', line 414 def update(tokens) clear_line if spinning? @tokens.merge!(tokens) end |