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.
represents a void return value for a command
The block we pass into a command so long as `:takes_block` is not equal to `false` @example
my-command | do puts "block content" end
Properties of one execution of a command (passed by {Pry#run_command} as a hash of context and expanded in `initialize`
# File lib/pry/command.rb, line 58 def block @block || instance_method(:process) end
# File lib/pry/command.rb, line 118 def command_name self.options[:listing] end
Define or get the command's options
# File lib/pry/command.rb, line 43 def command_options(arg=nil) @command_options ||= default_options(match) @command_options.merge!(arg) if arg @command_options end
# File lib/pry/command.rb, line 177 def command_regex pr = defined?(Pry.config.command_prefix) ? Pry.config.command_prefix : "" prefix = convert_to_regex(pr) prefix = "(?:#{prefix})?" unless options[:use_prefix] /^#{prefix}#{convert_to_regex(match)}(?!\S)/ end
# File lib/pry/command.rb, line 185 def convert_to_regex(obj) case obj when String Regexp.escape(obj) else obj end end
# File lib/pry/command.rb, line 85 def default_options(match) { :requires_gem => [], :keep_retval => false, :argument_required => false, :interpolate => true, :shellwords => true, :listing => (String === match ? match : match.inspect), :use_prefix => true, :takes_block => false } end
Define or get the command's description
# File lib/pry/command.rb, line 37 def description(arg=nil) @description = arg if arg @description end
# File lib/pry/command.rb, line 67 def doc new.help end
The group in which the command should be displayed in "help" output. This is usually auto-generated from directory naming, but it can be manually overridden if necessary.
# File lib/pry/command.rb, line 197 def group(name=nil) @group ||= if name name else case Pry::Method(block).source_file when %r{/pry/.*_commands/(.*).rb} $1.capitalize.gsub(/_/, " ") when %r{(pry-\w+)-([\d\.]+([\w\d\.]+)?)} name, version = $1, $2 "#{name.to_s} (v#{version.to_s})" when /pryrc/ "~/.pryrc" else "(other)" end end end
Store hooks to be run before or after the command body. @see {Pry::CommandSet#before_command} @see {Pry::CommandSet#after_command}
# File lib/pry/command.rb, line 173 def hooks @hooks ||= {:before => [], :after => []} end
# File lib/pry/command.rb, line 114 def inspect name end
# File lib/pry/command.rb, line 27 def match(arg=nil) if arg @command_options ||= default_options(arg) @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect @match = arg end @match end
How well does this command match the given line?
Higher scores are better because they imply that this command matches the line more closely.
The score is calculated by taking the number of characters at the start of the string that are used only to identify the command, not as part of the arguments.
@example
/\.(.*)/.match_score(".foo") #=> 1 /\.*(.*)/.match_score("...foo") #=> 3 'hi'.match_score("hi there") #=> 2
@param [String] val A line input at the REPL @return [Fixnum]
# File lib/pry/command.rb, line 162 def match_score(val) if command_regex =~ val Regexp.last_match.size > 1 ? Regexp.last_match.begin(1) : Regexp.last_match.end(0) else -1 end end
Should this command be called for the given line? @param [String] val A line input at the REPL @return [Boolean]
# File lib/pry/command.rb, line 142 def matches?(val) command_regex =~ val end
# File lib/pry/command.rb, line 110 def name super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super end
Instantiate a command, in preparation for calling it. @param [Hash] context The runtime context to use with this command.
# File lib/pry/command.rb, line 266 def initialize(context={}) self.context = context self.target = context[:target] self.output = context[:output] self.eval_string = context[:eval_string] self.command_set = context[:command_set] self._pry_ = context[:pry_instance] end
# File lib/pry/command.rb, line 62 def source file, line = block.source_location strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line)) end
# File lib/pry/command.rb, line 75 def source_file Array(block.source_location).first end
# File lib/pry/command.rb, line 80 def source_line Array(block.source_location).last end
# File lib/pry/command.rb, line 71 def source_location block.source_location end
Create a new command with the given properties. @param [String, Regex] match The thing that triggers this command @param [String] description The description to appear in `help` @param [Hash] options Behavioral options (see {Pry::CommandSet#command}) @param [Module] helpers A module of helper functions to be included. @yield optional, used for BlockCommands @return [Class] (a subclass of {Pry::Command})
# File lib/pry/command.rb, line 129 def subclass(match, description, options, helpers, &block) klass = Class.new(self) klass.send(:include, helpers) klass.match = match klass.description = description klass.command_options = options klass.block = block klass end
# File lib/pry/command.rb, line 103 def block; self.class.block; end
Run the command with the given `args`.
This is a public wrapper around `call` which ensures all preconditions are met.
@param [Array<String>] args The arguments to pass to this command. @return [Object] The return value of the `call` method, or
{Command::VOID_VALUE}.
# File lib/pry/command.rb, line 412 def call_safely(*args) unless dependencies_met? gems_needed = Array(command_options[:requires_gem]) gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) } output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}" output.puts "-" 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 '#{command_name}' requires an argument." end ret = call_with_hooks(*args) command_options[:keep_retval] ? ret : void end
Display a warning if a command collides with a local/method in the current scope.
# File lib/pry/command.rb, line 305 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 "#{text.bold('WARNING:')} Calling Pry command '#{command_match}'," + "which conflicts with a #{collision_type}.\n\n" end rescue Pry::RescuableException end
# File lib/pry/command.rb, line 105 def command_name; self.class.command_name; end
# File lib/pry/command.rb, line 104 def command_options; self.class.options; end
# File lib/pry/command.rb, line 249 def commands command_set.commands end
Generate completions for this command
@param [String] search The line typed so far @return [Array<String>] Completion words
# File lib/pry/command.rb, line 441 def complete(search); Bond::DefaultMission.completions; end
Are all the gems required to use this command installed?
@return Boolean
# File lib/pry/command.rb, line 433 def dependencies_met? @dependencies_met ||= command_dependencies_met?(command_options) end
# File lib/pry/command.rb, line 102 def description; self.class.description; end
Revaluate the string (str) and perform interpolation. @param [String] str The string to reevaluate with interpolation.
@return [String] The reevaluated string with interpolations
applied (if any).
# File lib/pry/command.rb, line 294 def interpolate_string(str) dumped_str = str.dump if dumped_str.gsub!(/\\#\{/, '#{') target.eval(dumped_str) else str end end
# File lib/pry/command.rb, line 101 def match; self.class.match; end
Make those properties accessible to instances
# File lib/pry/command.rb, line 100 def name; self.class.name; end
Process a line that ::matches? this command. @param [String] line The line to process @return [Object, Command::VOID_VALUE]
# File lib/pry/command.rb, line 360 def process_line(line) command_match, arg_string, captures, args = tokenize(line) check_for_command_collision(command_match, arg_string) if Pry.config.collision_warning self.arg_string = arg_string self.captures = captures call_safely(*(captures + args)) end
Run a command from another command. @param [String] command_string The string that invokes the command @param [Array] args Further arguments to pass to the command @example
run "show-input"
@example
run ".ls"
@example
run "amend-line", "5", 'puts "hello world"'
# File lib/pry/command.rb, line 244 def run(command_string, *args) complete_string = "#{command_string} #{args.join(" ")}".rstrip command_set.process_line(complete_string, context) end
# File lib/pry/command.rb, line 106 def source; self.class.source; end
# File lib/pry/command.rb, line 107 def source_location; self.class.source_location; end
@return [Hash] Pry commands can store arbitrary state
here. This state persists between subsequent command invocations. All state saved here is unique to the command, it does not need to be namespaced.
@example
state.my_state = "my state" # this will not conflict with any # `state.my_state` used in another command.
# File lib/pry/command.rb, line 285 def state _pry_.command_state[match] ||= OpenStruct.new end
@return [Object] The value of `self` inside the `target` binding.
# File lib/pry/command.rb, line 276 def target_self; target.eval('self'); end
# File lib/pry/command.rb, line 253 def text Pry::Helpers::Text end
Extract necessary information from a line that ::matches? this command.
Returns an array of four elements:
"`
[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] the arguments obtained by splitting the arg_string
"`
@param [String] val The line of input @return [Array]
# File lib/pry/command.rb, line 330 def tokenize(val) val.replace(interpolate_string(val)) if command_options[:interpolate] self.class.command_regex =~ val # please call Command.matches? before Command#call_safely raise CommandError, "fatal: called a command which didn't match?!" unless Regexp.last_match captures = Regexp.last_match.captures pos = Regexp.last_match.end(0) arg_string = val[pos..-1] # remove the one leading space if it exists arg_string.slice!(0) if arg_string.start_with?(" ") # process and pass a block if one is found pass_block(arg_string) if command_options[:takes_block] if arg_string args = command_options[:shellwords] ? Shellwords.shellwords(arg_string) : arg_string.split(" ") else args = [] end [val[0..pos].rstrip, arg_string, captures, args] end
# File lib/pry/command.rb, line 257 def void VOID_VALUE end