class Pry::REPL

def self.start(options)

Options Hash: (**options)
  • See (Pry#initialize) --
def self.start(options)
  new(Pry.new(options)).start
end

def calculate_overhang(current_prompt, original_val, indented_val)

Other tags:
    Note: - This doesn't calculate overhang for Readline's emacs mode with an

Returns:
  • (Integer) -
def calculate_overhang(current_prompt, original_val, indented_val)
  overhang = original_val.length - indented_val.length
  if readline_available? && Readline.respond_to?(:vi_editing_mode?)
    begin
      # rb-readline doesn't support this method:
      # https://github.com/ConnorAtherton/rb-readline/issues/152
      if Readline.vi_editing_mode?
        overhang = output.width - current_prompt.size - indented_val.size
      end
    rescue NotImplementedError
      # VI editing mode is unsupported on JRuby.
      # https://github.com/pry/pry/issues/1840
      nil
    end
  end
  [0, overhang].max
end

def complete_expression?(multiline_input)

def complete_expression?(multiline_input)
  if prism_available?
    lex = Prism.lex(multiline_input)
    errors = lex.errors
    return true if errors.empty?
    errors.any? { |error| UNEXPECTED_TOKENS.include?(error.type) }
  else
    Pry::Code.complete_expression?(multiline_input)
  end
end

def coolline_available?

def coolline_available?
  defined?(Coolline) && input.is_a?(Coolline)
end

def epilogue

Returns:
  • (void) -
def epilogue
  pry.exec_hook :after_session, pry.output, pry.current_binding, pry
end

def handle_read_errors

Returns:
  • (:no_more_input) - Indicates that no more input can be read.
  • (Object) - Whatever the given block returns.
def handle_read_errors
  should_retry = true
  exception_count = 0
  begin
    yield
  rescue EOFError
    pry.config.input = Pry.config.input
    unless should_retry
      output.puts "Error: Pry ran out of things to read from! " \
        "Attempting to break out of REPL."
      return :no_more_input
    end
    should_retry = false
    retry
  # Handle <Ctrl+C> like Bash: empty the current input buffer, but don't
  # quit.
  rescue Interrupt
    return :control_c
  # If we get a random error when trying to read a line we don't want to
  # automatically retry, as the user will see a lot of error messages
  # scroll past and be unable to do anything about it.
  rescue RescuableException => e
    puts "Error: #{e.message}"
    output.puts e.backtrace
    exception_count += 1
    retry if exception_count < 5
    puts "FATAL: Pry failed to get user input using `#{input}`."
    puts "To fix this you may be able to pass input and output file " \
      "descriptors to pry directly. e.g."
    puts "  Pry.config.input = STDIN"
    puts "  Pry.config.output = STDOUT"
    puts "  binding.pry"
    return :no_more_input
  end
end

def initialize(pry, options = {})

Options Hash: (**options)
  • :target (Object) -- The initial target of the session.

Parameters:
  • options (Hash) -- Options for this {REPL} instance.
  • pry (Pry) -- The instance of {Pry} that this {REPL} will control.
def initialize(pry, options = {})
  @pry    = pry
  @indent = Pry::Indent.new(pry)
  @readline_output = nil
  @pry.push_binding options[:target] if options[:target]
end

def input_multiline?

def input_multiline?
  !!pry.config.multiline && reline_available?
end

def input_readline(*args)

def input_readline(*args)
  Pry::InputLock.for(:all).interruptible_region do
    input.readline(*args)
  end
end

def input_readmultiline(*args)

def input_readmultiline(*args)
  Pry::InputLock.for(:all).interruptible_region do
    input.readmultiline(*args) do |multiline_input|
      Pry.commands.find_command(multiline_input) ||
        (complete_expression?(multiline_input) && !Reline::IOGate.in_pasting?)
    end
  end
end

def piping?

% pry | tee log
# `piping?` returns `true`

[1] pry(main)
% pry
# `piping?` returns `false`
@example
If `$stdout` is not a tty, it's probably a pipe.
def piping?
  return false unless $stdout.respond_to?(:tty?)
  !$stdout.tty? && $stdin.tty? && !Helpers::Platform.windows?
end

def prism_available?

def prism_available?
  @prism_available ||= begin
    # rubocop:disable Lint/SuppressedException
    begin
      require 'prism'
    rescue LoadError
    end
    # rubocop:enable Lint/SuppressedException
    defined?(Prism::VERSION) &&
      Gem::Version.new(Prism::VERSION) >= Gem::Version.new('0.25.0')
  end
end

def prologue

Returns:
  • (void) -
def prologue
  pry.exec_hook :before_session, pry.output, pry.current_binding, pry
  return unless pry.config.correct_indent
  # Clear the line before starting Pry. This fixes issue #566.
  output.print(Helpers::Platform.windows_ansi? ? "\e[0F" : "\e[0G")
end

def read

Returns:
  • (:no_more_input) - On EOF.
  • (:control_c) - On ``.
  • (nil) - On ``.
  • (String) - The line entered by the user.
def read
  @indent.reset if pry.eval_string.empty?
  current_prompt = pry.select_prompt
  indentation = pry.config.auto_indent ? @indent.current_prefix : ''
  val = read_line("#{current_prompt}#{indentation}")
  # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
  return val unless val.is_a?(String)
  if pry.config.auto_indent && !input_multiline?
    original_val = "#{indentation}#{val}"
    indented_val = @indent.indent(val)
    if output.tty? &&
       pry.config.correct_indent &&
       Pry::Helpers::BaseHelpers.use_ansi_codes?
      output.print @indent.correct_indentation(
        current_prompt,
        indented_val,
        calculate_overhang(current_prompt, original_val, indented_val)
      )
      output.flush
    end
  else
    indented_val = val
  end
  indented_val
end

def read_line(current_prompt)

Returns:
  • (String?) - The next line of input, or `nil` on .

Parameters:
  • current_prompt (String) -- The prompt to use for input.
def read_line(current_prompt)
  handle_read_errors do
    if coolline_available?
      input.completion_proc = proc do |cool|
        completions = @pry.complete cool.completed_word
        completions.compact
      end
    elsif input.respond_to? :completion_proc=
      input.completion_proc = proc do |inp|
        @pry.complete inp
      end
    end
    if reline_available?
      Reline.output_modifier_proc = lambda do |text, _|
        if pry.color
          SyntaxHighlighter.highlight(text)
        else
          text
        end
      end
      if pry.config.auto_indent
        Reline.auto_indent_proc = lambda do |lines, line_index, _byte_ptr, _newline|
          if line_index == 0
            0
          else
            pry_indentation = Pry::Indent.new
            pry_indentation.indent(lines.join("\n"))
            pry_indentation.last_indent_level.length
          end
        end
      end
    end
    if input_multiline?
      input_readmultiline(current_prompt, false)
    elsif readline_available?
      set_readline_output
      input_readline(current_prompt, false) # false since we'll add it manually
    elsif coolline_available?
      input_readline(current_prompt)
    elsif input.method(:readline).arity == 1
      input_readline(current_prompt)
    else
      input_readline
    end
  end
end

def readline_available?

def readline_available?
  defined?(Readline) && input == Readline
end

def reline_available?

def reline_available?
  defined?(Reline) && input == Reline
end

def repl

Raises:
  • (Exception) - If the session throws `:raise_up`, raise the exception

Returns:
  • (Object?) - If the session throws `:breakout`, return the value
def repl
  loop do
    case val = read
    when :control_c
      output.puts ""
      pry.reset_eval_string
    when :no_more_input
      output.puts "" if output.tty?
      break
    else
      output.puts "" if val.nil? && output.tty?
      return pry.exit_value unless pry.eval(val)
    end
  end
end

def set_readline_output

Returns:
  • (void) -
def set_readline_output
  return if @readline_output
  @readline_output = (Readline.output = Pry.config.output) if piping?
end

def start

Raises:
  • (Exception) - If the session throws `:raise_up`, raise the exception

Returns:
  • (Object?) - If the session throws `:breakout`, return the value
def start
  prologue
  Pry::InputLock.for(:all).with_ownership { repl }
ensure
  epilogue
end