mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
saving before refactor to implement action block instead of action proc for commands. All tests passing in 1.8 and 1.9.
This commit is contained in:
parent
8e006829fe
commit
ebdcfdf145
8 changed files with 359 additions and 275 deletions
80
lib/pry/command_base.rb
Normal file
80
lib/pry/command_base.rb
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
class Pry
|
||||||
|
|
||||||
|
class CommandBase
|
||||||
|
class << self
|
||||||
|
attr_accessor :commands
|
||||||
|
attr_accessor :command_info
|
||||||
|
end
|
||||||
|
|
||||||
|
class Command
|
||||||
|
Elements = [:name, :describe, :pattern, :action]
|
||||||
|
|
||||||
|
Elements.each do |e|
|
||||||
|
define_method(e) { |s| instance_variable_set("@#{e}", s) }
|
||||||
|
define_method("get_#{e}") { instance_variable_get("@#{e}") }
|
||||||
|
end
|
||||||
|
|
||||||
|
# define action here since it needs to take a block
|
||||||
|
def action(&block)
|
||||||
|
@action = block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.check_command(c)
|
||||||
|
c.pattern(c.get_name) if !c.get_pattern
|
||||||
|
c.describe "No description." if !c.get_describe
|
||||||
|
|
||||||
|
Command::Elements.each do |e|
|
||||||
|
raise "command has no #{e}!" if !c.send("get_#{e}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.command(name, &block)
|
||||||
|
@commands ||= {}
|
||||||
|
@command_info ||= {}
|
||||||
|
|
||||||
|
c = Command.new
|
||||||
|
c.name name
|
||||||
|
|
||||||
|
c.instance_eval(&block)
|
||||||
|
|
||||||
|
check_command(c)
|
||||||
|
|
||||||
|
@commands.merge! c.get_pattern => c.get_action
|
||||||
|
@command_info.merge! c.get_name => c.get_describe
|
||||||
|
end
|
||||||
|
|
||||||
|
command "help" do
|
||||||
|
pattern /^help\s*(.+)?/
|
||||||
|
describe "This menu."
|
||||||
|
|
||||||
|
action do |opts|
|
||||||
|
out = opts[:output]
|
||||||
|
command_info = opts[:command_info]
|
||||||
|
param = opts[:captures].first
|
||||||
|
|
||||||
|
if !param
|
||||||
|
out.puts "Command list:"
|
||||||
|
out.puts "--"
|
||||||
|
command_info.each do |k, v|
|
||||||
|
puts "#{Array(k).first}".ljust(18) + v
|
||||||
|
end
|
||||||
|
else
|
||||||
|
key = command_info.keys.find { |v| Array(v).any? { |k| k === param } }
|
||||||
|
if key
|
||||||
|
out.puts command_info[key]
|
||||||
|
else
|
||||||
|
out.puts "No info for command: #{param}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
opts[:val].clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.inherited(klass)
|
||||||
|
klass.commands = @commands.dup
|
||||||
|
klass.command_info = @command_info.dup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,81 +1,12 @@
|
||||||
|
direc = File.dirname(__FILE__)
|
||||||
|
require "#{direc}/command_base"
|
||||||
|
|
||||||
class Pry
|
class Pry
|
||||||
|
|
||||||
class CommandBase
|
|
||||||
|
|
||||||
class << self
|
|
||||||
attr_accessor :commands
|
|
||||||
attr_accessor :command_info
|
|
||||||
end
|
|
||||||
|
|
||||||
@commands = {}
|
|
||||||
@command_info = {}
|
|
||||||
|
|
||||||
class Command
|
|
||||||
Elements = [:name, :description, :pattern, :action]
|
|
||||||
|
|
||||||
Elements.each do |e|
|
|
||||||
define_method(e) { |s| instance_variable_set("@#{e}", s) }
|
|
||||||
define_method("get_#{e}") { instance_variable_get("@#{e}") }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.check_command(c)
|
|
||||||
|
|
||||||
c.pattern(c.get_name) if !c.get_pattern
|
|
||||||
|
|
||||||
Command::Elements.each do |e|
|
|
||||||
raise "command has no #{e}!" if !c.send("get_#{e}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.command(name, &block)
|
|
||||||
c = Command.new
|
|
||||||
c.name name
|
|
||||||
|
|
||||||
c.instance_eval(&block)
|
|
||||||
check_command(c)
|
|
||||||
|
|
||||||
commands.merge! c.get_pattern => c.get_action
|
|
||||||
command_info.merge! c.get_name => c.get_description
|
|
||||||
end
|
|
||||||
|
|
||||||
command "help" do
|
|
||||||
pattern /^help\s*(.+)?/
|
|
||||||
description "This menu."
|
|
||||||
|
|
||||||
action proc { |opts|
|
|
||||||
out = opts[:output]
|
|
||||||
command_info = opts[:command_info]
|
|
||||||
param = opts[:captures].first
|
|
||||||
|
|
||||||
puts opts[:captures].inspect
|
|
||||||
|
|
||||||
if !param
|
|
||||||
out.puts "Command list:"
|
|
||||||
out.puts "--"
|
|
||||||
command_info.each do |k, v|
|
|
||||||
puts "#{Array(k).first}".ljust(18) + v
|
|
||||||
end
|
|
||||||
else
|
|
||||||
key = command_info.keys.find { |v| Array(v).any? { |k| k === param } }
|
|
||||||
if key
|
|
||||||
out.puts command_info[key]
|
|
||||||
else
|
|
||||||
out.puts "No info for command: #{param}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
opts[:val].clear
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Default commands used by Pry.
|
# Default commands used by Pry.
|
||||||
# @note
|
# @note
|
||||||
# If you plan to replace the default Commands class with a custom
|
# If you plan to replace the default Commands class with a custom
|
||||||
# one then it must have a `commands` method that returns a Hash.
|
# one then it must have a `commands` method that returns a Hash.
|
||||||
class Commands
|
class Commands < CommandBase
|
||||||
|
|
||||||
# This method returns a hash that defines the commands implemented for the REPL session.
|
# This method returns a hash that defines the commands implemented for the REPL session.
|
||||||
# The hash has the following form:
|
# The hash has the following form:
|
||||||
|
@ -107,165 +38,183 @@ class Pry
|
||||||
# opts[:output].puts "hello #{opts[:captures].first}"
|
# opts[:output].puts "hello #{opts[:captures].first}"
|
||||||
# }
|
# }
|
||||||
# end
|
# end
|
||||||
def commands
|
command "!" do
|
||||||
@commands ||= {
|
describe "Refresh the REPL"
|
||||||
"!" => proc do |opts|
|
action do |opts|
|
||||||
opts[:output].puts "Refreshed REPL"
|
opts[:output].puts "Refreshed REPL"
|
||||||
opts[:val].clear
|
|
||||||
opts[:eval_string].clear
|
|
||||||
end,
|
|
||||||
"!pry" => proc do |opts|
|
|
||||||
Pry.start(opts[:target])
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
["exit_program", "quit_program"] => proc do
|
|
||||||
exit
|
|
||||||
end,
|
|
||||||
/^help\s*(.+)?/ => proc do |opts|
|
|
||||||
param = opts[:captures].first
|
|
||||||
self.show_help(opts[:output], param)
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
"nesting" => proc do |opts|
|
|
||||||
self.show_nesting(opts[:output], opts[:nesting])
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
"status" => proc do |opts|
|
|
||||||
self.show_status(opts[:output], opts[:nesting], opts[:target])
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
"exit_all" => proc do
|
|
||||||
throw(:breakout, 0)
|
|
||||||
end,
|
|
||||||
["exit", "quit", "back", /^cd\s*\.\./] => proc do |opts|
|
|
||||||
throw(:breakout, opts[:nesting].level)
|
|
||||||
end,
|
|
||||||
"ls" => proc do |opts|
|
|
||||||
opts[:output].puts "#{opts[:target].eval('Pry.view(local_variables + instance_variables)')}"
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^cat\s+(.+)/ => proc do |opts|
|
|
||||||
obj = opts[:captures].first
|
|
||||||
opts[:output].puts opts[:target].eval("#{obj}.inspect")
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^cd\s+(.+)/ => proc do |opts|
|
|
||||||
obj = opts[:captures].first
|
|
||||||
|
|
||||||
throw(:breakout, opts[:nesting].level) if obj == ".."
|
opts[:eval_string].clear
|
||||||
|
end
|
||||||
opts[:target].eval("#{obj}.pry")
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^show_doc\s*(.+)/ => proc do |opts|
|
|
||||||
meth_name = opts[:captures].first
|
|
||||||
doc = opts[:target].eval("method(:#{meth_name})").comment
|
|
||||||
opts[:output].puts doc
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^show_idoc\s*(.+)/ => proc do |opts|
|
|
||||||
meth_name = opts[:captures].first
|
|
||||||
doc = opts[:target].eval("instance_method(:#{meth_name})").comment
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^show_method\s*(.+)/ => proc do |opts|
|
|
||||||
meth_name = opts[:captures].first
|
|
||||||
code = opts[:target].eval("method(:#{meth_name})").source
|
|
||||||
opts[:output].puts code
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^show_imethod\s*(.+)/ => proc do |opts|
|
|
||||||
meth_name = opts[:captures].first
|
|
||||||
code = opts[:target].eval("instance_method(:#{meth_name})").source
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
/^jump_to\s*(\d*)/ => proc do |opts|
|
|
||||||
break_level = opts[:captures].first.to_i
|
|
||||||
nesting = opts[:nesting]
|
|
||||||
|
|
||||||
case break_level
|
|
||||||
when nesting.level
|
|
||||||
opts[:output].puts "Already at nesting level #{nesting.level}"
|
|
||||||
opts[:val].clear
|
|
||||||
when (0...nesting.level)
|
|
||||||
throw(:breakout, break_level + 1)
|
|
||||||
else
|
|
||||||
max_nest_level = nesting.level - 1
|
|
||||||
opts[:output].puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
|
||||||
opts[:val].clear
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
"ls_methods" => proc do |opts|
|
|
||||||
opts[:output].puts "#{Pry.view(opts[:target].eval('public_methods(false)'))}"
|
|
||||||
opts[:val].clear
|
|
||||||
end,
|
|
||||||
"ls_imethods" => proc do |opts|
|
|
||||||
opts[:output].puts "#{Pry.view(opts[:target].eval('public_instance_methods(false)'))}"
|
|
||||||
opts[:val].clear
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def command_info
|
command "!pry" do
|
||||||
@command_info ||= {
|
describe "Start a Pry session on current self; this even works mid-expression."
|
||||||
"!" => "Refresh the REPL.",
|
action do |opts|
|
||||||
"!pry" => "Start a Pry session on current self; this even works mid-expression.",
|
Pry.start(opts[:target])
|
||||||
["exit_program", "quit_program"] => "end the current program.",
|
|
||||||
"help" => "This menu.",
|
end
|
||||||
"nesting" => "Show nesting information.",
|
|
||||||
"status" => "Show status information.",
|
|
||||||
"exit_all" => "End all nested Pry sessions",
|
|
||||||
["exit", "quit", "back", /cd\s*\.\./] => "End the current Pry session.",
|
|
||||||
"ls" => "Show the list of vars in the current scope.",
|
|
||||||
"cat" => "Show output of <var>.inspect",
|
|
||||||
"cd" => "Start a Pry session on <var> (use `cd ..` to go back)",
|
|
||||||
"show_doc" => "Show the comments above <methname>",
|
|
||||||
"show_idoc" => "Show the comments above instance method <methname>",
|
|
||||||
"show_method" => "Show sourcecode for method <methname>",
|
|
||||||
"show_imethod" => "Show sourcecode for instance method <methname>",
|
|
||||||
"jump_to" => "Jump to a Pry session further up the stack, exiting all sessions below.",
|
|
||||||
"ls_methods" => "List public methods defined on class of receiver.",
|
|
||||||
"ls_imethods" => "List public instance methods defined on receiver."
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_help(out, param)
|
command ["exit_program", "quit_program"] do
|
||||||
if !param
|
describe "End the current program."
|
||||||
out.puts "Command list:"
|
action { |opts| exit }
|
||||||
|
end
|
||||||
|
|
||||||
|
command "nesting" do
|
||||||
|
describe "Show nesting information."
|
||||||
|
|
||||||
|
action do |opts|
|
||||||
|
out = opts[:output]
|
||||||
|
nesting = opts[:nesting]
|
||||||
|
|
||||||
|
out.puts "Nesting status:"
|
||||||
out.puts "--"
|
out.puts "--"
|
||||||
command_info.each do |k, v|
|
nesting.each do |level, obj|
|
||||||
puts "#{Array(k).first}".ljust(18) + v
|
if level == 0
|
||||||
|
out.puts "#{level}. #{Pry.view(obj)} (Pry top level)"
|
||||||
|
else
|
||||||
|
out.puts "#{level}. #{Pry.view(obj)}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
|
||||||
key = command_info.keys.find { |v| Array(v).any? { |k| k === param } }
|
|
||||||
if key
|
end
|
||||||
out.puts command_info[key]
|
end
|
||||||
|
|
||||||
|
command "status" do
|
||||||
|
describe "Show status information."
|
||||||
|
|
||||||
|
action do |opts|
|
||||||
|
out = opts[:output]
|
||||||
|
nesting = opts[:nesting]
|
||||||
|
target = opts[:target]
|
||||||
|
|
||||||
|
out.puts "Status:"
|
||||||
|
out.puts "--"
|
||||||
|
out.puts "Receiver: #{Pry.view(target.eval('self'))}"
|
||||||
|
out.puts "Nesting level: #{nesting.level}"
|
||||||
|
out.puts "Local variables: #{Pry.view(target.eval('local_variables'))}"
|
||||||
|
out.puts "Pry instance: #{Pry.active_instance}"
|
||||||
|
out.puts "Last result: #{Pry.view(Pry.last_result)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "exit_all" do
|
||||||
|
describe "End all nested Pry sessions."
|
||||||
|
action { |opts| throw(:breakout, 0) }
|
||||||
|
end
|
||||||
|
|
||||||
|
command "ls" do
|
||||||
|
describe "Show the list of vars in the current scope."
|
||||||
|
action do |opts|
|
||||||
|
opts[:output].puts "#{opts[:target].eval('Pry.view(local_variables + instance_variables)')}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "cat" do
|
||||||
|
describe "Show output of <var>.inspect."
|
||||||
|
pattern /^cat\s+(.+)/
|
||||||
|
action do |opts|
|
||||||
|
out = opts[:output]
|
||||||
|
obj = opts[:captures].first
|
||||||
|
|
||||||
|
out.puts opts[:target].eval("#{obj}.inspect")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "cd" do
|
||||||
|
pattern /^cd\s+(.+)/
|
||||||
|
describe "Start a Pry session on <var> (use `cd ..` to go back)"
|
||||||
|
|
||||||
|
action do |opts|
|
||||||
|
obj = opts[:captures].first
|
||||||
|
throw(:breakout, opts[:nesting].level) if obj == ".."
|
||||||
|
opts[:target].eval("#{obj}.pry")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "show_doc" do
|
||||||
|
pattern /^show_doc\s*(.+)/
|
||||||
|
describe "Show the comments above <methname>"
|
||||||
|
action do |opts|
|
||||||
|
meth_name = opts[:captures].first
|
||||||
|
doc = opts[:target].eval("method(:#{meth_name})").comment
|
||||||
|
opts[:output].puts doc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "show_idoc" do
|
||||||
|
pattern /^show_idoc\s*(.+)/
|
||||||
|
describe "Show the comments above instance method <methname>"
|
||||||
|
action do |opts|
|
||||||
|
meth_name = opts[:captures].first
|
||||||
|
doc = opts[:target].eval("instance_method(:#{meth_name})").comment
|
||||||
|
opts[:output].puts doc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "show_method" do
|
||||||
|
pattern /^show_method\s*(.+)/
|
||||||
|
describe "Show sourcecode for method <methname>."
|
||||||
|
action do |opts|
|
||||||
|
meth_name = opts[:captures].first
|
||||||
|
doc = opts[:target].eval("method(:#{meth_name})").source
|
||||||
|
opts[:output].puts doc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "show_imethod" do
|
||||||
|
pattern /^show_imethod\s*(.+)/
|
||||||
|
describe "Show sourcecode for instance method <methname>."
|
||||||
|
action do |opts|
|
||||||
|
meth_name = opts[:captures].first
|
||||||
|
doc = opts[:target].eval("instance_method(:#{meth_name})").source
|
||||||
|
opts[:output].puts doc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command "jump_to" do
|
||||||
|
pattern /^jump_to\s*(\d*)/
|
||||||
|
|
||||||
|
describe "Jump to a Pry session further up the stack, exiting all sessions below."
|
||||||
|
|
||||||
|
action do |opts|
|
||||||
|
break_level = opts[:captures].first.to_i
|
||||||
|
nesting = opts[:nesting]
|
||||||
|
|
||||||
|
case break_level
|
||||||
|
when nesting.level
|
||||||
|
opts[:output].puts "Already at nesting level #{nesting.level}"
|
||||||
|
when (0...nesting.level)
|
||||||
|
throw(:breakout, break_level + 1)
|
||||||
else
|
else
|
||||||
out.puts "No info for command: #{param}"
|
max_nest_level = nesting.level - 1
|
||||||
|
opts[:output].puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_nesting(out, nesting)
|
command "ls_methods" do
|
||||||
out.puts "Nesting status:"
|
describe "List public methods defined on class of receiver."
|
||||||
out.puts "--"
|
|
||||||
nesting.each do |level, obj|
|
action do |opts|
|
||||||
if level == 0
|
opts[:output].puts "#{Pry.view(opts[:target].eval('public_methods(false)'))}"
|
||||||
out.puts "#{level}. #{Pry.view(obj)} (Pry top level)"
|
|
||||||
else
|
|
||||||
out.puts "#{level}. #{Pry.view(obj)}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_status(out, nesting, target)
|
command "ls_imethods" do
|
||||||
out.puts "Status:"
|
describe "List public instance methods defined on class of receiver."
|
||||||
out.puts "--"
|
|
||||||
out.puts "Receiver: #{Pry.view(target.eval('self'))}"
|
action do |opts|
|
||||||
out.puts "Nesting level: #{nesting.level}"
|
opts[:output].puts "#{Pry.view(opts[:target].eval('public_instance_methods(false)'))}"
|
||||||
out.puts "Local variables: #{Pry.view(target.eval('local_variables'))}"
|
end
|
||||||
out.puts "Pry instance: #{Pry.active_instance}"
|
end
|
||||||
out.puts "Last result: #{Pry.view(Pry.last_result)}"
|
|
||||||
|
command ["exit", "quit", "back"] do
|
||||||
|
describe "End the current Pry session."
|
||||||
|
action do |opts|
|
||||||
|
throw(:breakout, opts[:nesting].level)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
# stolen from irb
|
# taken from irb
|
||||||
|
|
||||||
require "readline"
|
require "readline"
|
||||||
|
|
||||||
class Pry
|
class Pry
|
||||||
module InputCompleter
|
module InputCompleter
|
||||||
|
|
||||||
|
if Readline.respond_to?("basic_word_break_characters=")
|
||||||
|
Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
|
||||||
|
end
|
||||||
|
|
||||||
|
Readline.completion_append_character = nil
|
||||||
|
|
||||||
ReservedWords = [
|
ReservedWords = [
|
||||||
"BEGIN", "END",
|
"BEGIN", "END",
|
||||||
"alias", "and",
|
"alias", "and",
|
||||||
|
@ -30,7 +36,7 @@ class Pry
|
||||||
"[]", "[]=", "^", "!", "!=", "!~"]
|
"[]", "[]=", "^", "!", "!=", "!~"]
|
||||||
|
|
||||||
def self.build_completion_proc(target, commands=[""])
|
def self.build_completion_proc(target, commands=[""])
|
||||||
proc { |input|
|
proc do |input|
|
||||||
bind = target
|
bind = target
|
||||||
|
|
||||||
case input
|
case input
|
||||||
|
@ -75,7 +81,6 @@ class Pry
|
||||||
candidates = Object.constants.collect{|m| m.to_s}
|
candidates = Object.constants.collect{|m| m.to_s}
|
||||||
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
|
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
|
||||||
|
|
||||||
# when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
|
|
||||||
when /^([A-Z].*)::([^:.]*)$/
|
when /^([A-Z].*)::([^:.]*)$/
|
||||||
# Constant or class methods
|
# Constant or class methods
|
||||||
receiver = $1
|
receiver = $1
|
||||||
|
@ -124,8 +129,6 @@ class Pry
|
||||||
regmessage = Regexp.new(Regexp.quote($1))
|
regmessage = Regexp.new(Regexp.quote($1))
|
||||||
candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
|
candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
|
||||||
|
|
||||||
# when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
|
|
||||||
# when /^((\.?[^.]+)+)\.([^.]*)$/
|
|
||||||
when /^([^."].*)\.([^.]*)$/
|
when /^([^."].*)\.([^.]*)$/
|
||||||
# variable
|
# variable
|
||||||
receiver = $1
|
receiver = $1
|
||||||
|
@ -175,11 +178,9 @@ class Pry
|
||||||
|
|
||||||
(candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
|
(candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
|
||||||
end
|
end
|
||||||
}
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def self.select_message(receiver, message, candidates)
|
def self.select_message(receiver, message, candidates)
|
||||||
candidates.grep(/^#{message}/).collect do |e|
|
candidates.grep(/^#{message}/).collect do |e|
|
||||||
case e
|
case e
|
||||||
|
@ -194,7 +195,3 @@ class Pry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Readline.respond_to?("basic_word_break_characters=")
|
|
||||||
Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
|
|
||||||
end
|
|
||||||
Readline.completion_append_character = nil
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'readline'
|
||||||
|
|
||||||
# @author John Mair (banisterfiend)
|
# @author John Mair (banisterfiend)
|
||||||
class Pry
|
class Pry
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ class Pry
|
||||||
def self.reset_defaults
|
def self.reset_defaults
|
||||||
@input = Readline
|
@input = Readline
|
||||||
@output = $stdout
|
@output = $stdout
|
||||||
@commands = Commands.new
|
@commands = Commands
|
||||||
@prompt = DEFAULT_PROMPT
|
@prompt = DEFAULT_PROMPT
|
||||||
@print = DEFAULT_PRINT
|
@print = DEFAULT_PRINT
|
||||||
@hooks = DEFAULT_HOOKS
|
@hooks = DEFAULT_HOOKS
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'readline'
|
||||||
|
|
||||||
class Pry
|
class Pry
|
||||||
|
|
||||||
# The list of configuration options.
|
# The list of configuration options.
|
||||||
|
@ -10,7 +12,7 @@ class Pry
|
||||||
# @param [Hash] options The optional configuration parameters.
|
# @param [Hash] options The optional configuration parameters.
|
||||||
# @option options [#read] :input The object to use for input. (see input.rb)
|
# @option options [#read] :input The object to use for input. (see input.rb)
|
||||||
# @option options [#puts] :output The object to use for output. (see output.rb)
|
# @option options [#puts] :output The object to use for output. (see output.rb)
|
||||||
# @option options [#commands] :commands The object to use for
|
# @option options [Pry::CommandBase] :commands The object to use for
|
||||||
# commands. (see commands.rb)
|
# commands. (see commands.rb)
|
||||||
# @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
|
# @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
|
||||||
# @option options [Array<Proc>] :default_prompt The array of Procs
|
# @option options [Array<Proc>] :default_prompt The array of Procs
|
||||||
|
@ -110,7 +112,6 @@ class Pry
|
||||||
def re(target=TOPLEVEL_BINDING)
|
def re(target=TOPLEVEL_BINDING)
|
||||||
target = binding_for(target)
|
target = binding_for(target)
|
||||||
|
|
||||||
# FIXME!!!!!!!! Should not hardcode command_info in here!
|
|
||||||
if input == Readline
|
if input == Readline
|
||||||
Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, Pry.commands.command_info.keys.flatten)
|
Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, Pry.commands.command_info.keys.flatten)
|
||||||
end
|
end
|
||||||
|
@ -167,6 +168,7 @@ class Pry
|
||||||
# @param [Binding] target The receiver of the commands.
|
# @param [Binding] target The receiver of the commands.
|
||||||
def process_commands(val, eval_string, target)
|
def process_commands(val, eval_string, target)
|
||||||
def val.clear() replace("") end
|
def val.clear() replace("") end
|
||||||
|
def eval_string.clear() replace("") end
|
||||||
|
|
||||||
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
|
pattern, action = commands.commands.find { |k, v| Array(k).any? { |a| a === val } }
|
||||||
|
|
||||||
|
@ -184,6 +186,7 @@ class Pry
|
||||||
}
|
}
|
||||||
|
|
||||||
action.call(options)
|
action.call(options)
|
||||||
|
val.clear
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -191,7 +194,7 @@ class Pry
|
||||||
# This method should not need to be invoked directly.
|
# This method should not need to be invoked directly.
|
||||||
# @param [String] current_prompt The prompt to use for input.
|
# @param [String] current_prompt The prompt to use for input.
|
||||||
# @return [String] The next line of input.
|
# @return [String] The next line of input.
|
||||||
def readline(current_prompt)
|
def readline(current_prompt="> ")
|
||||||
|
|
||||||
if input == Readline
|
if input == Readline
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
class Pry
|
class Pry
|
||||||
VERSION = "0.4.0"
|
VERSION = "0.4.0pre1"
|
||||||
end
|
end
|
||||||
|
|
82
test/test.rb
82
test/test.rb
|
@ -5,8 +5,6 @@ require 'bacon'
|
||||||
require "#{direc}/../lib/pry"
|
require "#{direc}/../lib/pry"
|
||||||
require "#{direc}/test_helper"
|
require "#{direc}/test_helper"
|
||||||
|
|
||||||
NOT_FOR_RUBY_18 = [/show_doc/, /show_idoc/, /show_method/, /show_imethod/]
|
|
||||||
|
|
||||||
puts "Ruby Version #{RUBY_VERSION}"
|
puts "Ruby Version #{RUBY_VERSION}"
|
||||||
puts "Testing Pry #{Pry::VERSION}"
|
puts "Testing Pry #{Pry::VERSION}"
|
||||||
puts "With method_source version #{MethodSource::VERSION}"
|
puts "With method_source version #{MethodSource::VERSION}"
|
||||||
|
@ -105,9 +103,9 @@ describe Pry do
|
||||||
describe "commands" do
|
describe "commands" do
|
||||||
it 'should run command1' do
|
it 'should run command1' do
|
||||||
pry_tester = Pry.new
|
pry_tester = Pry.new
|
||||||
pry_tester.commands = CommandTester.new
|
pry_tester.commands = CommandTester
|
||||||
pry_tester.input = InputTester.new("command1", "exit_all")
|
pry_tester.input = InputTester.new("command1", "exit_all")
|
||||||
pry_tester.commands = CommandTester.new
|
pry_tester.commands = CommandTester
|
||||||
|
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
pry_tester.output = str_output
|
pry_tester.output = str_output
|
||||||
|
@ -119,9 +117,9 @@ describe Pry do
|
||||||
|
|
||||||
it 'should run command2' do
|
it 'should run command2' do
|
||||||
pry_tester = Pry.new
|
pry_tester = Pry.new
|
||||||
pry_tester.commands = CommandTester.new
|
pry_tester.commands = CommandTester
|
||||||
pry_tester.input = InputTester.new("command2 horsey", "exit_all")
|
pry_tester.input = InputTester.new("command2 horsey", "exit_all")
|
||||||
pry_tester.commands = CommandTester.new
|
pry_tester.commands = CommandTester
|
||||||
|
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
pry_tester.output = str_output
|
pry_tester.output = str_output
|
||||||
|
@ -262,31 +260,69 @@ describe Pry do
|
||||||
str_output2.string.should =~ /7/
|
str_output2.string.should =~ /7/
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should set the commands default, and the default should be overridable' do
|
describe "commands" do
|
||||||
commands = {
|
|
||||||
"hello" => proc { |opts| opts[:output].puts "hello world"; opts[:val].clear }
|
|
||||||
}
|
|
||||||
|
|
||||||
def commands.commands() self end
|
it 'should set the commands default, and the default should be overridable' do
|
||||||
|
class Command0 < Pry::CommandBase
|
||||||
|
command "hello" do
|
||||||
|
describe ""
|
||||||
|
action { |opts| opts[:output].puts "hello world"; opts[:val].clear }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Pry.commands = commands
|
Pry.commands = Command0
|
||||||
|
|
||||||
str_output = StringIO.new
|
str_output = StringIO.new
|
||||||
Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
|
Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
|
||||||
str_output.string.should =~ /hello world/
|
str_output.string.should =~ /hello world/
|
||||||
|
|
||||||
commands = {
|
class Command1 < Pry::CommandBase
|
||||||
"goodbye" => proc { |opts| opts[:output].puts "goodbye world"; opts[:val].clear }
|
command "goodbye" do
|
||||||
}
|
describe ""
|
||||||
|
action { |opts| opts[:output].puts "goodbye world"; opts[:val].clear }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def commands.commands() self end
|
str_output = StringIO.new
|
||||||
str_output = StringIO.new
|
|
||||||
|
|
||||||
Pry.new(:input => InputTester.new("goodbye"), :output => str_output, :commands => commands).rep
|
Pry.new(:input => InputTester.new("goodbye"), :output => str_output, :commands => Command1).rep
|
||||||
str_output.string.should =~ /goodbye world/
|
str_output.string.should =~ /goodbye world/
|
||||||
|
|
||||||
|
Object.remove_const(:Command0)
|
||||||
|
Object.remove_const(:Command1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should inherit "help" command from Pry::CommandBase' do
|
||||||
|
class Command2 < Pry::CommandBase
|
||||||
|
command "h" do |v|
|
||||||
|
v.describe "h command"
|
||||||
|
v.action { }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Command2.commands.keys.size.should == 2
|
||||||
|
Command2.command_info.keys.include?("help").should == true
|
||||||
|
Command2.command_info.keys.include?("h").should == true
|
||||||
|
|
||||||
|
Object.remove_const(:Command2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should inherit comands from Pry::Commands' do
|
||||||
|
class Command3 < Pry::Commands
|
||||||
|
command "v" do
|
||||||
|
action {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Command3.command_info.include?("nesting").should == true
|
||||||
|
Command3.command_info.include?("jump_to").should == true
|
||||||
|
Command3.command_info.include?("cd").should == true
|
||||||
|
Command3.command_info.include?("v").should == true
|
||||||
|
|
||||||
|
Object.remove_const(:Command3)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it "should set the print default, and the default should be overridable" do
|
it "should set the print default, and the default should be overridable" do
|
||||||
new_print = proc { |out, value| out.puts value }
|
new_print = proc { |out, value| out.puts value }
|
||||||
Pry.print = new_print
|
Pry.print = new_print
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Object
|
class Module
|
||||||
def test_method
|
public :remove_const
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class InputTester
|
class InputTester
|
||||||
|
@ -18,15 +17,33 @@ class InputTester
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class CommandTester
|
class CommandTester < Pry::CommandBase
|
||||||
def commands
|
|
||||||
@commands ||= {
|
command "command1" do
|
||||||
"command1" => proc { |opts| opts[:output].puts "command1"; opts[:val].clear },
|
describe "command 1 test"
|
||||||
/command2\s*(.*)/ => proc do |opts|
|
action { |opts| opts[:output].puts "command1"; opts[:val].clear }
|
||||||
arg = opts[:captures].first
|
end
|
||||||
opts[:output].puts arg
|
|
||||||
opts[:val].clear
|
command "command2" do
|
||||||
end
|
describe "command 2 test"
|
||||||
|
pattern /command2\s*(.*)/
|
||||||
|
action { |opts|
|
||||||
|
arg = opts[:captures].first
|
||||||
|
opts[:output].puts arg
|
||||||
|
opts[:val].clear
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# def commands
|
||||||
|
# @commands ||= {
|
||||||
|
# "command1" => proc { |opts| opts[:output].puts "command1"; opts[:val].clear },
|
||||||
|
# /command2\s*(.*)/ => proc do |opts|
|
||||||
|
# arg = opts[:captures].first
|
||||||
|
# opts[:output].puts arg
|
||||||
|
# opts[:val].clear
|
||||||
|
# end
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# e
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue