irb 1.11.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/README.md +11 -9
- data/Rakefile +1 -1
- data/lib/irb/cmd/nop.rb +3 -52
- data/lib/irb/{cmd → command}/backtrace.rb +1 -1
- data/lib/irb/command/base.rb +64 -0
- data/lib/irb/{cmd → command}/break.rb +1 -1
- data/lib/irb/{cmd → command}/catch.rb +1 -1
- data/lib/irb/{cmd → command}/chws.rb +4 -6
- data/lib/irb/{cmd → command}/continue.rb +1 -1
- data/lib/irb/{cmd → command}/debug.rb +3 -4
- data/lib/irb/{cmd → command}/delete.rb +1 -1
- data/lib/irb/command/edit.rb +70 -0
- data/lib/irb/{cmd → command}/exit.rb +2 -4
- data/lib/irb/{cmd → command}/finish.rb +1 -1
- data/lib/irb/command/force_exit.rb +20 -0
- data/lib/irb/command/help.rb +84 -0
- data/lib/irb/{cmd → command}/history.rb +3 -3
- data/lib/irb/{cmd → command}/info.rb +1 -1
- data/lib/irb/{cmd → command}/irb_info.rb +5 -6
- data/lib/irb/{cmd → command}/load.rb +3 -5
- data/lib/irb/{cmd → command}/ls.rb +10 -4
- data/lib/irb/{cmd → command}/measure.rb +2 -4
- data/lib/irb/{cmd → command}/next.rb +1 -1
- data/lib/irb/{cmd → command}/pushws.rb +20 -5
- data/lib/irb/{cmd → command}/show_doc.rb +17 -5
- data/lib/irb/{cmd → command}/show_source.rb +26 -10
- data/lib/irb/{cmd → command}/step.rb +1 -1
- data/lib/irb/{cmd → command}/subirb.rb +3 -5
- data/lib/irb/{cmd → command}/whereami.rb +2 -4
- data/lib/irb/{extend-command.rb → command.rb} +50 -86
- data/lib/irb/completion.rb +1 -1
- data/lib/irb/context.rb +63 -20
- data/lib/irb/ext/change-ws.rb +4 -4
- data/lib/irb/ext/eval_history.rb +3 -3
- data/lib/irb/ext/loader.rb +4 -4
- data/lib/irb/ext/multi-irb.rb +1 -1
- data/lib/irb/ext/tracer.rb +12 -51
- data/lib/irb/ext/use-loader.rb +6 -8
- data/lib/irb/ext/workspaces.rb +11 -34
- data/lib/irb/frame.rb +1 -1
- data/lib/irb/help.rb +1 -1
- data/lib/irb/history.rb +12 -4
- data/lib/irb/init.rb +28 -17
- data/lib/irb/input-method.rb +18 -2
- data/lib/irb/inspector.rb +3 -3
- data/lib/irb/lc/error.rb +1 -6
- data/lib/irb/lc/ja/error.rb +1 -6
- data/lib/irb/locale.rb +2 -2
- data/lib/irb/nesting_parser.rb +13 -3
- data/lib/irb/notifier.rb +1 -1
- data/lib/irb/output-method.rb +2 -8
- data/lib/irb/ruby-lex.rb +2 -2
- data/lib/irb/source_finder.rb +98 -38
- data/lib/irb/statement.rb +25 -3
- data/lib/irb/version.rb +3 -3
- data/lib/irb/workspace.rb +4 -4
- data/lib/irb/ws-for-case-2.rb +1 -1
- data/lib/irb/xmp.rb +1 -1
- data/lib/irb.rb +38 -32
- metadata +30 -29
- data/lib/irb/cmd/edit.rb +0 -60
- data/lib/irb/cmd/help.rb +0 -23
- data/lib/irb/cmd/show_cmds.rb +0 -59
    
        data/lib/irb/source_finder.rb
    CHANGED
    
    | @@ -4,12 +4,63 @@ require_relative "ruby-lex" | |
| 4 4 |  | 
| 5 5 | 
             
            module IRB
         | 
| 6 6 | 
             
              class SourceFinder
         | 
| 7 | 
            -
                 | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
                  : | 
| 11 | 
            -
                   | 
| 12 | 
            -
             | 
| 7 | 
            +
                class EvaluationError < StandardError; end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                class Source
         | 
| 10 | 
            +
                  attr_reader :file, :line
         | 
| 11 | 
            +
                  def initialize(file, line, ast_source = nil)
         | 
| 12 | 
            +
                    @file = file
         | 
| 13 | 
            +
                    @line = line
         | 
| 14 | 
            +
                    @ast_source = ast_source
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def file_exist?
         | 
| 18 | 
            +
                    File.exist?(@file)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def binary_file?
         | 
| 22 | 
            +
                    # If the line is zero, it means that the target's source is probably in a binary file.
         | 
| 23 | 
            +
                    @line.zero?
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def file_content
         | 
| 27 | 
            +
                    @file_content ||= File.read(@file)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def colorized_content
         | 
| 31 | 
            +
                    if !binary_file? && file_exist?
         | 
| 32 | 
            +
                      end_line = find_end
         | 
| 33 | 
            +
                      # To correctly colorize, we need to colorize full content and extract the relevant lines.
         | 
| 34 | 
            +
                      colored = IRB::Color.colorize_code(file_content)
         | 
| 35 | 
            +
                      colored.lines[@line - 1...end_line].join
         | 
| 36 | 
            +
                    elsif @ast_source
         | 
| 37 | 
            +
                      IRB::Color.colorize_code(@ast_source)
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  private
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def find_end
         | 
| 44 | 
            +
                    lex = RubyLex.new
         | 
| 45 | 
            +
                    code = file_content
         | 
| 46 | 
            +
                    lines = code.lines[(@line - 1)..-1]
         | 
| 47 | 
            +
                    tokens = RubyLex.ripper_lex_without_warning(lines.join)
         | 
| 48 | 
            +
                    prev_tokens = []
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    # chunk with line number
         | 
| 51 | 
            +
                    tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
         | 
| 52 | 
            +
                      code = lines[0..lnum].join
         | 
| 53 | 
            +
                      prev_tokens.concat chunk
         | 
| 54 | 
            +
                      continue = lex.should_continue?(prev_tokens)
         | 
| 55 | 
            +
                      syntax = lex.check_code_syntax(code, local_variables: [])
         | 
| 56 | 
            +
                      if !continue && syntax == :valid
         | 
| 57 | 
            +
                        return @line + lnum
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                    @line
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 13 64 | 
             
                private_constant :Source
         | 
| 14 65 |  | 
| 15 66 | 
             
                def initialize(irb_context)
         | 
| @@ -17,50 +68,47 @@ module IRB | |
| 17 68 | 
             
                end
         | 
| 18 69 |  | 
| 19 70 | 
             
                def find_source(signature, super_level = 0)
         | 
| 20 | 
            -
                  context_binding = @irb_context.workspace.binding
         | 
| 21 71 | 
             
                  case signature
         | 
| 22 | 
            -
                  when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ #  | 
| 23 | 
            -
                     | 
| 24 | 
            -
                     | 
| 25 | 
            -
                     | 
| 72 | 
            +
                  when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName
         | 
| 73 | 
            +
                    eval_receiver_or_owner(signature) # trigger autoload
         | 
| 74 | 
            +
                    *parts, name = signature.split('::', -1)
         | 
| 75 | 
            +
                    base =
         | 
| 76 | 
            +
                      if parts.empty? # ConstName
         | 
| 77 | 
            +
                        find_const_owner(name)
         | 
| 78 | 
            +
                      elsif parts == [''] # ::ConstName
         | 
| 79 | 
            +
                        Object
         | 
| 80 | 
            +
                      else # ConstPath::ConstName
         | 
| 81 | 
            +
                        eval_receiver_or_owner(parts.join('::'))
         | 
| 82 | 
            +
                      end
         | 
| 83 | 
            +
                    file, line = base.const_source_location(name)
         | 
| 26 84 | 
             
                  when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
         | 
| 27 | 
            -
                    owner =  | 
| 85 | 
            +
                    owner = eval_receiver_or_owner(Regexp.last_match[:owner])
         | 
| 28 86 | 
             
                    method = Regexp.last_match[:method]
         | 
| 29 87 | 
             
                    return unless owner.respond_to?(:instance_method)
         | 
| 30 | 
            -
                     | 
| 88 | 
            +
                    method = method_target(owner, super_level, method, "owner")
         | 
| 89 | 
            +
                    file, line = method&.source_location
         | 
| 31 90 | 
             
                  when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
         | 
| 32 | 
            -
                    receiver =  | 
| 91 | 
            +
                    receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self')
         | 
| 33 92 | 
             
                    method = Regexp.last_match[:method]
         | 
| 34 93 | 
             
                    return unless receiver.respond_to?(method, true)
         | 
| 35 | 
            -
                     | 
| 94 | 
            +
                    method = method_target(receiver, super_level, method, "receiver")
         | 
| 95 | 
            +
                    file, line = method&.source_location
         | 
| 36 96 | 
             
                  end
         | 
| 37 | 
            -
                   | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 97 | 
            +
                  return unless file && line
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  if File.exist?(file)
         | 
| 100 | 
            +
                    Source.new(file, line)
         | 
| 101 | 
            +
                  elsif method
         | 
| 102 | 
            +
                    # Method defined with eval, probably in IRB session
         | 
| 103 | 
            +
                    source = RubyVM::AbstractSyntaxTree.of(method)&.source rescue nil
         | 
| 104 | 
            +
                    Source.new(file, line, source)
         | 
| 40 105 | 
             
                  end
         | 
| 106 | 
            +
                rescue EvaluationError
         | 
| 107 | 
            +
                  nil
         | 
| 41 108 | 
             
                end
         | 
| 42 109 |  | 
| 43 110 | 
             
                private
         | 
| 44 111 |  | 
| 45 | 
            -
                def find_end(file, first_line)
         | 
| 46 | 
            -
                  lex = RubyLex.new
         | 
| 47 | 
            -
                  lines = File.read(file).lines[(first_line - 1)..-1]
         | 
| 48 | 
            -
                  tokens = RubyLex.ripper_lex_without_warning(lines.join)
         | 
| 49 | 
            -
                  prev_tokens = []
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  # chunk with line number
         | 
| 52 | 
            -
                  tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
         | 
| 53 | 
            -
                    code = lines[0..lnum].join
         | 
| 54 | 
            -
                    prev_tokens.concat chunk
         | 
| 55 | 
            -
                    continue = lex.should_continue?(prev_tokens)
         | 
| 56 | 
            -
                    syntax = lex.check_code_syntax(code, local_variables: [])
         | 
| 57 | 
            -
                    if !continue && syntax == :valid
         | 
| 58 | 
            -
                      return first_line + lnum
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
                  first_line
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
             | 
| 64 112 | 
             
                def method_target(owner_receiver, super_level, method, type)
         | 
| 65 113 | 
             
                  case type
         | 
| 66 114 | 
             
                  when "owner"
         | 
| @@ -71,9 +119,21 @@ module IRB | |
| 71 119 | 
             
                  super_level.times do |s|
         | 
| 72 120 | 
             
                    target_method = target_method.super_method if target_method
         | 
| 73 121 | 
             
                  end
         | 
| 74 | 
            -
                  target_method | 
| 122 | 
            +
                  target_method
         | 
| 75 123 | 
             
                rescue NameError
         | 
| 76 124 | 
             
                  nil
         | 
| 77 125 | 
             
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def eval_receiver_or_owner(code)
         | 
| 128 | 
            +
                  context_binding = @irb_context.workspace.binding
         | 
| 129 | 
            +
                  eval(code, context_binding)
         | 
| 130 | 
            +
                rescue NameError
         | 
| 131 | 
            +
                  raise EvaluationError
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                def find_const_owner(name)
         | 
| 135 | 
            +
                  module_nesting = @irb_context.workspace.binding.eval('::Module.nesting')
         | 
| 136 | 
            +
                  module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object
         | 
| 137 | 
            +
                end
         | 
| 78 138 | 
             
              end
         | 
| 79 139 | 
             
            end
         | 
    
        data/lib/irb/statement.rb
    CHANGED
    
    | @@ -20,6 +20,29 @@ module IRB | |
| 20 20 | 
             
                  raise NotImplementedError
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 | 
            +
                class EmptyInput < Statement
         | 
| 24 | 
            +
                  def is_assignment?
         | 
| 25 | 
            +
                    false
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def suppresses_echo?
         | 
| 29 | 
            +
                    true
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  # Debugger takes empty input to repeat the last command
         | 
| 33 | 
            +
                  def should_be_handled_by_debugger?
         | 
| 34 | 
            +
                    true
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def code
         | 
| 38 | 
            +
                    ""
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def evaluable_code
         | 
| 42 | 
            +
                    code
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 23 46 | 
             
                class Expression < Statement
         | 
| 24 47 | 
             
                  def initialize(code, is_assignment)
         | 
| 25 48 | 
             
                    @code = code
         | 
| @@ -60,9 +83,8 @@ module IRB | |
| 60 83 | 
             
                  end
         | 
| 61 84 |  | 
| 62 85 | 
             
                  def should_be_handled_by_debugger?
         | 
| 63 | 
            -
                    require_relative ' | 
| 64 | 
            -
                     | 
| 65 | 
            -
                    IRB::ExtendCommand::DebugCommand > @command_class || IRB::ExtendCommand::Help == @command_class
         | 
| 86 | 
            +
                    require_relative 'command/debug'
         | 
| 87 | 
            +
                    IRB::Command::DebugCommand > @command_class
         | 
| 66 88 | 
             
                  end
         | 
| 67 89 |  | 
| 68 90 | 
             
                  def evaluable_code
         | 
    
        data/lib/irb/version.rb
    CHANGED
    
    | @@ -1,11 +1,11 @@ | |
| 1 | 
            -
            # frozen_string_literal:  | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            #   irb/version.rb - irb version definition file
         | 
| 4 4 | 
             
            #   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
         | 
| 5 5 | 
             
            #
         | 
| 6 6 |  | 
| 7 7 | 
             
            module IRB # :nodoc:
         | 
| 8 | 
            -
              VERSION = "1. | 
| 8 | 
            +
              VERSION = "1.12.0"
         | 
| 9 9 | 
             
              @RELEASE_VERSION = VERSION
         | 
| 10 | 
            -
              @LAST_UPDATE_DATE = "2024- | 
| 10 | 
            +
              @LAST_UPDATE_DATE = "2024-03-06"
         | 
| 11 11 | 
             
            end
         | 
    
        data/lib/irb/workspace.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # frozen_string_literal:  | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            #   irb/workspace-binding.rb -
         | 
| 4 4 | 
             
            #   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
         | 
| @@ -90,11 +90,11 @@ EOF | |
| 90 90 | 
             
                    IRB.conf[:__MAIN__] = @main
         | 
| 91 91 | 
             
                    @main.singleton_class.class_eval do
         | 
| 92 92 | 
             
                      private
         | 
| 93 | 
            -
                      define_method(:exit) do |*a, &b|
         | 
| 94 | 
            -
                        # Do nothing, will be overridden
         | 
| 95 | 
            -
                      end
         | 
| 96 93 | 
             
                      define_method(:binding, Kernel.instance_method(:binding))
         | 
| 97 94 | 
             
                      define_method(:local_variables, Kernel.instance_method(:local_variables))
         | 
| 95 | 
            +
                      # Define empty method to avoid delegator warning, will be overridden.
         | 
| 96 | 
            +
                      define_method(:exit) {|*a, &b| }
         | 
| 97 | 
            +
                      define_method(:exit!) {|*a, &b| }
         | 
| 98 98 | 
             
                    end
         | 
| 99 99 | 
             
                    @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
         | 
| 100 100 | 
             
                  end
         | 
    
        data/lib/irb/ws-for-case-2.rb
    CHANGED
    
    
    
        data/lib/irb/xmp.rb
    CHANGED
    
    
    
        data/lib/irb.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # frozen_string_literal:  | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            #   irb.rb - irb main module
         | 
| 4 4 | 
             
            #       by Keiju ISHITSUKA(keiju@ruby-lang.org)
         | 
| @@ -9,7 +9,7 @@ require "reline" | |
| 9 9 |  | 
| 10 10 | 
             
            require_relative "irb/init"
         | 
| 11 11 | 
             
            require_relative "irb/context"
         | 
| 12 | 
            -
            require_relative "irb/ | 
| 12 | 
            +
            require_relative "irb/command"
         | 
| 13 13 |  | 
| 14 14 | 
             
            require_relative "irb/ruby-lex"
         | 
| 15 15 | 
             
            require_relative "irb/statement"
         | 
| @@ -203,11 +203,10 @@ require_relative "irb/pager" | |
| 203 203 | 
             
            #
         | 
| 204 204 | 
             
            # === Input Command History
         | 
| 205 205 | 
             
            #
         | 
| 206 | 
            -
            # By default, \IRB stores a history of up to 1000 input commands
         | 
| 207 | 
            -
            #  | 
| 208 | 
            -
            #  | 
| 209 | 
            -
            #  | 
| 210 | 
            -
            # inin the same directory as that file).
         | 
| 206 | 
            +
            # By default, \IRB stores a history of up to 1000 input commands in a
         | 
| 207 | 
            +
            # file named <tt>.irb_history</tt>. The history file will be in the same directory
         | 
| 208 | 
            +
            # as the {configuration file}[rdoc-ref:IRB@Configuration+File] if one is found, or
         | 
| 209 | 
            +
            # in <tt>~/</tt> otherwise.
         | 
| 211 210 | 
             
            #
         | 
| 212 211 | 
             
            # A new \IRB session creates the history file if it does not exist,
         | 
| 213 212 | 
             
            # and appends to the file if it does exist.
         | 
| @@ -365,7 +364,7 @@ require_relative "irb/pager" | |
| 365 364 | 
             
            # You can change the initial behavior and suppress all echoing by:
         | 
| 366 365 | 
             
            #
         | 
| 367 366 | 
             
            # - Adding to the configuration file: <tt>IRB.conf[:ECHO] = false</tt>.
         | 
| 368 | 
            -
            #   (The default value for this entry is + | 
| 367 | 
            +
            #   (The default value for this entry is +nil+, which means the same as +true+.)
         | 
| 369 368 | 
             
            # - Giving command-line option <tt>--noecho</tt>.
         | 
| 370 369 | 
             
            #   (The default is <tt>--echo</tt>.)
         | 
| 371 370 | 
             
            #
         | 
| @@ -392,7 +391,7 @@ require_relative "irb/pager" | |
| 392 391 | 
             
            #   (The default value for this entry is +niL+, which means the same as +:truncate+.)
         | 
| 393 392 | 
             
            # - Giving command-line option <tt>--noecho-on-assignment</tt>
         | 
| 394 393 | 
             
            #   or <tt>--echo-on-assignment</tt>.
         | 
| 395 | 
            -
            #   (The default is <tt>--truncate-echo-on- | 
| 394 | 
            +
            #   (The default is <tt>--truncate-echo-on-assignment</tt>.)
         | 
| 396 395 | 
             
            #
         | 
| 397 396 | 
             
            # During the session, you can change the current setting
         | 
| 398 397 | 
             
            # with configuration method <tt>conf.echo_on_assignment=</tt>
         | 
| @@ -413,7 +412,7 @@ require_relative "irb/pager" | |
| 413 412 | 
             
            #
         | 
| 414 413 | 
             
            # By default, \IRB prefixes a newline to a multiline response.
         | 
| 415 414 | 
             
            #
         | 
| 416 | 
            -
            # You can change the initial default value by adding to the  | 
| 415 | 
            +
            # You can change the initial default value by adding to the configuration file:
         | 
| 417 416 | 
             
            #
         | 
| 418 417 | 
             
            #   IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] = false
         | 
| 419 418 | 
             
            #
         | 
| @@ -812,7 +811,7 @@ require_relative "irb/pager" | |
| 812 811 | 
             
            #
         | 
| 813 812 | 
             
            # === Commands
         | 
| 814 813 | 
             
            #
         | 
| 815 | 
            -
            # Please use the ` | 
| 814 | 
            +
            # Please use the `help` command to see the list of available commands.
         | 
| 816 815 | 
             
            #
         | 
| 817 816 | 
             
            # === IRB Sessions
         | 
| 818 817 | 
             
            #
         | 
| @@ -887,7 +886,7 @@ module IRB | |
| 887 886 |  | 
| 888 887 | 
             
              # Quits irb
         | 
| 889 888 | 
             
              def IRB.irb_exit(*)
         | 
| 890 | 
            -
                throw :IRB_EXIT
         | 
| 889 | 
            +
                throw :IRB_EXIT, false
         | 
| 891 890 | 
             
              end
         | 
| 892 891 |  | 
| 893 892 | 
             
              # Aborts then interrupts irb.
         | 
| @@ -904,8 +903,8 @@ module IRB | |
| 904 903 | 
             
                # parsed as a :method_add_arg and the output won't be suppressed
         | 
| 905 904 |  | 
| 906 905 | 
             
                PROMPT_MAIN_TRUNCATE_LENGTH = 32
         | 
| 907 | 
            -
                PROMPT_MAIN_TRUNCATE_OMISSION = '...' | 
| 908 | 
            -
                CONTROL_CHARACTERS_PATTERN = "\x00-\x1F" | 
| 906 | 
            +
                PROMPT_MAIN_TRUNCATE_OMISSION = '...'
         | 
| 907 | 
            +
                CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
         | 
| 909 908 |  | 
| 910 909 | 
             
                # Returns the current context of this irb session
         | 
| 911 910 | 
             
                attr_reader :context
         | 
| @@ -934,7 +933,7 @@ module IRB | |
| 934 933 |  | 
| 935 934 | 
             
                def debug_readline(binding)
         | 
| 936 935 | 
             
                  workspace = IRB::WorkSpace.new(binding)
         | 
| 937 | 
            -
                  context.workspace | 
| 936 | 
            +
                  context.replace_workspace(workspace)
         | 
| 938 937 | 
             
                  context.workspace.load_commands_to_main
         | 
| 939 938 | 
             
                  @line_no += 1
         | 
| 940 939 |  | 
| @@ -945,7 +944,7 @@ module IRB | |
| 945 944 | 
             
                  # Irb#eval_input will simply return the input, and we need to pass it to the debugger.
         | 
| 946 945 | 
             
                  input = if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
         | 
| 947 946 | 
             
                    # Previous IRB session's history has been saved when `Irb#run` is exited
         | 
| 948 | 
            -
                    # We need to make sure the saved history is not saved again by  | 
| 947 | 
            +
                    # We need to make sure the saved history is not saved again by resetting the counter
         | 
| 949 948 | 
             
                    context.io.reset_history_counter
         | 
| 950 949 |  | 
| 951 950 | 
             
                    begin
         | 
| @@ -980,13 +979,21 @@ module IRB | |
| 980 979 | 
             
                  end
         | 
| 981 980 |  | 
| 982 981 | 
             
                  begin
         | 
| 983 | 
            -
                     | 
| 982 | 
            +
                    if defined?(RubyVM.keep_script_lines)
         | 
| 983 | 
            +
                      keep_script_lines_backup = RubyVM.keep_script_lines
         | 
| 984 | 
            +
                      RubyVM.keep_script_lines = true
         | 
| 985 | 
            +
                    end
         | 
| 986 | 
            +
             | 
| 987 | 
            +
                    forced_exit = catch(:IRB_EXIT) do
         | 
| 984 988 | 
             
                      eval_input
         | 
| 985 989 | 
             
                    end
         | 
| 986 990 | 
             
                  ensure
         | 
| 991 | 
            +
                    RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines)
         | 
| 987 992 | 
             
                    trap("SIGINT", prev_trap)
         | 
| 988 993 | 
             
                    conf[:AT_EXIT].each{|hook| hook.call}
         | 
| 994 | 
            +
             | 
| 989 995 | 
             
                    context.io.save_history if save_history
         | 
| 996 | 
            +
                    Kernel.exit if forced_exit
         | 
| 990 997 | 
             
                  end
         | 
| 991 998 | 
             
                end
         | 
| 992 999 |  | 
| @@ -1049,7 +1056,7 @@ module IRB | |
| 1049 1056 | 
             
                  return read_input(prompt) if @context.io.respond_to?(:check_termination)
         | 
| 1050 1057 |  | 
| 1051 1058 | 
             
                  # nomultiline
         | 
| 1052 | 
            -
                  code = ''
         | 
| 1059 | 
            +
                  code = +''
         | 
| 1053 1060 | 
             
                  line_offset = 0
         | 
| 1054 1061 | 
             
                  loop do
         | 
| 1055 1062 | 
             
                    line = read_input(prompt)
         | 
| @@ -1075,16 +1082,17 @@ module IRB | |
| 1075 1082 | 
             
                  loop do
         | 
| 1076 1083 | 
             
                    code = readmultiline
         | 
| 1077 1084 | 
             
                    break unless code
         | 
| 1078 | 
            -
             | 
| 1079 | 
            -
                    if code != "\n"
         | 
| 1080 | 
            -
                      yield build_statement(code), @line_no
         | 
| 1081 | 
            -
                    end
         | 
| 1085 | 
            +
                    yield build_statement(code), @line_no
         | 
| 1082 1086 | 
             
                    @line_no += code.count("\n")
         | 
| 1083 1087 | 
             
                  rescue RubyLex::TerminateLineInput
         | 
| 1084 1088 | 
             
                  end
         | 
| 1085 1089 | 
             
                end
         | 
| 1086 1090 |  | 
| 1087 1091 | 
             
                def build_statement(code)
         | 
| 1092 | 
            +
                  if code.match?(/\A\n*\z/)
         | 
| 1093 | 
            +
                    return Statement::EmptyInput.new
         | 
| 1094 | 
            +
                  end
         | 
| 1095 | 
            +
             | 
| 1088 1096 | 
             
                  code.force_encoding(@context.io.encoding)
         | 
| 1089 1097 | 
             
                  command_or_alias, arg = code.split(/\s/, 2)
         | 
| 1090 1098 | 
             
                  # Transform a non-identifier alias (@, $) or keywords (next, break)
         | 
| @@ -1130,7 +1138,6 @@ module IRB | |
| 1130 1138 | 
             
                  end
         | 
| 1131 1139 | 
             
                  if @context.io.respond_to?(:dynamic_prompt)
         | 
| 1132 1140 | 
             
                    @context.io.dynamic_prompt do |lines|
         | 
| 1133 | 
            -
                      lines << '' if lines.empty?
         | 
| 1134 1141 | 
             
                      tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables)
         | 
| 1135 1142 | 
             
                      line_results = IRB::NestingParser.parse_by_line(tokens)
         | 
| 1136 1143 | 
             
                      tokens_until_line = []
         | 
| @@ -1228,7 +1235,7 @@ module IRB | |
| 1228 1235 | 
             
                    lines.map{ |l| l + "\n" }.join
         | 
| 1229 1236 | 
             
                  }
         | 
| 1230 1237 | 
             
                  # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
         | 
| 1231 | 
            -
                  message = message.gsub(/\(irb\):(?<num>\d+):in  | 
| 1238 | 
            +
                  message = message.gsub(/\(irb\):(?<num>\d+):in (?<open_quote>[`'])<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}<main>'" }
         | 
| 1232 1239 | 
             
                  puts message
         | 
| 1233 1240 | 
             
                  puts 'Maybe IRB bug!' if irb_bug
         | 
| 1234 1241 | 
             
                rescue Exception => handler_exc
         | 
| @@ -1262,12 +1269,11 @@ module IRB | |
| 1262 1269 | 
             
                # Used by the irb command +irb_load+, see IRB@IRB+Sessions for more
         | 
| 1263 1270 | 
             
                # information.
         | 
| 1264 1271 | 
             
                def suspend_workspace(workspace)
         | 
| 1265 | 
            -
                   | 
| 1266 | 
            -
                   | 
| 1267 | 
            -
             | 
| 1268 | 
            -
             | 
| 1269 | 
            -
             | 
| 1270 | 
            -
                  end
         | 
| 1272 | 
            +
                  current_workspace = @context.workspace
         | 
| 1273 | 
            +
                  @context.replace_workspace(workspace)
         | 
| 1274 | 
            +
                  yield
         | 
| 1275 | 
            +
                ensure
         | 
| 1276 | 
            +
                  @context.replace_workspace current_workspace
         | 
| 1271 1277 | 
             
                end
         | 
| 1272 1278 |  | 
| 1273 1279 | 
             
                # Evaluates the given block using the given +input_method+ as the
         | 
| @@ -1515,7 +1521,7 @@ class Binding | |
| 1515 1521 | 
             
              # See IRB for more information.
         | 
| 1516 1522 | 
             
              def irb(show_code: true)
         | 
| 1517 1523 | 
             
                # Setup IRB with the current file's path and no command line arguments
         | 
| 1518 | 
            -
                IRB.setup(source_location[0], argv: [])
         | 
| 1524 | 
            +
                IRB.setup(source_location[0], argv: []) unless IRB.initialized?
         | 
| 1519 1525 | 
             
                # Create a new workspace using the current binding
         | 
| 1520 1526 | 
             
                workspace = IRB::WorkSpace.new(self)
         | 
| 1521 1527 | 
             
                # Print the code around the binding if show_code is true
         | 
| @@ -1527,7 +1533,7 @@ class Binding | |
| 1527 1533 |  | 
| 1528 1534 | 
             
                if debugger_irb
         | 
| 1529 1535 | 
             
                  # If we're already in a debugger session, set the workspace and irb_path for the original IRB instance
         | 
| 1530 | 
            -
                  debugger_irb.context.workspace | 
| 1536 | 
            +
                  debugger_irb.context.replace_workspace(workspace)
         | 
| 1531 1537 | 
             
                  debugger_irb.context.irb_path = irb_path
         | 
| 1532 1538 | 
             
                  # If we've started a debugger session and hit another binding.irb, we don't want to start an IRB session
         | 
| 1533 1539 | 
             
                  # instead, we want to resume the irb:rdbg session.
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: irb
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.12.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - aycabta
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire:
         | 
| 10 10 | 
             
            bindir: exe
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2024- | 
| 12 | 
            +
            date: 2024-03-07 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: reline
         | 
| @@ -60,34 +60,36 @@ files: | |
| 60 60 | 
             
            - exe/irb
         | 
| 61 61 | 
             
            - irb.gemspec
         | 
| 62 62 | 
             
            - lib/irb.rb
         | 
| 63 | 
            -
            - lib/irb/cmd/backtrace.rb
         | 
| 64 | 
            -
            - lib/irb/cmd/break.rb
         | 
| 65 | 
            -
            - lib/irb/cmd/catch.rb
         | 
| 66 | 
            -
            - lib/irb/cmd/chws.rb
         | 
| 67 | 
            -
            - lib/irb/cmd/continue.rb
         | 
| 68 | 
            -
            - lib/irb/cmd/debug.rb
         | 
| 69 | 
            -
            - lib/irb/cmd/delete.rb
         | 
| 70 | 
            -
            - lib/irb/cmd/edit.rb
         | 
| 71 | 
            -
            - lib/irb/cmd/exit.rb
         | 
| 72 | 
            -
            - lib/irb/cmd/finish.rb
         | 
| 73 | 
            -
            - lib/irb/cmd/help.rb
         | 
| 74 | 
            -
            - lib/irb/cmd/history.rb
         | 
| 75 | 
            -
            - lib/irb/cmd/info.rb
         | 
| 76 | 
            -
            - lib/irb/cmd/irb_info.rb
         | 
| 77 | 
            -
            - lib/irb/cmd/load.rb
         | 
| 78 | 
            -
            - lib/irb/cmd/ls.rb
         | 
| 79 | 
            -
            - lib/irb/cmd/measure.rb
         | 
| 80 | 
            -
            - lib/irb/cmd/next.rb
         | 
| 81 63 | 
             
            - lib/irb/cmd/nop.rb
         | 
| 82 | 
            -
            - lib/irb/cmd/pushws.rb
         | 
| 83 | 
            -
            - lib/irb/cmd/show_cmds.rb
         | 
| 84 | 
            -
            - lib/irb/cmd/show_doc.rb
         | 
| 85 | 
            -
            - lib/irb/cmd/show_source.rb
         | 
| 86 | 
            -
            - lib/irb/cmd/step.rb
         | 
| 87 | 
            -
            - lib/irb/cmd/subirb.rb
         | 
| 88 | 
            -
            - lib/irb/cmd/whereami.rb
         | 
| 89 64 | 
             
            - lib/irb/color.rb
         | 
| 90 65 | 
             
            - lib/irb/color_printer.rb
         | 
| 66 | 
            +
            - lib/irb/command.rb
         | 
| 67 | 
            +
            - lib/irb/command/backtrace.rb
         | 
| 68 | 
            +
            - lib/irb/command/base.rb
         | 
| 69 | 
            +
            - lib/irb/command/break.rb
         | 
| 70 | 
            +
            - lib/irb/command/catch.rb
         | 
| 71 | 
            +
            - lib/irb/command/chws.rb
         | 
| 72 | 
            +
            - lib/irb/command/continue.rb
         | 
| 73 | 
            +
            - lib/irb/command/debug.rb
         | 
| 74 | 
            +
            - lib/irb/command/delete.rb
         | 
| 75 | 
            +
            - lib/irb/command/edit.rb
         | 
| 76 | 
            +
            - lib/irb/command/exit.rb
         | 
| 77 | 
            +
            - lib/irb/command/finish.rb
         | 
| 78 | 
            +
            - lib/irb/command/force_exit.rb
         | 
| 79 | 
            +
            - lib/irb/command/help.rb
         | 
| 80 | 
            +
            - lib/irb/command/history.rb
         | 
| 81 | 
            +
            - lib/irb/command/info.rb
         | 
| 82 | 
            +
            - lib/irb/command/irb_info.rb
         | 
| 83 | 
            +
            - lib/irb/command/load.rb
         | 
| 84 | 
            +
            - lib/irb/command/ls.rb
         | 
| 85 | 
            +
            - lib/irb/command/measure.rb
         | 
| 86 | 
            +
            - lib/irb/command/next.rb
         | 
| 87 | 
            +
            - lib/irb/command/pushws.rb
         | 
| 88 | 
            +
            - lib/irb/command/show_doc.rb
         | 
| 89 | 
            +
            - lib/irb/command/show_source.rb
         | 
| 90 | 
            +
            - lib/irb/command/step.rb
         | 
| 91 | 
            +
            - lib/irb/command/subirb.rb
         | 
| 92 | 
            +
            - lib/irb/command/whereami.rb
         | 
| 91 93 | 
             
            - lib/irb/completion.rb
         | 
| 92 94 | 
             
            - lib/irb/context.rb
         | 
| 93 95 | 
             
            - lib/irb/debug.rb
         | 
| @@ -100,7 +102,6 @@ files: | |
| 100 102 | 
             
            - lib/irb/ext/tracer.rb
         | 
| 101 103 | 
             
            - lib/irb/ext/use-loader.rb
         | 
| 102 104 | 
             
            - lib/irb/ext/workspaces.rb
         | 
| 103 | 
            -
            - lib/irb/extend-command.rb
         | 
| 104 105 | 
             
            - lib/irb/frame.rb
         | 
| 105 106 | 
             
            - lib/irb/help.rb
         | 
| 106 107 | 
             
            - lib/irb/history.rb
         | 
| @@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 149 150 | 
             
                - !ruby/object:Gem::Version
         | 
| 150 151 | 
             
                  version: '0'
         | 
| 151 152 | 
             
            requirements: []
         | 
| 152 | 
            -
            rubygems_version: 3.5. | 
| 153 | 
            +
            rubygems_version: 3.5.1
         | 
| 153 154 | 
             
            signing_key:
         | 
| 154 155 | 
             
            specification_version: 4
         | 
| 155 156 | 
             
            summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
         | 
    
        data/lib/irb/cmd/edit.rb
    DELETED
    
    | @@ -1,60 +0,0 @@ | |
| 1 | 
            -
            require 'shellwords'
         | 
| 2 | 
            -
            require_relative "nop"
         | 
| 3 | 
            -
            require_relative "../source_finder"
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            module IRB
         | 
| 6 | 
            -
              # :stopdoc:
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              module ExtendCommand
         | 
| 9 | 
            -
                class Edit < Nop
         | 
| 10 | 
            -
                  category "Misc"
         | 
| 11 | 
            -
                  description 'Open a file with the editor command defined with `ENV["VISUAL"]` or `ENV["EDITOR"]`.'
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                  class << self
         | 
| 14 | 
            -
                    def transform_args(args)
         | 
| 15 | 
            -
                      # Return a string literal as is for backward compatibility
         | 
| 16 | 
            -
                      if args.nil? || args.empty? || string_literal?(args)
         | 
| 17 | 
            -
                        args
         | 
| 18 | 
            -
                      else # Otherwise, consider the input as a String for convenience
         | 
| 19 | 
            -
                        args.strip.dump
         | 
| 20 | 
            -
                      end
         | 
| 21 | 
            -
                    end
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  def execute(*args)
         | 
| 25 | 
            -
                    path = args.first
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                    if path.nil? && (irb_path = @irb_context.irb_path)
         | 
| 28 | 
            -
                      path = irb_path
         | 
| 29 | 
            -
                    end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                    if !File.exist?(path)
         | 
| 32 | 
            -
                      source =
         | 
| 33 | 
            -
                        begin
         | 
| 34 | 
            -
                          SourceFinder.new(@irb_context).find_source(path)
         | 
| 35 | 
            -
                        rescue NameError
         | 
| 36 | 
            -
                          # if user enters a path that doesn't exist, it'll cause NameError when passed here because find_source would try to evaluate it as well
         | 
| 37 | 
            -
                          # in this case, we should just ignore the error
         | 
| 38 | 
            -
                        end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                      if source
         | 
| 41 | 
            -
                        path = source.file
         | 
| 42 | 
            -
                      else
         | 
| 43 | 
            -
                        puts "Can not find file: #{path}"
         | 
| 44 | 
            -
                        return
         | 
| 45 | 
            -
                      end
         | 
| 46 | 
            -
                    end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                    if editor = (ENV['VISUAL'] || ENV['EDITOR'])
         | 
| 49 | 
            -
                      puts "command: '#{editor}'"
         | 
| 50 | 
            -
                      puts "   path: #{path}"
         | 
| 51 | 
            -
                      system(*Shellwords.split(editor), path)
         | 
| 52 | 
            -
                    else
         | 
| 53 | 
            -
                      puts "Can not find editor setting: ENV['VISUAL'] or ENV['EDITOR']"
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              # :startdoc:
         | 
| 60 | 
            -
            end
         | 
    
        data/lib/irb/cmd/help.rb
    DELETED
    
    | @@ -1,23 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require_relative "show_doc"
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            module IRB
         | 
| 6 | 
            -
              module ExtendCommand
         | 
| 7 | 
            -
                class Help < ShowDoc
         | 
| 8 | 
            -
                  category "Context"
         | 
| 9 | 
            -
                  description "[DEPRECATED] Enter the mode to look up RI documents."
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  DEPRECATION_MESSAGE = <<~MSG
         | 
| 12 | 
            -
                    [Deprecation] The `help` command will be repurposed to display command help in the future.
         | 
| 13 | 
            -
                    For RI document lookup, please use the `show_doc` command instead.
         | 
| 14 | 
            -
                    For command help, please use `show_cmds` for now.
         | 
| 15 | 
            -
                  MSG
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  def execute(*names)
         | 
| 18 | 
            -
                    warn DEPRECATION_MESSAGE
         | 
| 19 | 
            -
                    super
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         |