2011-04-24 11:56:47 +00:00
|
|
|
require "pry/command_processor.rb"
|
2011-10-08 11:57:42 +00:00
|
|
|
require "pry/indent"
|
2011-04-07 06:09:03 +00:00
|
|
|
|
2010-12-25 13:59:37 +00:00
|
|
|
class Pry
|
|
|
|
|
2011-05-19 15:53:44 +00:00
|
|
|
attr_accessor :input
|
|
|
|
attr_accessor :output
|
|
|
|
attr_accessor :commands
|
|
|
|
attr_accessor :print
|
|
|
|
attr_accessor :exception_handler
|
|
|
|
attr_accessor :hooks
|
2011-09-15 09:08:05 +00:00
|
|
|
attr_accessor :input_stack
|
|
|
|
|
2011-05-19 15:53:44 +00:00
|
|
|
attr_accessor :custom_completions
|
2011-01-07 12:18:09 +00:00
|
|
|
|
2011-08-21 06:22:45 +00:00
|
|
|
attr_accessor :binding_stack
|
2011-03-16 07:02:15 +00:00
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
attr_accessor :last_result
|
|
|
|
attr_accessor :last_exception
|
|
|
|
attr_accessor :last_file
|
|
|
|
attr_accessor :last_dir
|
|
|
|
|
2011-09-02 16:09:17 +00:00
|
|
|
attr_reader :input_array
|
|
|
|
attr_reader :output_array
|
|
|
|
|
2010-12-29 09:14:12 +00:00
|
|
|
# Create a new `Pry` object.
|
|
|
|
# @param [Hash] options The optional configuration parameters.
|
2011-04-16 21:17:30 +00:00
|
|
|
# @option options [#readline] :input The object to use for input.
|
|
|
|
# @option options [#puts] :output The object to use for output.
|
2011-05-31 15:12:29 +00:00
|
|
|
# @option options [Pry::CommandBase] :commands The object to use for commands.
|
|
|
|
# @option options [Hash] :hooks The defined hook Procs
|
|
|
|
# @option options [Array<Proc>] :prompt The array of Procs to use for the prompts.
|
2010-12-30 15:01:11 +00:00
|
|
|
# @option options [Proc] :print The Proc to use for the 'print'
|
|
|
|
# component of the REPL. (see print.rb)
|
2010-12-25 13:59:37 +00:00
|
|
|
def initialize(options={})
|
2011-05-31 15:12:29 +00:00
|
|
|
refresh(options)
|
2011-06-05 16:07:13 +00:00
|
|
|
|
2011-05-31 15:12:29 +00:00
|
|
|
@command_processor = CommandProcessor.new(self)
|
2011-08-21 06:22:45 +00:00
|
|
|
@binding_stack = []
|
2011-10-05 17:04:44 +00:00
|
|
|
@indent = Pry::Indent.new
|
2011-05-31 15:12:29 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Refresh the Pry instance settings from the Pry class.
|
|
|
|
# Allows options to be specified to override settings from Pry class.
|
|
|
|
# @param [Hash] options The options to override Pry class settings
|
|
|
|
# for this instance.
|
|
|
|
def refresh(options={})
|
2011-05-19 15:53:44 +00:00
|
|
|
defaults = {}
|
2011-05-24 08:16:46 +00:00
|
|
|
attributes = [
|
2011-05-19 15:53:44 +00:00
|
|
|
:input, :output, :commands, :print,
|
|
|
|
:exception_handler, :hooks, :custom_completions,
|
2011-09-15 09:08:05 +00:00
|
|
|
:prompt, :memory_size, :input_stack
|
2011-05-19 15:53:44 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
attributes.each do |attribute|
|
|
|
|
defaults[attribute] = Pry.send attribute
|
2010-12-27 10:56:55 +00:00
|
|
|
end
|
2010-12-25 13:59:37 +00:00
|
|
|
|
2011-05-31 15:12:29 +00:00
|
|
|
defaults.merge!(options).each do |key, value|
|
|
|
|
send "#{key}=", value
|
2010-12-27 10:56:55 +00:00
|
|
|
end
|
2011-04-07 06:09:03 +00:00
|
|
|
|
2011-05-31 15:12:29 +00:00
|
|
|
true
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
|
2011-05-24 08:16:46 +00:00
|
|
|
# The current prompt.
|
2011-05-19 15:53:44 +00:00
|
|
|
# This is the prompt at the top of the prompt stack.
|
2011-05-24 08:16:46 +00:00
|
|
|
#
|
2011-05-19 15:53:44 +00:00
|
|
|
# @example
|
|
|
|
# self.prompt = Pry::SIMPLE_PROMPT
|
|
|
|
# self.prompt # => Pry::SIMPLE_PROMPT
|
|
|
|
#
|
|
|
|
# @return [Array<Proc>] Current prompt.
|
|
|
|
def prompt
|
|
|
|
prompt_stack.last
|
|
|
|
end
|
|
|
|
|
|
|
|
def prompt=(new_prompt)
|
|
|
|
if prompt_stack.empty?
|
|
|
|
push_prompt new_prompt
|
|
|
|
else
|
|
|
|
prompt_stack[-1] = new_prompt
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-08-30 17:35:41 +00:00
|
|
|
# Injects a local variable into the provided binding.
|
|
|
|
# @param [String] name The name of the local to inject.
|
|
|
|
# @param [Object] value The value to set the local to.
|
|
|
|
# @param [Binding] b The binding to set the local on.
|
|
|
|
# @return [Object] The value the local was set to.
|
|
|
|
def inject_local(name, value, b)
|
|
|
|
Thread.current[:__pry_local__] = value
|
|
|
|
b.eval("#{name} = Thread.current[:__pry_local__]")
|
|
|
|
ensure
|
|
|
|
Thread.current[:__pry_local__] = nil
|
|
|
|
end
|
|
|
|
|
2011-06-07 12:57:01 +00:00
|
|
|
# @return [Integer] The maximum amount of objects remembered by the inp and
|
|
|
|
# out arrays. Defaults to 100.
|
2011-06-06 15:14:16 +00:00
|
|
|
def memory_size
|
|
|
|
@output_array.max_size
|
|
|
|
end
|
|
|
|
|
|
|
|
def memory_size=(size)
|
|
|
|
@input_array = Pry::HistoryArray.new(size)
|
|
|
|
@output_array = Pry::HistoryArray.new(size)
|
|
|
|
end
|
|
|
|
|
2010-12-29 09:14:12 +00:00
|
|
|
# Execute the hook `hook_name`, if it is defined.
|
|
|
|
# @param [Symbol] hook_name The hook to execute
|
|
|
|
# @param [Array] args The arguments to pass to the hook.
|
|
|
|
def exec_hook(hook_name, *args, &block)
|
|
|
|
hooks[hook_name].call(*args, &block) if hooks[hook_name]
|
|
|
|
end
|
2011-01-13 14:35:46 +00:00
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
# Make sure special locals exist at start of session
|
|
|
|
def initialize_special_locals(target)
|
2011-09-01 04:58:38 +00:00
|
|
|
inject_local("_in_", @input_array, target)
|
|
|
|
inject_local("_out_", @output_array, target)
|
2011-08-30 17:35:41 +00:00
|
|
|
inject_local("_pry_", self, target)
|
|
|
|
inject_local("_ex_", nil, target)
|
2011-08-31 17:05:21 +00:00
|
|
|
inject_local("_file_", nil, target)
|
2011-08-30 17:35:41 +00:00
|
|
|
inject_local("_dir_", nil, target)
|
2011-08-31 17:05:21 +00:00
|
|
|
|
|
|
|
# without this line we get 1 test failure, ask Mon_Ouie
|
2011-08-30 17:35:41 +00:00
|
|
|
set_last_result(nil, target)
|
2011-08-31 17:05:21 +00:00
|
|
|
inject_local("_", nil, target)
|
|
|
|
end
|
|
|
|
private :initialize_special_locals
|
|
|
|
|
|
|
|
def inject_special_locals(target)
|
2011-10-02 00:41:53 +00:00
|
|
|
special_locals.each_pair do |name, value|
|
|
|
|
inject_local(name, value, target)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def special_locals
|
|
|
|
{
|
|
|
|
:_in_ => @input_array,
|
|
|
|
:_out_ => @output_array,
|
|
|
|
:_pry_ => self,
|
|
|
|
:_ex_ => last_exception,
|
|
|
|
:_file_ => last_file,
|
|
|
|
:_dir_ => last_dir,
|
|
|
|
:_ => last_result
|
|
|
|
}
|
2011-08-31 17:05:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Initialize the repl session.
|
|
|
|
# @param [Binding] target The target binding for the session.
|
|
|
|
def repl_prologue(target)
|
2011-10-17 01:09:12 +00:00
|
|
|
hooks.exec_hook :before_session, output, target, self
|
2011-08-31 17:05:21 +00:00
|
|
|
initialize_special_locals(target)
|
2011-05-15 10:03:16 +00:00
|
|
|
|
2011-09-15 09:08:05 +00:00
|
|
|
@input_array << nil # add empty input so _in_ and _out_ match
|
2011-06-05 16:07:13 +00:00
|
|
|
|
2011-08-25 07:32:09 +00:00
|
|
|
Pry.active_sessions += 1
|
2011-08-21 06:22:45 +00:00
|
|
|
binding_stack.push target
|
2011-03-16 07:02:15 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Clean-up after the repl session.
|
|
|
|
# @param [Binding] target The target binding for the session.
|
2011-09-17 22:34:58 +00:00
|
|
|
def repl_epilogue(target)
|
2011-10-17 01:09:12 +00:00
|
|
|
hooks.exec_hook :after_session, output, target, self
|
2011-03-16 07:02:15 +00:00
|
|
|
|
2011-08-25 07:32:09 +00:00
|
|
|
Pry.active_sessions -= 1
|
2011-08-21 06:22:45 +00:00
|
|
|
binding_stack.pop
|
2011-09-05 09:03:52 +00:00
|
|
|
Pry.save_history if Pry.config.history.should_save && Pry.active_sessions == 0
|
2011-03-16 07:02:15 +00:00
|
|
|
end
|
2011-04-06 16:59:09 +00:00
|
|
|
|
2010-12-29 09:14:12 +00:00
|
|
|
# Start a read-eval-print-loop.
|
2010-12-28 03:56:23 +00:00
|
|
|
# If no parameter is given, default to top-level (main).
|
2010-12-29 09:14:12 +00:00
|
|
|
# @param [Object, Binding] target The receiver of the Pry session
|
2011-02-26 01:00:55 +00:00
|
|
|
# @return [Object] The target of the Pry session or an explictly given
|
|
|
|
# return value. If given return value is `nil` or no return value
|
|
|
|
# is specified then `target` will be returned.
|
2010-12-28 03:56:23 +00:00
|
|
|
# @example
|
|
|
|
# Pry.new.repl(Object.new)
|
2010-12-25 13:59:37 +00:00
|
|
|
def repl(target=TOPLEVEL_BINDING)
|
2011-02-16 16:27:55 +00:00
|
|
|
target = Pry.binding_for(target)
|
2010-12-25 13:59:37 +00:00
|
|
|
target_self = target.eval('self')
|
|
|
|
|
2011-03-16 07:02:15 +00:00
|
|
|
repl_prologue(target)
|
2011-04-16 21:17:30 +00:00
|
|
|
|
2011-02-25 07:31:38 +00:00
|
|
|
break_data = catch(:breakout) do
|
2010-12-25 13:59:37 +00:00
|
|
|
loop do
|
2011-08-22 02:57:09 +00:00
|
|
|
rep(binding_stack.last)
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-09-17 22:34:58 +00:00
|
|
|
repl_epilogue(target)
|
2011-11-05 06:22:21 +00:00
|
|
|
break_data || nil
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
2011-01-13 14:35:46 +00:00
|
|
|
|
2010-12-29 09:14:12 +00:00
|
|
|
# Perform a read-eval-print.
|
2010-12-28 03:56:23 +00:00
|
|
|
# If no parameter is given, default to top-level (main).
|
2010-12-29 09:14:12 +00:00
|
|
|
# @param [Object, Binding] target The receiver of the read-eval-print
|
2010-12-28 03:56:23 +00:00
|
|
|
# @example
|
|
|
|
# Pry.new.rep(Object.new)
|
2010-12-25 13:59:37 +00:00
|
|
|
def rep(target=TOPLEVEL_BINDING)
|
2011-02-16 16:27:55 +00:00
|
|
|
target = Pry.binding_for(target)
|
2011-04-07 14:13:16 +00:00
|
|
|
result = re(target)
|
2011-04-08 01:06:39 +00:00
|
|
|
|
2011-04-18 04:47:35 +00:00
|
|
|
show_result(result) if should_print?
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
|
2010-12-28 03:56:23 +00:00
|
|
|
# Perform a read-eval
|
|
|
|
# If no parameter is given, default to top-level (main).
|
2010-12-29 09:14:12 +00:00
|
|
|
# @param [Object, Binding] target The receiver of the read-eval-print
|
2011-04-16 21:17:30 +00:00
|
|
|
# @return [Object] The result of the eval or an `Exception` object in case of
|
2011-04-16 21:27:48 +00:00
|
|
|
# error. In the latter case, you can check whether the exception was raised
|
|
|
|
# or is just the result of the expression using #last_result_is_exception?
|
2010-12-28 03:56:23 +00:00
|
|
|
# @example
|
|
|
|
# Pry.new.re(Object.new)
|
2010-12-25 13:59:37 +00:00
|
|
|
def re(target=TOPLEVEL_BINDING)
|
2011-02-16 16:27:55 +00:00
|
|
|
target = Pry.binding_for(target)
|
2011-01-07 12:18:09 +00:00
|
|
|
|
2011-11-02 10:09:29 +00:00
|
|
|
compl = Pry::InputCompleter.build_completion_proc(target,
|
|
|
|
instance_eval(&custom_completions))
|
|
|
|
|
|
|
|
if defined? Coolline and input.is_a? Coolline
|
|
|
|
input.completion_proc = proc do |cool|
|
|
|
|
compl.call cool.completed_word
|
|
|
|
end
|
|
|
|
elsif input.respond_to? :completion_proc=
|
|
|
|
input.completion_proc = compl
|
2011-01-10 13:54:17 +00:00
|
|
|
end
|
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
# It's not actually redundant to inject them continually as we may have
|
|
|
|
# moved into the scope of a new Binding (e.g the user typed `cd`)
|
|
|
|
inject_special_locals(target)
|
2011-04-16 21:17:30 +00:00
|
|
|
|
2011-05-15 10:08:59 +00:00
|
|
|
code = r(target)
|
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
|
|
|
|
result
|
2011-08-27 00:44:13 +00:00
|
|
|
rescue RescuableException => e
|
2011-10-17 01:09:12 +00:00
|
|
|
result = set_last_exception(e, target)
|
2011-05-24 12:34:55 +00:00
|
|
|
ensure
|
2011-08-07 08:19:28 +00:00
|
|
|
update_input_history(code)
|
2011-10-17 01:09:12 +00:00
|
|
|
hooks.exec_hook :after_eval, result, self
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
|
2010-12-28 03:56:23 +00:00
|
|
|
# Perform a read.
|
|
|
|
# If no parameter is given, default to top-level (main).
|
|
|
|
# This is a multi-line read; so the read continues until a valid
|
|
|
|
# Ruby expression is received.
|
|
|
|
# Pry commands are also accepted here and operate on the target.
|
2010-12-29 09:14:12 +00:00
|
|
|
# @param [Object, Binding] target The receiver of the read.
|
2011-05-16 17:08:40 +00:00
|
|
|
# @param [String] eval_string Optionally Prime `eval_string` with a start value.
|
2010-12-28 03:56:23 +00:00
|
|
|
# @return [String] The Ruby expression.
|
|
|
|
# @example
|
|
|
|
# Pry.new.r(Object.new)
|
2011-05-11 07:32:29 +00:00
|
|
|
def r(target=TOPLEVEL_BINDING, eval_string="")
|
2011-02-16 16:27:55 +00:00
|
|
|
target = Pry.binding_for(target)
|
2011-04-07 14:13:16 +00:00
|
|
|
@suppress_output = false
|
2011-01-09 11:51:45 +00:00
|
|
|
|
2011-04-16 04:47:48 +00:00
|
|
|
val = ""
|
2011-01-10 06:29:26 +00:00
|
|
|
loop do
|
2011-11-05 06:10:10 +00:00
|
|
|
begin
|
2011-11-20 02:16:23 +00:00
|
|
|
# eval_string will probably be mutated by this method
|
|
|
|
retrieve_line(eval_string, target)
|
2011-11-05 06:10:10 +00:00
|
|
|
rescue CommandError, Slop::InvalidOptionError => e
|
|
|
|
output.puts "Error: #{e.message}"
|
|
|
|
end
|
2011-05-24 12:34:55 +00:00
|
|
|
|
2011-04-16 21:17:30 +00:00
|
|
|
break if valid_expression?(eval_string)
|
2011-03-31 13:14:04 +00:00
|
|
|
end
|
2011-04-07 14:13:16 +00:00
|
|
|
|
2011-09-05 04:12:56 +00:00
|
|
|
@suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
|
2011-04-16 21:17:30 +00:00
|
|
|
|
2011-10-17 01:09:12 +00:00
|
|
|
hooks.exec_hook :after_read, eval_string, self
|
2011-04-07 14:13:16 +00:00
|
|
|
eval_string
|
2011-04-15 03:58:29 +00:00
|
|
|
end
|
|
|
|
|
2011-05-29 15:46:25 +00:00
|
|
|
# Output the result or pass to an exception handler (if result is an exception).
|
2011-04-16 04:47:48 +00:00
|
|
|
def show_result(result)
|
2011-04-16 21:17:30 +00:00
|
|
|
if last_result_is_exception?
|
2011-09-10 16:39:51 +00:00
|
|
|
exception_handler.call output, result, self
|
2011-04-16 21:17:30 +00:00
|
|
|
else
|
|
|
|
print.call output, result
|
|
|
|
end
|
2011-08-27 08:58:53 +00:00
|
|
|
rescue RescuableException => e
|
2011-08-23 07:54:58 +00:00
|
|
|
# Being uber-paranoid here, given that this exception arose because we couldn't
|
|
|
|
# serialize something in the user's program, let's not assume we can serialize
|
|
|
|
# the exception either.
|
|
|
|
begin
|
2011-09-14 22:48:20 +00:00
|
|
|
output.puts "(pry) output error: #{e.inspect}"
|
2011-08-27 08:58:53 +00:00
|
|
|
rescue RescuableException => e
|
2011-08-23 07:54:58 +00:00
|
|
|
if last_result_is_exception?
|
2011-09-14 22:48:20 +00:00
|
|
|
output.puts "(pry) output error: failed to show exception"
|
2011-08-23 07:54:58 +00:00
|
|
|
else
|
2011-09-14 22:48:20 +00:00
|
|
|
output.puts "(pry) output error: failed to show result"
|
2011-08-23 07:54:58 +00:00
|
|
|
end
|
|
|
|
end
|
2011-04-15 03:58:29 +00:00
|
|
|
end
|
2011-04-07 14:13:16 +00:00
|
|
|
|
2011-11-20 02:16:23 +00:00
|
|
|
# Read and process a line of input -- check for ^D, determine which prompt to
|
|
|
|
# use, rewrite the indentation if `Pry.config.auto_indent` is enabled, and,
|
|
|
|
# if the line is a command, process it and alter the eval_string accordingly.
|
|
|
|
# This method should not need to be invoked directly.
|
2011-10-05 17:04:44 +00:00
|
|
|
#
|
2011-03-31 13:14:04 +00:00
|
|
|
# @param [String] eval_string The cumulative lines of input.
|
|
|
|
# @param [Binding] target The target of the session.
|
|
|
|
# @return [String] The line received.
|
|
|
|
def retrieve_line(eval_string, target)
|
2011-10-08 17:49:01 +00:00
|
|
|
@indent.reset if eval_string.empty?
|
|
|
|
|
2011-03-31 13:14:04 +00:00
|
|
|
current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
|
2011-10-10 01:13:09 +00:00
|
|
|
indentation = Pry.config.auto_indent ? @indent.indent_level : ''
|
2011-10-08 17:49:01 +00:00
|
|
|
|
2011-10-10 01:13:09 +00:00
|
|
|
val = readline(current_prompt + indentation)
|
2011-03-31 13:14:04 +00:00
|
|
|
|
2011-10-27 11:10:12 +00:00
|
|
|
# invoke handler if we receive EOF character (^D)
|
2011-03-31 13:14:04 +00:00
|
|
|
if !val
|
2011-08-29 14:21:51 +00:00
|
|
|
output.puts ""
|
|
|
|
Pry.config.control_d_handler.call(eval_string, self)
|
2011-11-20 02:16:23 +00:00
|
|
|
return
|
|
|
|
end
|
2011-10-01 20:10:59 +00:00
|
|
|
|
2011-11-20 02:16:23 +00:00
|
|
|
# Change the eval_string into the input encoding (Issue 284)
|
|
|
|
# TODO: This wouldn't be necessary if the eval_string was constructed from
|
|
|
|
# input strings only.
|
|
|
|
if eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding
|
|
|
|
eval_string.force_encoding(val.encoding)
|
|
|
|
end
|
2011-10-09 19:03:24 +00:00
|
|
|
|
2011-11-20 02:16:23 +00:00
|
|
|
if Pry.config.auto_indent && !input.is_a?(StringIO)
|
|
|
|
original_val = "#{indentation}#{val}"
|
|
|
|
indented_val = @indent.indent(val)
|
|
|
|
|
|
|
|
if original_val != indented_val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
|
|
|
|
output.print @indent.correct_indentation(current_prompt + indented_val, original_val.length - indented_val.length)
|
2011-10-05 17:04:44 +00:00
|
|
|
end
|
2011-11-20 02:16:23 +00:00
|
|
|
else
|
|
|
|
indented_val = val
|
|
|
|
end
|
2011-10-05 17:04:44 +00:00
|
|
|
|
2011-11-20 02:16:23 +00:00
|
|
|
if !process_command(val, eval_string, target)
|
|
|
|
eval_string << "#{indented_val.rstrip}\n" unless val.empty?
|
2011-03-31 13:14:04 +00:00
|
|
|
end
|
2011-11-20 02:16:23 +00:00
|
|
|
Pry.history << indented_val unless input.is_a?(StringIO)
|
2011-03-31 13:14:04 +00:00
|
|
|
end
|
2011-01-13 14:35:46 +00:00
|
|
|
|
2011-11-20 02:16:23 +00:00
|
|
|
# If the given line is a valid command, process it in the context of the
|
|
|
|
# current `eval_string` and context.
|
2011-03-31 13:14:04 +00:00
|
|
|
# This method should not need to be invoked directly.
|
|
|
|
# @param [String] val The line to process.
|
|
|
|
# @param [String] eval_string The cumulative lines of input.
|
2011-06-16 13:45:33 +00:00
|
|
|
# @param [Binding] target The target of the Pry session.
|
2011-11-20 02:16:23 +00:00
|
|
|
# @return [Boolean] `true` if `val` is a command, `false` otherwise
|
|
|
|
def process_command(val, eval_string, target)
|
2011-09-04 13:50:27 +00:00
|
|
|
result = @command_processor.process_commands(val, eval_string, target)
|
2011-09-05 16:12:53 +00:00
|
|
|
|
|
|
|
# set a temporary (just so we can inject the value we want into eval_string)
|
2011-09-04 13:50:27 +00:00
|
|
|
Thread.current[:__pry_cmd_result__] = result
|
|
|
|
|
|
|
|
# note that `result` wraps the result of command processing; if a
|
|
|
|
# command was matched and invoked then `result.command?` returns true,
|
|
|
|
# otherwise it returns false.
|
2011-11-20 02:16:23 +00:00
|
|
|
if result.command?
|
|
|
|
if !result.void_command?
|
|
|
|
# the command that was invoked was non-void (had a return value) and so we make
|
|
|
|
# the value of the current expression equal to the return value
|
|
|
|
# of the command.
|
|
|
|
eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
|
|
|
|
end
|
|
|
|
true
|
2011-03-31 13:14:04 +00:00
|
|
|
else
|
2011-11-20 02:16:23 +00:00
|
|
|
false
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
end
|
2011-01-13 14:35:46 +00:00
|
|
|
|
2011-09-10 16:41:51 +00:00
|
|
|
# Run the specified command.
|
2011-10-27 11:10:12 +00:00
|
|
|
# @param [String] val The command (and its params) to execute.
|
|
|
|
# @param [String] eval_string The current input buffer.
|
|
|
|
# @param [Binding] target The binding to use..
|
|
|
|
# @return [Pry::CommandContext::VOID_VALUE]
|
2011-09-10 16:41:51 +00:00
|
|
|
# @example
|
|
|
|
# pry_instance.run_command("ls -m")
|
2011-10-27 11:10:12 +00:00
|
|
|
def run_command(val, eval_string = "", target = binding_stack.last)
|
2011-11-20 02:16:23 +00:00
|
|
|
@command_processor.process_commands(val, eval_string, target)
|
2011-09-10 16:41:51 +00:00
|
|
|
Pry::CommandContext::VOID_VALUE
|
|
|
|
end
|
|
|
|
|
2011-03-14 10:55:22 +00:00
|
|
|
# Set the last result of an eval.
|
2011-03-31 13:14:04 +00:00
|
|
|
# This method should not need to be invoked directly.
|
2011-03-14 10:55:22 +00:00
|
|
|
# @param [Object] result The result.
|
|
|
|
# @param [Binding] target The binding to set `_` on.
|
|
|
|
def set_last_result(result, target)
|
2011-08-07 08:19:28 +00:00
|
|
|
@last_result_is_exception = false
|
2011-05-15 10:03:16 +00:00
|
|
|
@output_array << result
|
2011-08-07 08:19:28 +00:00
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
self.last_result = result
|
2011-03-14 10:55:22 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Set the last exception for a session.
|
2011-03-31 13:14:04 +00:00
|
|
|
# This method should not need to be invoked directly.
|
2011-03-14 10:55:22 +00:00
|
|
|
# @param [Exception] ex The exception.
|
|
|
|
# @param [Binding] target The binding to set `_ex_` on.
|
|
|
|
def set_last_exception(ex, target)
|
2011-06-16 13:45:33 +00:00
|
|
|
class << ex
|
2011-09-13 17:39:48 +00:00
|
|
|
attr_accessor :file, :line, :bt_index
|
2011-09-12 17:07:05 +00:00
|
|
|
def bt_source_location_for(index)
|
|
|
|
backtrace[index] =~ /(.*):(\d+)/
|
|
|
|
[$1, $2.to_i]
|
|
|
|
end
|
2011-06-16 13:45:33 +00:00
|
|
|
end
|
|
|
|
|
2011-09-13 17:39:48 +00:00
|
|
|
ex.bt_index = 0
|
|
|
|
ex.file, ex.line = ex.bt_source_location_for(0)
|
2011-06-16 13:45:33 +00:00
|
|
|
|
2011-08-07 08:19:28 +00:00
|
|
|
@last_result_is_exception = true
|
|
|
|
@output_array << ex
|
|
|
|
|
2011-08-31 17:05:21 +00:00
|
|
|
self.last_exception = ex
|
2011-03-14 10:55:22 +00:00
|
|
|
end
|
|
|
|
|
2011-08-07 08:19:28 +00:00
|
|
|
# Update Pry's internal state after evalling code.
|
|
|
|
# This method should not need to be invoked directly.
|
2011-08-11 11:35:04 +00:00
|
|
|
# @param [String] code The code we just eval'd
|
2011-08-07 08:19:28 +00:00
|
|
|
def update_input_history(code)
|
|
|
|
# Always push to the @input_array as the @output_array is always pushed to.
|
|
|
|
@input_array << code
|
|
|
|
if code
|
|
|
|
Pry.line_buffer.push(*code.each_line)
|
|
|
|
Pry.current_line += code.each_line.count
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-04-16 21:17:30 +00:00
|
|
|
# @return [Boolean] True if the last result is an exception that was raised,
|
|
|
|
# as opposed to simply an instance of Exception (like the result of
|
|
|
|
# Exception.new)
|
|
|
|
def last_result_is_exception?
|
|
|
|
@last_result_is_exception
|
|
|
|
end
|
|
|
|
|
2011-09-16 06:14:47 +00:00
|
|
|
# Manage switching of input objects on encountering EOFErrors
|
|
|
|
def handle_read_errors
|
|
|
|
should_retry = true
|
|
|
|
begin
|
|
|
|
yield
|
|
|
|
rescue EOFError
|
|
|
|
if input_stack.empty?
|
|
|
|
self.input = Pry.config.input
|
|
|
|
if !should_retry
|
|
|
|
output.puts "Error: Pry ran out of things to read from! Attempting to break out of REPL."
|
|
|
|
throw(:breakout)
|
|
|
|
end
|
|
|
|
should_retry = false
|
|
|
|
else
|
|
|
|
self.input = input_stack.pop
|
|
|
|
end
|
|
|
|
retry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private :handle_read_errors
|
|
|
|
|
2011-01-10 06:29:26 +00:00
|
|
|
# Returns the next line of input to be used by the pry instance.
|
|
|
|
# This method should not need to be invoked directly.
|
|
|
|
# @param [String] current_prompt The prompt to use for input.
|
|
|
|
# @return [String] The next line of input.
|
2011-01-12 01:16:04 +00:00
|
|
|
def readline(current_prompt="> ")
|
2011-09-16 06:14:47 +00:00
|
|
|
handle_read_errors do
|
2011-09-16 04:19:42 +00:00
|
|
|
if input == Readline
|
2011-10-09 08:41:42 +00:00
|
|
|
input.readline(current_prompt, false) # false since we'll add it manually
|
2011-11-02 10:09:29 +00:00
|
|
|
elsif defined? Coolline and input.is_a? Coolline
|
|
|
|
input.readline(current_prompt)
|
2011-09-16 04:19:42 +00:00
|
|
|
else
|
2011-04-14 19:51:00 +00:00
|
|
|
if input.method(:readline).arity == 1
|
|
|
|
input.readline(current_prompt)
|
|
|
|
else
|
|
|
|
input.readline
|
|
|
|
end
|
2011-09-16 04:19:42 +00:00
|
|
|
end
|
2011-01-10 06:29:26 +00:00
|
|
|
end
|
2011-01-13 14:35:46 +00:00
|
|
|
end
|
2011-01-10 06:29:26 +00:00
|
|
|
|
2011-04-10 23:10:05 +00:00
|
|
|
# Whether the print proc should be invoked.
|
2011-04-18 04:47:35 +00:00
|
|
|
# Currently only invoked if the output is not suppressed OR the last result
|
2011-04-10 23:10:05 +00:00
|
|
|
# is an exception regardless of suppression.
|
|
|
|
# @return [Boolean] Whether the print proc should be invoked.
|
2011-04-18 04:47:35 +00:00
|
|
|
def should_print?
|
|
|
|
!@suppress_output || last_result_is_exception?
|
2011-04-10 23:10:05 +00:00
|
|
|
end
|
2011-04-16 21:17:30 +00:00
|
|
|
|
2010-12-28 03:56:23 +00:00
|
|
|
# Returns the appropriate prompt to use.
|
|
|
|
# This method should not need to be invoked directly.
|
2011-01-07 12:18:09 +00:00
|
|
|
# @param [Boolean] first_line Whether this is the first line of input
|
|
|
|
# (and not multi-line input).
|
|
|
|
# @param [Object] target_self The receiver of the Pry session.
|
2010-12-28 03:56:23 +00:00
|
|
|
# @return [String] The prompt.
|
2011-01-09 11:51:45 +00:00
|
|
|
def select_prompt(first_line, target_self)
|
2011-01-13 14:35:46 +00:00
|
|
|
|
2011-01-07 12:18:09 +00:00
|
|
|
if first_line
|
2011-09-02 09:12:05 +00:00
|
|
|
Array(prompt).first.call(target_self, binding_stack.size - 1, self)
|
2010-12-25 13:59:37 +00:00
|
|
|
else
|
2011-09-02 09:12:05 +00:00
|
|
|
Array(prompt).last.call(target_self, binding_stack.size - 1, self)
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-04-30 21:16:20 +00:00
|
|
|
# the array that the prompt stack is stored in
|
|
|
|
def prompt_stack
|
|
|
|
@prompt_stack ||= Array.new
|
|
|
|
end
|
|
|
|
private :prompt_stack
|
|
|
|
|
|
|
|
# Pushes the current prompt onto a stack that it can be restored from later.
|
|
|
|
# Use this if you wish to temporarily change the prompt.
|
|
|
|
# @param [Array<Proc>] new_prompt
|
|
|
|
# @return [Array<Proc>] new_prompt
|
|
|
|
# @example
|
|
|
|
# new_prompt = [ proc { '>' }, proc { '>>' } ]
|
|
|
|
# push_prompt(new_prompt) # => new_prompt
|
|
|
|
def push_prompt(new_prompt)
|
|
|
|
prompt_stack.push new_prompt
|
|
|
|
end
|
|
|
|
|
|
|
|
# Pops the current prompt off of the prompt stack.
|
|
|
|
# If the prompt you are popping is the last prompt, it will not be popped.
|
|
|
|
# Use this to restore the previous prompt.
|
|
|
|
# @return [Array<Proc>] Prompt being popped.
|
|
|
|
# @example
|
|
|
|
# prompt1 = [ proc { '>' }, proc { '>>' } ]
|
|
|
|
# prompt2 = [ proc { '$' }, proc { '>' } ]
|
|
|
|
# pry = Pry.new :prompt => prompt1
|
|
|
|
# pry.push_prompt(prompt2)
|
|
|
|
# pry.pop_prompt # => prompt2
|
|
|
|
# pry.pop_prompt # => prompt1
|
|
|
|
# pry.pop_prompt # => prompt1
|
|
|
|
def pop_prompt
|
2011-05-19 17:18:21 +00:00
|
|
|
prompt_stack.size > 1 ? prompt_stack.pop : prompt
|
2011-04-30 21:16:20 +00:00
|
|
|
end
|
|
|
|
|
2011-08-22 04:33:39 +00:00
|
|
|
if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == "ruby"
|
|
|
|
require 'ripper'
|
|
|
|
|
|
|
|
# Determine if a string of code is a valid Ruby expression.
|
|
|
|
# Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
|
|
|
|
# @param [String] code The code to validate.
|
|
|
|
# @return [Boolean] Whether or not the code is a valid Ruby expression.
|
|
|
|
# @example
|
|
|
|
# valid_expression?("class Hello") #=> false
|
|
|
|
# valid_expression?("class Hello; end") #=> true
|
|
|
|
def valid_expression?(code)
|
|
|
|
!!Ripper::SexpBuilder.new(code).parse
|
|
|
|
end
|
|
|
|
|
2011-10-19 00:12:57 +00:00
|
|
|
elsif RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == 'jruby'
|
|
|
|
|
|
|
|
# JRuby doesn't have Ripper, so use its native parser for 1.9 mode.
|
|
|
|
def valid_expression?(code)
|
|
|
|
JRuby.parse(code)
|
|
|
|
true
|
|
|
|
rescue SyntaxError
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
2011-08-22 04:33:39 +00:00
|
|
|
else
|
|
|
|
require 'ruby_parser'
|
|
|
|
|
|
|
|
# Determine if a string of code is a valid Ruby expression.
|
|
|
|
# Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
|
|
|
|
# @param [String] code The code to validate.
|
|
|
|
# @return [Boolean] Whether or not the code is a valid Ruby expression.
|
|
|
|
# @example
|
|
|
|
# valid_expression?("class Hello") #=> false
|
|
|
|
# valid_expression?("class Hello; end") #=> true
|
|
|
|
def valid_expression?(code)
|
2011-10-12 06:19:37 +00:00
|
|
|
# NOTE: we're using .dup because RubyParser mutates the input
|
|
|
|
RubyParser.new.parse(code.dup)
|
2011-08-22 04:33:39 +00:00
|
|
|
true
|
|
|
|
rescue Racc::ParseError, SyntaxError
|
|
|
|
false
|
2010-12-25 13:59:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|