mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Merge branch 'master' into refactor/direct_tests
Conflicts: lib/pry/commands/cd.rb test/test_default_commands/test_documentation.rb
This commit is contained in:
commit
6271b16aee
20 changed files with 593 additions and 246 deletions
|
@ -120,6 +120,10 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
# Store the current working directory. This allows show-source etc. to work if
|
||||
# your process has changed directory since boot. [Issue #675]
|
||||
INITIAL_PWD = Dir.pwd
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -57,12 +57,18 @@ class Pry
|
|||
end
|
||||
|
||||
def parse_options(args=ARGV.dup)
|
||||
raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options." if !options
|
||||
unless options
|
||||
raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options."
|
||||
end
|
||||
|
||||
self.input_args = args
|
||||
|
||||
opts = Slop.parse!(args, :help => true, :multiple_switches => false, &options)
|
||||
option_processors.each { |processor| processor.call(opts) } if option_processors # option processors are optional
|
||||
|
||||
# Option processors are optional.
|
||||
if option_processors
|
||||
option_processors.each { |processor| processor.call(opts) }
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
@ -139,8 +145,12 @@ Copyright (c) 2011 John Mair (banisterfiend)
|
|||
Pry.config.requires << file
|
||||
end
|
||||
|
||||
on :I, "Add a path to the $LOAD_PATH", :argument => true do |path|
|
||||
$LOAD_PATH << path
|
||||
on :I, "Add a path to the $LOAD_PATH", :argument => true, :as => Array, :delimiter => ":" do |load_path|
|
||||
load_path.map! do |path|
|
||||
/\A\.\// =~ path ? path : File.expand_path(path)
|
||||
end
|
||||
|
||||
$LOAD_PATH.unshift(*load_path)
|
||||
end
|
||||
|
||||
on :v, :version, "Display the Pry version" do
|
||||
|
|
|
@ -35,20 +35,23 @@ class Pry
|
|||
# @param [String] fn The name of a file, or "(pry)".
|
||||
# @param [Symbol] code_type The type of code the file contains.
|
||||
# @return [Code]
|
||||
def from_file(fn, code_type = nil)
|
||||
def from_file(fn, code_type=type_from_filename(fn))
|
||||
|
||||
if fn == Pry.eval_path
|
||||
f = Pry.line_buffer.drop(1)
|
||||
new(Pry.line_buffer.drop(1), 1, code_type)
|
||||
else
|
||||
if File.readable?(fn)
|
||||
f = File.open(fn, 'r')
|
||||
code_type ||= type_from_filename(fn)
|
||||
else
|
||||
abs_path = [File.expand_path(fn, Dir.pwd),
|
||||
File.expand_path(fn, Pry::INITIAL_PWD)
|
||||
].detect{ |abs_path| File.readable?(abs_path) }
|
||||
|
||||
unless abs_path
|
||||
raise MethodSource::SourceNotFoundError, "Cannot open #{fn.inspect} for reading."
|
||||
end
|
||||
|
||||
File.open(abs_path, 'r') do |f|
|
||||
new(f, 1, code_type)
|
||||
end
|
||||
end
|
||||
new(f, 1, code_type || :ruby)
|
||||
ensure
|
||||
f.close if f.respond_to?(:close)
|
||||
end
|
||||
|
||||
# Instantiate a `Code` object containing code extracted from a
|
||||
|
@ -85,8 +88,9 @@ class Pry
|
|||
# unknown.
|
||||
#
|
||||
# @param [String] filename
|
||||
# @param [Symbol] default (:ruby) the file type to assume if none could be detected
|
||||
# @return [Symbol, nil]
|
||||
def type_from_filename(filename)
|
||||
def type_from_filename(filename, default=:ruby)
|
||||
map = {
|
||||
%w(.c .h) => :c,
|
||||
%w(.cpp .hpp .cc .h cxx) => :cpp,
|
||||
|
@ -108,7 +112,7 @@ class Pry
|
|||
k.any? { |ext| ext == File.extname(filename) }
|
||||
end
|
||||
|
||||
type
|
||||
type || default
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
require 'pry/helpers/documentation_helpers'
|
||||
|
||||
class Pry
|
||||
|
||||
# The super-class of all commands, new commands should be created by calling
|
||||
# {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command}
|
||||
# which creates a ClassCommand. Please don't use this class directly.
|
||||
class Command
|
||||
extend Helpers::DocumentationHelpers
|
||||
|
||||
# represents a void return value for a command
|
||||
VOID_VALUE = Object.new
|
||||
|
@ -49,6 +52,14 @@ class Pry
|
|||
def block
|
||||
@block || instance_method(:process) && instance_method(:process)
|
||||
end
|
||||
|
||||
def source
|
||||
strip_leading_whitespace(block.source)
|
||||
end
|
||||
|
||||
def source_location
|
||||
block.source_location
|
||||
end
|
||||
end
|
||||
|
||||
# Make those properties accessible to instances
|
||||
|
@ -58,6 +69,8 @@ class Pry
|
|||
def block; self.class.block; end
|
||||
def command_options; self.class.options; end
|
||||
def command_name; command_options[:listing]; end
|
||||
def source; self.class.source; end
|
||||
def source_location; self.class.source_location; end
|
||||
|
||||
class << self
|
||||
def name
|
||||
|
|
|
@ -20,64 +20,9 @@ class Pry
|
|||
BANNER
|
||||
|
||||
def process
|
||||
# Extract command arguments. Delete blank arguments like " ", but
|
||||
# don't delete empty strings like "".
|
||||
path = arg_string.split(/\//).delete_if { |a| a =~ /\A\s+\z/ }
|
||||
stack = _pry_.binding_stack.dup
|
||||
old_stack = state.old_stack || []
|
||||
|
||||
# Special case when we only get a single "/", return to root.
|
||||
if path.empty?
|
||||
state.old_stack = stack.dup unless old_stack.empty?
|
||||
stack = [stack.first]
|
||||
end
|
||||
|
||||
path.each_with_index do |context, i|
|
||||
begin
|
||||
case context.chomp
|
||||
when ""
|
||||
state.old_stack = stack.dup
|
||||
stack = [stack.first]
|
||||
when "::"
|
||||
state.old_stack = stack.dup
|
||||
stack.push(TOPLEVEL_BINDING)
|
||||
when "."
|
||||
next
|
||||
when ".."
|
||||
unless stack.size == 1
|
||||
# Don't rewrite old_stack if we're in complex expression
|
||||
# (e.g.: `cd 1/2/3/../4).
|
||||
state.old_stack = stack.dup if path.first == ".."
|
||||
stack.pop
|
||||
end
|
||||
when "-"
|
||||
unless old_stack.empty?
|
||||
# Interchange current stack and old stack with each other.
|
||||
stack, state.old_stack = state.old_stack, stack
|
||||
end
|
||||
else
|
||||
state.old_stack = stack.dup if i == 0
|
||||
stack.push(Pry.binding_for(stack.last.eval(context)))
|
||||
end
|
||||
|
||||
rescue RescuableException => e
|
||||
# Restore old stack to its initial values.
|
||||
state.old_stack = old_stack
|
||||
|
||||
msg = [
|
||||
"Bad object path: #{arg_string}.",
|
||||
"Failed trying to resolve: #{context}.",
|
||||
e.inspect
|
||||
].join(' ')
|
||||
|
||||
CommandError.new(msg).tap do |err|
|
||||
err.set_backtrace e.backtrace
|
||||
raise err
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
_pry_.binding_stack = stack
|
||||
stack, old_stack = context_from_object_path(arg_string, _pry_, state.old_stack||[])
|
||||
state.old_stack = old_stack
|
||||
_pry_.binding_stack = stack unless stack.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,40 +8,15 @@ class Pry
|
|||
|
||||
opts = Slop.parse!(args) do |opt|
|
||||
opt.banner unindent <<-USAGE
|
||||
Usage: show-command [OPTIONS] [CMD]
|
||||
Show the source for command CMD.
|
||||
e.g: show-command show-method
|
||||
NOTE: show-command is DEPRACTED. Use show-source [command_name] instead.
|
||||
USAGE
|
||||
|
||||
opt.on :l, "line-numbers", "Show line numbers."
|
||||
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
||||
opt.on :h, :help, "This message." do
|
||||
output.puts opt.help
|
||||
end
|
||||
end
|
||||
|
||||
return if opts.present?(:help)
|
||||
|
||||
command_name = args.shift
|
||||
if !command_name
|
||||
raise CommandError, "You must provide a command name."
|
||||
end
|
||||
|
||||
if find_command(command_name)
|
||||
block = Pry::Method.new(find_command(command_name).block)
|
||||
|
||||
return unless block.source
|
||||
set_file_and_dir_locals(block.source_file)
|
||||
|
||||
output.puts make_header(block)
|
||||
output.puts
|
||||
|
||||
code = Pry::Code.from_method(block).with_line_numbers(opts.present?(:'line-numbers')).to_s
|
||||
|
||||
render_output(code, opts)
|
||||
else
|
||||
raise CommandError, "No such command: #{command_name}."
|
||||
end
|
||||
render_output opts.banner
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -111,6 +111,24 @@ class Pry
|
|||
doc
|
||||
end
|
||||
|
||||
def process_command
|
||||
name = args.join(" ").gsub(/\"/,"")
|
||||
command = find_command(name)
|
||||
|
||||
doc = command.new.help
|
||||
doc = strip_leading_whitespace(doc)
|
||||
|
||||
file_name, line = command.source_location
|
||||
set_file_and_dir_locals(file_name)
|
||||
|
||||
|
||||
result = ""
|
||||
result << "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line}:\n"
|
||||
result << "#{Pry::Helpers::Text.bold('Number of lines:')} #{doc.lines.count}\n\n"
|
||||
result << doc
|
||||
result << "\n"
|
||||
end
|
||||
|
||||
def module_start_line(mod, candidate=0)
|
||||
if opts.present?(:'base-one')
|
||||
1
|
||||
|
|
|
@ -111,6 +111,23 @@ class Pry
|
|||
result
|
||||
end
|
||||
|
||||
def process_command
|
||||
name = args.join(" ").gsub(/\"/,"")
|
||||
command = find_command(name)
|
||||
|
||||
file_name, line = command.source_location
|
||||
set_file_and_dir_locals(file_name)
|
||||
|
||||
code = Pry::Code.new(command.source, line).with_line_numbers(use_line_numbers?).to_s
|
||||
|
||||
result = ""
|
||||
result << "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line}:\n"
|
||||
result << "#{Pry::Helpers::Text.bold('Number of lines:')} #{code.lines.count}\n\n"
|
||||
result << "\n"
|
||||
|
||||
result << code
|
||||
end
|
||||
|
||||
def use_line_numbers?
|
||||
opts.present?(:b) || opts.present?(:l)
|
||||
end
|
||||
|
|
|
@ -41,36 +41,50 @@ class Pry
|
|||
# Return a new completion proc for use by Readline.
|
||||
# @param [Binding] target The current binding context.
|
||||
# @param [Array<String>] commands The array of Pry commands.
|
||||
def self.build_completion_proc(target, commands=[""])
|
||||
def self.build_completion_proc(target, pry=nil, commands=[""])
|
||||
proc do |input|
|
||||
|
||||
# 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(input)
|
||||
|
||||
unless path.call.empty?
|
||||
target, _ = Pry::Helpers::BaseHelpers.context_from_object_path(path.call, pry)
|
||||
target = target.last
|
||||
end
|
||||
|
||||
begin
|
||||
bind = target
|
||||
|
||||
case input
|
||||
|
||||
|
||||
# Complete stdlib symbols
|
||||
|
||||
when /^(\/[^\/]*\/)\.([^.]*)$/
|
||||
# Regexp
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
candidates = Regexp.instance_methods.collect{|m| m.to_s}
|
||||
select_message(receiver, message, candidates)
|
||||
candidates = Regexp.instance_methods.collect(&:to_s)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^([^\]]*\])\.([^.]*)$/
|
||||
# Array
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
candidates = Array.instance_methods.collect{|m| m.to_s}
|
||||
select_message(receiver, message, candidates)
|
||||
candidates = Array.instance_methods.collect(&:to_s)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^([^\}]*\})\.([^.]*)$/
|
||||
# Proc or Hash
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
candidates = Proc.instance_methods.collect{|m| m.to_s}
|
||||
candidates |= Hash.instance_methods.collect{|m| m.to_s}
|
||||
select_message(receiver, message, candidates)
|
||||
candidates = Proc.instance_methods.collect(&:to_s)
|
||||
candidates |= Hash.instance_methods.collect(&:to_s)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^(:[^:.]*)$/
|
||||
# Symbol
|
||||
|
@ -86,16 +100,32 @@ class Pry
|
|||
when /^::([A-Z][^:\.\(]*)$/
|
||||
# Absolute Constant or class methods
|
||||
receiver = $1
|
||||
candidates = Object.constants.collect{|m| m.to_s}
|
||||
candidates = Object.constants.collect(&:to_s)
|
||||
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
|
||||
|
||||
|
||||
# Complete target symbols
|
||||
|
||||
when /^([A-Z][A-Za-z0-9]*)$/
|
||||
# Constant
|
||||
message = $1
|
||||
|
||||
begin
|
||||
context = target.eval("self")
|
||||
context = context.class unless context.respond_to? :constants
|
||||
candidates = context.constants.collect(&:to_s)
|
||||
rescue
|
||||
candidates = []
|
||||
end
|
||||
candidates = candidates.grep(/^#{message}/).collect(&path)
|
||||
|
||||
when /^([A-Z].*)::([^:.]*)$/
|
||||
# Constant or class methods
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
begin
|
||||
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
|
||||
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
|
||||
candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
|
||||
candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
|
||||
rescue RescuableException
|
||||
candidates = []
|
||||
end
|
||||
|
@ -106,8 +136,8 @@ class Pry
|
|||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
candidates = Symbol.instance_methods.collect{|m| m.to_s}
|
||||
select_message(receiver, message, candidates)
|
||||
candidates = Symbol.instance_methods.collect(&:to_s)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
|
||||
# Numeric
|
||||
|
@ -115,42 +145,43 @@ class Pry
|
|||
message = Regexp.quote($5)
|
||||
|
||||
begin
|
||||
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
|
||||
candidates = eval(receiver, bind).methods.collect(&:to_s)
|
||||
rescue RescuableException
|
||||
candidates = []
|
||||
end
|
||||
select_message(receiver, message, candidates)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
|
||||
when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/#
|
||||
# Numeric(0xFFFF)
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
begin
|
||||
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
|
||||
candidates = eval(receiver, bind).methods.collect(&:to_s)
|
||||
rescue RescuableException
|
||||
candidates = []
|
||||
end
|
||||
select_message(receiver, message, candidates)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^(\$[^.]*)$/
|
||||
# Global variables
|
||||
regmessage = Regexp.new(Regexp.quote($1))
|
||||
candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
|
||||
candidates = global_variables.collect(&:to_s).grep(regmessage)
|
||||
|
||||
when /^([^."].*)\.([^.]*)$/
|
||||
# variable
|
||||
# Variable
|
||||
receiver = $1
|
||||
message = Regexp.quote($2)
|
||||
|
||||
gv = eval("global_variables", bind).collect{|m| m.to_s}
|
||||
lv = eval("local_variables", bind).collect{|m| m.to_s}
|
||||
cv = eval("self.class.constants", bind).collect{|m| m.to_s}
|
||||
gv = eval("global_variables", bind).collect(&:to_s)
|
||||
lv = eval("local_variables", bind).collect(&:to_s)
|
||||
cv = eval("self.class.constants", bind).collect(&:to_s)
|
||||
|
||||
if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
|
||||
# foo.func and foo is local var. OR
|
||||
# Foo::Bar.func
|
||||
begin
|
||||
candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
|
||||
candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
|
||||
rescue RescuableException
|
||||
candidates = []
|
||||
end
|
||||
|
@ -169,35 +200,35 @@ class Pry
|
|||
# jruby doesn't always provide #instance_methods() on each
|
||||
# object.
|
||||
if m.respond_to?(:instance_methods)
|
||||
candidates.concat m.instance_methods(false).collect{|x| x.to_s}
|
||||
candidates.concat m.instance_methods(false).collect(&:to_s)
|
||||
end
|
||||
}
|
||||
candidates.sort!
|
||||
candidates.uniq!
|
||||
end
|
||||
select_message(receiver, message, candidates)
|
||||
select_message(path, receiver, message, candidates)
|
||||
|
||||
when /^\.([^.]*)$/
|
||||
# unknown(maybe String)
|
||||
|
||||
# Unknown(maybe String)
|
||||
receiver = ""
|
||||
message = Regexp.quote($1)
|
||||
|
||||
candidates = String.instance_methods(true).collect{|m| m.to_s}
|
||||
select_message(receiver, message, candidates)
|
||||
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
|
||||
).collect{|m| m.to_s}
|
||||
).collect(&:to_s)
|
||||
|
||||
if eval("respond_to?(:class_variables)", bind)
|
||||
candidates += eval("class_variables", bind).collect { |m| m.to_s }
|
||||
candidates += eval("class_variables", bind).collect(&:to_s)
|
||||
end
|
||||
|
||||
(candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
|
||||
candidates = (candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
|
||||
candidates.collect(&path)
|
||||
end
|
||||
rescue RescuableException
|
||||
[]
|
||||
|
@ -205,17 +236,38 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
def self.select_message(receiver, message, candidates)
|
||||
def self.select_message(path, receiver, message, candidates)
|
||||
candidates.grep(/^#{message}/).collect do |e|
|
||||
case e
|
||||
when /^[a-zA-Z_]/
|
||||
receiver + "." + e
|
||||
when /^[0-9]/
|
||||
when *Operators
|
||||
#receiver + " " + e
|
||||
end
|
||||
case e
|
||||
when /^[a-zA-Z_]/
|
||||
path.call(receiver + "." + e)
|
||||
when /^[0-9]/
|
||||
when *Operators
|
||||
#receiver + " " + e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# build_path seperates the input into two parts: path and input.
|
||||
# input is the partial string that should be completed
|
||||
# path is a proc that takes an input and builds a full path.
|
||||
def self.build_path(input)
|
||||
|
||||
# check to see if the input is a regex
|
||||
return proc {|input| input.to_s }, input if input[/\/\./]
|
||||
|
||||
trailing_slash = input.end_with?('/')
|
||||
contexts = input.chomp('/').split(/\//)
|
||||
input = contexts[-1]
|
||||
|
||||
path = proc do |input|
|
||||
p = contexts[0..-2].push(input).join('/')
|
||||
p += '/' if trailing_slash && !input.nil?
|
||||
p
|
||||
end
|
||||
|
||||
return path, input
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class Pry
|
|||
end
|
||||
|
||||
def use_ansi_codes?
|
||||
windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb"
|
||||
windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb"
|
||||
end
|
||||
|
||||
def colorize_code(code)
|
||||
|
@ -123,16 +123,16 @@ class Pry
|
|||
# simple_pager. Also do not page if Pry.pager is falsey
|
||||
def stagger_output(text, out = nil)
|
||||
out ||= case
|
||||
when respond_to?(:output)
|
||||
# Mixin.
|
||||
output
|
||||
when Pry.respond_to?(:output)
|
||||
# Parent.
|
||||
Pry.output
|
||||
else
|
||||
# Sys.
|
||||
$stdout
|
||||
end
|
||||
when respond_to?(:output)
|
||||
# Mixin.
|
||||
output
|
||||
when Pry.respond_to?(:output)
|
||||
# Parent.
|
||||
Pry.output
|
||||
else
|
||||
# Sys.
|
||||
$stdout
|
||||
end
|
||||
|
||||
if text.lines.count < Pry::Pager.page_size || !Pry.pager
|
||||
out.puts text
|
||||
|
@ -143,6 +143,73 @@ class Pry
|
|||
Pry::Pager.page(text, :simple)
|
||||
rescue Errno::EPIPE
|
||||
end
|
||||
|
||||
# @param [String] arg_string The object path expressed as a string.
|
||||
# @param [Pry] _pry_ The relevant Pry instance.
|
||||
# @param [Array<Binding>] old_stack The state of the old binding stack
|
||||
# @return [Array<Array<Binding>, Array<Binding>>] An array
|
||||
# containing two elements: The new `binding_stack` and the old `binding_stack`.
|
||||
def context_from_object_path(arg_string, _pry_=nil, old_stack=[])
|
||||
|
||||
# Extract command arguments. Delete blank arguments like " ", but
|
||||
# don't delete empty strings like "".
|
||||
path = arg_string.split(/\//).delete_if { |a| a =~ /\A\s+\z/ }
|
||||
stack = _pry_.binding_stack.dup
|
||||
state_old_stack = old_stack
|
||||
|
||||
# Special case when we only get a single "/", return to root.
|
||||
if path.empty?
|
||||
state_old_stack = stack.dup unless old_stack.empty?
|
||||
stack = [stack.first]
|
||||
end
|
||||
|
||||
path.each_with_index do |context, i|
|
||||
begin
|
||||
case context.chomp
|
||||
when ""
|
||||
state_old_stack = stack.dup
|
||||
stack = [stack.first]
|
||||
when "::"
|
||||
state_old_stack = stack.dup
|
||||
stack.push(TOPLEVEL_BINDING)
|
||||
when "."
|
||||
next
|
||||
when ".."
|
||||
unless stack.size == 1
|
||||
# Don't rewrite old_stack if we're in complex expression
|
||||
# (e.g.: `cd 1/2/3/../4).
|
||||
state_old_stack = stack.dup if path.first == ".."
|
||||
stack.pop
|
||||
end
|
||||
when "-"
|
||||
unless old_stack.empty?
|
||||
# Interchange current stack and old stack with each other.
|
||||
stack, state_old_stack = state_old_stack, stack
|
||||
end
|
||||
else
|
||||
state_old_stack = stack.dup if i == 0
|
||||
stack.push(Pry.binding_for(stack.last.eval(context)))
|
||||
end
|
||||
|
||||
rescue RescuableException => e
|
||||
# Restore old stack to its initial values.
|
||||
state_old_stack = old_stack
|
||||
|
||||
msg = [
|
||||
"Bad object path: #{arg_string}.",
|
||||
"Failed trying to resolve: #{context}.",
|
||||
e.inspect
|
||||
].join(' ')
|
||||
|
||||
CommandError.new(msg).tap do |err|
|
||||
err.set_backtrace e.backtrace
|
||||
raise err
|
||||
end
|
||||
end
|
||||
end
|
||||
return stack, state_old_stack
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,13 +31,23 @@ class Pry
|
|||
:method
|
||||
elsif Pry::WrappedModule.from_str(input, target)
|
||||
:module
|
||||
elsif target.eval("defined? #{input} ") =~ /variable|constant/
|
||||
:variable_or_constant
|
||||
elsif find_command(input)
|
||||
:command
|
||||
else
|
||||
:unknown
|
||||
end
|
||||
rescue SyntaxError
|
||||
if find_command(input)
|
||||
:command
|
||||
else
|
||||
:unknown
|
||||
end
|
||||
end
|
||||
|
||||
def process(name)
|
||||
input = args.join(" ")
|
||||
input = args.join(" ").gsub(/\"/,"")
|
||||
type = input_type(input, target)
|
||||
|
||||
code_or_doc = case type
|
||||
|
@ -49,8 +59,12 @@ class Pry
|
|||
process_method
|
||||
when :module
|
||||
process_module
|
||||
when :variable_or_constant
|
||||
process_variable_or_constant
|
||||
when :command
|
||||
process_command
|
||||
else
|
||||
command_error("method or module for '#{input}' could not be found or derived", false)
|
||||
command_error("method/module/command for '#{input}' could not be found or derived", false)
|
||||
end
|
||||
|
||||
render_output(code_or_doc, opts)
|
||||
|
@ -79,6 +93,14 @@ class Pry
|
|||
Pry::Method.from_binding(target)
|
||||
end
|
||||
|
||||
def process_variable_or_constant
|
||||
name = args.first
|
||||
object = target.eval(name)
|
||||
|
||||
@module_object = Pry::WrappedModule(object.class)
|
||||
process_module
|
||||
end
|
||||
|
||||
def module_start_line(mod, candidate_rank=0)
|
||||
if opts.present?(:'base-one')
|
||||
1
|
||||
|
|
|
@ -365,7 +365,7 @@ class Pry
|
|||
@indent.reset if eval_string.empty?
|
||||
|
||||
current_prompt = select_prompt(eval_string, target)
|
||||
completion_proc = Pry::InputCompleter.build_completion_proc(target,
|
||||
completion_proc = Pry::InputCompleter.build_completion_proc(target, self,
|
||||
instance_eval(&custom_completions))
|
||||
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["John Mair (banisterfiend)", "Conrad Irwin"]
|
||||
s.date = "2012-08-10"
|
||||
s.date = "2012-08-13"
|
||||
s.description = "An IRB alternative and runtime developer console"
|
||||
s.email = ["jrmair@gmail.com", "conrad.irwin@gmail.com"]
|
||||
s.executables = ["pry"]
|
||||
s.files = [".document", ".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "CONTRIBUTORS", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "TODO", "bin/pry", "examples/example_basic.rb", "examples/example_command_override.rb", "examples/example_commands.rb", "examples/example_hooks.rb", "examples/example_image_edit.rb", "examples/example_input.rb", "examples/example_input2.rb", "examples/example_output.rb", "examples/example_print.rb", "examples/example_prompt.rb", "examples/helper.rb", "lib/pry.rb", "lib/pry/cli.rb", "lib/pry/code.rb", "lib/pry/command.rb", "lib/pry/command_set.rb", "lib/pry/commands.rb", "lib/pry/completion.rb", "lib/pry/config.rb", "lib/pry/core_extensions.rb", "lib/pry/custom_completions.rb", "lib/pry/default_commands/cd.rb", "lib/pry/default_commands/commands.rb", "lib/pry/default_commands/context.rb", "lib/pry/default_commands/easter_eggs.rb", "lib/pry/default_commands/editing.rb", "lib/pry/default_commands/find_method.rb", "lib/pry/default_commands/gems.rb", "lib/pry/default_commands/gist.rb", "lib/pry/default_commands/help.rb", "lib/pry/default_commands/hist.rb", "lib/pry/default_commands/input_and_output.rb", "lib/pry/default_commands/introspection.rb", "lib/pry/default_commands/ls.rb", "lib/pry/default_commands/misc.rb", "lib/pry/default_commands/navigating_pry.rb", "lib/pry/default_commands/whereami.rb", "lib/pry/extended_commands/experimental.rb", "lib/pry/helpers.rb", "lib/pry/helpers/base_helpers.rb", "lib/pry/helpers/command_helpers.rb", "lib/pry/helpers/documentation_helpers.rb", "lib/pry/helpers/options_helpers.rb", "lib/pry/helpers/text.rb", "lib/pry/history.rb", "lib/pry/history_array.rb", "lib/pry/hooks.rb", "lib/pry/indent.rb", "lib/pry/method.rb", "lib/pry/module_candidate.rb", "lib/pry/pager.rb", "lib/pry/plugins.rb", "lib/pry/pry_class.rb", "lib/pry/pry_instance.rb", "lib/pry/rbx_method.rb", "lib/pry/rbx_path.rb", "lib/pry/repl_file_loader.rb", "lib/pry/version.rb", "lib/pry/wrapped_module.rb", "man/pry.1", "man/pry.1.html", "man/pry.1.ronn", "pry.gemspec", "test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/example_nesting.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_prompt.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad", "wiki/Customizing-pry.md", "wiki/Home.md"]
|
||||
s.files = [".document", ".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "CONTRIBUTORS", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "TODO", "bin/pry", "examples/example_basic.rb", "examples/example_command_override.rb", "examples/example_commands.rb", "examples/example_hooks.rb", "examples/example_image_edit.rb", "examples/example_input.rb", "examples/example_input2.rb", "examples/example_output.rb", "examples/example_print.rb", "examples/example_prompt.rb", "examples/helper.rb", "lib/pry.rb", "lib/pry/cli.rb", "lib/pry/code.rb", "lib/pry/command.rb", "lib/pry/command_set.rb", "lib/pry/commands.rb", "lib/pry/commands/amend_line.rb", "lib/pry/commands/bang.rb", "lib/pry/commands/bang_pry.rb", "lib/pry/commands/cat.rb", "lib/pry/commands/cd.rb", "lib/pry/commands/easter_eggs.rb", "lib/pry/commands/edit.rb", "lib/pry/commands/edit_method.rb", "lib/pry/commands/exit.rb", "lib/pry/commands/exit_all.rb", "lib/pry/commands/exit_program.rb", "lib/pry/commands/find_method.rb", "lib/pry/commands/gem_cd.rb", "lib/pry/commands/gem_install.rb", "lib/pry/commands/gem_list.rb", "lib/pry/commands/gist.rb", "lib/pry/commands/help.rb", "lib/pry/commands/hist.rb", "lib/pry/commands/import_set.rb", "lib/pry/commands/install_command.rb", "lib/pry/commands/jump_to.rb", "lib/pry/commands/ls.rb", "lib/pry/commands/nesting.rb", "lib/pry/commands/play.rb", "lib/pry/commands/pry_backtrace.rb", "lib/pry/commands/pry_version.rb", "lib/pry/commands/raise_up.rb", "lib/pry/commands/reload_method.rb", "lib/pry/commands/reset.rb", "lib/pry/commands/ri.rb", "lib/pry/commands/save_file.rb", "lib/pry/commands/shell_command.rb", "lib/pry/commands/shell_mode.rb", "lib/pry/commands/show_command.rb", "lib/pry/commands/show_doc.rb", "lib/pry/commands/show_input.rb", "lib/pry/commands/show_source.rb", "lib/pry/commands/simple_prompt.rb", "lib/pry/commands/stat.rb", "lib/pry/commands/switch_to.rb", "lib/pry/commands/toggle_color.rb", "lib/pry/commands/whereami.rb", "lib/pry/commands/wtf.rb", "lib/pry/completion.rb", "lib/pry/config.rb", "lib/pry/core_extensions.rb", "lib/pry/custom_completions.rb", "lib/pry/helpers.rb", "lib/pry/helpers/base_helpers.rb", "lib/pry/helpers/command_helpers.rb", "lib/pry/helpers/documentation_helpers.rb", "lib/pry/helpers/module_introspection_helpers.rb", "lib/pry/helpers/options_helpers.rb", "lib/pry/helpers/text.rb", "lib/pry/history.rb", "lib/pry/history_array.rb", "lib/pry/hooks.rb", "lib/pry/indent.rb", "lib/pry/method.rb", "lib/pry/module_candidate.rb", "lib/pry/pager.rb", "lib/pry/plugins.rb", "lib/pry/pry_class.rb", "lib/pry/pry_instance.rb", "lib/pry/rbx_method.rb", "lib/pry/rbx_path.rb", "lib/pry/repl_file_loader.rb", "lib/pry/version.rb", "lib/pry/wrapped_module.rb", "man/pry.1", "man/pry.1.html", "man/pry.1.ronn", "pry.gemspec", "test/candidate_helper1.rb", "test/candidate_helper2.rb", "test/example_nesting.rb", "test/helper.rb", "test/test_cli.rb", "test/test_code.rb", "test/test_command.rb", "test/test_command_helpers.rb", "test/test_command_integration.rb", "test/test_command_set.rb", "test/test_completion.rb", "test/test_control_d_handler.rb", "test/test_default_commands/example.erb", "test/test_default_commands/test_cd.rb", "test/test_default_commands/test_context.rb", "test/test_default_commands/test_documentation.rb", "test/test_default_commands/test_find_method.rb", "test/test_default_commands/test_gems.rb", "test/test_default_commands/test_help.rb", "test/test_default_commands/test_input.rb", "test/test_default_commands/test_introspection.rb", "test/test_default_commands/test_ls.rb", "test/test_default_commands/test_shell.rb", "test/test_default_commands/test_show_source.rb", "test/test_exception_whitelist.rb", "test/test_history_array.rb", "test/test_hooks.rb", "test/test_indent.rb", "test/test_input_stack.rb", "test/test_method.rb", "test/test_prompt.rb", "test/test_pry.rb", "test/test_pry_defaults.rb", "test/test_pry_history.rb", "test/test_pry_output.rb", "test/test_sticky_locals.rb", "test/test_syntax_checking.rb", "test/test_wrapped_module.rb", "test/testrc", "test/testrcbad", "wiki/Customizing-pry.md", "wiki/Home.md"]
|
||||
s.homepage = "http://pry.github.com"
|
||||
s.require_paths = ["lib"]
|
||||
s.rubygems_version = "1.8.24"
|
||||
|
|
|
@ -34,6 +34,18 @@ describe Pry::Code do
|
|||
Pry::Code.from_file('/knalkjsdnalsd/alkjdlkq')
|
||||
end.should.raise(MethodSource::SourceNotFoundError)
|
||||
end
|
||||
|
||||
should 'check for files relative to origin pwd' do
|
||||
Dir.chdir('test') do |f|
|
||||
Pry::Code.from_file('test/' + File.basename(__FILE__)).code_type.should == :ruby
|
||||
end
|
||||
end
|
||||
|
||||
should 'find files that are relative to the current working directory' do
|
||||
Dir.chdir('test') do |f|
|
||||
Pry::Code.from_file(File.basename(__FILE__)).code_type.should == :ruby
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.from_method' do
|
||||
|
|
|
@ -619,8 +619,10 @@ describe "Pry::Command" do
|
|||
mock_pry("my---test").should =~ /my-testmy-test/
|
||||
end
|
||||
|
||||
it "should show the source of the process method" do
|
||||
mock_pry("show-command my-test").should =~ /output.puts command_name/
|
||||
if !mri18_and_no_real_source_location?
|
||||
it "should show the source of the process method" do
|
||||
mock_pry("show-source my-test").should =~ /output.puts command_name/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
require 'helper'
|
||||
|
||||
def new_completer(bind, pry=nil)
|
||||
Pry::InputCompleter.build_completion_proc(Pry.binding_for(bind), pry)
|
||||
end
|
||||
|
||||
def completer_test(bind, pry=nil, assert_flag=true)
|
||||
completer = new_completer(bind, pry)
|
||||
test = proc {|symbol| completer.call(symbol[0..-2]).include?(symbol).should == assert_flag}
|
||||
return proc {|*symbols| symbols.each(&test) }
|
||||
end
|
||||
|
||||
|
||||
describe Pry::InputCompleter do
|
||||
|
||||
before do
|
||||
|
@ -33,30 +44,176 @@ describe Pry::InputCompleter do
|
|||
it 'should complete instance variables' do
|
||||
object = Object.new
|
||||
|
||||
# set variables in appropriate scope
|
||||
object.instance_variable_set(:'@name', 'Pry')
|
||||
object.class.send(:class_variable_set, :'@@number', 10)
|
||||
|
||||
object.instance_variables.map { |v| v.to_sym } \
|
||||
.include?(:'@name').should == true
|
||||
# check to see if variables are in scope
|
||||
object.instance_variables.
|
||||
map { |v| v.to_sym }.
|
||||
include?(:'@name').should == true
|
||||
|
||||
object.class.class_variables.map { |v| v.to_sym } \
|
||||
.include?(:'@@number').should == true
|
||||
|
||||
completer = Pry::InputCompleter.build_completion_proc(
|
||||
Pry.binding_for(object)
|
||||
)
|
||||
object.class.class_variables.
|
||||
map { |v| v.to_sym }.
|
||||
include?(:'@@number').should == true
|
||||
|
||||
# Complete instance variables.
|
||||
completer.call('@na').include?('@name').should == true
|
||||
completer.call('@name.down').include?('@name.downcase').should == true
|
||||
b = Pry.binding_for(object)
|
||||
completer_test(b).call('@name', '@name.downcase')
|
||||
|
||||
# Complete class variables.
|
||||
completer = Pry::InputCompleter.build_completion_proc(
|
||||
Pry.binding_for(object.class)
|
||||
)
|
||||
b = Pry.binding_for(object.class)
|
||||
completer_test(b).call('@@number', '@@number.class')
|
||||
|
||||
completer.call('@@nu').include?('@@number').should == true
|
||||
completer.call('@@number.cl').include?('@@number.class').should == true
|
||||
end
|
||||
|
||||
|
||||
it 'should complete for stdlib symbols' do
|
||||
|
||||
o = Object.new
|
||||
# Regexp
|
||||
completer_test(o).call('/foo/.extend')
|
||||
|
||||
# Array
|
||||
completer_test(o).call('[1].push')
|
||||
|
||||
# Hash
|
||||
completer_test(o).call('{"a" => "b"}.keys')
|
||||
|
||||
# Proc
|
||||
completer_test(o).call('{2}.call')
|
||||
|
||||
# Symbol
|
||||
completer_test(o).call(':symbol.to_s')
|
||||
|
||||
# Absolute Constant
|
||||
completer_test(o).call('::IndexError')
|
||||
end
|
||||
|
||||
it 'should complete for target symbols' do
|
||||
o = Object.new
|
||||
|
||||
# Constant
|
||||
module Mod
|
||||
Con = 'Constant'
|
||||
module Mod2
|
||||
end
|
||||
end
|
||||
|
||||
completer_test(Mod).call('Con')
|
||||
|
||||
# Constants or Class Methods
|
||||
completer_test(o).call('Mod::Con')
|
||||
|
||||
# Symbol
|
||||
foo = :symbol
|
||||
completer_test(o).call(':symbol')
|
||||
|
||||
# Variables
|
||||
class << o
|
||||
attr_accessor :foo
|
||||
end
|
||||
o.foo = 'bar'
|
||||
completer_test(binding).call('o.foo')
|
||||
|
||||
# trailing slash
|
||||
new_completer(Mod).call('Mod2/').include?('Mod2/').should == true
|
||||
end
|
||||
|
||||
it 'should complete for arbitrary scopes' do
|
||||
module Bar
|
||||
@barvar = :bar
|
||||
end
|
||||
|
||||
module Baz
|
||||
@bar = Bar
|
||||
@bazvar = :baz
|
||||
Con = :constant
|
||||
end
|
||||
|
||||
pry = Pry.new()
|
||||
stack = pry.binding_stack
|
||||
stack.push(Pry.binding_for(Baz))
|
||||
stack.push(Pry.binding_for(Bar))
|
||||
|
||||
b = Pry.binding_for(Bar)
|
||||
completer_test(b, pry).call("../@bazvar")
|
||||
completer_test(b, pry).call('/Con')
|
||||
end
|
||||
|
||||
it 'should complete for stdlib symbols' do
|
||||
|
||||
o = Object.new
|
||||
# Regexp
|
||||
completer_test(o).call('/foo/.extend')
|
||||
|
||||
# Array
|
||||
completer_test(o).call('[1].push')
|
||||
|
||||
# Hash
|
||||
completer_test(o).call('{"a" => "b"}.keys')
|
||||
|
||||
# Proc
|
||||
completer_test(o).call('{2}.call')
|
||||
|
||||
# Symbol
|
||||
completer_test(o).call(':symbol.to_s')
|
||||
|
||||
# Absolute Constant
|
||||
completer_test(o).call('::IndexError')
|
||||
end
|
||||
|
||||
it 'should complete for target symbols' do
|
||||
o = Object.new
|
||||
|
||||
# Constant
|
||||
module Mod
|
||||
Con = 'Constant'
|
||||
module Mod2
|
||||
end
|
||||
end
|
||||
|
||||
completer_test(Mod).call('Con')
|
||||
|
||||
# Constants or Class Methods
|
||||
completer_test(o).call('Mod::Con')
|
||||
|
||||
# Symbol
|
||||
foo = :symbol
|
||||
completer_test(o).call(':symbol')
|
||||
|
||||
# Variables
|
||||
class << o
|
||||
attr_accessor :foo
|
||||
end
|
||||
o.foo = 'bar'
|
||||
completer_test(binding).call('o.foo')
|
||||
|
||||
# trailing slash
|
||||
new_completer(Mod).call('Mod2/').include?('Mod2/').should == true
|
||||
|
||||
end
|
||||
|
||||
it 'should complete for arbitrary scopes' do
|
||||
module Bar
|
||||
@barvar = :bar
|
||||
end
|
||||
|
||||
module Baz
|
||||
@bar = Bar
|
||||
@bazvar = :baz
|
||||
Con = :constant
|
||||
end
|
||||
|
||||
pry = Pry.new()
|
||||
stack = pry.binding_stack
|
||||
stack.push(Pry.binding_for(Baz))
|
||||
stack.push(Pry.binding_for(Bar))
|
||||
|
||||
b = Pry.binding_for(Bar)
|
||||
completer_test(b, pry).call("../@bazvar")
|
||||
completer_test(b, pry).call('/Con')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ describe 'Pry::DefaultCommands::Cd' do
|
|||
eval '_pry_.command_state["cd"]'
|
||||
end
|
||||
|
||||
def old_stack
|
||||
eval '_pry_.command_state["cd"].old_stack.dup'
|
||||
end
|
||||
# def old_stack
|
||||
# eval '_pry_.command_state["cd"].old_stack.dup'
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -42,20 +42,20 @@ describe 'Pry::DefaultCommands::Cd' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'when an error was raised' do
|
||||
it 'should not toggle and should keep correct stacks' do
|
||||
proc {
|
||||
@t.eval 'cd @'
|
||||
}.should.raise(Pry::CommandError)
|
||||
# describe 'when an error was raised' do
|
||||
# it 'should not toggle and should keep correct stacks' do
|
||||
# proc {
|
||||
# @t.eval 'cd @'
|
||||
# }.should.raise(Pry::CommandError)
|
||||
|
||||
@t.old_stack.should == []
|
||||
@t.assert_binding_stack [@o]
|
||||
# @t.old_stack.should == []
|
||||
# @t.assert_binding_stack [@o]
|
||||
|
||||
@t.eval 'cd -'
|
||||
@t.old_stack.should == []
|
||||
@t.assert_binding_stack [@o]
|
||||
end
|
||||
end
|
||||
# @t.eval 'cd -'
|
||||
# @t.old_stack.should == []
|
||||
# @t.assert_binding_stack [@o]
|
||||
# end
|
||||
# end
|
||||
|
||||
describe 'when using simple cd syntax' do
|
||||
it 'should toggle' do
|
||||
|
|
|
@ -307,5 +307,35 @@ if !mri18_and_no_real_source_location?
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "on commands" do
|
||||
|
||||
# mostly copied & modified from test_help.rb
|
||||
before do
|
||||
@oldset = Pry.config.commands
|
||||
@set = Pry.config.commands = Pry::CommandSet.new do
|
||||
import Pry::Commands
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Pry.config.commands = @oldset
|
||||
end
|
||||
|
||||
it 'should display help for a specific command' do
|
||||
mock_pry('show-doc ls').should =~ /Usage: ls/
|
||||
end
|
||||
|
||||
it 'should display help for a regex command with a "listing"' do
|
||||
@set.command /bar(.*)/, "Test listing", :listing => "foo" do; end
|
||||
mock_pry('show-doc foo').should =~ /Test listing/
|
||||
end
|
||||
|
||||
it 'should display help for a command with a spaces in its name' do
|
||||
@set.command "command with spaces", "description of a command with spaces" do; end
|
||||
mock_pry('show-doc "command with spaces"').should =~ /description of a command with spaces/
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -470,58 +470,4 @@ describe "Pry::DefaultCommands::Introspection" do
|
|||
|
||||
end
|
||||
end
|
||||
|
||||
# show-command only works in implementations that support Proc#source_location
|
||||
if Proc.method_defined?(:source_location)
|
||||
describe "show-command" do
|
||||
before do
|
||||
@str_output = StringIO.new
|
||||
end
|
||||
|
||||
it 'should show source for an ordinary command' do
|
||||
set = Pry::CommandSet.new do
|
||||
import_from Pry::Commands, "show-command"
|
||||
command "foo" do
|
||||
:body_of_foo
|
||||
end
|
||||
end
|
||||
|
||||
redirect_pry_io(InputTester.new("show-command foo"), @str_output) do
|
||||
Pry.new(:commands => set).rep
|
||||
end
|
||||
|
||||
@str_output.string.should =~ /:body_of_foo/
|
||||
end
|
||||
|
||||
it 'should show source for a command with spaces in its name' do
|
||||
set = Pry::CommandSet.new do
|
||||
import_from Pry::Commands, "show-command"
|
||||
command "foo bar" do
|
||||
:body_of_foo_bar
|
||||
end
|
||||
end
|
||||
|
||||
redirect_pry_io(InputTester.new("show-command \"foo bar\""), @str_output) do
|
||||
Pry.new(:commands => set).rep
|
||||
end
|
||||
|
||||
@str_output.string.should =~ /:body_of_foo_bar/
|
||||
end
|
||||
|
||||
it 'should show source for a command by listing name' do
|
||||
set = Pry::CommandSet.new do
|
||||
import_from Pry::Commands, "show-command"
|
||||
command /foo(.*)/, "", :listing => "bar" do
|
||||
:body_of_foo_regex
|
||||
end
|
||||
end
|
||||
|
||||
redirect_pry_io(InputTester.new("show-command bar"), @str_output) do
|
||||
Pry.new(:commands => set).rep
|
||||
end
|
||||
|
||||
@str_output.string.should =~ /:body_of_foo_regex/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -255,6 +255,34 @@ if !mri18_and_no_real_source_location?
|
|||
|
||||
end
|
||||
|
||||
describe "on variable or constant" do
|
||||
before do
|
||||
class TestHost
|
||||
def hello
|
||||
"hi there"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Object.remove_const(:TestHost)
|
||||
end
|
||||
|
||||
it "should output source of its class if variable doesn't respond to source_location" do
|
||||
test_host = TestHost.new
|
||||
string = mock_pry(binding,"show-source test_host","exit-all")
|
||||
string.should =~ /class TestHost\n.*def hello/
|
||||
end
|
||||
|
||||
it "should output source of its class if constant doesn't respond to source_location" do
|
||||
TEST_HOST = TestHost.new
|
||||
string = mock_pry(binding,"show-source TEST_HOST","exit-all")
|
||||
string.should =~ /class TestHost\n.*def hello/
|
||||
|
||||
Object.remove_const(:TEST_HOST)
|
||||
end
|
||||
end
|
||||
|
||||
describe "on modules" do
|
||||
before do
|
||||
class ShowSourceTestSuperClass
|
||||
|
@ -525,6 +553,51 @@ if !mri18_and_no_real_source_location?
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "on commands" do
|
||||
before do
|
||||
@oldset = Pry.config.commands
|
||||
@set = Pry.config.commands = Pry::CommandSet.new do
|
||||
import Pry::Commands
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Pry.config.commands = @oldset
|
||||
end
|
||||
|
||||
it 'should show source for an ordinary command' do
|
||||
@set.command "foo", :body_of_foo do; end
|
||||
|
||||
|
||||
string = mock_pry("show-source foo")
|
||||
string.should =~ /:body_of_foo/
|
||||
end
|
||||
|
||||
it "should output source of commands using special characters" do
|
||||
@set.command "!", "Clear the input buffer" do; end
|
||||
|
||||
|
||||
string = mock_pry("show-source !")
|
||||
string.should =~ /Clear the input buffer/
|
||||
end
|
||||
|
||||
it 'should show source for a command with spaces in its name' do
|
||||
@set.command "foo bar", :body_of_foo_bar do; end
|
||||
|
||||
|
||||
string = mock_pry("show-source \"foo bar\"")
|
||||
string.should =~ /:body_of_foo_bar/
|
||||
end
|
||||
|
||||
it 'should show source for a command by listing name' do
|
||||
@set.command /foo(.*)/, :body_of_foo_bar_regex, :listing => "bar" do; end
|
||||
|
||||
string = mock_pry("show-source bar")
|
||||
string.should =~ /:body_of_foo_bar_regex/
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue