<commit_before>
class AngryMob
  class UI
    # Embed in a String to clear all previous ANSI sequences.
    CLEAR      = "\e[0m"
    # The start of an ANSI bold sequence.
    BOLD       = "\e[1m"

    # Set the terminal's foreground ANSI color to black.
    BLACK      = "\e[30m"
    # Set the terminal's foreground ANSI color to red.
    RED        = "\e[31m"
    # Set the terminal's foreground ANSI color to green.
    GREEN      = "\e[32m"
    # Set the terminal's foreground ANSI color to yellow.
    YELLOW     = "\e[33m"
    # Set the terminal's foreground ANSI color to blue.
    BLUE       = "\e[34m"
    # Set the terminal's foreground ANSI color to magenta.
    MAGENTA    = "\e[35m"
    # Set the terminal's foreground ANSI color to cyan.
    CYAN       = "\e[36m"
    # Set the terminal's foreground ANSI color to white.
    WHITE      = "\e[37m"

    GRAY      = "#{BOLD}#{BLACK}"

    BRIGHT_WHITE = "#{BOLD}#{WHITE}"

    # Set the terminal's background ANSI color to black.
    ON_BLACK   = "\e[40m"
    # Set the terminal's background ANSI color to red.
    ON_RED     = "\e[41m"
    # Set the terminal's background ANSI color to green.
    ON_GREEN   = "\e[42m"
    # Set the terminal's background ANSI color to yellow.
    ON_YELLOW  = "\e[43m"
    # Set the terminal's background ANSI color to blue.
    ON_BLUE    = "\e[44m"
    # Set the terminal's background ANSI color to magenta.
    ON_MAGENTA = "\e[45m"
    # Set the terminal's background ANSI color to cyan.
    ON_CYAN    = "\e[46m"
    # Set the terminal's background ANSI color to white.
    ON_WHITE   = "\e[47m"
    
    attr_reader :level, :result, :message, :stack

    def initialize(options={}, min_level=0, stack=[])
      @options = options
      @stack = stack
      @min_level = @level = min_level
      @colour = CLEAR
    end

    #def self.stack; @stack ||= [] end
    #def stack; self.class.stack end
    def current
      stack.last || self
    end

    def colourise(string, colour, bold=false)
      color = self.class.const_get(colour.to_s.upcase) if colour.is_a?(Symbol)
      bold  = bold ? BOLD : ""
      "#{bold}#{color}#{string}#{CLEAR}"
    end

    def recolourize(colour)
      $stdout.print("\e[s\e[1G#{RED}\e[u")
    end

    def say(message="", colour=nil, force_new_line=(message.to_s !~ /( |\t)$/))
      return if self.class.silence?

      message  = message.to_s
      message  = colourise(message, colour) if colour

      if force_new_line
        $stdout.puts(message)
      else
        $stdout.print(message)
        $stdout.flush
      end
    end

    def isay(message, colour=nil, force_new_line=(message.to_s !~ /( |\t)$/))
      say spaces+message, colour, force_new_line
    end

    def newline
      $stdout.puts "\n" unless self.class.silence?
    end

    def spaces
      "  " * @level
    end

    def indent
      @level += 1
    end

    def outdent
      @level -= 1
      @level = @min_level if @level < @min_level
    end

    def self.silence(&block)
      old_silence,@silence = @silence,true
      yield
    ensure
      @silence = old_silence
    end
    def self.silence?
      @silence
    end
    def silence(&block)
      self.class.silence(&block)
    end
    def silence(&block)
      self.class.silence(&block)
    end

    def info(message)
      say spaces+message, :bright_white
    end

    def good(message)
      say spaces+message, :green
    end

    def task(message)
      sigil('>>', message)
    end

    def sigil(sigil,message,colour=:blue)
      isay "#{sigil} ", colour
      say message
    end

    def log(message)
      say spaces+indent_string(message, @level+1), :white
    end

    def point(message)
      say spaces+"● #{message}", :blue
    end

    def error(message)
      say spaces+message, :red
    end
    alias_method :bad, :error

    def debug?
      @debug ||= !(FalseClass === @options[:debug])
    end
    def debug(message)
      say spaces+message, :gray if debug?
    end

    def benchmark?
      @benchmark ||= !(FalseClass === @options[:benchmark])
    end

    def warn(message)
      say spaces+message, :yellow
    end

    def push(message,opts={},&block)
      start_time = Time.now
      start! message<commit_msg>add an exception printer (as opposed to the existing exception bubbler)<commit_after>
class AngryMob
  class UI
    # Embed in a String to clear all previous ANSI sequences.
    CLEAR      = "\e[0m"
    # The start of an ANSI bold sequence.
    BOLD       = "\e[1m"

    # Set the terminal's foreground ANSI color to black.
    BLACK      = "\e[30m"
    # Set the terminal's foreground ANSI color to red.
    RED        = "\e[31m"
    # Set the terminal's foreground ANSI color to green.
    GREEN      = "\e[32m"
    # Set the terminal's foreground ANSI color to yellow.
    YELLOW     = "\e[33m"
    # Set the terminal's foreground ANSI color to blue.
    BLUE       = "\e[34m"
    # Set the terminal's foreground ANSI color to magenta.
    MAGENTA    = "\e[35m"
    # Set the terminal's foreground ANSI color to cyan.
    CYAN       = "\e[36m"
    # Set the terminal's foreground ANSI color to white.
    WHITE      = "\e[37m"

    GRAY      = "#{BOLD}#{BLACK}"

    BRIGHT_WHITE = "#{BOLD}#{WHITE}"

    # Set the terminal's background ANSI color to black.
    ON_BLACK   = "\e[40m"
    # Set the terminal's background ANSI color to red.
    ON_RED     = "\e[41m"
    # Set the terminal's background ANSI color to green.
    ON_GREEN   = "\e[42m"
    # Set the terminal's background ANSI color to yellow.
    ON_YELLOW  = "\e[43m"
    # Set the terminal's background ANSI color to blue.
    ON_BLUE    = "\e[44m"
    # Set the terminal's background ANSI color to magenta.
    ON_MAGENTA = "\e[45m"
    # Set the terminal's background ANSI color to cyan.
    ON_CYAN    = "\e[46m"
    # Set the terminal's background ANSI color to white.
    ON_WHITE   = "\e[47m"
    
    attr_reader :level, :result, :message, :stack

    def initialize(options={}, min_level=0, stack=[])
      @options = options
      @stack = stack
      @min_level = @level = min_level
      @colour = CLEAR
    end

    #def self.stack; @stack ||= [] end
    #def stack; self.class.stack end
    def current
      stack.last || self
    end

    def colourise(string, colour, bold=false)
      color = self.class.const_get(colour.to_s.upcase) if colour.is_a?(Symbol)
      bold  = bold ? BOLD : ""
      "#{bold}#{color}#{string}#{CLEAR}"
    end

    def recolourize(colour)
      $stdout.print("\e[s\e[1G#{RED}\e[u")
    end

    def say(message="", colour=nil, force_new_line=(message.to_s !~ /( |\t)$/))
      return if self.class.silence?

      message  = message.to_s
      message  = colourise(message, colour) if colour

      if force_new_line
        $stdout.puts(message)
      else
        $stdout.print(message)
        $stdout.flush
      end
    end

    def isay(message, colour=nil, force_new_line=(message.to_s !~ /( |\t)$/))
      say spaces+message, colour, force_new_line
    end

    def newline
      $stdout.puts "\n" unless self.class.silence?
    end

    def spaces
      "  " * @level
    end

    def indent
      @level += 1
    end

    def outdent
      @level -= 1
      @level = @min_level if @level < @min_level
    end

    def self.silence(&block)
      old_silence,@silence = @silence,true
      yield
    ensure
      @silence = old_silence
    end
    def self.silence?
      @silence
    end
    def silence(&block)
      self.class.silence(&block)
    end
    def silence(&block)
      self.class.silence(&block)
    end

    def info(message)
      say spaces+message, :bright_white
    end

    def good(message)
      say spaces+message, :green
    end

    def task(message)
      sigil('>>', message)
    end

    def sigil(sigil,message,colour=:blue)
      isay "#{sigil} ", colour
      say message
    end

    def log(message)
      say spaces+indent_string(message, @level+1), :white
    end

    def point(message)
      say spaces+"● #{message}", :blue
    end

    def error(message)
      say spaces+message, :red
    end
    alias_method :bad, :error

    def ex(message,ex)
      error "#{message} [#{$!.class}] #{$!}"
      ex.backtrace.each {|line| error line}
    end

    def debug?
      @debug ||= !(FalseClass === @options[:debug])
    end
    def debug(message)
      say spaces+message, :gray if debug?
    end

    def benchmark?
      @benchmark ||= !(FalseClass === @options[:benchmark])
    end

    def warn(message)
      say spaces+message, :yellow
    end

    def push(message,opts={},&block)
      start_time = Time.now
      start! message
{'fraction_non_alphanumeric': 0.11627366709257754, 'fraction_numerical': 0.009060285747473574, 'mean_word_length': 2.244159758854559, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1414391', 'n_tokens_mistral': 3008, 'n_tokens_neox': 2847, 'n_words': 817}