Class: MrMurano::Progress

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/MrMurano/progress.rb

Overview

Progress is a singleton (evil!) that implements a terminal progress bar.

Constant Summary collapse

EXO_QUADRANTS =
[
  '▚',
  '▘',
  '▝',
  '▞',
  '▖',
  '▗',
].freeze
EXO_QUADRANTS_7 =
[
  '-',
  '\\',
  '|',
  '/',
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProgress

Returns a new instance of Progress.



19
20
21
22
23
24
25
# File 'lib/MrMurano/progress.rb', line 19

def initialize
  @whirly_msg = ''
  @whirly_time = nil
  @whirly_users = 0
  @whirly_cols = 0
  @whirly_pauses = 0
end

Class Method Details

.strip_color(str) ⇒ Object

(lb): MAYBE: Move strip_color to a string helper module…

like lib/MrMurano/variegated/...?


155
156
157
# File 'lib/MrMurano/progress.rb', line 155

def self.strip_color(str)
  str.gsub(/\e\[[;0-9]+m/, '')
end

Instance Method Details

#strip_color(str) ⇒ Object



159
160
161
# File 'lib/MrMurano/progress.rb', line 159

def strip_color(str)
  MrMurano::Progress.strip_color(str)
end

#whirly_clearObject



103
104
105
106
107
108
109
# File 'lib/MrMurano/progress.rb', line 103

def whirly_clear
  Whirly.stop
  # The progress indicator is always overwritten.
  return unless @whirly_cols
  $stdout.print((' ' * @whirly_cols) + "\r")
  $stdout.flush
end

#whirly_interjectObject



147
148
149
150
151
# File 'lib/MrMurano/progress.rb', line 147

def whirly_interject
  whirly_pause
  yield
  whirly_unpause
end

#whirly_lingerObject



111
112
113
114
115
116
# File 'lib/MrMurano/progress.rb', line 111

def whirly_linger
  return if $cfg['tool.no-progress'] || @whirly_time.nil?
  not_so_fast = 0.55 - (Time.now - @whirly_time)
  @whirly_time = nil
  sleep(not_so_fast) if not_so_fast > 0
end

#whirly_msg(msg) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/MrMurano/progress.rb', line 118

def whirly_msg(msg)
  return if $cfg['tool.no-progress']
  if @whirly_time.nil?
    whirly_start msg
  else
    @whirly_msg = msg
    #self.whirly_linger
    # Clear the line.
    Whirly.configure(status: ' ' * @whirly_cols)
    Whirly.configure(status: @whirly_msg)
    @whirly_cols = strip_color(@whirly_msg).length + '...'.length
  end
end

#whirly_pauseObject



132
133
134
135
136
137
# File 'lib/MrMurano/progress.rb', line 132

def whirly_pause
  @whirly_pauses += 1
  return if @whirly_pauses > 1
  return if @whirly_users.zero?
  whirly_clear
end

#whirly_showObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/MrMurano/progress.rb', line 63

def whirly_show
  if $cfg['tool.ascii'] || OS.windows?
    spinner = EXO_QUADRANTS_7
    ansi_escape_mode = 'line'
  else
    spinner = EXO_QUADRANTS
    ansi_escape_mode = 'restore'
  end
  Whirly.start(
    spinner: spinner,
    status: @whirly_msg,
    append_newline: false,
    #remove_after_stop: false,
    #stream: $stderr,
    ansi_escape_mode: ansi_escape_mode,
  )
  @whirly_time = Time.now
  # The whitespace we add ends up getting picked up if you copy
  # from the terminal. [lb] not sure if we can fix that... but
  # we can at least minimize the amount of it to the longest
  # message, rather than the terminal column width.
  #@whirly_cols, _rows = HighLine::SystemExtensions.terminal_size
  # Note that Whirly adds '...', so add its length, too.
  # rubocop:disable Performance/FixedSize
  #   Do not compute the size of statically sized objects.
  @whirly_cols = strip_color(@whirly_msg).length + '...'.length
end

#whirly_start(msg) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/MrMurano/progress.rb', line 43

def whirly_start(msg)
  if $cfg['tool.verbose']
    whirly_pause if @whirly_users > 0
    say msg
    whirly_unpause if @whirly_users > 0
  end
  return if $cfg['tool.no-progress']
  # Count the number of calls to whirly_start, so that the
  # first call to whirly_start is the message that gets
  # printed. This way, methods can define a default message
  # to use, but then callers of those methods can choose to
  # display a different message.
  @whirly_users += 1
  # The first Whirly message is the one we show.
  return if @whirly_users > 1
  @whirly_msg = msg
  whirly_stop
  whirly_show
end

#whirly_stop(force: false) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/MrMurano/progress.rb', line 91

def whirly_stop(force: false)
  return if $cfg['tool.no-progress'] || @whirly_time.nil?
  if force
    @whirly_users = 0
  else
    @whirly_users -= 1
  end
  return unless @whirly_users.zero?
  whirly_linger
  whirly_clear
end

#whirly_unpauseObject



139
140
141
142
143
144
145
# File 'lib/MrMurano/progress.rb', line 139

def whirly_unpause
  @whirly_pauses -= 1
  raise 'Whirly unpaused once too many' if @whirly_pauses < 0
  return unless @whirly_pauses == 0
  return if @whirly_users.zero?
  whirly_show
end