Class: Thor::Interactive::TUI::Spinner

Inherits:
Object
  • Object
show all
Defined in:
lib/thor/interactive/tui/spinner.rb

Overview

Spinner animation for indicating activity during command execution. Shows rotating fun messages like Claude Code.

Constant Summary collapse

FRAMES =
%w[         ].freeze
INTERVAL =

seconds between frames

0.08
DEFAULT_MESSAGES =

Rotate through fun messages during long operations. Apps can provide their own list via configure_interactive(spinner_messages: […])

[
  "Thinking",
  "Pondering",
  "Crunching",
  "Churning",
  "Whirring",
  "Brewing",
  "Conjuring",
  "Simmering",
  "Percolating",
  "Contemplating",
  "Noodling",
  "Ruminating",
  "Calculating",
  "Assembling",
  "Composing"
].freeze
MESSAGE_ROTATE_INTERVAL =

seconds between message changes

3.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(messages: nil) ⇒ Spinner

Returns a new instance of Spinner.



36
37
38
39
40
41
42
43
44
45
# File 'lib/thor/interactive/tui/spinner.rb', line 36

def initialize(messages: nil)
  @messages = messages || DEFAULT_MESSAGES
  @message = @messages.first
  @message_index = 0
  @last_message_change = Time.now
  @frame_index = 0
  @last_advance = Time.now
  @active = false
  @start_time = nil
end

Instance Attribute Details

#messageObject (readonly)

Returns the value of attribute message.



34
35
36
# File 'lib/thor/interactive/tui/spinner.rb', line 34

def message
  @message
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/thor/interactive/tui/spinner.rb', line 61

def active?
  @active
end

#advanceObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/thor/interactive/tui/spinner.rb', line 65

def advance
  now = Time.now
  if now - @last_advance >= INTERVAL
    @frame_index = (@frame_index + 1) % FRAMES.length
    @last_advance = now
  end

  # Rotate message periodically
  if now - @last_message_change >= MESSAGE_ROTATE_INTERVAL
    @message_index = (@message_index + 1) % @messages.length
    @message = @messages[@message_index]
    @last_message_change = now
  end
end

#elapsedObject



80
81
82
83
# File 'lib/thor/interactive/tui/spinner.rb', line 80

def elapsed
  return 0 unless @start_time
  Time.now - @start_time
end

#start(message = nil) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/thor/interactive/tui/spinner.rb', line 47

def start(message = nil)
  @message = message || @messages.sample
  @message_index = @messages.index(@message) || 0
  @last_message_change = Time.now
  @active = true
  @start_time = Time.now
  @frame_index = 0
end

#stopObject



56
57
58
59
# File 'lib/thor/interactive/tui/spinner.rb', line 56

def stop
  @active = false
  @start_time = nil
end

#to_sObject



85
86
87
88
89
90
91
# File 'lib/thor/interactive/tui/spinner.rb', line 85

def to_s
  return "" unless @active

  advance
  elapsed_str = format_elapsed(elapsed)
  " #{FRAMES[@frame_index]} #{@message}... #{elapsed_str} "
end