2010-12-29 04:14:12 -05:00
|
|
|
# @author John Mair (banisterfiend)
|
2010-12-25 08:59:37 -05:00
|
|
|
class Pry
|
|
|
|
|
2011-04-16 17:17:30 -04:00
|
|
|
# The RC Files to load.
|
2011-03-04 07:37:59 -05:00
|
|
|
RC_FILES = ["~/.pryrc"]
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2010-12-25 08:59:37 -05:00
|
|
|
# class accessors
|
|
|
|
class << self
|
2010-12-29 04:14:12 -05:00
|
|
|
|
|
|
|
# Get nesting data.
|
|
|
|
# This method should not need to be accessed directly.
|
|
|
|
# @return [Array] The unparsed nesting information.
|
2010-12-25 08:59:37 -05:00
|
|
|
attr_reader :nesting
|
2010-12-29 04:14:12 -05:00
|
|
|
|
|
|
|
# Get last value evaluated by Pry.
|
|
|
|
# This method should not need to be accessed directly.
|
|
|
|
# @return [Object] The last result.
|
|
|
|
attr_accessor :last_result
|
|
|
|
|
2011-03-14 06:55:22 -04:00
|
|
|
# Get last exception raised.
|
|
|
|
# This method should not need to be accessed directly.
|
|
|
|
# @return [Exception] The last exception.
|
|
|
|
attr_accessor :last_exception
|
|
|
|
|
2010-12-29 04:14:12 -05:00
|
|
|
# Get the active Pry instance that manages the active Pry session.
|
|
|
|
# This method should not need to be accessed directly.
|
|
|
|
# @return [Pry] The active Pry instance.
|
|
|
|
attr_accessor :active_instance
|
2011-01-13 09:35:46 -05:00
|
|
|
|
2010-12-30 10:01:11 -05:00
|
|
|
# Get/Set the object to use for input by default by all Pry instances.
|
2011-01-12 08:03:45 -05:00
|
|
|
# @return [#readline] The object to use for input by default by all
|
2010-12-29 04:14:12 -05:00
|
|
|
# Pry instances.
|
|
|
|
attr_accessor :input
|
|
|
|
|
2010-12-30 10:01:11 -05:00
|
|
|
# Get/Set the object to use for output by default by all Pry instances.
|
2010-12-29 04:14:12 -05:00
|
|
|
# @return [#puts] The object to use for output by default by all
|
|
|
|
# Pry instances.
|
|
|
|
attr_accessor :output
|
|
|
|
|
2010-12-30 10:01:11 -05:00
|
|
|
# Get/Set the object to use for commands by default by all Pry instances.
|
2011-01-12 08:03:45 -05:00
|
|
|
# @return [Pry::CommandBase] The object to use for commands by default by all
|
2010-12-29 04:14:12 -05:00
|
|
|
# Pry instances.
|
|
|
|
attr_accessor :commands
|
|
|
|
|
2010-12-30 10:01:11 -05:00
|
|
|
# Get/Set the Proc to use for printing by default by all Pry
|
2010-12-29 04:14:12 -05:00
|
|
|
# instances.
|
2010-12-30 10:01:11 -05:00
|
|
|
# This is the 'print' component of the REPL.
|
2010-12-29 04:14:12 -05:00
|
|
|
# @return [Proc] The Proc to use for printing by default by all
|
|
|
|
# Pry instances.
|
|
|
|
attr_accessor :print
|
|
|
|
|
2011-04-18 10:11:00 -04:00
|
|
|
# @return [Proc] The Proc to use for printing exceptions by default by all
|
2011-04-16 17:17:30 -04:00
|
|
|
# Pry instances.
|
|
|
|
attr_accessor :exception_handler
|
|
|
|
|
2010-12-30 10:01:11 -05:00
|
|
|
# Get/Set the Hash that defines Pry hooks used by default by all Pry
|
2010-12-29 04:14:12 -05:00
|
|
|
# instances.
|
|
|
|
# @return [Hash] The hooks used by default by all Pry instances.
|
|
|
|
# @example
|
|
|
|
# Pry.hooks :before_session => proc { puts "hello" },
|
|
|
|
# :after_session => proc { puts "goodbye" }
|
|
|
|
attr_accessor :hooks
|
|
|
|
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2011-04-07 04:38:50 -04:00
|
|
|
# Get/Set the Proc that defines extra Readline completions (on top
|
|
|
|
# of the ones defined for IRB).
|
|
|
|
# @return [Proc] The Proc that defines extra Readline completions (on top
|
|
|
|
# @example Add file names to completion list
|
|
|
|
# Pry.custom_completions = proc { Dir.entries('.') }
|
2011-04-06 12:59:09 -04:00
|
|
|
attr_accessor :custom_completions
|
|
|
|
|
2011-01-07 07:18:09 -05:00
|
|
|
# Get the array of Procs to be used for the prompts by default by
|
2010-12-29 04:14:12 -05:00
|
|
|
# all Pry instances.
|
|
|
|
# @return [Array<Proc>] The array of Procs to be used for the
|
|
|
|
# prompts by default by all Pry instances.
|
2011-01-07 07:18:09 -05:00
|
|
|
attr_accessor :prompt
|
2011-02-25 10:32:54 -05:00
|
|
|
|
2011-02-27 11:06:52 -05:00
|
|
|
# Value returned by last executed Pry command.
|
|
|
|
# @return [Object] The command value
|
2011-02-25 10:32:54 -05:00
|
|
|
attr_accessor :cmd_ret_value
|
2011-03-02 06:18:26 -05:00
|
|
|
|
|
|
|
# Determines whether colored output is enabled.
|
2011-04-16 17:17:30 -04:00
|
|
|
# @return [Boolean]
|
2011-03-02 06:18:26 -05:00
|
|
|
attr_accessor :color
|
2011-03-04 07:37:59 -05:00
|
|
|
|
2011-04-18 10:11:00 -04:00
|
|
|
# Determines whether paging (of long blocks of text) is enabled.
|
|
|
|
# @return [Boolean]
|
|
|
|
attr_accessor :pager
|
|
|
|
|
2011-03-04 07:37:59 -05:00
|
|
|
# Determines whether the rc file (~/.pryrc) should be loaded.
|
2011-04-16 17:17:30 -04:00
|
|
|
# @return [Boolean]
|
2011-03-04 07:37:59 -05:00
|
|
|
attr_accessor :should_load_rc
|
|
|
|
|
|
|
|
# Set to true if Pry is invoked from command line using `pry` executable
|
|
|
|
# @return [Boolean]
|
|
|
|
attr_accessor :cli
|
2011-03-13 21:46:50 -04:00
|
|
|
|
|
|
|
# Set to true if the pry-doc extension is loaded.
|
|
|
|
# @return [Boolean]
|
|
|
|
attr_accessor :has_pry_doc
|
2011-04-25 11:21:42 -04:00
|
|
|
|
|
|
|
# The default editor to use. Defaults to $EDITOR or nano if
|
|
|
|
# $EDITOR is not defined.
|
2011-04-30 12:38:17 -04:00
|
|
|
# If `editor` is a String then that string is used as the shell
|
|
|
|
# command to invoke the editor. If `editor` is callable (e.g a
|
|
|
|
# Proc) then `file` and `line` are passed in as parameters and the
|
|
|
|
# return value of that callable invocation is used as the exact
|
|
|
|
# shell command to invoke the editor.
|
|
|
|
# @example String
|
|
|
|
# Pry.editor = "emacsclient"
|
|
|
|
# @example Callable
|
|
|
|
# Pry.editor = proc { |file, line| "emacsclient #{file} +#{line}" }
|
|
|
|
# @return [String, #call]
|
2011-04-25 11:21:42 -04:00
|
|
|
attr_accessor :editor
|
2011-03-04 07:37:59 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Load the rc files given in the `Pry::RC_FILES` array.
|
|
|
|
# Defaults to loading just `~/.pryrc`. This method can also
|
|
|
|
# be used to reload the files if they have changed.
|
|
|
|
def self.load_rc
|
|
|
|
RC_FILES.each do |file_name|
|
|
|
|
file_name = File.expand_path(file_name)
|
|
|
|
load(file_name) if File.exists?(file_name)
|
|
|
|
end
|
2010-12-25 08:59:37 -05:00
|
|
|
end
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2010-12-29 04:14:12 -05:00
|
|
|
# Start a Pry REPL.
|
2011-03-04 07:37:59 -05:00
|
|
|
# This method also loads the files specified in `Pry::RC_FILES` the
|
|
|
|
# first time it is invoked.
|
2010-12-29 04:14:12 -05:00
|
|
|
# @param [Object, Binding] target The receiver of the Pry session
|
2010-12-30 10:01:11 -05:00
|
|
|
# @param [Hash] options
|
|
|
|
# @option options (see Pry#initialize)
|
2010-12-29 04:14:12 -05:00
|
|
|
# @example
|
|
|
|
# Pry.start(Object.new, :input => MyInput.new)
|
2010-12-25 08:59:37 -05:00
|
|
|
def self.start(target=TOPLEVEL_BINDING, options={})
|
2011-03-04 07:37:59 -05:00
|
|
|
if should_load_rc && !@rc_loaded
|
|
|
|
load_rc
|
|
|
|
@rc_loaded = true
|
|
|
|
end
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2010-12-25 08:59:37 -05:00
|
|
|
new(options).repl(target)
|
|
|
|
end
|
|
|
|
|
2010-12-29 04:14:12 -05:00
|
|
|
# A custom version of `Kernel#inspect`.
|
|
|
|
# This method should not need to be accessed directly.
|
|
|
|
# @param obj The object to view.
|
|
|
|
# @return [String] The string representation of `obj`.
|
2010-12-25 08:59:37 -05:00
|
|
|
def self.view(obj)
|
|
|
|
case obj
|
2011-04-17 03:23:48 -04:00
|
|
|
when String, Hash, Array, Symbol, Exception, nil
|
2010-12-25 08:59:37 -05:00
|
|
|
obj.inspect
|
|
|
|
else
|
|
|
|
obj.to_s
|
|
|
|
end
|
2011-04-04 08:18:07 -04:00
|
|
|
|
|
|
|
rescue NoMethodError
|
|
|
|
"unknown"
|
2010-12-25 08:59:37 -05:00
|
|
|
end
|
|
|
|
|
2011-02-13 10:49:53 -05:00
|
|
|
# A version of `Pry.view` that clips the output to `max_size` chars.
|
|
|
|
# In case of > `max_size` chars the `#<Object...> notation is used.
|
|
|
|
# @param obj The object to view.
|
|
|
|
# @param max_size The maximum number of chars before clipping occurs.
|
|
|
|
# @return [String] The string representation of `obj`.
|
|
|
|
def self.view_clip(obj, max_size=60)
|
|
|
|
if Pry.view(obj).size < max_size
|
|
|
|
Pry.view(obj)
|
|
|
|
else
|
|
|
|
"#<#{obj.class}:%#x>" % (obj.object_id << 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-18 12:01:21 -05:00
|
|
|
# Run a Pry command from outside a session. The commands available are
|
|
|
|
# those referenced by `Pry.commands` (the default command set).
|
|
|
|
# Command output is suppresed by default, this is because the return
|
|
|
|
# value (if there is one) is likely to be more useful.
|
|
|
|
# @param [String] arg_string The Pry command (including arguments,
|
|
|
|
# if any).
|
|
|
|
# @param [Hash] options Optional named parameters.
|
2011-02-18 13:01:02 -05:00
|
|
|
# @return [Object] The return value of the Pry command.
|
2011-02-18 12:01:21 -05:00
|
|
|
# @option options [Object, Binding] :context The object context to run the
|
|
|
|
# command under. Defaults to `TOPLEVEL_BINDING` (main).
|
|
|
|
# @option options [Boolean] :show_output Whether to show command
|
|
|
|
# output. Defaults to false.
|
|
|
|
# @example Run at top-level with no output.
|
|
|
|
# Pry.run_command "ls"
|
|
|
|
# @example Run under Pry class, returning only public methods.
|
|
|
|
# Pry.run_command "ls -m", :context => Pry
|
|
|
|
# @example Display command output.
|
|
|
|
# Pry.run_command "ls -av", :show_output => true
|
|
|
|
def self.run_command(arg_string, options={})
|
|
|
|
name, arg_string = arg_string.split(/\s+/, 2)
|
|
|
|
arg_string = "" if !arg_string
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2011-02-18 12:01:21 -05:00
|
|
|
options = {
|
|
|
|
:context => TOPLEVEL_BINDING,
|
2011-03-05 09:17:54 -05:00
|
|
|
:show_output => false,
|
|
|
|
:output => Pry.output,
|
|
|
|
:commands => Pry.commands
|
2011-02-18 12:01:21 -05:00
|
|
|
}.merge!(options)
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2011-04-25 07:26:25 -04:00
|
|
|
null_output = StringIO.new
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2011-04-25 07:26:25 -04:00
|
|
|
context = CommandContext.new
|
2011-04-23 20:05:41 -04:00
|
|
|
commands = options[:commands]
|
2011-04-16 17:17:30 -04:00
|
|
|
|
2011-04-25 17:13:36 -04:00
|
|
|
context.opts = {}
|
|
|
|
context.output = options[:show_output] ? options[:output] : null_output
|
|
|
|
context.target = Pry.binding_for(options[:context])
|
|
|
|
context.command_set = commands
|
2011-02-18 12:01:21 -05:00
|
|
|
|
2011-04-25 07:26:25 -04:00
|
|
|
commands.run_command(context, name, *Shellwords.shellwords(arg_string))
|
2011-02-18 12:01:21 -05:00
|
|
|
end
|
|
|
|
|
2011-04-25 12:17:20 -04:00
|
|
|
def self.default_editor_for_platform
|
|
|
|
if RUBY_PLATFORM =~ /mswin|mingw/
|
|
|
|
ENV['EDITOR'] ? ENV['EDITOR'] : "notepad"
|
|
|
|
else
|
|
|
|
ENV['EDITOR'] ? ENV['EDITOR'] : "nano"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-12-29 04:14:12 -05:00
|
|
|
# Set all the configurable options back to their default values
|
2010-12-25 08:59:37 -05:00
|
|
|
def self.reset_defaults
|
2011-01-09 06:51:45 -05:00
|
|
|
@input = Readline
|
|
|
|
@output = $stdout
|
2011-01-17 09:38:09 -05:00
|
|
|
@commands = Pry::Commands
|
2011-01-07 07:18:09 -05:00
|
|
|
@prompt = DEFAULT_PROMPT
|
2010-12-27 05:56:55 -05:00
|
|
|
@print = DEFAULT_PRINT
|
2011-04-16 17:17:30 -04:00
|
|
|
@exception_handler = DEFAULT_EXCEPTION_HANDLER
|
2010-12-27 05:56:55 -05:00
|
|
|
@hooks = DEFAULT_HOOKS
|
2011-04-06 12:59:09 -04:00
|
|
|
@custom_completions = DEFAULT_CUSTOM_COMPLETIONS
|
2011-03-05 09:17:54 -05:00
|
|
|
@color = true
|
2011-04-18 10:11:00 -04:00
|
|
|
@pager = true
|
2011-03-04 07:37:59 -05:00
|
|
|
@should_load_rc = true
|
|
|
|
@rc_loaded = false
|
|
|
|
@cli = false
|
2011-04-25 12:17:20 -04:00
|
|
|
@editor = default_editor_for_platform
|
2010-12-25 08:59:37 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
self.reset_defaults
|
|
|
|
|
|
|
|
@nesting = []
|
|
|
|
def @nesting.level
|
|
|
|
last.is_a?(Array) ? last.first : nil
|
|
|
|
end
|
2011-01-13 09:35:46 -05:00
|
|
|
|
|
|
|
# Return all active Pry sessions.
|
|
|
|
# @return [Array<Pry>] Active Pry sessions.
|
|
|
|
def self.sessions
|
|
|
|
# last element in nesting array is the pry instance
|
|
|
|
nesting.map(&:last)
|
|
|
|
end
|
2011-02-16 11:27:55 -05:00
|
|
|
|
|
|
|
# Return a `Binding` object for `target` or return `target` if it is
|
|
|
|
# already a `Binding`.
|
|
|
|
# In the case where `target` is top-level then return `TOPLEVEL_BINDING`
|
|
|
|
# @param [Object] target The object to get a `Binding` object for.
|
|
|
|
# @return [Binding] The `Binding` object.
|
|
|
|
def self.binding_for(target)
|
|
|
|
if target.is_a?(Binding)
|
|
|
|
target
|
|
|
|
else
|
|
|
|
if target == TOPLEVEL_BINDING.eval('self')
|
|
|
|
TOPLEVEL_BINDING
|
|
|
|
else
|
|
|
|
target.__binding__
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-12-25 08:59:37 -05:00
|
|
|
end
|