Class: Pry::Command

Inherits:
Object show all
Includes:
Helpers::BaseHelpers, Helpers::CommandHelpers
Defined in:
lib/pry/command.rb

Overview

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.

Direct Known Subclasses

BlockCommand, ClassCommand

Constant Summary

VOID_VALUE =

represents a void return value for a command

Object.new

Class Attribute Summary (collapse)

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Helpers::CommandHelpers

#absolute_index_number, absolute_index_number, absolute_index_range, #absolute_index_range, blocking_flag_for_editor, #blocking_flag_for_editor, command_error, #command_error, editor_name, #editor_name, file_and_line_from_binding, #file_and_line_from_binding, #get_method_or_raise, get_method_or_raise, #invoke_editor, invoke_editor, make_header, #make_header, one_index_number, #one_index_number, one_index_range, #one_index_range, one_index_range_or_number, #one_index_range_or_number, #render_output, render_output, #restrict_to_lines, restrict_to_lines, #start_line_syntax_for_editor, start_line_syntax_for_editor, #temp_file, temp_file, #unindent, unindent

Methods included from Helpers::OptionsHelpers

method_object, #method_object, method_options, #method_options

Methods included from Helpers::BaseHelpers

colorize_code, #colorize_code, command_dependencies_met?, #command_dependencies_met?, #create_command_stub, create_command_stub, #find_command, find_command, #gem_installed?, gem_installed?, #heading, heading, highlight, #highlight, jruby?, #jruby?, #lesspipe, lesspipe, #mri_18?, mri_18?, mri_19?, #mri_19?, #not_a_real_file?, not_a_real_file?, #page_size, page_size, #rbx?, rbx?, set_file_and_dir_locals, #set_file_and_dir_locals, silence_warnings, #silence_warnings, simple_pager, #simple_pager, stagger_output, #stagger_output, #stub_proc, stub_proc, #use_ansi_codes?, use_ansi_codes?, #windows?, windows?

Constructor Details

- (Command) initialize(context = {})

Instantiate a command, in preparation for calling it.

Parameters:

  • Hash

    context The runtime context to use with this command.



219
220
221
222
223
224
225
226
# File 'lib/pry/command.rb', line 219

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

Class Attribute Details

+ (Object) block



49
50
51
# File 'lib/pry/command.rb', line 49

def block
  @block || instance_method(:process) && instance_method(:process)
end

+ (Object) command_options(arg = nil)

Define or get the command’s options



34
35
36
37
38
# File 'lib/pry/command.rb', line 34

def command_options(arg=nil)
  @command_options ||= {}
  @command_options.merge!(arg) if arg
  @command_options
end

+ (Object) description(arg = nil)

Define or get the command’s description



28
29
30
31
# File 'lib/pry/command.rb', line 28

def description(arg=nil)
  @description = arg if arg
  @description
end

+ (Object) match(arg = nil)



22
23
24
25
# File 'lib/pry/command.rb', line 22

def match(arg=nil)
  @match = arg if arg
  @match
end

Instance Attribute Details

- (Object) _pry_

Returns the value of attribute pry



176
177
178
# File 'lib/pry/command.rb', line 176

def _pry_
  @_pry_
end

- (Object) arg_string

Returns the value of attribute arg_string



173
174
175
# File 'lib/pry/command.rb', line 173

def arg_string
  @arg_string
end

- (Object) captures

Returns the value of attribute captures



171
172
173
# File 'lib/pry/command.rb', line 171

def captures
  @captures
end

- (Object) command_block

The block we pass into a command so long as :takes_block is not equal to false

Examples:

my-command | do
  puts "block content"
end


184
185
186
# File 'lib/pry/command.rb', line 184

def command_block
  @command_block
end

- (Object) command_set

Returns the value of attribute command_set



175
176
177
# File 'lib/pry/command.rb', line 175

def command_set
  @command_set
end

- (Object) context

Returns the value of attribute context



174
175
176
# File 'lib/pry/command.rb', line 174

def context
  @context
end

- (Object) eval_string

Returns the value of attribute eval_string



172
173
174
# File 'lib/pry/command.rb', line 172

def eval_string
  @eval_string
end

- (Object) output

Properties of one execution of a command (passed by Pry#run_command as a hash of context and expanded in #initialize



169
170
171
# File 'lib/pry/command.rb', line 169

def output
  @output
end

- (Object) target

Returns the value of attribute target



170
171
172
# File 'lib/pry/command.rb', line 170

def target
  @target
end

Class Method Details

Define or get the command’s banner



44
45
46
47
# File 'lib/pry/command.rb', line 44

def banner(arg=nil)
  @banner = arg if arg
  @banner || description
end

+ (Object) command_regex



129
130
131
132
133
134
135
# File 'lib/pry/command.rb', line 129

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

+ (Object) convert_to_regex(obj)



137
138
139
140
141
142
143
144
# File 'lib/pry/command.rb', line 137

def convert_to_regex(obj)
  case obj
  when String
    Regexp.escape(obj)
  else
    obj
  end
end

+ (Object) group(name = nil)

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.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/pry/command.rb', line 149

def group(name=nil)
  @group = name if name
  @group ||=(
    case Pry::Method(block).source_file
    when %r{/pry/.*_commands/(.*).rb}
      $1.capitalize.gsub(/_/, " ")
    when %r{(pry-[\w]+)-([\d\.]+)}
      name, version = $1, $2
      "#{name.to_s} (v#{version.to_s})"
    when /pryrc/
      "~/.pryrc"
    else
      "(other)"
    end
  )
end

+ (Object) hooks

Store hooks to be run before or after the command body.

See Also:

  • {Pry{Pry::CommandSet{Pry::CommandSet#before_command}
  • {Pry{Pry::CommandSet{Pry::CommandSet#after_command}


125
126
127
# File 'lib/pry/command.rb', line 125

def hooks
  @hooks ||= {:before => [], :after => []}
end

+ (Object) inspect



66
67
68
# File 'lib/pry/command.rb', line 66

def inspect
  name
end

+ (Object) match_score(val)

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.

Examples:

/\.(.*)/.match_score(".foo") #=> 1
/\.*(.*)/.match_score("...foo") #=> 3
'hi'.match_score("hi there") #=> 2

Parameters:

  • String

    a line input at the REPL

Returns:

  • Fixnum



114
115
116
117
118
119
120
# File 'lib/pry/command.rb', line 114

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

+ (Boolean) matches?(val)

Should this command be called for the given line?

Parameters:

  • String

    a line input at the REPL

Returns:

  • (Boolean)

    Boolean



94
95
96
# File 'lib/pry/command.rb', line 94

def matches?(val)
  command_regex =~ val
end

+ (Object) name



63
64
65
# File 'lib/pry/command.rb', line 63

def name
  super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super
end

+ (Object) options

Define or get the command’s options backward compatibility



40
41
42
43
44
# File 'lib/pry/command.rb', line 40

def command_options(arg=nil)
  @command_options ||= {}
  @command_options.merge!(arg) if arg
  @command_options
end

+ (Object) subclass(match, description, options, helpers, &block)

Create a new command with the given properties.

Parameters:

  • String/Regex

    match the thing that triggers this command

  • String

    description the description to appear in help

  • Hash

    options behavioural options (@see Pry::CommandSet#command)

  • Module

    helpers a module of helper functions to be included.

  • Proc

    &block (optional, a block, used for BlockCommands)



80
81
82
83
84
85
86
87
88
# File 'lib/pry/command.rb', line 80

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

Instance Method Details

- (Object) block



58
# File 'lib/pry/command.rb', line 58

def block; self.class.block; end

- (Object) call_safely(*args)

Run the command with the given args.

This is a public wrapper around #call which ensures all preconditions are met.

Parameters:

  • * (String)

    the arguments to pass to this command.

Returns:

  • Object the return value of the #call method, or Command::VOID_VALUE



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/pry/command.rb', line 347

def call_safely(*args)
  unless dependencies_met?
    gems_needed = Array(command_options[:requires_gem])
    gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
    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 #{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

- (Object) call_with_hooks(*args) (private)

Run the #call method and all the registered hooks.

Parameters:

  • *String

    the arguments to #call

Returns:

  • Object the return value from #call



378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/pry/command.rb', line 378

def call_with_hooks(*args)
  self.class.hooks[:before].each do |block|
    instance_exec(*args, &block)
  end

  ret = call(*args)

  self.class.hooks[:after].each do |block|
    ret = instance_exec(*args, &block)
  end

  ret
end

- (Object) check_for_command_collision(command_match, arg_string)

Display a warning if a command collides with a local/method in the current scope.

Parameters:

  • command_name_match (String)

    The name of the colliding command.

  • target (Binding)

    The current binding context.



249
250
251
252
253
254
255
256
257
258
# File 'lib/pry/command.rb', line 249

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_match}'," +
                                                      "which conflicts with a #{collision_type}.\n\n"
  end
rescue Pry::RescuableException
end

- (Object) command_name



60
# File 'lib/pry/command.rb', line 60

def command_name; command_options[:listing]; end

- (Object) command_options



59
# File 'lib/pry/command.rb', line 59

def command_options; self.class.options; end

- (Object) commands



200
201
202
# File 'lib/pry/command.rb', line 200

def commands
  command_set.commands
end

- (Object) correct_arg_arity(arity, args) (private)

Fix the number of arguments we pass to a block to avoid arity warnings.

Parameters:

  • Number

    the arity of the block

  • Array

    the arguments to pass

Returns:

  • Array a (possibly shorter) array of the arguments to pass



397
398
399
400
401
402
403
404
405
406
# File 'lib/pry/command.rb', line 397

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

- (Boolean) dependencies_met?

Are all the gems required to use this command installed?

Returns:

  • (Boolean)

    Boolean



368
369
370
# File 'lib/pry/command.rb', line 368

def dependencies_met?
  @dependencies_met ||= command_dependencies_met?(command_options)
end

- (Object) description



57
# File 'lib/pry/command.rb', line 57

def description; self.class.description; end

- (String) interpolate_string(str)

Revaluate the string (str) and perform interpolation.

Parameters:

  • str (String)

    The string to reevaluate with interpolation.

Returns:

  • (String)

    The reevaluated string with interpolations applied (if any).



236
237
238
239
240
241
242
243
# File 'lib/pry/command.rb', line 236

def interpolate_string(str)
  dumped_str = str.dump
  if dumped_str.gsub!(/\\\#\{/, '#{')
    target.eval(dumped_str)
  else
    str
  end
end

- (Object) match



56
# File 'lib/pry/command.rb', line 56

def match; self.class.match; end

- (Object) name

Make those properties accessible to instances



55
# File 'lib/pry/command.rb', line 55

def name; self.class.name; end

- (Object) pass_block(arg_string) (private)

Pass a block argument to a command.

Parameters:

  • arg_string (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 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. Note that if we find the ‘| do’ or ‘| {‘ we delete this and the elements following it from arg_string.



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/pry/command.rb', line 318

def pass_block(arg_string)
  block_index = arg_string.rindex(/\| *(?:do|\{)/)

  return if !block_index

  block_init_string = arg_string.slice!(block_index..-1)[1..-1]
  prime_string = "proc #{block_init_string}\n"

  if !Pry::Code.complete_expression?(prime_string)
    block_string = _pry_.r(target, prime_string)
  else
    block_string = prime_string
  end

  begin
    self.command_block = target.eval(block_string)
  rescue Pry::RescuableException
    raise CommandError, "Incomplete block definition."
  end
end

- (Object) process_line(line)

Process a line that Command.matches? this command.

Parameters:

  • String

    the line to process

Returns:

  • Object or Command::VOID_VALUE



300
301
302
303
304
305
306
307
308
309
# File 'lib/pry/command.rb', line 300

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

- (Object) run(command_string, *args)

Run a command from another command.

Examples:

run "show-input"
run ".ls"
run "amend-line",  "5", 'puts "hello world"'

Parameters:

  • command_string (String)

    The string that invokes the command

  • args (Array)

    Further arguments to pass to the command



195
196
197
198
# File 'lib/pry/command.rb', line 195

def run(command_string, *args)
  complete_string = "#{command_string} #{args.join(" ")}".rstrip
  command_set.process_line(complete_string, context)
end

- (Object) target_self

The value of self inside the target binding.



229
# File 'lib/pry/command.rb', line 229

def target_self; target.eval('self'); end

- (Object) text



204
205
206
# File 'lib/pry/command.rb', line 204

def text
  Pry::Helpers::Text
end

- (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) tokenize(val)

Extract necessary information from a line that Command.matches? this command.

]

Parameters:

  • String

    the line of input

Returns:

  • (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)

    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

Raises:



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
# File 'lib/pry/command.rb', line 269

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

- (Object) void



208
209
210
# File 'lib/pry/command.rb', line 208

def void
  VOID_VALUE
end