/usr/lib/ruby/vendor_ruby/pry/command_set.rb is in pry 0.10.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | class Pry
class NoCommandError < StandardError
def initialize(match, owner)
super "Command '#{match}' not found in command set #{owner}"
end
end
# This class is used to create sets of commands. Commands can be imported from
# different sets, aliased, removed, etc.
class CommandSet
include Enumerable
include Pry::Helpers::BaseHelpers
attr_reader :helper_module
# @param [Array<Commandset>] imported_sets
# Sets which will be imported automatically
# @yield Optional block run to define commands
def initialize(*imported_sets, &block)
@commands = {}
@helper_module = Module.new
import(*imported_sets)
instance_eval(&block) if block
end
# Defines a new Pry command.
# @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
# of the block for return of `command` or just to return `nil`
# (the default).
# @option options [Array<String>] :requires_gem Whether the command has
# any gem dependencies, if it does and dependencies not met then
# command is disabled and a stub proc giving instructions to
# install command is provided.
# @option options [Boolean] :interpolate Whether string #{} based
# interpolation is applied to the command arguments before
# 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 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.
# @option options [Boolean] :shellwords Whether the command's arguments
# should be split using Shellwords instead of just split on spaces.
# Defaults to true.
# @yield The action to perform. The parameters in the block
# determines the parameters the command will receive. All
# parameters passed into the block will be strings. Successive
# command parameters are separated by whitespace at the Pry prompt.
# @example
# MyCommands = Pry::CommandSet.new do
# command "greet", "Greet somebody" do |name|
# puts "Good afternoon #{name.capitalize}!"
# end
# end
#
# # From pry:
# # pry(main)> _pry_.commands = MyCommands
# # pry(main)> greet john
# # Good afternoon John!
# # pry(main)> help greet
# # Greet somebody
# @example Regexp command
# MyCommands = Pry::CommandSet.new do
# command /number-(\d+)/, "number-N regex command", :listing => "number" do |num, name|
# puts "hello #{name}, nice number: #{num}"
# end
# end
#
# # From pry:
# # pry(main)> _pry_.commands = MyCommands
# # pry(main)> number-10 john
# # hello john, nice number: 10
# # pry(main)> help number
# # number-N regex command
def block_command(match, description="No description.", options={}, &block)
description, options = ["No description.", description] if description.is_a?(Hash)
options = Pry::Command.default_options(match).merge!(options)
@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] 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}
# @yield The class body's definition.
#
# @example
# Pry::Commands.create_command "echo", "echo's the input", :shellwords => false do
# def options(opt)
# opt.banner "Usage: echo [-u | -d] <string to echo>"
# opt.on :u, :upcase, "ensure the output is all upper-case"
# opt.on :d, :downcase, "ensure the output is all lower-case"
# end
#
# def process
# raise Pry::CommandError, "-u and -d makes no sense" if opts.present?(:u) && opts.present?(:d)
# result = args.join(" ")
# result.downcase! if opts.present?(:downcase)
# result.upcase! if opts.present?(:upcase)
# output.puts result
# end
# end
#
def create_command(match, description="No description.", options={}, &block)
description, options = ["No description.", description] if description.is_a?(Hash)
options = Pry::Command.default_options(match).merge!(options)
@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] search The match or listing of the command.
# @yield The block to be run before the command.
# @example Display parameter before invoking command
# Pry.config.commands.before_command("whereami") do |n|
# output.puts "parameter passed was #{n}"
# end
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] 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.config.commands.after_command("whereami") do |n|
# output.puts "command complete!"
# end
def after_command(search, &block)
cmd = find_command_by_match_or_listing(search)
cmd.hooks[:after] << block
end
def each(&block)
@commands.each(&block)
end
# Removes some commands from the set
# @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
# Imports all the commands from one or more sets.
# @param [Array<CommandSet>] sets Command sets, all of the commands of which
# will be imported.
# @return [Pry::CommandSet] Returns the reciever (a command set).
def import(*sets)
sets.each do |set|
@commands.merge! set.to_hash
helper_module.send :include, set.helper_module
end
self
end
# Imports some commands from a set
# @param [CommandSet] set Set to import commands from
# @param [Array<String>] matches Commands to import
# @return [Pry::CommandSet] Returns the reciever (a command set).
def import_from(set, *matches)
helper_module.send :include, set.helper_module
matches.each do |match|
cmd = set.find_command_by_match_or_listing(match)
@commands[cmd.match] = cmd
end
self
end
# @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_match_or_listing(match_or_listing)
cmd = (@commands[match_or_listing] ||
Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!"
end
# Aliases a command
# @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,
# accepts the same as the `command` method, but also allows the
# command description to be passed this way too as `:desc`
# @example Creating an alias for `ls -M`
# 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(match, action, options={})
cmd = find_command(action) or fail "Command: `#{action}` not found"
original_options = cmd.options.dup
options = original_options.merge!({
:desc => "Alias for `#{action}`",
:listing => match
}).merge!(options)
# ensure default description is used if desc is nil
desc = options.delete(:desc).to_s
c = block_command match, desc, options do |*args|
run action, *args
end
c.class_eval do
define_method(:complete) do |input|
cmd.new(context).complete(input)
end
end
c.group "Aliases"
c
end
# Rename a command. Accepts either match or listing for the search.
#
# @param [String, Regexp] new_match 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_match, search, options={})
cmd = find_command_by_match_or_listing(search)
options = {
:listing => new_match,
:description => cmd.description
}.merge!(options)
@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
def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command)
create_command name_of_disabled_command do
match matcher
description ""
define_method(:process) do
output.puts "DISABLED: #{message}"
end
end
end
# Sets or gets the description for a command (replacing the old
# description). Returns current description if no description
# parameter provided.
# @param [String, Regexp] search The command match.
# @param [String?] description (nil) The command description.
# @example Setting
# MyCommands = Pry::CommandSet.new do
# desc "help", "help description"
# end
# @example Getting
# Pry.config.commands.desc "amend-line"
def desc(search, description=nil)
cmd = find_command_by_match_or_listing(search)
return cmd.description if !description
cmd.description = description
end
# Defines helpers methods for this command sets.
# Those helpers are only defined in this command set.
#
# @yield A block defining helper methods
# @example
# helpers do
# def hello
# puts "Hello!"
# end
#
# include OtherModule
# end
def helpers(&block)
helper_module.class_eval(&block)
end
# @return [Array]
# The list of commands provided by the command set.
def list_commands
@commands.keys
end
alias_method :keys, :list_commands
def to_hash
@commands.dup
end
alias_method :to_h, :to_hash
# Find a command that matches the given line
# @param [String] pattern The line that might be a command invocation
# @return [Pry::Command, nil]
def [](pattern)
@commands.values.select do |command|
command.matches?(pattern)
end.sort_by do |command|
command.match_score(pattern)
end.last
end
alias_method :find_command, :[]
#
# Re-assign the command found at _pattern_ with _command_.
#
# @param [Regexp, String] pattern
# The command to add or replace(found at _pattern_).
#
# @param [Pry::Command] command
# The command to add.
#
# @return [Pry::Command]
# Returns the new command (matched with "pattern".)
#
# @example
# Pry.config.commands["help"] = MyHelpCommand
#
def []=(pattern, command)
if command.equal?(nil)
return @commands.delete(pattern)
end
unless Class === command && command < Pry::Command
raise TypeError, "command is not a subclass of Pry::Command"
end
bind_command_to_pattern = pattern != command.match
if bind_command_to_pattern
command_copy = command.dup
command_copy.match = pattern
@commands[pattern] = command_copy
else
@commands[pattern] = command
end
end
#
# Add a command to set.
#
# @param [Command] command
# a subclass of Pry::Command.
#
def add_command(command)
self[command.match] = command
end
# Find the command that the user might be trying to refer to.
# @param [String] search The user's search.
# @return [Pry::Command?]
def find_command_for_help(search)
find_command(search) || (begin
find_command_by_match_or_listing(search)
rescue ArgumentError
nil
end)
end
# Is the given line a command invocation?
# @param [String] val
# @return [Boolean]
def valid_command?(val)
!!find_command(val)
end
# Process the given line to see whether it needs executing as a command.
# @param [String] val The line to execute
# @param [Hash] context The context to execute the commands with
# @return [CommandSet::Result]
def process_line(val, context={})
if command = find_command(val)
context = context.merge(:command_set => self)
retval = command.new(context).process_line(val)
Result.new(true, retval)
else
Result.new(false)
end
end
# @private (used for testing)
def run_command(context, match, *args)
command = @commands[match] or raise NoCommandError.new(match, self)
command.new(context).call_safely(*args)
end
# Generate completions for the user's search.
# @param [String] search The line to search for
# @param [Hash] context The context to create the command with
# @return [Array<String>]
def complete(search, context={})
if command = find_command(search)
command.new(context).complete(search)
else
@commands.keys.select do |key|
String === key && key.start_with?(search)
end.map{ |key| key + " " }
end
end
end
# Wraps the return result of process_commands, indicates if the
# result IS a command and what kind of command (e.g void)
class Result
attr_reader :retval
def initialize(is_command, retval = nil)
@is_command, @retval = is_command, retval
end
# Is the result a command?
# @return [Boolean]
def command?
@is_command
end
# Is the result a command and if it is, is it a void command?
# (one that does not return a value)
# @return [Boolean]
def void_command?
retval == Command::VOID_VALUE
end
end
end
|