b0VIM 7.4,Xdanok~dan/dev/gems/whirly/lib/whirly.rbutf-8 3210#"! Utpyadqplk]GF3xZ?( } r q V C /    y c [ U T 1  t f 5 ,   ] *   X P O C = <  B.XN4|rji^XWx_WV98[ZzH/.qp # only do something if we are on a real terminal (or forced) @enabled = true # set status to enabled return false if defined?(@enabled) && @enabled # only enable once configure(**options) # optionally overwrite configuration on start def self.start(**options) end @status = @options[:status] @stop = @options[:stop] || spinner["stop"] @interval = (@options[:interval] || spinner["interval"] || SOFT_DEFAULT_OPTIONS[:interval]) * 0.001 @frames = configure_frames(spinner.merge(spinner_overwrites)) spinner_overwrites["mode"] = @options[:mode] if @options.key?(:mode) spinner_overwrites = {} spinner = configure_spinner(@options[:spinner]) @options.merge!(options) end @configured = true @options = DEFAULT_OPTIONS.dup if !defined?(@configured) || !@configured || !defined?(@options) || !@options def self.configure(**options) # save options and preprocess, set defaults if value is still unknown end frames end end alias next call class << frames if frames.is_a? Proc end raise(ArgumentError, "Whirly: Invalid spinner given") else frames = spinner["proc"].dup elsif spinner["proc"] end frames = spinner["frames"].cycle else frames = spinner["frames"].to_a.reverse.cycle when "reverse" frames = ->(){ frame_pool.sample } frame_pool = spinner["frames"].to_a when "random" frames = (spinner["frames"].to_a + spinner["frames"].to_a[1..-2].reverse).cycle when "swing" case spinner["mode"] if spinner["frames"] def self.configure_frames(spinner) # frames can be generated from enumerables or procs end spinner end raise(ArgumentError, "Whirly: Invalid spinner given") if !spinner || (!spinner["frames"] && !spinner["proc"]) # validate spinner end } } end throw(:found) spinner = spinners[spinner_option].dup if spinners[spinner_option] spinners = Whirly::Spinners.const_get(spinner_pack.to_s.upcase) @options[:spinner_packs].each{ |spinner_pack| catch(:found){ spinner = nil else spinner = { "proc" => spinner_option.dup } when Proc spinner = { "frames" => spinner_option.dup } when Enumerable spinner = spinner_option.dup when Hash case spinner_option def self.configure_spinner(spinner_option) # set spinner directly or lookup end end !!(@configured) def configured? end !!(defined?(@enabled) && @enabled) def enabled? attr_reader :options attr_accessor :status class << self }.freeze stop: nil, mode: "linear", interval: 100, SOFT_DEFAULT_OPTIONS = { }.freeze stream: $stdout, status: nil, spinner_packs: [:whirly, :cli], spinner: "whirly", remove_after_stop: false, position: "normal", non_tty: false, hide_cursor: true, color_change_rate: 30, color: !!defined?(Paint), append_newline: true, ansi_escape_mode: "restore", ambiguous_character_width: 1, DEFAULT_OPTIONS = { }.freeze show_cursor: "\x1b[?25h", hide_cursor: "\x1b[?25l", CLI_COMMANDS = { @configured = falsemodule Whirlyendrescue LoadError require "paint"beginrequire "unicode/display_width"require_relative "whirly/spinners"require_relative "whirly/version"ady\ogfU,+ w :   n d \ [ R L K )  U ( }  { z p o [ :   mTDf65H f^XW;#zrlkU`J9eend endeend end }.join "%.2x" % nc end @color_directions[i] = rand(3) - 1 nc = 255 elsif nc >= 255 @color_directions[i] = rand(3) - 1 nc = 0 if nc <= 0 nc = c.to_i(16) + color_change color_change = rand(@options[:color_change_rate]) * @color_directions[i] @color = @color.scan(/../).map.with_index{ |c, i| def self.next_color end end @color_directions = (0..2).map{ |e| rand(3) - 1 } @color = "%.6x" % rand(16777216) else warn "Whirly warning: Using colors requires the paint gem" if !defined?(Paint) def self.initialize_color end res res << "\e[1A" if @options[:position] == "below" res << "\e8" if @options[:ansi_escape_mode] == "restore" res = "" def self.render_suffix end res res << "\e[G" if @options[:ansi_escape_mode] == "line" res << "\e7" if @options[:ansi_escape_mode] == "restore" res << "\n" if @options[:position] == "below" res = "" def self.render_prefix end @options[:stream].print(render_prefix + @current_frame.to_s + render_suffix) @current_frame += " #{@status}" if @status @current_frame = Paint[@current_frame, @color] if @options[:color] @current_frame = next_frame || @frames.next unrender def self.render(next_frame = nil) end end @options[:stream].print "\e[1K" when "line" ) + render_suffix) ' ' * (Unicode::DisplayWidth.of(@current_frame, @options[:ambiguous_character_width]) + 1) @options[:stream].print(render_prefix + ( when "restore" case @options[:ansi_escape_mode] return unless @current_frame def self.unrender # - - - end @configured = false @at_exit_handler_registered = at_exit_handler_registered instance_variables.each{ |iv| remove_instance_variable(iv) } at_exit_handler_registered = defined?(@at_exit_handler_registered) && @at_exit_handler_registered def self.reset end true @options[:stream].print CLI_COMMANDS[:show_cursor] if @options[:hide_cursor] @options[:stream].puts if @options[:append_newline] unrender if @options[:remove_after_stop] render(stop_frame || @stop) if stop_frame || @stop @thread.terminate if @thread return false unless @options[:stream].tty? || @options[:non_tty] @enabled = false return false unless @enabled def self.stop(stop_frame = nil) end true end end Whirly.stop ensure yield begin if block_given? # idiomatic block syntax support end end sleep(@interval) render next_color if @color while true # it's just a spinner, no exact timing here @current_frame = nil @thread = Thread.new do # start spinner loop @options[:stream].print CLI_COMMANDS[:hide_cursor] if @options[:hide_cursor] # hide cursor initialize_color if @options[:color] # init color end at_exit{ stream.print CLI_COMMANDS[:show_cursor] } stream = @options[:stream] @at_exit_handler_registered = true if (!defined?(@at_exit_handler_registered) || !@at_exit_handler_registered) && @options[:hide_cursor] # ensure cursor is visible after exit the program (only register for the very first time) return false unless @options[:stream].tty? || @options[:non_tty]