1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

Rename Command#name -> Command#match

The problem with using "name" for this is that several tools expect
Class#name to return a String, and Commands are classes.

This could cause some subtle breakage, but the tests seem ok™
This commit is contained in:
Conrad Irwin 2012-04-01 16:00:59 -07:00
parent c2f06f3da2
commit 4fe5f70447
3 changed files with 88 additions and 82 deletions

View file

@ -15,9 +15,14 @@ class Pry
# {CommandSet#command} or {CommandSet#create_command}).
class << self
attr_accessor :block
attr_accessor :name
attr_writer :description
attr_writer :command_options
attr_writer :match
def match(arg=nil)
@match = arg if arg
@match
end
# Define or get the command's description
def description(arg=nil)
@ -44,19 +49,23 @@ class Pry
# Make those properties accessible to instances
def name; self.class.name; end
def match; self.class.match; end
def description; self.class.description; end
def block; self.class.block; end
def command_options; self.class.options; end
def command_name; command_options[:listing]; end
class << self
def name
super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super
end
def inspect
"#<class(Pry::Command #{name.inspect})>"
name
end
# Create a new command with the given properties.
#
# @param String name the name of the command
# @param String/Regex match the thing that triggers this command
# @param String description the description to appear in {help}
# @param Hash options behavioural options (@see {Pry::CommandSet#command})
# @param Module helpers a module of helper functions to be included.
@ -64,10 +73,10 @@ class Pry
#
# @return Class (a subclass of Pry::Command)
#
def subclass(name, description, options, helpers, &block)
def subclass(match, description, options, helpers, &block)
klass = Class.new(self)
klass.send(:include, helpers)
klass.name = name
klass.match = match
klass.description = description
klass.command_options = options
klass.block = block
@ -117,7 +126,7 @@ class Pry
prefix = convert_to_regex(Pry.config.command_prefix)
prefix = "(?:#{prefix})?" unless options[:use_prefix]
/^#{prefix}#{convert_to_regex(name)}(?!\S)/
/^#{prefix}#{convert_to_regex(match)}(?!\S)/
end
def convert_to_regex(obj)
@ -232,12 +241,12 @@ class Pry
# the current scope.
# @param [String] command_name_match The name of the colliding command.
# @param [Binding] target The current binding context.
def check_for_command_name_collision(command_name_match, arg_string)
collision_type = target.eval("defined?(#{command_name_match})")
def check_for_command_collision(command_match, arg_string)
collision_type = target.eval("defined?(#{command_match})")
collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=})
if collision_type
output.puts "#{Pry::Helpers::Text.bold('WARNING:')} Calling Pry command '#{command_name_match}'," +
output.puts "#{Pry::Helpers::Text.bold('WARNING:')} Calling Pry command '#{command_match}'," +
"which conflicts with a #{collision_type}.\n\n"
end
rescue Pry::RescuableException
@ -247,8 +256,8 @@ class Pry
#
# @param String the line of input
# @return [
# String the command name used, or portion of line that matched the command_regex
# String a string of all the arguments (i.e. everything but the name)
# String the portion of the line that matched with the Command match
# String a string of all the arguments (i.e. everything but the match)
# Array the captures caught by the command_regex
# Array args the arguments got by splitting the arg_string
# ]
@ -284,9 +293,9 @@ class Pry
# @param String the line to process
# @return Object or Command::VOID_VALUE
def process_line(line)
command_name, arg_string, captures, args = tokenize(line)
command_match, arg_string, captures, args = tokenize(line)
check_for_command_name_collision(command_name, arg_string) if Pry.config.collision_warning
check_for_command_collision(command_match, arg_string) if Pry.config.collision_warning
self.arg_string = arg_string
self.captures = captures
@ -334,14 +343,14 @@ class Pry
unless dependencies_met?
gems_needed = Array(command_options[:requires_gem])
gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
output.puts "\nThe command '#{name}' is #{Helpers::Text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
output.puts "\nThe command '#{command_name}' is #{Helpers::Text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
output.puts "-"
output.puts "Type `install-command #{name}` to install the required gems and activate this command."
output.puts "Type `install-command #{command_name}` to install the required gems and activate this command."
return void
end
if command_options[:argument_required] && args.empty?
raise CommandError, "The command '#{name}' requires an argument."
raise CommandError, "The command '#{command_name}' requires an argument."
end
ret = call_with_hooks(*args)
@ -506,6 +515,6 @@ class Pry
# gist_method
# end
# end
def process; raise CommandError, "command '#{name}' not implemented" end
def process; raise CommandError, "command '#{command_name}' not implemented" end
end
end

View file

@ -1,7 +1,7 @@
class Pry
class NoCommandError < StandardError
def initialize(name, owner)
super "Command '#{name}' not found in command set #{owner}"
def initialize(match, owner)
super "Command '#{match}' not found in command set #{owner}"
end
end
@ -27,8 +27,7 @@ class Pry
end
# Defines a new Pry command.
# @param [String, Regexp] name The name of the command. Can be
# Regexp as well as String.
# @param [String, Regexp] match The start of invocations of this command.
# @param [String] description A description of the command.
# @param [Hash] options The optional configuration parameters.
# @option options [Boolean] :keep_retval Whether or not to use return value
@ -43,7 +42,7 @@ class Pry
# executing the command. Defaults to true.
# @option options [String] :listing The listing name of the
# command. That is the name by which the command is looked up by
# help and by show-command. Necessary for regex based commands.
# help and by show-command. Necessary for commands with regex matches.
# @option options [Boolean] :use_prefix Whether the command uses
# `Pry.config.command_prefix` prefix (if one is defined). Defaults
# to true.
@ -80,18 +79,17 @@ class Pry
# # hello john, nice number: 10
# # pry(main)> help number
# # number-N regex command
def block_command(name, description="No description.", options={}, &block)
def block_command(match, description="No description.", options={}, &block)
description, options = ["No description.", description] if description.is_a?(Hash)
options = default_options(name).merge!(options)
options = default_options(match).merge!(options)
commands[name] = Pry::BlockCommand.subclass(name, description, options, helper_module, &block)
commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block)
end
alias_method :command, :block_command
# Defines a new Pry command class.
#
# @param [String, Regexp] name The name of the command. Can be
# Regexp as well as String.
# @param [String, Regexp] match The start of invocations of this command.
# @param [String] description A description of the command.
# @param [Hash] options The optional configuration parameters, see {#command}
# @param &Block The class body's definition.
@ -113,40 +111,40 @@ class Pry
# end
# end
#
def create_command(name, description="No description.", options={}, &block)
def create_command(match, description="No description.", options={}, &block)
description, options = ["No description.", description] if description.is_a?(Hash)
options = default_options(name).merge!(options)
options = default_options(match).merge!(options)
commands[name] = Pry::ClassCommand.subclass(name, description, options, helper_module, &block)
commands[name].class_eval(&block)
commands[name]
commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block)
commands[match].class_eval(&block)
commands[match]
end
# Execute a block of code before a command is invoked. The block also
# gets access to parameters that will be passed to the command and
# is evaluated in the same context.
# @param [String, Regexp] name The name of the command.
# @param [String, Regexp] search The match or listing of the command.
# @yield The block to be run before the command.
# @example Display parameter before invoking command
# Pry.commands.before_command("whereami") do |n|
# output.puts "parameter passed was #{n}"
# end
def before_command(name, &block)
cmd = find_command_by_name_or_listing(name)
def before_command(search, &block)
cmd = find_command_by_match_or_listing(search)
cmd.hooks[:before].unshift block
end
# Execute a block of code after a command is invoked. The block also
# gets access to parameters that will be passed to the command and
# is evaluated in the same context.
# @param [String, Regexp] name The name of the command.
# @param [String, Regexp] search The match or listing of the command.
# @yield The block to be run after the command.
# @example Display text 'command complete' after invoking command
# Pry.commands.after_command("whereami") do |n|
# output.puts "command complete!"
# end
def after_command(name, &block)
cmd = find_command_by_name_or_listing(name)
def after_command(search, &block)
cmd = find_command_by_match_or_listing(search)
cmd.hooks[:after] << block
end
@ -155,11 +153,11 @@ class Pry
end
# Removes some commands from the set
# @param [Array<String>] names name of the commands to remove
def delete(*names)
names.each do |name|
cmd = find_command_by_name_or_listing(name)
commands.delete cmd.name
# @param [Array<String>] searches the matches or listings of the commands to remove
def delete(*searches)
searches.each do |search|
cmd = find_command_by_match_or_listing(search)
commands.delete cmd.match
end
end
@ -175,34 +173,34 @@ class Pry
# Imports some commands from a set
# @param [CommandSet] set Set to import commands from
# @param [Array<String>] names Commands to import
def import_from(set, *names)
# @param [Array<String>] matches Commands to import
def import_from(set, *matches)
helper_module.send :include, set.helper_module
names.each do |name|
cmd = set.find_command_by_name_or_listing(name)
commands[cmd.name] = cmd
matches.each do |match|
cmd = set.find_command_by_match_or_listing(match)
commands[cmd.match] = cmd
end
end
# @param [String, Regexp] name_or_listing The name or listing name
# @param [String, Regexp] match_or_listing The match or listing of a command.
# of the command to retrieve.
# @return [Command] The command object matched.
def find_command_by_name_or_listing(name_or_listing)
if commands[name_or_listing]
cmd = commands[name_or_listing]
def find_command_by_match_or_listing(match_or_listing)
if commands[match_or_listing]
cmd = commands[match_or_listing]
else
_, cmd = commands.find { |name, command| command.options[:listing] == name_or_listing }
_, cmd = commands.find { |match, command| command.options[:listing] == match_or_listing }
end
raise ArgumentError, "Cannot find a command with name: '#{name_or_listing}'!" if !cmd
raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!" if !cmd
cmd
end
protected :find_command_by_name_or_listing
protected :find_command_by_match_or_listing
# Aliases a command
# Note that if `desc` parameter is `nil` then the default
# description is used.
# @param [String, Regex] name The name of the alias (can be a regex).
# @param [String, Regex] match The match of the alias (can be a regex).
# @param [String] action The action to be performed (typically
# another command).
# @param [Hash] options The optional configuration parameters,
@ -212,7 +210,7 @@ class Pry
# Pry.config.commands.alias_command "lM", "ls -M"
# @example Pass explicit description (overriding default).
# Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie"
def alias_command(name, action, options={})
def alias_command(match, action, options={})
options = {
:desc => "Alias for `#{action}`",
}.merge!(options)
@ -220,7 +218,7 @@ class Pry
# ensure default description is used if desc is nil
desc = options.delete(:desc).to_s
c = block_command name, desc, options do |*args|
c = block_command match, desc, options do |*args|
run action, *args
end
@ -229,35 +227,34 @@ class Pry
c
end
# Rename a command. Accepts either actual name or listing name for
# the `old_name`.
# `new_name` must be the actual name of the new command.
# @param [String, Regexp] new_name The new name for the command.
# @param [String, Regexp] old_name The command's current name.
# Rename a command. Accepts either match or listing for the search.
#
# @param [String, Regexp] new_name The new match for the command.
# @param [String, Regexp] search The command's current match or listing.
# @param [Hash] options The optional configuration parameters,
# accepts the same as the `command` method, but also allows the
# command description to be passed this way too.
# @example Renaming the `ls` command and changing its description.
# Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls"
def rename_command(new_name, old_name, options={})
cmd = find_command_by_name_or_listing(old_name)
def rename_command(new_match, search, options={})
cmd = find_command_by_match_or_listing(search)
options = {
:listing => new_name,
:listing => new_match,
:description => cmd.description
}.merge!(options)
commands[new_name] = cmd.dup
commands[new_name].name = new_name
commands[new_name].description = options.delete(:description)
commands[new_name].options.merge!(options)
commands.delete(cmd.name)
commands[new_match] = cmd.dup
commands[new_match].match = new_match
commands[new_match].description = options.delete(:description)
commands[new_match].options.merge!(options)
commands.delete(cmd.match)
end
# Sets or gets the description for a command (replacing the old
# description). Returns current description if no description
# parameter provided.
# @param [String, Regexp] name The command name.
# @param [String, Regexp] match The command match.
# @param [String] description The command description.
# @example Setting
# MyCommands = Pry::CommandSet.new do
@ -265,8 +262,8 @@ class Pry
# end
# @example Getting
# Pry.config.commands.desc "amend-line"
def desc(name, description=nil)
cmd = find_command_by_name_or_listing(name)
def desc(search, description=nil)
cmd = find_command_by_match_or_listing(search)
return cmd.description if !description
cmd.description = description
@ -308,7 +305,7 @@ class Pry
# @return [Pry::Command, nil]
def find_command_for_help(search)
find_command(search) || (begin
find_command_by_name_or_listing(search)
find_command_by_match_or_listing(search)
rescue ArgumentError
nil
end)
@ -339,21 +336,21 @@ class Pry
end
# @nodoc used for testing
def run_command(context, name, *args)
command = commands[name] or raise NoCommandError.new(name, self)
def run_command(context, match, *args)
command = commands[match] or raise NoCommandError.new(match, self)
command.new(context).call_safely(*args)
end
private
def default_options(name)
def default_options(match)
{
:requires_gem => [],
:keep_retval => false,
:argument_required => false,
:interpolate => true,
:shellwords => true,
:listing => name,
:listing => (String === match ? match : match.inspect),
:use_prefix => true,
:takes_block => false
}

View file

@ -127,7 +127,7 @@ describe Pry::CommandSet do
@set.command('foo', 'stuff') { run = true }
@set.alias_command 'bar', 'foo'
@set.commands['bar'].name.should == 'bar'
@set.commands['bar'].match.should == 'bar'
@set.commands['bar'].description.should == 'Alias for `foo`'
@set.run_command @ctx, 'bar'
@ -139,7 +139,7 @@ describe Pry::CommandSet do
@set.command('foo', 'stuff') { run = true }
@set.alias_command 'bar', 'foo', :desc => "tobina"
@set.commands['bar'].name.should == 'bar'
@set.commands['bar'].match.should == 'bar'
@set.commands['bar'].description.should == "tobina"
@set.run_command @ctx, 'bar'
@ -151,7 +151,7 @@ describe Pry::CommandSet do
@set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
@set.alias_command 'bar', 'foo1'
@set.commands['bar'].name.should == 'bar'
@set.commands['bar'].match.should == 'bar'
@set.commands['bar'].description.should == 'Alias for `foo1`'
@set.run_command @ctx, 'bar'