require'forwardable'classPryclassCommandProcessor# Wraps the return result of process_commands, indicates if the# result IS a command and what kind of command (e.g void)classResultattr_reader:retvaldefinitialize(is_command,keep_retval=false,retval=nil)@is_command,@keep_retval,@retval=is_command,keep_retval,retvalend# Is the result a command?# @return [Boolean]defcommand?@is_commandend# Is the result a command and if it is, is it a void command?# (one that does not return a value)# @return [Boolean]defvoid_command?(command?&&!keep_retval?)||retval==CommandContext::VOID_VALUEend# Is the return value kept for this command? (i.e :keep_retval => true)# @return [Boolean]defkeep_retval?@keep_retvalendendextendForwardableattr_accessor:pry_instancedefinitialize(pry_instance)@pry_instance=pry_instanceenddef_delegators:@pry_instance,:commands,:output# Is the string a valid command?# @param [String] val The string passed in from the Pry prompt.# @param [Binding] target The context where the string should be# interpolated in.# @return [Boolean] Whether the string is a valid command.defvalid_command?(val,target=binding)!!(command_matched(val,target)[0])end# Convert the object to a form that can be interpolated into a# Regexp cleanly.# @return [String] The string to interpolate into a Regexpdefconvert_to_regex(obj)caseobjwhenStringRegexp.escape(obj)elseobjendend# Revaluate the string (str) and perform interpolation.# @param [String] str The string to reevaluate with interpolation.# @param [Binding] target The context where the string should be# interpolated in.# @return [String] The reevaluated string with interpolations# applied (if any).definterpolate_string(str,target)dumped_str=str.dumpdumped_str.gsub!(/\\\#\{/,'#{')target.eval(dumped_str)end# Determine whether a Pry command was matched and return command data# and argument string.# This method should not need to be invoked directly.# @param [String] val The line of input.# @param [Binding] target The binding to perform string# interpolation against.# @return [Array] The command data and arg string pairdefcommand_matched(val,target)_,cmd_data=commands.commands.finddo|name,data|prefix=convert_to_regex(Pry.config.command_prefix)prefix="(?:#{prefix})?"unlessdata.options[:use_prefix]command_regex=/^#{prefix}#{convert_to_regex(name)}(?!\S)/ifcommand_regex=~valifdata.options[:interpolate]val.replace(interpolate_string(val,target))command_regex=~val# re-match with the interpolated stringendtrueendend[cmd_data,(Regexp.last_match?Regexp.last_match.captures:nil),(Regexp.last_match?Regexp.last_match.end(0):nil)]end# Process Pry commands. Pry commands are not Ruby methods and are evaluated# prior to Ruby expressions.# Commands can be modified/configured by the user: see `Pry::Commands`# This method should not need to be invoked directly - it is called# by `Pry#r`.# @param [String] val The current line of input.# @param [String] eval_string The cumulative lines of input for# multi-line input.# @param [Binding] target The receiver of the commands.# @return [Pry::CommandProcessor::Result] A wrapper object# containing info about the result of the command processing# (indicating whether it is a command and if it is what kind of# command it is.defprocess_commands(val,eval_string,target)command,captures,pos=command_matched(val,target)# no command was matched, so return to callerreturnResult.new(false)if!commandarg_string=val[pos..-1]# remove the one leading space if it existsarg_string.slice!(0)ifarg_string.start_with?(" ")ifarg_stringargs=command.options[:shellwords]?Shellwords.shellwords(arg_string):arg_string.split(" ")elseargs=[]endoptions={:val=>val,:arg_string=>arg_string,:eval_string=>eval_string,:commands=>commands.commands,:captures=>captures}ret=execute_command(target,command.name,options,*(captures+args))Result.new(true,command.options[:keep_retval],ret)end# Execute a Pry command.# This method should not need to be invoked directly.# @param [Binding] target The target of the Pry session.# @param [String] command The name of the command to be run.# @param [Hash] options The options to set on the Commands object.# @param [Array] args The command arguments.# @return [Object] The value returned by the commanddefexecute_command(target,command,options,*args)context=CommandContext.new# set some useful methods to be used by the action blockscontext.opts=optionscontext.target=targetcontext.target_self=target.eval('self')context.output=outputcontext.captures=options[:captures]context.eval_string=options[:eval_string]context.arg_string=options[:arg_string]context.command_set=commandscontext._pry_=@pry_instancecontext.command_processor=selfret=nilcatch(:command_done)doret=commands.run_command(context,command,*args)endoptions[:val].replace("")retendendend