Module: IRB
Overview
history.rb -
by Keiju ISHITSUKA(keiju@ruby-lang.org)
Constant Summary
-
ExtendCommand =
# File 'lib/irb/default_commands.rb', line 255Command
-
IRBRC_EXT =
Internal use only
# File 'lib/irb/init.rb', line 407"rc"
-
TOPLEVEL_BINDING =
# File 'lib/irb/workspace.rb', line 9binding
-
VERSION =
Internal use only
# File 'lib/irb/version.rb', line 8"1.15.0"
Class Attribute Summary
- .initialized? ⇒ Boolean readonly Internal use only
Class Method Summary
- .easter_egg(type = nil)
- .easter_egg_logo(type)
-
.start(ap_path = nil)
Initializes IRB and creates a new
Irb.irb
object at the TOPLEVEL_BINDING -
.conf
Internal use only
Displays current configuration.
- CurrentContext Internal use only
- .init_config(ap_path) Internal use only
- .init_error Internal use only
- .inspect Internal use only
-
Inspector(inspect, init = nil)
Internal use only
Convenience method to create a new
Inspector
, using the given .inspect proc, and optionalinit
proc and passes them to Inspector.new -
.irb(file = nil, *main)
Internal use only
Creates a new
IRB
session, see Irb.new. -
.irb_abort(irb, exception = Abort)
Internal use only
Aborts then interrupts irb.
-
.irb_exit
Internal use only
Quits irb.
- .irbrc_files Internal use only
-
JobManager
Internal use only
The current
JobManager
in the session. -
.load_modules
Internal use only
loading modules.
-
.parse_opts(argv: ::ARGV)
Internal use only
option analyzing.
-
.print_usage
Internal use only
Outputs the irb help message, see IRB@Command-Line+Options.
- .raise_validation_error(msg) Internal use only
- .rc_file(ext) Internal use only
-
.run_config
Internal use only
Run the config file.
- .set_measure_callback(type = nil, arg = nil, &block) Internal use only
-
.setup(ap_path, argv: ::ARGV)
Internal use only
initialize config.
- .unset_measure_callback(type = nil) Internal use only
- .validate_config Internal use only
-
.version
Internal use only
Returns the current version of
IRB
, including release version and last updated date. -
.generate_current_dir_irbrc_files
private
Internal use only
possible irbrc files in current directory.
- .prepare_irbrc_name_generators private Internal use only
-
.rc_file_generators
private
Internal use only
enumerate possible rc-file base name generators.
- .set_encoding(extern, intern = nil, override: true) private Internal use only
Class Attribute Details
.initialized? ⇒ Boolean
(readonly)
# File 'lib/irb/init.rb', line 45
def IRB.initialized? !!@INITIALIZED end
Class Method Details
.conf
Displays current configuration.
Modifying the configuration is achieved by sending a message to conf
.
See IRB@Configuration for more information.
# File 'lib/irb/init.rb', line 15
def IRB.conf @CONF end
CurrentContext
The current ::IRB::Context
of the session, see .conf
irb
irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
See additional method definition at file lib/irb.rb line 38.
# File 'lib/irb/ext/multi-irb.rb', line 174
def CurrentContext # :nodoc: conf[:MAIN_CONTEXT] end
.easter_egg(type = nil)
[ GitHub ]# File 'lib/irb/easter-egg.rb', line 109
private def easter_egg(type = nil) print "\e[?1049h" type ||= [:logo, :dancing].sample case type when :logo Pager.page do |io| logo_type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode_large : :ascii_large io.write easter_egg_logo(logo_type) STDIN.raw { STDIN.getc } if io == STDOUT end when :dancing STDOUT.cooked do interrupted = false prev_trap = trap("SIGINT") { interrupted = true } canvas = Canvas.new(Reline.get_screen_size) Reline::IOGate.set_winch_handler do canvas = Canvas.new(Reline.get_screen_size) end ruby_model = RubyModel.new print "\e[?25l" # hide cursor 0.step do |i| # TODO (0..).each needs Ruby 2.6 or later buff = canvas.draw do ruby_model.render_frame(i) do |p1, p2| canvas.line(p1, p2) end end buff[0, 20] = "\e[0mPress Ctrl+C to stop\e[31m\e[1m" print "\e[H" + buff sleep 0.05 break if interrupted end rescue Interrupt ensure print "\e[?25h" # show cursor trap("SIGINT", prev_trap) end end ensure print "\e[0m\e[?1049l" end
.easter_egg_logo(type)
[ GitHub ]# File 'lib/irb/easter-egg.rb', line 101
private def easter_egg_logo(type) @easter_egg_logos ||= File.read(File.join(__dir__, 'ruby_logo.aa'), encoding: 'UTF-8:UTF-8') .split(/TYPE: ([A-Z_]+)\n/)[1..] .each_slice(2) .to_h @easter_egg_logos[type.to_s.upcase] end
.generate_current_dir_irbrc_files (private)
possible irbrc files in current directory
# File 'lib/irb/init.rb', line 517
def generate_current_dir_irbrc_files current_dir = Dir.pwd %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{current_dir}/#{file}" } end
.init_config(ap_path)
# File 'lib/irb/init.rb', line 65
def IRB.init_config(ap_path) # default configurations unless ap_path and @CONF[:AP_NAME] ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") end @CONF[:VERSION] = version @CONF[:AP_NAME] = File::basename(ap_path, ".rb") @CONF[:IRB_NAME] = "irb" @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) @CONF[:RC] = true @CONF[:LOAD_MODULES] = [] @CONF[:IRB_RC] = nil @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod) @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty? @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false" @CONF[:COMPLETOR] = ENV["IRB_COMPLETOR"]&.to_sym @CONF[:INSPECT_MODE] = true @CONF[:USE_TRACER] = false @CONF[:USE_LOADER] = false @CONF[:IGNORE_SIGINT] = true @CONF[:IGNORE_EOF] = false @CONF[:USE_PAGER] = true @CONF[:EXTRA_DOC_DIRS] = [] @CONF[:ECHO] = nil @CONF[:ECHO_ON_ASSIGNMENT] = nil @CONF[:VERBOSE] = nil @CONF[:EVAL_HISTORY] = nil @CONF[:SAVE_HISTORY] = History::DEFAULT_ENTRY_LIMIT @CONF[:BACK_TRACE_LIMIT] = 16 @CONF[:PROMPT] = { :NULL => { :PROMPT_I => nil, :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => "%s\n" }, :DEFAULT => { :PROMPT_I => "%N(%m):%03n> ", :PROMPT_S => "%N(%m):%03n%l ", :PROMPT_C => "%N(%m):%03n* ", :RETURN => "=> %s\n" }, :CLASSIC => { :PROMPT_I => "%N(%m):%03n:%i> ", :PROMPT_S => "%N(%m):%03n:%i%l ", :PROMPT_C => "%N(%m):%03n:%i* ", :RETURN => "%s\n" }, :SIMPLE => { :PROMPT_I => ">> ", :PROMPT_S => "%l> ", :PROMPT_C => "?> ", :RETURN => "=> %s\n" }, :INF_RUBY => { :PROMPT_I => "%N(%m):%03n> ", :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => "%s\n", :AUTO_INDENT => true }, :XMP => { :PROMPT_I => nil, :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => " ==>%s\n" } } @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL) @CONF[:AUTO_INDENT] = true @CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING @CONF[:SINGLE_IRB] = false @CONF[:MEASURE] = false @CONF[:MEASURE_PROC] = {} @CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block| time = Time.now result = block.() now = Time.now puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE] result } # arg can be either a symbol for the mode (:cpu, :wall, ..) or a hash for # a more complete configuration. # See https://github.com/tmm1/stackprof#all-options. @CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block| return block.() unless IRB.conf[:MEASURE] success = false begin require 'stackprof' success = true rescue LoadError puts 'Please run "gem install stackprof" before measuring by StackProf.' end if success result = nil arg = { mode: arg || :cpu } unless arg.is_a?(Hash) stackprof_result = StackProf.run(**arg) do result = block.() end case stackprof_result when File puts "StackProf report saved to #{stackprof_result.path}" when Hash StackProf::Report.new(stackprof_result).print_text else puts "Stackprof ran with #{arg.inspect}" end result else block.() end } @CONF[:MEASURE_CALLBACKS] = [] @CONF[:LC_MESSAGES] = Locale.new @CONF[:AT_EXIT] = [] @CONF[:COMMAND_ALIASES] = { # Symbol aliases :'$' => :show_source, :'@' => :whereami, } end
.init_error
# File 'lib/irb/init.rb', line 246
def IRB.init_error @CONF[:LC_MESSAGES].load("irb/error.rb") end
.inspect
# File 'lib/irb/init.rb', line 19
def @CONF.inspect array = [] for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name} case k when :MAIN_CONTEXT, :__TMP__EHV__ array.push format("CONF[:%s]=...myself...", k.id2name) when :PROMPT s = v.collect{ |kk, vv| ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"} format(":%s=>{%s}", kk.id2name, ss.join(", ")) } array.push format("CONF[:%s]={%s}", k.id2name, s.join(", ")) else array.push format("CONF[:%s]=%s", k.id2name, v.inspect) end end array.join("\n") end
Inspector(inspect, init = nil)
Convenience method to create a new ::IRB::Inspector
, using the given .inspect proc, and optional init
proc and passes them to Inspector.new
irb(main):001:0> ins = IRB::Inspector(proc{ |v| "omg! #{v}" })
irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
irb(main):001:0> "what?" #=> omg! what?
.irb(file = nil, *main)
Creates a new IRB
session, see Irb.new.
The optional file
argument is given to Context.new, along with the workspace created with the remaining arguments, see WorkSpace.new
# File 'lib/irb/ext/multi-irb.rb', line 182
def IRB.irb(file = nil, *main) # :nodoc: workspace = WorkSpace.new(*main) parent_thread = Thread.current Thread.start do begin irb = Irb.new(workspace, file) rescue print "Subirb can't start with context(self): ", workspace.main.inspect, "\n" print "return to main irb\n" Thread.pass Thread.main.wakeup Thread.exit end @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] @JobManager.insert(irb) @JobManager.current_job = irb begin system_exit = false catch(:IRB_EXIT) do irb.eval_input end rescue SystemExit system_exit = true raise #fail ensure unless system_exit @JobManager.delete(irb) if @JobManager.current_job == irb if parent_thread.alive? @JobManager.current_job = @JobManager.irb(parent_thread) parent_thread.run else @JobManager.current_job = @JobManager.main_irb @JobManager.main_thread.run end end end end end Thread.stop @JobManager.current_job = @JobManager.irb(Thread.current) end
.irb_abort(irb, exception = Abort)
Aborts then interrupts irb.
Will raise an ::IRB::Abort
exception, or the given exception
.
.irb_exit
Quits irb
# File 'lib/irb.rb', line 58
def irb_exit(*) # :nodoc: throw :IRB_EXIT, false end
.irbrc_files
# File 'lib/irb/init.rb', line 426
def IRB.irbrc_files prepare_irbrc_name_generators @irbrc_files end
JobManager
The current ::IRB::JobManager
in the session
# File 'lib/irb/ext/multi-irb.rb', line 169
def IRB.JobManager # :nodoc: @JobManager end
.load_modules
loading modules
# File 'lib/irb/init.rb', line 466
def IRB.load_modules for m in @CONF[:LOAD_MODULES] begin require m rescue LoadError => err warn "#{err.class}: #{err}", uplevel: 0 end end end
.parse_opts(argv: ::ARGV)
option analyzing
# File 'lib/irb/init.rb', line 251
def IRB.parse_opts(argv: ::ARGV) load_path = [] while opt = argv.shift case opt when "-f" @CONF[:RC] = false when "-d" $DEBUG = true $VERBOSE = true when "-w" Warning[:deprecated] = $VERBOSE = true when /^-W(.+)?/ opt = $1 || argv.shift case opt when "0" $VERBOSE = nil when "1" $VERBOSE = false else Warning[:deprecated] = $VERBOSE = true end when /^-r(.+)?/ opt = $1 || argv.shift @CONF[:LOAD_MODULES].push opt if opt when /^-I(.+)?/ opt = $1 || argv.shift load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt when '-U' set_encoding("UTF-8", "UTF-8") when /^-E(.+)?/, /^--encoding(?:=(.+))?/ opt = $1 || argv.shift set_encoding(*opt.split(':', 2)) when "--inspect" if /^-/ !~ argv.first @CONF[:INSPECT_MODE] = argv.shift else @CONF[:INSPECT_MODE] = true end when "--noinspect" @CONF[:INSPECT_MODE] = false when "--no-pager" @CONF[:USE_PAGER] = false when "--singleline", "--readline", "--legacy" @CONF[:USE_SINGLELINE] = true when "--nosingleline", "--noreadline" @CONF[:USE_SINGLELINE] = false when "--multiline", "--reidline" if opt == "--reidline" warn <<~MSG.strip --reidline is deprecated, please use --multiline instead. MSG end @CONF[:USE_MULTILINE] = true when "--nomultiline", "--noreidline" if opt == "--noreidline" warn <<~MSG.strip --noreidline is deprecated, please use --nomultiline instead. MSG end @CONF[:USE_MULTILINE] = false when /^--extra-doc-dir(?:=(.+))?/ opt = $1 || argv.shift @CONF[:EXTRA_DOC_DIRS] << opt when "--echo" @CONF[:ECHO] = true when "--noecho" @CONF[:ECHO] = false when "--echo-on-assignment" @CONF[:ECHO_ON_ASSIGNMENT] = true when "--noecho-on-assignment" @CONF[:ECHO_ON_ASSIGNMENT] = false when "--truncate-echo-on-assignment" @CONF[:ECHO_ON_ASSIGNMENT] = :truncate when "--verbose" @CONF[:VERBOSE] = true when "--noverbose" @CONF[:VERBOSE] = false when "--colorize" @CONF[:USE_COLORIZE] = true when "--nocolorize" @CONF[:USE_COLORIZE] = false when "--autocomplete" @CONF[:USE_AUTOCOMPLETE] = true when "--noautocomplete" @CONF[:USE_AUTOCOMPLETE] = false when "--regexp-completor" @CONF[:COMPLETOR] = :regexp when "--type-completor" @CONF[:COMPLETOR] = :type when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/ opt = $1 || argv.shift prompt_mode = opt.upcase.tr("-", "_").intern @CONF[:PROMPT_MODE] = prompt_mode when "--noprompt" @CONF[:PROMPT_MODE] = :NULL when "--script" noscript = false when "--noscript" noscript = true when "--inf-ruby-mode" @CONF[:PROMPT_MODE] = :INF_RUBY when "--sample-book-mode", "--simple-prompt" @CONF[:PROMPT_MODE] = :SIMPLE when "--tracer" @CONF[:USE_TRACER] = true when /^--back-trace-limit(?:=(.+))?/ @CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i when /^--context-mode(?:=(.+))?/ @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i when "--single-irb" @CONF[:SINGLE_IRB] = true when "-v", "--version" print IRB.version, "\n" exit 0 when "-h", "--help" require_relative "help" IRB.print_usage exit 0 when "--" if !noscript && (opt = argv.shift) @CONF[:SCRIPT] = opt $0 = opt end break when /^-./ fail UnrecognizedSwitch, opt else if noscript argv.unshift(opt) else @CONF[:SCRIPT] = opt $0 = opt end break end end load_path.collect! do |path| /\A\.\// =~ path ? path : File. (path) end $LOAD_PATH.unshift(*load_path) end
.prepare_irbrc_name_generators (private)
# File 'lib/irb/init.rb', line 479
def prepare_irbrc_name_generators return if @existing_rc_name_generators @existing_rc_name_generators = [] @irbrc_files = [] rc_file_generators do |rcgen| irbrc = rcgen.call(IRBRC_EXT) if File.exist?(irbrc) @irbrc_files << irbrc @existing_rc_name_generators << rcgen end end generate_current_dir_irbrc_files.each do |irbrc| @irbrc_files << irbrc if File.exist?(irbrc) end @irbrc_files.uniq! end
.print_usage
Outputs the irb help message, see IRB@Command-Line+Options.
# File 'lib/irb/help.rb', line 9
def IRB.print_usage # :nodoc: lc = IRB.conf[:LC_MESSAGES] path = lc.find("irb/help-message") space_line = false File.open(path){|f| f.each_line do |l| if /^\s*$/ =~ l lc.puts l unless space_line space_line = true next end space_line = false l.sub!(/#.*$/, "") next if /^\s*$/ =~ l lc.puts l end } end
.raise_validation_error(msg)
# File 'lib/irb/init.rb', line 461
def IRB.raise_validation_error(msg) raise TypeError, msg, @irbrc_files end
.rc_file(ext)
# File 'lib/irb/init.rb', line 409
def IRB.rc_file(ext) prepare_irbrc_name_generators # When irbrc exist in default location if (rcgen = @existing_rc_name_generators.first) return rcgen.call(ext) end # When irbrc does not exist in default location rc_file_generators do |rcgen| return rcgen.call(ext) end # When HOME and XDG_CONFIG_HOME are not available nil end
.rc_file_generators (private)
enumerate possible rc-file base name generators
# File 'lib/irb/init.rb', line 498
def rc_file_generators if irbrc = ENV["IRBRC"] yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc} end if xdg_config_home = ENV["XDG_CONFIG_HOME"] irb_home = File.join(xdg_config_home, "irb") if File.directory?(irb_home) yield proc{|rc| irb_home + "/irb#{rc}"} end end if home = ENV["HOME"] yield proc{|rc| home+"/.irb#{rc}"} if xdg_config_home.nil? || xdg_config_home.empty? yield proc{|rc| home+"/.config/irb/irb#{rc}"} end end end
.run_config
Run the config file
# File 'lib/irb/init.rb', line 397
def IRB.run_config if @CONF[:RC] irbrc_files.each do |rc| load rc rescue StandardError, ScriptError => e warn "Error loading RC file '#{rc}':\n#{e. (highlight: false)}" end end end
.set_encoding(extern, intern = nil, override: true) (private)
# File 'lib/irb/init.rb', line 522
def set_encoding(extern, intern = nil, override: true) verbose, $VERBOSE = $VERBOSE, nil Encoding.default_external = extern unless extern.nil? || extern.empty? Encoding.default_internal = intern unless intern.nil? || intern.empty? [$stdin, $stdout, $stderr].each do |io| io.set_encoding(extern, intern) end if override @CONF[:LC_MESSAGES].instance_variable_set(:@override_encoding, extern) else @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern) end ensure $VERBOSE = verbose end
.set_measure_callback(type = nil, arg = nil, &block)
# File 'lib/irb/init.rb', line 199
def IRB.set_measure_callback(type = nil, arg = nil, &block) added = nil if type type_sym = type.upcase.to_sym if IRB.conf[:MEASURE_PROC][type_sym] added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym], arg] end elsif IRB.conf[:MEASURE_PROC][:CUSTOM] added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM], arg] elsif block_given? added = [:BLOCK, block, arg] found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] } if found found[1] = block return added else IRB.conf[:MEASURE_CALLBACKS] << added return added end else added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg] end if added IRB.conf[:MEASURE] = true found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] } if found # already added nil else IRB.conf[:MEASURE_CALLBACKS] << added if added added end else nil end end
.setup(ap_path, argv: ::ARGV)
initialize config
# File 'lib/irb/init.rb', line 50
def IRB.setup(ap_path, argv: ::ARGV) IRB.init_config(ap_path) IRB.init_error IRB.parse_opts(argv: argv) IRB.run_config IRB.validate_config IRB.load_modules unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]] fail UndefinedPromptMode, @CONF[:PROMPT_MODE] end @INITIALIZED = true end
.start(ap_path = nil)
Initializes IRB and creates a new Irb.irb
object at the TOPLEVEL_BINDING
.unset_measure_callback(type = nil)
.validate_config
# File 'lib/irb/init.rb', line 431
def IRB.validate_config conf[:IRB_NAME] = conf[:IRB_NAME].to_s irb_rc = conf[:IRB_RC] unless irb_rc.nil? || irb_rc.respond_to?(:call) raise_validation_error "IRB.conf[:IRB_RC] should be a callable object. Got #{irb_rc.inspect}." end back_trace_limit = conf[:BACK_TRACE_LIMIT] unless back_trace_limit.is_a?(Integer) raise_validation_error "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got #{back_trace_limit.inspect}." end prompt = conf[:PROMPT] unless prompt.is_a?(Hash) msg = "IRB.conf[:PROMPT] should be a Hash. Got #{prompt.inspect}." if prompt.is_a?(Symbol) msg += " Did you mean to set `IRB.conf[:PROMPT_MODE]`?" end raise_validation_error msg end eval_history = conf[:EVAL_HISTORY] unless eval_history.nil? || eval_history.is_a?(Integer) raise_validation_error "IRB.conf[:EVAL_HISTORY] should be an integer. Got #{eval_history.inspect}." end end
.version
Returns the current version of IRB
, including release version and last updated date.
# File 'lib/irb/init.rb', line 41
def IRB.version format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE) end