Class: Pry::Command
- 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
Constant Summary collapse
- VOID_VALUE =
represents a void return value for a command
Object.new
Class Attribute Summary collapse
- .block ⇒ Object
-
.command_options(arg = nil) ⇒ Object
Define or get the command's options.
-
.description(arg = nil) ⇒ Object
Define or get the command's description.
- .match(arg = nil) ⇒ Object
Instance Attribute Summary collapse
-
#_pry_ ⇒ Object
Returns the value of attribute pry.
-
#arg_string ⇒ Object
Returns the value of attribute arg_string.
-
#captures ⇒ Object
Returns the value of attribute captures.
-
#command_block ⇒ Object
The block we pass into a command so long as
:takes_blockis not equal tofalse. -
#command_set ⇒ Object
Returns the value of attribute command_set.
-
#context ⇒ Object
Returns the value of attribute context.
-
#eval_string ⇒ Object
Returns the value of attribute eval_string.
-
#output ⇒ Object
Properties of one execution of a command (passed by #run_command as a hash of context and expanded in
#initialize. -
#target ⇒ Object
Returns the value of attribute target.
Class Method Summary collapse
-
.banner(arg = nil) ⇒ Object
Define or get the command's banner.
- .command_regex ⇒ Object
- .convert_to_regex(obj) ⇒ Object
-
.group(name = nil) ⇒ Object
The group in which the command should be displayed in "help" output.
-
.hooks ⇒ Object
Store hooks to be run before or after the command body.
- .inspect ⇒ Object
-
.match_score(val) ⇒ Fixnum
How well does this command match the given line?.
-
.matches?(val) ⇒ Boolean
Should this command be called for the given line?.
- .name ⇒ Object
-
.options ⇒ Object
Define or get the command's options backward compatibility.
-
.subclass(match, description, options, helpers) { ... } ⇒ Class
Create a new command with the given properties.
Instance Method Summary collapse
- #block ⇒ Object
-
#call_safely(*args) ⇒ Object
Run the command with the given
args. -
#call_with_hooks(*args) ⇒ Object
private
Run the
#callmethod and all the registered hooks. -
#check_for_command_collision(command_match, arg_string) ⇒ Object
Display a warning if a command collides with a local/method in the current scope.
- #command_name ⇒ Object
- #command_options ⇒ Object
- #commands ⇒ Object
-
#correct_arg_arity(arity, args) ⇒ Array
private
Fix the number of arguments we pass to a block to avoid arity warnings.
-
#dependencies_met? ⇒ Boolean
Are all the gems required to use this command installed?.
- #description ⇒ Object
-
#initialize(context = {}) ⇒ Command
constructor
Instantiate a command, in preparation for calling it.
-
#interpolate_string(str) ⇒ String
Revaluate the string (str) and perform interpolation.
- #match ⇒ Object
-
#name ⇒ Object
Make those properties accessible to instances.
-
#pass_block(arg_string) ⇒ Object
private
Pass a block argument to a command.
-
#process_line(line) ⇒ Object, Command::VOID_VALUE
Process a line that Command.matches? this command.
-
#run(command_string, *args) ⇒ Object
Run a command from another command.
-
#state ⇒ Hash
Pry commands can store arbitrary state here.
-
#target_self ⇒ Object
The value of
selfinside thetargetbinding. - #text ⇒ Object
-
#tokenize(val) ⇒ Array
Extract necessary information from a line that Command.matches? this command.
- #void ⇒ Object
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, #internal_binding?, internal_binding?, #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?, #windows_ansi?, windows_ansi?
Constructor Details
#initialize(context = {}) ⇒ Command
Instantiate a command, in preparation for calling it.
215 216 217 218 219 220 221 222 |
# File 'lib/pry/command.rb', line 215 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
.block ⇒ Object
49 50 51 |
# File 'lib/pry/command.rb', line 49 def block @block || instance_method(:process) && instance_method(:process) end |
.command_options(arg = nil) ⇒ Object
Define or get the command's options
34 35 36 37 38 |
# File 'lib/pry/command.rb', line 34 def (arg=nil) ||= {} .merge!(arg) if arg end |
.description(arg = nil) ⇒ Object
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 |
.match(arg = nil) ⇒ Object
22 23 24 25 |
# File 'lib/pry/command.rb', line 22 def match(arg=nil) @match = arg if arg @match end |
Instance Attribute Details
#_pry_ ⇒ Object
Returns the value of attribute pry.
173 174 175 |
# File 'lib/pry/command.rb', line 173 def _pry_ @_pry_ end |
#arg_string ⇒ Object
Returns the value of attribute arg_string.
170 171 172 |
# File 'lib/pry/command.rb', line 170 def arg_string @arg_string end |
#captures ⇒ Object
Returns the value of attribute captures.
168 169 170 |
# File 'lib/pry/command.rb', line 168 def captures @captures end |
#command_block ⇒ Object
The block we pass into a command so long as :takes_block is
not equal to false
181 182 183 |
# File 'lib/pry/command.rb', line 181 def command_block @command_block end |
#command_set ⇒ Object
Returns the value of attribute command_set.
172 173 174 |
# File 'lib/pry/command.rb', line 172 def command_set @command_set end |
#context ⇒ Object
Returns the value of attribute context.
171 172 173 |
# File 'lib/pry/command.rb', line 171 def context @context end |
#eval_string ⇒ Object
Returns the value of attribute eval_string.
169 170 171 |
# File 'lib/pry/command.rb', line 169 def eval_string @eval_string end |
#output ⇒ Object
Properties of one execution of a command (passed by Pry#run_command as a hash of
context and expanded in #initialize
166 167 168 |
# File 'lib/pry/command.rb', line 166 def output @output end |
#target ⇒ Object
Returns the value of attribute target.
167 168 169 |
# File 'lib/pry/command.rb', line 167 def target @target end |
Class Method Details
.banner(arg = nil) ⇒ Object
Define or get the command's banner
44 45 46 47 |
# File 'lib/pry/command.rb', line 44 def (arg=nil) = arg if arg || description end |
.command_regex ⇒ Object
125 126 127 128 129 130 131 |
# File 'lib/pry/command.rb', line 125 def command_regex pr = defined?(Pry.config.command_prefix) ? Pry.config.command_prefix : "" prefix = convert_to_regex(pr) prefix = "(?:#{prefix})?" unless [:use_prefix] /^#{prefix}#{convert_to_regex(match)}(?!\S)/ end |
.convert_to_regex(obj) ⇒ Object
133 134 135 136 137 138 139 140 |
# File 'lib/pry/command.rb', line 133 def convert_to_regex(obj) case obj when String Regexp.escape(obj) else obj end end |
.group(name = nil) ⇒ Object
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.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/pry/command.rb', line 145 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 |
.hooks ⇒ Object
Store hooks to be run before or after the command body.
121 122 123 |
# File 'lib/pry/command.rb', line 121 def hooks @hooks ||= {:before => [], :after => []} end |
.inspect ⇒ Object
66 67 68 |
# File 'lib/pry/command.rb', line 66 def inspect name end |
.match_score(val) ⇒ Fixnum
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.
110 111 112 113 114 115 116 |
# File 'lib/pry/command.rb', line 110 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 |
.matches?(val) ⇒ Boolean
Should this command be called for the given line?
90 91 92 |
# File 'lib/pry/command.rb', line 90 def matches?(val) command_regex =~ val end |
.name ⇒ Object
63 64 65 |
# File 'lib/pry/command.rb', line 63 def name super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super end |
.options ⇒ Object
Define or get the command's options backward compatibility
40 41 42 43 44 |
# File 'lib/pry/command.rb', line 40 def (arg=nil) ||= {} .merge!(arg) if arg end |
.subclass(match, description, options, helpers) { ... } ⇒ Class
Create a new command with the given properties.
77 78 79 80 81 82 83 84 85 |
# File 'lib/pry/command.rb', line 77 def subclass(match, description, , helpers, &block) klass = Class.new(self) klass.send(:include, helpers) klass.match = match klass.description = description klass. = klass.block = block klass end |
Instance Method Details
#block ⇒ Object
58 |
# File 'lib/pry/command.rb', line 58 def block; self.class.block; end |
#call_safely(*args) ⇒ Object
Run the command with the given args.
This is a public wrapper around #call which ensures all preconditions
are met.
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/pry/command.rb', line 358 def call_safely(*args) unless dependencies_met? gems_needed = Array([: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 [:argument_required] && args.empty? raise CommandError, "The command '#{command_name}' requires an argument." end ret = call_with_hooks(*args) [:keep_retval] ? ret : void end |
#call_with_hooks(*args) ⇒ Object (private)
Run the #call method and all the registered hooks.
388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/pry/command.rb', line 388 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 |
#check_for_command_collision(command_match, arg_string) ⇒ Object
Display a warning if a command collides with a local/method in the current scope.
254 255 256 257 258 259 260 261 262 263 |
# File 'lib/pry/command.rb', line 254 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 |
#command_name ⇒ Object
60 |
# File 'lib/pry/command.rb', line 60 def command_name; [:listing]; end |
#command_options ⇒ Object
59 |
# File 'lib/pry/command.rb', line 59 def ; self.class.; end |
#commands ⇒ Object
197 198 199 |
# File 'lib/pry/command.rb', line 197 def commands command_set.commands end |
#correct_arg_arity(arity, args) ⇒ Array (private)
Fix the number of arguments we pass to a block to avoid arity warnings.
406 407 408 409 410 411 412 413 414 415 |
# File 'lib/pry/command.rb', line 406 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 |
#dependencies_met? ⇒ Boolean
Are all the gems required to use this command installed?
379 380 381 |
# File 'lib/pry/command.rb', line 379 def dependencies_met? @dependencies_met ||= command_dependencies_met?() end |
#description ⇒ Object
57 |
# File 'lib/pry/command.rb', line 57 def description; self.class.description; end |
#interpolate_string(str) ⇒ String
Revaluate the string (str) and perform interpolation.
243 244 245 246 247 248 249 250 |
# File 'lib/pry/command.rb', line 243 def interpolate_string(str) dumped_str = str.dump if dumped_str.gsub!(/\\\#\{/, '#{') target.eval(dumped_str) else str end end |
#match ⇒ Object
56 |
# File 'lib/pry/command.rb', line 56 def match; self.class.match; end |
#name ⇒ Object
Make those properties accessible to instances
55 |
# File 'lib/pry/command.rb', line 55 def name; self.class.name; end |
#pass_block(arg_string) ⇒ Object (private)
Pass a block argument to a command.
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/pry/command.rb', line 327 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 |
#process_line(line) ⇒ Object, Command::VOID_VALUE
Process a line that Command.matches? this command.
309 310 311 312 313 314 315 316 317 318 |
# File 'lib/pry/command.rb', line 309 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(command_string, *args) ⇒ Object
Run a command from another command.
192 193 194 195 |
# File 'lib/pry/command.rb', line 192 def run(command_string, *args) complete_string = "#{command_string} #{args.join(" ")}".rstrip command_set.process_line(complete_string, context) end |
#state ⇒ Hash
Returns 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.
234 235 236 |
# File 'lib/pry/command.rb', line 234 def state _pry_.command_state[match] ||= OpenStruct.new end |
#target_self ⇒ Object
Returns The value of self inside the target binding.
225 |
# File 'lib/pry/command.rb', line 225 def target_self; target.eval('self'); end |
#text ⇒ Object
201 202 203 |
# File 'lib/pry/command.rb', line 201 def text Pry::Helpers::Text end |
#tokenize(val) ⇒ Array
Extract necessary information from a line that Command.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
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 |
# File 'lib/pry/command.rb', line 279 def tokenize(val) val.replace(interpolate_string(val)) if [: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 [:takes_block] if arg_string args = [:shellwords] ? Shellwords.shellwords(arg_string) : arg_string.split(" ") else args = [] end [val[0..pos].rstrip, arg_string, captures, args] end |
#void ⇒ Object
205 206 207 |
# File 'lib/pry/command.rb', line 205 def void VOID_VALUE end |