class Pry::InputCompleter

def call(str, options = {})

rubocop:disable Metrics/AbcSize, Metrics/MethodLength
Return a new completion proc for use by Readline.
def call(str, options = {})
  custom_completions = options[:custom_completions] || []
  # if there are multiple contexts e.g. cd 1/2/3
  # get new target for 1/2 and find candidates for 3
  path, input = build_path(str)
  if path.call.empty?
    target = options[:target]
  else
    # Assume the user is tab-completing the 'cd' command
    begin
      target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
    # but if that doesn't work, assume they're doing division with no spaces
    rescue Pry::CommandError
      target = options[:target]
    end
  end
  begin
    bind = target
    # Complete stdlib symbols
    case input
    when REGEX_REGEXP # Regexp
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      candidates = Regexp.instance_methods.collect(&:to_s)
      select_message(path, receiver, message, candidates)
    when ARRAY_REGEXP # Array
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      candidates = Array.instance_methods.collect(&:to_s)
      select_message(path, receiver, message, candidates)
    when PROC_OR_HASH_REGEXP # Proc or Hash
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      candidates = Proc.instance_methods.collect(&:to_s)
      candidates |= Hash.instance_methods.collect(&:to_s)
      select_message(path, receiver, message, candidates)
    when SYMBOL_REGEXP # Symbol
      if Symbol.respond_to?(:all_symbols)
        sym = Regexp.quote(Regexp.last_match(1))
        candidates = Symbol.all_symbols.collect { |s| ":" + s.id2name }
        candidates.grep(/^#{sym}/)
      else
        []
      end
    when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods
      receiver = Regexp.last_match(1)
      candidates = Object.constants.collect(&:to_s)
      candidates.grep(/^#{receiver}/).collect { |e| "::" + e }
    when CONSTANT_REGEXP # Constant
      message = Regexp.last_match(1)
      begin
        context = target.eval("self")
        context = context.class unless context.respond_to? :constants
        candidates = context.constants.collect(&:to_s)
      rescue StandardError
        candidates = []
      end
      candidates = candidates.grep(/^#{message}/).collect(&path)
    when CONSTANT_OR_METHOD_REGEXP # Constant or class methods
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      begin
        candidates = eval( # rubocop:disable Security/Eval
          "#{receiver}.constants.collect(&:to_s)", bind, __FILE__, __LINE__
        )
        candidates |= eval( # rubocop:disable Security/Eval
          "#{receiver}.methods.collect(&:to_s)", bind, __FILE__, __LINE__
        )
      rescue Pry::RescuableException
        candidates = []
      end
      candidates.grep(/^#{message}/).collect { |e| receiver + "::" + e }
    when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      candidates = Symbol.instance_methods.collect(&:to_s)
      select_message(path, receiver, message, candidates)
    when NUMERIC_REGEXP
      # Numeric
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(5))
      begin
        # rubocop:disable Security/Eval
        candidates = eval(receiver, bind).methods.collect(&:to_s)
        # rubocop:enable Security/Eval
      rescue Pry::RescuableException
        candidates = []
      end
      select_message(path, receiver, message, candidates)
    when HEX_REGEXP
      # Numeric(0xFFFF)
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      begin
        # rubocop:disable Security/Eval
        candidates = eval(receiver, bind).methods.collect(&:to_s)
        # rubocop:enable Security/Eval
      rescue Pry::RescuableException
        candidates = []
      end
      select_message(path, receiver, message, candidates)
    when GLOBALVARIABLE_REGEXP # global
      regmessage = Regexp.new(Regexp.quote(Regexp.last_match(1)))
      candidates = global_variables.collect(&:to_s).grep(regmessage)
    when VARIABLE_REGEXP # variable
      receiver = Regexp.last_match(1)
      message = Regexp.quote(Regexp.last_match(2))
      gv = eval("global_variables", bind, __FILE__, __LINE__).collect(&:to_s)
      lv = eval("local_variables", bind, __FILE__, __LINE__).collect(&:to_s)
      cv = eval("self.class.constants", bind, __FILE__, __LINE__).collect(&:to_s)
      if (gv | lv | cv).include?(receiver) || /^[A-Z]/ =~ receiver && /\./ !~ receiver
        # foo.func and foo is local var. OR
        # Foo::Bar.func
        begin
          candidates = eval( # rubocop:disable Security/Eval
            "#{receiver}.methods", bind, __FILE__, __LINE__
          ).collect(&:to_s)
        rescue Pry::RescuableException
          candidates = []
        end
      else
        # func1.func2
        require 'set'
        candidates = Set.new
        to_ignore = ignored_modules
        ObjectSpace.each_object(Module) do |m|
          next if begin
                    to_ignore.include?(m)
                  rescue StandardError
                    true
                  end
          # jruby doesn't always provide #instance_methods() on each
          # object.
          if m.respond_to?(:instance_methods)
            candidates.merge m.instance_methods(false).collect(&:to_s)
          end
        end
      end
      select_message(path, receiver, message, candidates.sort)
    when /^\.([^.]*)$/
      # Unknown(maybe String)
      receiver = ""
      message = Regexp.quote(Regexp.last_match(1))
      candidates = String.instance_methods(true).collect(&:to_s)
      select_message(path, receiver, message, candidates)
    else
      candidates = eval(
        "methods | private_methods | local_variables | " \
        "self.class.constants | instance_variables",
        bind, __FILE__, __LINE__ - 2
      ).collect(&:to_s)
      if eval("respond_to?(:class_variables)", bind, __FILE__, __LINE__)
        candidates += eval(
          "class_variables", bind, __FILE__, __LINE__
        ).collect(&:to_s)
      end
      candidates =
        (candidates | RESERVED_WORDS | custom_completions)
          .grep(/^#{Regexp.quote(input)}/)
      candidates.collect(&path)
    end
  rescue Pry::RescuableException
    []
  end
end