2012-08-08 00:08:30 -04:00
require 'delegate'
2012-08-13 23:54:07 -04:00
require 'pry/helpers/documentation_helpers'
2011-12-31 06:50:04 -05:00
class Pry
2011-12-31 07:40:01 -05:00
# The super-class of all commands, new commands should be created by calling
2012-01-21 18:17:43 -05:00
# {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command}
2011-12-31 07:40:01 -05:00
# which creates a ClassCommand. Please don't use this class directly.
2011-12-31 06:50:04 -05:00
class Command
2012-08-13 23:54:07 -04:00
extend Helpers :: DocumentationHelpers
2011-12-31 06:50:04 -05:00
# represents a void return value for a command
VOID_VALUE = Object . new
# give it a nice inspect
def VOID_VALUE . inspect ( ) " void " end
2011-12-31 07:40:01 -05:00
# Properties of the command itself (as passed as arguments to
2012-01-21 18:17:43 -05:00
# {CommandSet#command} or {CommandSet#create_command}).
2011-12-31 06:50:04 -05:00
class << self
2012-04-01 19:20:35 -04:00
attr_writer :block
2012-01-15 15:21:28 -05:00
attr_writer :description
attr_writer :command_options
2012-04-01 19:00:59 -04:00
attr_writer :match
def match ( arg = nil )
@match = arg if arg
@match
end
2012-01-08 15:48:54 -05:00
# Define or get the command's description
def description ( arg = nil )
@description = arg if arg
@description
end
# Define or get the command's options
def command_options ( arg = nil )
2012-01-14 23:54:30 -05:00
@command_options || = { }
@command_options . merge! ( arg ) if arg
2012-01-08 15:48:54 -05:00
@command_options
end
# backward compatibility
alias_method :options , :command_options
alias_method :options = , :command_options =
# Define or get the command's banner
def banner ( arg = nil )
@banner = arg if arg
@banner || description
end
2012-04-01 19:20:35 -04:00
def block
@block || instance_method ( :process ) && instance_method ( :process )
end
2012-08-13 23:54:07 -04:00
def source
2012-12-20 14:14:11 -05:00
file , line = block . source_location
strip_leading_whitespace ( Pry :: Code . from_file ( file ) . expression_at ( line ) )
2012-08-13 23:54:07 -04:00
end
def source_location
block . source_location
end
2012-12-01 21:57:17 -05:00
def source_file
Array ( block . source_location ) . first
end
alias_method :file , :source_file
def source_line
Array ( block . source_location ) . last
end
alias_method :line , :source_line
2011-12-31 06:50:04 -05:00
end
2011-12-31 07:40:01 -05:00
# Make those properties accessible to instances
def name ; self . class . name ; end
2012-04-01 19:00:59 -04:00
def match ; self . class . match ; end
2011-12-31 07:40:01 -05:00
def description ; self . class . description ; end
def block ; self . class . block ; end
def command_options ; self . class . options ; end
2012-12-01 21:57:17 -05:00
def command_name ; self . class . command_name ; end
2012-08-13 23:54:07 -04:00
def source ; self . class . source ; end
def source_location ; self . class . source_location ; end
2011-12-31 07:40:01 -05:00
class << self
2012-04-01 19:00:59 -04:00
def name
super . to_s == " " ? " # <class(Pry::Command #{ match . inspect } )> " : super
end
2012-08-03 09:29:21 -04:00
2011-12-31 07:40:01 -05:00
def inspect
2012-04-01 19:00:59 -04:00
name
2011-12-31 07:40:01 -05:00
end
2012-12-01 21:57:17 -05:00
def command_name
self . options [ :listing ]
end
2011-12-31 07:40:01 -05:00
# Create a new command with the given properties.
2012-06-27 01:30:00 -04:00
# @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})
2012-04-01 19:00:59 -04:00
def subclass ( match , description , options , helpers , & block )
2011-12-31 07:40:01 -05:00
klass = Class . new ( self )
klass . send ( :include , helpers )
2012-04-01 19:00:59 -04:00
klass . match = match
2011-12-31 07:40:01 -05:00
klass . description = description
2012-01-08 15:48:54 -05:00
klass . command_options = options
2011-12-31 07:40:01 -05:00
klass . block = block
klass
end
2012-01-02 19:04:47 -05:00
# Should this command be called for the given line?
2012-06-27 01:30:00 -04:00
# @param [String] val A line input at the REPL
# @return [Boolean]
2012-01-02 19:04:47 -05:00
def matches? ( val )
command_regex =~ val
end
2012-02-11 18:15:22 -05:00
# 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
#
2012-06-27 01:30:00 -04:00
# @param [String] val A line input at the REPL
# @return [Fixnum]
2012-02-11 18:15:22 -05:00
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
2011-12-31 07:40:01 -05:00
# Store hooks to be run before or after the command body.
# @see {Pry::CommandSet#before_command}
# @see {Pry::CommandSet#after_command}
def hooks
@hooks || = { :before = > [ ] , :after = > [ ] }
end
2012-01-02 19:04:47 -05:00
def command_regex
2012-04-12 04:58:59 -04:00
pr = defined? ( Pry . config . command_prefix ) ? Pry . config . command_prefix : " "
prefix = convert_to_regex ( pr )
2012-01-02 19:04:47 -05:00
prefix = " (?: #{ prefix } )? " unless options [ :use_prefix ]
2012-04-01 19:00:59 -04:00
/ ^ #{ prefix } #{ convert_to_regex ( match ) } (?! \ S) /
2012-01-02 19:04:47 -05:00
end
def convert_to_regex ( obj )
case obj
when String
Regexp . escape ( obj )
else
obj
end
end
2012-02-20 02:08:16 -05:00
# 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.
def group ( name = nil )
2012-07-05 16:31:03 -04:00
@group || = if name
name
2012-06-30 19:09:49 -04:00
else
2012-07-05 16:31:03 -04:00
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
2012-06-30 19:09:49 -04:00
end
2012-02-20 02:08:16 -05:00
end
2011-12-31 07:40:01 -05:00
end
2012-01-02 19:04:47 -05:00
# Properties of one execution of a command (passed by {Pry#run_command} as a hash of
2012-06-27 01:30:00 -04:00
# context and expanded in `#initialize`
2011-12-31 06:50:04 -05:00
attr_accessor :output
attr_accessor :target
attr_accessor :captures
attr_accessor :eval_string
attr_accessor :arg_string
2011-12-31 07:40:01 -05:00
attr_accessor :context
2011-12-31 06:50:04 -05:00
attr_accessor :command_set
attr_accessor :_pry_
2012-02-26 07:05:19 -05:00
# The block we pass *into* a command so long as `:takes_block` is
# not equal to `false`
2012-02-23 09:30:48 -05:00
# @example
2012-02-26 07:05:19 -05:00
# my-command | do
2012-02-23 09:30:48 -05:00
# puts "block content"
# end
attr_accessor :command_block
2011-12-31 06:50:04 -05:00
# 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"'
def run ( command_string , * args )
2012-03-07 21:38:12 -05:00
complete_string = " #{ command_string } #{ args . join ( " " ) } " . rstrip
2012-01-02 19:04:47 -05:00
command_set . process_line ( complete_string , context )
2011-12-31 06:50:04 -05:00
end
def commands
command_set . commands
end
def text
Pry :: Helpers :: Text
end
def void
VOID_VALUE
end
include Pry :: Helpers :: BaseHelpers
include Pry :: Helpers :: CommandHelpers
2011-12-31 07:40:01 -05:00
# Instantiate a command, in preparation for calling it.
2012-06-27 01:30:00 -04:00
# @param [Hash] context The runtime context to use with this command.
2011-12-31 09:13:59 -05:00
def initialize ( context = { } )
2011-12-31 06:50:04 -05:00
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
2012-06-15 08:36:03 -04:00
# @return [Object] The value of `self` inside the `target` binding.
2011-12-31 09:13:59 -05:00
def target_self ; target . eval ( 'self' ) ; end
2012-06-15 08:36:03 -04:00
# @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.
def state
_pry_ . command_state [ match ] || = OpenStruct . new
end
2012-01-02 19:04:47 -05:00
# 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).
def interpolate_string ( str )
dumped_str = str . dump
if dumped_str . gsub! ( / \\ \ # \ { / , '#{' )
target . eval ( dumped_str )
else
str
end
end
# Display a warning if a command collides with a local/method in
# the current scope.
2012-04-01 19:00:59 -04:00
def check_for_command_collision ( command_match , arg_string )
collision_type = target . eval ( " defined?( #{ command_match } ) " )
2012-01-28 22:39:31 -05:00
collision_type || = 'local-variable' if arg_string . match ( %r{ \ A \ s*[-+*/%&|^]*= } )
if collision_type
2012-07-25 17:32:19 -04:00
output . puts " #{ text . bold ( 'WARNING:' ) } Calling Pry command ' #{ command_match } ', " +
2012-01-28 22:39:31 -05:00
" which conflicts with a #{ collision_type } . \n \n "
2012-01-02 19:04:47 -05:00
end
rescue Pry :: RescuableException
end
2012-06-27 01:30:00 -04:00
# Extract necessary information from a line that Command.matches? this
# command.
#
# Returns an array of four elements:
2012-01-02 19:04:47 -05:00
#
2012-06-27 01:30:00 -04:00
# ```
# [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]
2012-01-02 19:04:47 -05:00
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? ( " " )
2012-02-26 07:05:19 -05:00
# process and pass a block if one is found
pass_block ( arg_string ) if command_options [ :takes_block ]
2012-01-02 19:04:47 -05:00
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
# Process a line that Command.matches? this command.
2012-06-27 01:30:00 -04:00
# @param [String] line The line to process
# @return [Object, Command::VOID_VALUE]
2012-01-02 19:04:47 -05:00
def process_line ( line )
2012-04-01 19:00:59 -04:00
command_match , arg_string , captures , args = tokenize ( line )
2012-01-02 19:04:47 -05:00
2012-04-01 19:00:59 -04:00
check_for_command_collision ( command_match , arg_string ) if Pry . config . collision_warning
2012-01-02 19:04:47 -05:00
self . arg_string = arg_string
self . captures = captures
call_safely ( * ( captures + args ) )
end
2012-02-23 09:30:48 -05:00
# Pass a block argument to a command.
2012-02-26 07:05:19 -05:00
# @param [String] arg_string The arguments (as a string) passed to the command.
# We inspect these for a '| do' or a '| {' and if we find it we use it
2012-02-23 09:30:48 -05:00
# to start a block input sequence. Once we have a complete
# block, we save it to an accessor that can be retrieved from the command context.
2012-02-26 07:05:19 -05:00
# Note that if we find the '| do' or '| {' we delete this and the
# elements following it from `arg_string`.
def pass_block ( arg_string )
2012-10-13 22:46:37 -04:00
# Workaround for weird JRuby bug where rindex in this case can return nil
# even when there's a match.
arg_string . scan ( / \ | *(?:do| \ {) / )
block_index = $~ && $~ . offset ( 0 ) [ 0 ]
2012-02-23 09:30:48 -05:00
2012-02-26 07:05:19 -05:00
return if ! block_index
2012-02-23 09:30:48 -05:00
2012-02-26 07:05:19 -05:00
block_init_string = arg_string . slice! ( block_index .. - 1 ) [ 1 .. - 1 ]
prime_string = " proc #{ block_init_string } \n "
2012-04-10 09:39:29 -04:00
if ! Pry :: Code . complete_expression? ( prime_string )
2012-02-26 07:05:19 -05:00
block_string = _pry_ . r ( target , prime_string )
else
block_string = prime_string
end
2012-02-23 09:30:48 -05:00
2012-02-26 07:05:19 -05:00
begin
self . command_block = target . eval ( block_string )
rescue Pry :: RescuableException
raise CommandError , " Incomplete block definition. "
2012-02-23 09:30:48 -05:00
end
end
private :pass_block
2012-06-27 01:30:00 -04:00
# Run the command with the given `args`.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# This is a public wrapper around `#call` which ensures all preconditions
# are met.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# @param [Array<String>] args The arguments to pass to this command.
# @return [Object] The return value of the `#call` method, or
# {Command::VOID_VALUE}.
2011-12-31 06:50:04 -05:00
def call_safely ( * args )
2011-12-31 07:40:01 -05:00
unless dependencies_met?
2011-12-31 06:50:04 -05:00
gems_needed = Array ( command_options [ :requires_gem ] )
gems_not_installed = gems_needed . select { | g | ! gem_installed? ( g ) }
2012-07-25 17:32:19 -04:00
output . puts " \n The command ' #{ command_name } ' is #{ text . bold ( " unavailable " ) } because it requires the following gems to be installed: #{ ( gems_not_installed . join ( " , " ) ) } "
2011-12-31 06:50:04 -05:00
output . puts " - "
2012-04-01 19:00:59 -04:00
output . puts " Type `install-command #{ command_name } ` to install the required gems and activate this command. "
2011-12-31 07:40:01 -05:00
return void
end
if command_options [ :argument_required ] && args . empty?
2012-04-01 19:00:59 -04:00
raise CommandError , " The command ' #{ command_name } ' requires an argument. "
2011-12-31 06:50:04 -05:00
end
2011-12-31 07:40:01 -05:00
ret = call_with_hooks ( * args )
command_options [ :keep_retval ] ? ret : void
end
# Are all the gems required to use this command installed?
#
# @return Boolean
def dependencies_met?
@dependencies_met || = command_dependencies_met? ( command_options )
2011-12-31 06:50:04 -05:00
end
2012-08-21 01:12:03 -04:00
# Generate completions for this command
#
# @param [String] search The line typed so far
# @return [Array<String>] Completion words
def complete ( search ) ; Bond :: DefaultMission . completions ; end
2011-12-31 07:40:01 -05:00
private
2012-06-27 01:30:00 -04:00
# Run the `#call` method and all the registered hooks.
# @param [Array<String>] args The arguments to `#call`
# @return [Object] The return value from `#call`
2011-12-31 06:50:04 -05:00
def call_with_hooks ( * args )
self . class . hooks [ :before ] . each do | block |
instance_exec ( * args , & block )
end
2012-01-15 15:21:28 -05:00
ret = call ( * args )
2011-12-31 06:50:04 -05:00
self . class . hooks [ :after ] . each do | block |
ret = instance_exec ( * args , & block )
end
2011-12-31 07:40:01 -05:00
ret
2011-12-31 06:50:04 -05:00
end
2012-01-15 18:51:04 -05:00
# Fix the number of arguments we pass to a block to avoid arity warnings.
2012-06-27 01:30:00 -04:00
# @param [Fixnum] arity The arity of the block
# @param [Array] args The arguments to pass
# @return [Array] A (possibly shorter) array of the arguments to pass
2012-01-15 18:51:04 -05:00
def correct_arg_arity ( arity , args )
case
when arity < 0
args
when arity == 0
[ ]
when arity > 0
args . values_at ( * ( 0 .. ( arity - 1 ) ) . to_a )
end
end
2011-12-31 06:50:04 -05:00
end
2011-12-31 07:40:01 -05:00
# A super-class for Commands that are created with a single block.
#
# This class ensures that the block is called with the correct number of arguments
# and the right context.
#
# Create subclasses using {Pry::CommandSet#command}.
2011-12-31 06:50:04 -05:00
class BlockCommand < Command
# backwards compatibility
alias_method :opts , :context
2012-01-08 15:48:54 -05:00
# Call the block that was registered with this command.
2012-06-27 01:30:00 -04:00
# @param [Array<String>] args The arguments passed
# @return [Object] The return value of the block
2011-12-31 06:50:04 -05:00
def call ( * args )
2012-02-26 20:34:05 -05:00
instance_exec ( * correct_arg_arity ( block . arity , args ) , & block )
2011-12-31 06:50:04 -05:00
end
2012-02-26 04:00:50 -05:00
def help
" #{ command_options [ :listing ] . to_s . ljust ( 18 ) } #{ description } "
end
2011-12-31 06:50:04 -05:00
end
2012-08-03 09:29:21 -04:00
# A super-class of Commands with structure.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# This class implements the bare-minimum functionality that a command should
# have, namely a --help switch, and then delegates actual processing to its
# subclasses.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# Create subclasses using {Pry::CommandSet#create_command}, and override the
# `options(opt)` method to set up an instance of Slop, and the `process`
# method to actually run the command. If necessary, you can also override
# `setup` which will be called before `options`, for example to require any
# gems your command needs to run, or to set up state.
2011-12-31 06:50:04 -05:00
class ClassCommand < Command
2011-12-31 10:57:50 -05:00
2012-08-10 17:23:40 -04:00
# The class that couples together subcommands and top-level options (that
2012-08-08 00:08:30 -04:00
# are known as "default" options). The explicitly defined instance methods
# of this class provide the coupling with default options of a
# Slop::Commands instance. An instance of this class delegates all remaining
# methods to an instance of Slop::Commands class.
#
# @example
# # Define Slop commands.
# commands = Slop::Commands.new do |cmd|
# cmd.on :action do
# on :f, :force, "Use force"
# end
#
# cmd.default do
# on :v, :verbose, "Verbose mode"
# end
# end
#
# # Pass Slop commands as an argument to Options class.
# opts = Options.new(Slop::Commands.new)
# opts.default
# # => #<Slop ...>
#
2012-08-10 17:23:40 -04:00
# # Parse subcommands.
2012-08-08 00:08:30 -04:00
# opts.parse %'action --force'
# opts[:action].present?(:force)
# # => true
# opts.present?(:force)
# # => false
#
# # Parse default options.
# opts.parse %'--verbose'
# opts.verbose?
# # => true
# opts[:action].present?(:verbose)
# # => false
# opts.verbose
# # => NoMethodError
class Options < SimpleDelegator
2012-08-10 17:23:40 -04:00
# @param [Slop::Commands] opts The subcommands and options.
2012-08-08 00:08:30 -04:00
# @raise [ArgumentError] if the +opts+ isn't a kind of Slop::Commands.
# instance.
def initialize ( opts )
unless opts . kind_of? ( Slop :: Commands )
raise ArgumentError , " Expected an instance of Slop::Command, not #{ opts . class } one "
end
super
end
# Fetch the instance of Slop tied to a command or fetch an options
# argument value.
#
2012-08-10 17:23:40 -04:00
# If the +key+ doesn't correspond to any of the subcommands, the method
2012-08-08 00:08:30 -04:00
# tries to find the same +key+ in the list of default options.
#
# @example
2012-08-10 17:23:40 -04:00
# # A subcommand example.
2012-08-08 00:08:30 -04:00
# opts = Options.new(commands)
# opts.parse %w'download video.ogv'
#
# opts[:download]
# # => #<Slop ...>
#
# # A default option example.
# opts = Options.new(commands)
# opts.parse %w'--host=localhost download video.ogv'
# opts[:host]
# # => true
#
2012-08-10 17:23:40 -04:00
# @param [String, Symbol] key The subcommand name or the default option.
2012-08-08 00:08:30 -04:00
# @return [Slop, Boolean, nil] Either instance of Slop tied to the
# command, if any; or `true`, if the default option has the given +key+;
# or nil, if can't find the +key+.
# @note The method never returns `false`.
def [] ( key )
2012-11-21 08:26:11 -05:00
self . get ( key ) || default . get ( key )
2012-08-08 00:08:30 -04:00
end
2012-11-26 11:07:32 -05:00
# Check for default options presence.
2012-08-08 00:08:30 -04:00
#
# @param [String, Symbol] keys The list of keys to check.
# @return [Boolean] Whether all of the +keys+ are present in the parsed
# arguments.
def present? ( * keys )
default . present? ( * keys )
end
2012-11-26 11:07:32 -05:00
# Check for a command presence.
#
# @example
# opts.parse %w'install'
# opts.command?(:install)
# # => true
# opts.command?(:list)
# # => false
#
# @param [Symbol, String] name The name of the command to be checked
# @return [Boolean] `true` if the given +name+ is present in the parsed
# arguments
def command? ( name )
__getobj__ . present? ( name )
end
2012-08-08 00:08:30 -04:00
# Convenience method for {#present?}.
#
# @example
# opts.parse %w'--verbose'
# opts.verbose?
# # => true
# opts.terse?
# # => false
#
# @return [Boolean, void] On condition of +method_name+ ends with a
# question mark returns `true`, if the _default option_ is present (and
# `false`, if not). Otherwise, calls `super`.
def method_missing ( method_name , * args , & block )
name = method_name . to_s
if name . end_with? ( " ? " )
present? ( name . chop )
else
super
end
end
private
# @return [Slop] The instance of Slop representing default options.
def default
__getobj__ [ :default ]
end
end
2011-12-31 06:50:04 -05:00
attr_accessor :opts
attr_accessor :args
2012-06-27 01:30:00 -04:00
# Set up `opts` and `args`, and then call `process`.
2011-12-31 07:40:01 -05:00
#
2012-08-08 00:08:30 -04:00
# This method will display help if necessary.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# @param [Array<String>] args The arguments passed
# @return [Object] The return value of `process` or VOID_VALUE
2011-12-31 06:50:04 -05:00
def call ( * args )
setup
2012-08-08 00:08:30 -04:00
self . opts = Options . new ( slop )
2011-12-31 06:50:04 -05:00
self . args = self . opts . parse! ( args )
if opts . present? ( :help )
output . puts slop . help
2011-12-31 07:40:01 -05:00
void
2011-12-31 06:50:04 -05:00
else
2012-02-26 20:34:05 -05:00
process ( * correct_arg_arity ( method ( :process ) . arity , args ) )
2011-12-31 06:50:04 -05:00
end
end
2011-12-31 09:40:44 -05:00
# Return the help generated by Slop for this command.
def help
slop . help
end
2012-08-10 17:23:40 -04:00
# Return an instance of Slop::Commands that can parse either subcommands
2012-08-08 00:08:30 -04:00
# or the options that this command accepts.
2011-12-31 06:50:04 -05:00
def slop
2012-08-08 00:08:30 -04:00
Slop :: Commands . new do | cmd |
2012-08-10 17:23:40 -04:00
subcommands ( cmd )
2012-11-26 11:07:32 -05:00
cmd . default do | opt |
opt . banner ( unindent ( self . class . banner ) )
options ( opt )
opt . on ( :h , :help , " Show this message. " )
end
2012-08-08 00:08:30 -04:00
end
2011-12-31 06:50:04 -05:00
end
2011-12-31 07:40:01 -05:00
2012-08-21 01:12:03 -04:00
# Generate shell completions
# @param [String] search The line typed so far
# @return [Array<String>] the words to complete
def complete ( search )
2012-11-23 07:18:46 -05:00
slop [ :default ] . map do | opt |
2012-11-14 04:52:21 -05:00
[ opt . long && " -- #{ opt . long } " || opt . short && " - #{ opt . short } " ]
2012-08-21 01:12:03 -04:00
end . flatten ( 1 ) . compact + super
end
2012-08-08 00:08:30 -04:00
# A method called just before `options(opt)` as part of `call`.
2011-12-31 07:40:01 -05:00
#
2012-08-08 00:08:30 -04:00
# This method can be used to set up any context your command needs to run,
# for example requiring gems, or setting default values for options.
2011-12-31 07:40:01 -05:00
#
# @example
2012-08-08 00:08:30 -04:00
# def setup
2011-12-31 07:40:01 -05:00
# require 'gist'
# @action = :method
# end
def setup ; end
2012-08-10 17:23:40 -04:00
# A method to setup Slop::Commands so it can parse the subcommands your
2012-08-08 00:08:30 -04:00
# command expects. If you need to set up default values, use `setup`
# instead.
#
# @example
2012-08-10 17:23:40 -04:00
# def subcommands(cmd)
2012-08-08 00:08:30 -04:00
# cmd.on(:d, :download, "Download a content from a server.") do
# @action = :download
# end
# end
2012-08-10 17:23:40 -04:00
def subcommands ( cmd ) ; end
2012-08-08 00:08:30 -04:00
# A method to setup Slop so it can parse the options your command expects.
2011-12-31 07:40:01 -05:00
#
2012-08-08 00:08:30 -04:00
# @note Please don't do anything side-effecty in the main part of this
# method, as it may be called by Pry at any time for introspection reasons.
# If you need to set up default values, use `setup` instead.
2011-12-31 07:40:01 -05:00
#
# @example
# def options(opt)
# opt.banner "Gists methods or classes"
# opt.on(:c, :class, "gist a class") do
# @action = :class
# end
# end
def options ( opt ) ; end
# The actual body of your command should go here.
#
2012-06-27 01:30:00 -04:00
# The `opts` mehod can be called to get the options that Slop has passed,
# and `args` gives the remaining, unparsed arguments.
2011-12-31 07:40:01 -05:00
#
2012-06-27 01:30:00 -04:00
# The return value of this method is discarded unless the command was
# created with `:keep_retval => true`, in which case it is returned to the
# repl.
2011-12-31 07:40:01 -05:00
#
# @example
# def process
# if opts.present?(:class)
# gist_class
# else
# gist_method
# end
# end
2012-04-01 19:00:59 -04:00
def process ; raise CommandError , " command ' #{ command_name } ' not implemented " end
2011-12-31 06:50:04 -05:00
end
end