1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00
pry--pry/lib/pry.rb
John Mair 9142aa173f Added Pry::CLI class for processing command line options, with plugin support.
Plugins can define their own command line options by having a lib/plugin_name/cli.rb file. If this file exists
it is loaded immediately before command line options are processed. The contents of the file should be along the lines of:

Pry::CLI.add_options do
  on "my-option", "My first option!" do
    puts "I just defined an option!"
  end
end
2011-12-09 03:14:33 +13:00

195 lines
6.2 KiB
Ruby

# (C) John Mair (banisterfiend) 2011
# MIT License
#
require 'pp'
require 'pry/helpers/base_helpers'
require 'pry/hooks'
class Pry
# The default hooks - display messages when beginning and ending Pry sessions.
DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session, :default) do |out, target, _pry_|
# ensure we're actually in a method
file = target.eval('__FILE__')
# /unknown/ for rbx
if file !~ /(\(.*\))|<.*>/ && file !~ /__unknown__/ && file != "" && file != "-e"
_pry_.run_command("whereami 5", "", target)
end
end
# The default print
DEFAULT_PRINT = proc do |output, value|
stringified = begin
value.pretty_inspect
rescue RescuableException
nil
end
unless String === stringified
# Read the class name off of the singleton class to provide a default inspect.
klass = (class << value; self; end).ancestors.first
stringified = "#<#{klass}:0x#{value.__id__.to_s(16)}>"
end
nonce = rand(0x100000000).to_s(16) # whatever
colorized = Helpers::BaseHelpers.colorize_code(stringified.gsub(/#</, "%<#{nonce}"))
# avoid colour-leak from CodeRay and any of the users' previous output
colorized = colorized.sub(/(\n*)$/, "\e[0m\\1") if Pry.color
Helpers::BaseHelpers.stagger_output("=> #{colorized.gsub(/%<(.*?)#{nonce}/, '#<\1')}", output)
end
# may be convenient when working with enormous objects and
# pretty_print is too slow
SIMPLE_PRINT = proc do |output, value|
begin
output.puts "=> #{value.inspect}"
rescue RescuableException
output.puts "=> unknown"
end
end
# useful when playing with truly enormous objects
CLIPPED_PRINT = proc do |output, value|
output.puts "=> #{Pry.view_clip(value)}"
end
# Will only show the first line of the backtrace
DEFAULT_EXCEPTION_HANDLER = proc do |output, exception, _|
output.puts "#{exception.class}: #{exception.message}"
output.puts "from #{exception.backtrace.first}"
end
# Don't catch these exceptions
DEFAULT_EXCEPTION_WHITELIST = [SystemExit, SignalException]
# The default prompt; includes the target and nesting level
DEFAULT_PROMPT = [
proc { |target_self, nest_level, pry|
"[#{pry.input_array.size}] pry(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
},
proc { |target_self, nest_level, pry|
"[#{pry.input_array.size}] pry(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
}
]
# A simple prompt - doesn't display target or nesting level
SIMPLE_PROMPT = [proc { ">> " }, proc { " | " }]
SHELL_PROMPT = [
proc { |target_self, _, _| "pry #{Pry.view_clip(target_self)}:#{Dir.pwd} $ " },
proc { |target_self, _, _| "pry #{Pry.view_clip(target_self)}:#{Dir.pwd} * " }
]
# A prompt that includes the full object path as well as
# input/output (_in_ and _out_) information. Good for navigation.
NAV_PROMPT = [
proc do |_, level, pry|
tree = pry.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / "
"[#{pry.input_array.size}] (pry) #{tree}: #{level}> "
end,
proc do |_, level, pry|
tree = pry.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / "
"[#{pry.input_array.size}] (pry) #{tree}: #{level}* "
end,
]
# Deal with the ^D key being pressed, different behaviour in
# different cases:
# 1) In an expression - behave like `!` command (clear input buffer)
# 2) At top-level session - behave like `exit command (break out of repl loop)
# 3) In a nested session - behave like `cd ..` (pop a binding)
DEFAULT_CONTROL_D_HANDLER = proc do |eval_string, _pry_|
if !eval_string.empty?
# clear input buffer
eval_string.replace("")
elsif _pry_.binding_stack.one?
# ^D at top-level breaks out of loop
_pry_.binding_stack.clear
throw(:breakout)
else
# otherwise just pops a binding
_pry_.binding_stack.pop
end
end
DEFAULT_SYSTEM = proc do |output, cmd, _|
if !system(cmd)
output.puts "Error: there was a problem executing system command: #{cmd}"
end
end
# As a REPL, we often want to catch any unexpected exceptions that may have
# been raised; however we don't want to go overboard and prevent the user
# from exiting Pry when they want to.
module RescuableException
def self.===(exception)
case exception
# Catch when the user hits ^C (Interrupt < SignalException), and assume
# that they just wanted to stop the in-progress command (just like bash etc.)
when Interrupt
true
# Don't catch signals (particularly not SIGTERM) as these are unlikely to be
# intended for pry itself. We should also make sure that Kernel#exit works.
when *Pry.config.exception_whitelist
false
# All other exceptions will be caught.
else
true
end
end
end
# CommandErrors are caught by the REPL loop and displayed to the user. They
# indicate an exceptional condition that's fatal to the current command.
class CommandError < StandardError
end
end
require "method_source"
require 'shellwords'
require "readline"
require "stringio"
require "coderay"
require "optparse"
require "slop"
if RUBY_PLATFORM =~ /jruby/
begin
require 'ffi'
rescue LoadError
$stderr.puts "Need to `gem install ffi`"
end
end
if RUBY_PLATFORM =~ /mswin/ || RUBY_PLATFORM =~ /mingw/
begin
require 'win32console'
rescue LoadError
$stderr.puts "Need to `gem install win32console`"
exit 1
end
end
require "pry/version"
require "pry/rbx_method"
require "pry/rbx_path"
require "pry/method"
require "pry/wrapped_module"
require "pry/history_array"
require "pry/helpers"
require "pry/history"
require "pry/command_set"
require "pry/commands"
require "pry/command_context"
require "pry/custom_completions"
require "pry/completion"
require "pry/plugins"
require "pry/core_extensions"
require "pry/pry_class"
require "pry/pry_instance"
require "pry/cli"