# frozen_string_literal: true require 'pry' require 'helium/console/version' require 'helium/console/formatters/indent' require 'helium/console/formatters/overflow' require 'helium/console/formatters/max_lines' require 'helium/console/colorized_string' require 'helium/console/key_value' require 'helium/console/registry' require 'helium/console/printer' require 'helium/console/prompt' module Helium class Console Error = Class.new(StandardError) SIMPLE_OBJECTS = [ Numeric, NilClass, FalseClass, TrueClass, Symbol ].freeze def self.start(target = nil, options = {}) options = { print: ColorPrinter.method(:default), prompt: Prompt.new.pry_prompt }.merge(options) Pry.start(target, options) end def self.define_formatter_for(klass, &handler) Registry.instance_formatters.define(klass, &handler) end def self.define_class_formatter_for(klass, &handler) Registry.class_formatters.define(klass, &handler) end class << self def instance @instance ||= new end def method_missing(name, *args, **keywords, &block) super unless instance.respond_to?(name) instance.public_send(name, *args, **keywords, &block) end def respond_to_missing?(name, private = false) instance.respond_to?(name) || super end end def initialize(instance_registry: nil, class_registry: nil) @instance_registry = instance_registry || Registry.instance_formatters @class_registry = class_registry || Registry.class_formatters end def format(object, style = nil, **options) options = default_options.merge(options) return '(...)' if options[:ignore_objects].include?(object.object_id) handler_for(object, style, **options).() end def simple?(object, style = nil, **options) SIMPLE_OBJECTS.any? { |simple_obj_class| object.is_a? simple_obj_class } || handler_for(object, style, **options).simple? end def default_options { overflow: :wrap, indent: 0, level: 1, ignore_objects: [], short: false } end def format_string(string, ellipses: '...', **options) options = default_options.merge(options) max_width_without_indent = (options[:max_width] - options[:indent]) if options[:max_width] formatters = [ Formatters::Overflow.get(options[:overflow]).new(max_width: max_width_without_indent), Formatters::Indent.new(options[:indent]), Formatters::MaxLines.new( max_lines: options[:max_lines], max_width: options[:max_width], ellipses: ellipses ) ] formatters.inject(string) do |str, formatter| formatter.(str) end end private attr_reader :instance_registry, :class_registry def handler_for(object, style, **options) formatter_class = if object.is_a? Module class_registry.handler_for(object) else instance_registry.handler_for(object.class) end formatter_class&.new(object, style, self, **options) end end end Dir.glob(File.join(File.dirname(__FILE__), 'console', 'registry', '**/*.rb')).sort.each do |file| require file end