pry 0.8.0pre9-i386-mswin32 → 0.8.1-i386-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,18 @@
1
1
  class Pry
2
2
  class Commands < CommandBase
3
- module CommandHelpers
3
+ module CommandHelpers
4
4
 
5
5
  private
6
6
 
7
7
  def try_to_load_pry_doc
8
8
 
9
- # YARD crashes on rbx, so do not require it
9
+ # YARD crashes on rbx, so do not require it
10
10
  if !Object.const_defined?(:RUBY_ENGINE) || RUBY_ENGINE !~ /rbx/
11
11
  require "pry-doc"
12
12
  end
13
13
  rescue LoadError
14
14
  end
15
-
15
+
16
16
  def meth_name_from_binding(b)
17
17
  meth_name = b.eval('__method__')
18
18
  if [:__script__, nil, :__binding__, :__binding_impl__].include?(meth_name)
@@ -29,7 +29,7 @@ class Pry
29
29
  target.eval("_file_ = $_file_temp")
30
30
  target.eval("_dir_ = $_dir_temp")
31
31
  end
32
-
32
+
33
33
  def add_line_numbers(lines, start_line)
34
34
  line_array = lines.each_line.to_a
35
35
  line_array.each_with_index.map do |line, idx|
@@ -110,7 +110,7 @@ class Pry
110
110
  if !meth_name
111
111
  return nil
112
112
  end
113
-
113
+
114
114
  if options[:M]
115
115
  target.eval("instance_method(:#{meth_name})")
116
116
  elsif options[:m]
@@ -127,15 +127,16 @@ class Pry
127
127
  end
128
128
  end
129
129
  end
130
-
130
+
131
131
  def make_header(meth, code_type, content)
132
- file, line = meth.source_location
133
132
  num_lines = "Number of lines: #{bold(content.each_line.count.to_s)}"
134
133
  case code_type
135
134
  when :ruby
135
+ file, line = meth.source_location
136
136
  "\n#{bold('From:')} #{file} @ line #{line}:\n#{num_lines}\n\n"
137
137
  else
138
- "\n#{bold('From:')} Ruby Core (C Method):\n#{num_lines}\n\n"
138
+ file = Pry::MethodInfo.info_for(meth).file
139
+ "\n#{bold('From:')} #{file} in Ruby Core (C Method):\n#{num_lines}\n\n"
139
140
  end
140
141
  end
141
142
 
@@ -146,11 +147,11 @@ class Pry
146
147
  def should_use_pry_doc?(meth)
147
148
  Pry.has_pry_doc && is_a_c_method?(meth)
148
149
  end
149
-
150
+
150
151
  def code_type_for(meth)
151
152
  # only C methods
152
153
  if should_use_pry_doc?(meth)
153
- info = Pry::MethodInfo.info_for(meth)
154
+ info = Pry::MethodInfo.info_for(meth)
154
155
  if info && info.source
155
156
  code_type = :c
156
157
  else
@@ -168,7 +169,7 @@ class Pry
168
169
  end
169
170
  code_type
170
171
  end
171
-
172
+
172
173
  def file_map
173
174
  {
174
175
  [".c", ".h"] => :c,
@@ -187,7 +188,7 @@ class Pry
187
188
  ".json" => :json
188
189
  }
189
190
  end
190
-
191
+
191
192
  def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
192
193
  _, language_detected = file_map.find do |k, v|
193
194
  Array(k).any? do |matcher|
@@ -204,7 +205,7 @@ class Pry
204
205
  def normalized_line_number(line_number, total_lines)
205
206
  line_number < 0 ? line_number + total_lines : line_number
206
207
  end
207
-
208
+
208
209
  # returns the file content between the lines and the normalized
209
210
  # start and end line numbers.
210
211
  def read_between_the_lines(file_name, start_line, end_line)
@@ -274,6 +275,29 @@ class Pry
274
275
  code.sub /\A\s*\/\*.*?\*\/\s*/m, ''
275
276
  end
276
277
 
278
+ def prompt(message, options="Yn")
279
+ opts = options.scan(/./)
280
+ optstring = opts.join("/") # case maintained
281
+ defaults = opts.select{|o| o.upcase == o }
282
+ opts = opts.map{|o| o.downcase}
283
+
284
+ raise "Error: Too many default values for the prompt: #{default.inspect}" if defaults.size > 1
285
+
286
+ default = defaults.first
287
+
288
+ loop do
289
+ response = Pry.input.readline("#{message} (#{optstring}) ").downcase
290
+ case response
291
+ when *opts
292
+ return response
293
+ when ""
294
+ return default.downcase
295
+ else
296
+ output.puts " |_ Invalid option: #{response.inspect}. Try again."
297
+ end
298
+ end
299
+ end
300
+
277
301
  end
278
302
  end
279
303
  end
@@ -6,15 +6,15 @@ class Pry
6
6
  SYSTEM_COMMAND_REGEX = /^#{Regexp.escape(SYSTEM_COMMAND_DELIMITER)}(.*)/
7
7
 
8
8
  extend Forwardable
9
-
9
+
10
10
  attr_accessor :pry_instance
11
-
11
+
12
12
  def initialize(pry_instance)
13
13
  @pry_instance = pry_instance
14
14
  end
15
15
 
16
16
  def_delegators :@pry_instance, :commands, :nesting, :output
17
-
17
+
18
18
  # Is the string a command valid?
19
19
  # @param [String] val The string passed in from the Pry prompt.
20
20
  # @return [Boolean] Whether the string is a valid command.
@@ -59,21 +59,31 @@ class Pry
59
59
  def execute_system_command(val, target)
60
60
  SYSTEM_COMMAND_REGEX =~ val
61
61
  cmd = interpolate_string($1, target)
62
-
62
+
63
63
  if cmd =~ /^cd\s+(.+)/i
64
64
  begin
65
- Dir.chdir(File.expand_path($1))
65
+ @@cd_history ||= []
66
+ if $1 == "-"
67
+ dest = @@cd_history.pop || Dir.pwd
68
+ else
69
+ dest = File.expand_path($1)
70
+ end
71
+
72
+ @@cd_history << Dir.pwd
73
+ Dir.chdir(dest)
66
74
  rescue Errno::ENOENT
67
- output.puts "No such directory: #{$1}"
75
+ output.puts "No such directory: #{dest}"
68
76
  end
69
77
  else
70
- system(cmd)
78
+ if !system(cmd)
79
+ output.puts "Error: there was a problem executing system command: #{cmd}"
80
+ end
71
81
  end
72
82
 
73
83
  # Tick, tock, im getting rid of this shit soon.
74
84
  val.replace("")
75
85
  end
76
-
86
+
77
87
  # Determine whether a Pry command was matched and return command data
78
88
  # and argument string.
79
89
  # This method should not need to be invoked directly.
@@ -114,7 +124,7 @@ class Pry
114
124
  args = args_string ? Shellwords.shellwords(args_string) : []
115
125
  action = cmd_data[:action]
116
126
  keep_retval = cmd_data[:keep_retval]
117
-
127
+
118
128
  options = {
119
129
  :val => val,
120
130
  :eval_string => eval_string,
@@ -157,7 +167,7 @@ class Pry
157
167
 
158
168
  # Tick, tock, im getting rid of this shit soon.
159
169
  options[:val].clear
160
-
170
+
161
171
  ret_val
162
172
  end
163
173
  end
@@ -2,6 +2,8 @@ direc = File.dirname(__FILE__)
2
2
 
3
3
  require "optparse"
4
4
  require "method_source"
5
+ require 'slop'
6
+ require 'rubygems/dependency_installer'
5
7
  require "#{direc}/command_base"
6
8
  require "#{direc}/pry_instance"
7
9
  require "#{direc}/command_helpers"
@@ -23,31 +25,30 @@ class Pry
23
25
  Pry.start(target)
24
26
  end
25
27
 
26
- # this cannot be accessed, it's just for help purposed.
28
+ # this cannot be accessed, it's just for help purposes.
27
29
  command ".<shell command>", "All text following a '.' is forwarded to the shell." do
28
30
  end
29
31
 
30
- command "hist", "Show and replay Readline history" do |*args|
31
- require 'slop'
32
+ command "hist", "Show and replay Readline history. Type `hist --help` for more info." do |*args|
33
+ hist_array = Readline::HISTORY.to_a
34
+
32
35
  if args.empty?
33
- text = add_line_numbers(Readline::HISTORY.to_a.join("\n"), 0)
36
+ text = add_line_numbers(hist_array.join("\n"), 0)
34
37
  stagger_output(text)
35
38
  next
36
39
  end
37
40
 
38
- opts = Slop.parse(args) do
39
- banner "Usage: hist [-rSTART..END]"
40
- on :r, :replay, 'The line (or range of lines) to replay.', true, :as => Range do |r|
41
- options[:r].argument_value = r.to_i if r.is_a?(String)
41
+ opts = Slop.parse(args) do |opt|
42
+ opt.banner "Usage: hist [--replay START..END]\nView and replay history\ne.g hist --replay 2..8"
43
+ opt.on :r, :replay, 'The line (or range of lines) to replay.', true, :as => Range
44
+ opt.on :h, :help, 'Show this message.', :tail => true do
45
+ output.puts opt.help
42
46
  end
43
- on :h, :help, 'Show this message.', :tail => true do
44
- output.puts help
45
- end
46
47
  end
47
48
 
48
49
  next if opts.h?
49
50
 
50
- actions = Array(Readline::HISTORY.to_a[opts[:r]]).join("\n") + "\n"
51
+ actions = Array(hist_array[opts[:replay]]).join("\n") + "\n"
51
52
  Pry.active_instance.input = StringIO.new(actions)
52
53
  end
53
54
 
@@ -58,46 +59,67 @@ class Pry
58
59
  alias_command "quit-program", "exit-program", ""
59
60
  alias_command "!!!", "exit-program", ""
60
61
 
62
+ command "gem-install", "Install a gem and refresh the gem cache." do |gem_name|
63
+ gem_home = Gem.instance_variable_get(:@gem_home)
64
+ output.puts "Attempting to install gem: #{bold(gem_name)}"
65
+
66
+ begin
67
+ if File.writable?(gem_home)
68
+ Gem::DependencyInstaller.new.install(gem_name)
69
+ output.puts "Gem #{bold(gem_name)} successfully installed."
70
+ else
71
+ if system("sudo gem install #{gem_name}")
72
+ output.puts "Gem #{bold(gem_name)} successfully installed."
73
+ else
74
+ output.puts "Gem #{bold(gem_name)} could not be installed."
75
+ next
76
+ end
77
+ end
78
+ rescue Gem::GemNotFoundException
79
+ output.puts "Required Gem: #{bold(gem_name)} not found."
80
+ next
81
+ end
82
+
83
+ Gem.refresh
84
+ output.puts "Refreshed gem cache."
85
+ end
86
+
61
87
  command "ri", "View ri documentation. e.g `ri Array#each`" do |*args|
62
- run target, ".ri", *args
88
+ run ".ri", *args
63
89
  end
64
90
 
65
- command "stat", "View method information and set _file_ and _dir_ locals" do |*args|
66
- options = {}
91
+ command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
67
92
  target = target()
68
- meth_name = nil
69
-
70
- OptionParser.new do |opts|
71
- opts.banner = %{Usage: stat [OPTIONS] [METH]
72
- Show method information for method METH and set _file_ and _dir_ locals.
93
+
94
+ opts = Slop.parse!(args) do |opts|
95
+ opts.banner %{Usage: stat [OPTIONS] [METH]
96
+ Show method information for method METH and set _file_ and _dir_ locals.
73
97
  e.g: stat hello_method
74
98
  --
75
99
  }
76
- opts.on("-M", "--instance-methods", "Operate on instance methods.") do
77
- options[:M] = true
78
- end
79
-
80
- opts.on("-m", "--methods", "Operate on methods.") do
81
- options[:m] = true
82
- end
83
-
84
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
100
+ opts.on :M, "instance-methods", "Operate on instance methods."
101
+ opts.on :m, :methods, "Operate on methods."
102
+ opts.on :c, :context, "Select object context to run under.", true do |context|
85
103
  target = Pry.binding_for(target.eval(context))
86
104
  end
87
-
88
- opts.on_tail("-h", "--help", "This message.") do
105
+ opts.on :h, :help, "This message" do
89
106
  output.puts opts
90
- options[:h] = true
91
107
  end
92
- end.order(args) do |v|
93
- meth_name = v
94
108
  end
95
109
 
96
- next if options[:h]
97
-
98
- meth_name = meth_name_from_binding(target) if !meth_name
110
+ next if opts.help?
99
111
 
100
- if (meth = get_method_object(meth_name, target, options)).nil?
112
+ meth_name = args.shift
113
+ if meth_name
114
+ if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
115
+ context, meth_name = $1, $2
116
+ target = Pry.binding_for(target.eval(context))
117
+ end
118
+ else
119
+ meth_name = meth_name_from_binding(target)
120
+ end
121
+
122
+ if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
101
123
  output.puts "Invalid method name: #{meth_name}. Type `stat --help` for help"
102
124
  next
103
125
  end
@@ -108,50 +130,59 @@ e.g: stat hello_method
108
130
 
109
131
  output.puts make_header(meth, code_type, code)
110
132
  output.puts bold("Method Name: ") + meth_name
133
+ output.puts bold("Method Owner: ") + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
111
134
  output.puts bold("Method Language: ") + code_type.to_s.capitalize
112
135
  output.puts bold("Method Type: ") + (meth.is_a?(Method) ? "Bound" : "Unbound")
113
136
  output.puts bold("Method Arity: ") + meth.arity.to_s
137
+
138
+ name_map = { :req => "Required:", :opt => "Optional:", :rest => "Rest:" }
139
+ if meth.respond_to?(:parameters)
140
+ output.puts bold("Method Parameters: ") + meth.parameters.group_by(&:first).
141
+ map { |k, v| "#{name_map[k]} #{v.map { |kk, vv| vv ? vv.to_s : "noname" }.join(", ")}" }.join(". ")
142
+ end
114
143
  output.puts bold("Comment length: ") + (doc.empty? ? 'No comment.' : (doc.lines.count.to_s + ' lines.'))
115
144
  end
116
145
 
117
- command "gist-method", "Gist a method to github.", :requires_gem => "gist" do |*args|
118
- options = {}
119
- meth_name = nil
146
+ command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
147
+ target = target()
120
148
 
121
- OptionParser.new do |opts|
149
+ opts = Slop.parse!(args) do |opts|
122
150
  opts.banner = %{Usage: gist-method [OPTIONS] [METH]
123
151
  Gist the method (doc or source) to github.
152
+ Ensure the `gist` gem is properly working before use. http://github.com/defunkt/gist for instructions.
124
153
  e.g: gist -m my_method
125
154
  e.g: gist -d my_method
126
155
  --
127
156
  }
128
- opts.on("-m", "--method", "Gist a method's source.") do |line|
129
- options[:m] = true
130
- end
131
-
132
- opts.on("-d", "--doc", "Gist a method's documentation.") do
133
- options[:d] = true
134
- end
135
-
136
- opts.on_tail("-h", "--help", "This message.") do
157
+ opts.on :m, :method, "Gist a method's source."
158
+ opts.on :d, :doc, "Gist a method's documentation."
159
+ opts.on :p, :private, "Create a private gist (default: true)", :default => true
160
+ opts.on :h, :help, "This message" do
137
161
  output.puts opts
138
- options[:h] = true
139
162
  end
140
- end.order(args) do |v|
141
- meth_name = v
142
163
  end
143
164
 
144
- next if options[:h]
145
-
146
- meth_name = meth_name_from_binding(target) if !meth_name
165
+ next if opts.help?
147
166
 
148
- if (meth = get_method_object(meth_name, target, options)).nil?
167
+ # This needs to be extracted into its own method as it's shared
168
+ # by show-method and show-doc and stat commands
169
+ meth_name = args.shift
170
+ if meth_name
171
+ if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/
172
+ context, meth_name = $1, $2
173
+ target = Pry.binding_for(target.eval(context))
174
+ end
175
+ else
176
+ meth_name = meth_name_from_binding(target)
177
+ end
178
+
179
+ if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
149
180
  output.puts "Invalid method name: #{meth_name}. Type `gist-method --help` for help"
150
181
  next
151
182
  end
152
183
 
153
184
  type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
154
- if !options[:d]
185
+ if !opts.doc?
155
186
  content, code_type = code_and_code_type_for(meth)
156
187
  else
157
188
  content, code_type = doc_and_code_type_for(meth)
@@ -160,8 +191,8 @@ e.g: gist -d my_method
160
191
  end
161
192
  code_type = :plain
162
193
  end
163
-
164
- IO.popen("gist -p -t #{type_map[code_type]} -", "w") do |gist|
194
+
195
+ IO.popen("gist#{' -p' if opts.p?} -t #{type_map[code_type]} -", "w") do |gist|
165
196
  gist.puts content
166
197
  end
167
198
  end
@@ -189,22 +220,22 @@ e.g: gist -d my_method
189
220
 
190
221
  command "shell-mode", "Toggle shell mode. Bring in pwd prompt and file completion." do
191
222
  case Pry.active_instance.prompt
192
- when Pry::FILE_PROMPT
223
+ when Pry::SHELL_PROMPT
193
224
  Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
194
225
  Pry.active_instance.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
195
226
  else
196
- Pry.active_instance.prompt = Pry::FILE_PROMPT
227
+ Pry.active_instance.prompt = Pry::SHELL_PROMPT
197
228
  Pry.active_instance.custom_completions = Pry::FILE_COMPLETIONS
198
229
  Readline.completion_proc = Pry::InputCompleter.build_completion_proc target,
199
230
  Pry.active_instance.instance_eval(&Pry::FILE_COMPLETIONS)
200
- end
231
+ end
201
232
  end
202
233
 
203
234
  alias_command "file-mode", "shell-mode", ""
204
235
 
205
- command "nesting", "Show nesting information." do
236
+ command "nesting", "Show nesting information." do
206
237
  nesting = opts[:nesting]
207
-
238
+
208
239
  output.puts "Nesting status:"
209
240
  output.puts "--"
210
241
  nesting.each do |level, obj|
@@ -218,7 +249,7 @@ e.g: gist -d my_method
218
249
 
219
250
  command "status", "Show status information." do
220
251
  nesting = opts[:nesting]
221
-
252
+
222
253
  output.puts "Status:"
223
254
  output.puts "--"
224
255
  output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
@@ -232,7 +263,53 @@ e.g: gist -d my_method
232
263
  output.puts "Last result: #{Pry.view(Pry.last_result)}"
233
264
  end
234
265
 
235
- command "whereami", "Show the code context for the session. Shows AROUND lines around the invocation line. AROUND defaults to 5 lines. " do |num|
266
+
267
+ command "req", "Requires gem(s). No need for quotes! (If the gem isn't installed, it will ask if you want to install it.)" do |*gems|
268
+ gems = gems.join(' ').gsub(',', '').split(/\s+/)
269
+ gems.each do |gem|
270
+ begin
271
+ if require gem
272
+ output.puts "#{bright_yellow(gem)} loaded"
273
+ else
274
+ output.puts "#{bright_white(gem)} already loaded"
275
+ end
276
+
277
+ rescue LoadError => e
278
+
279
+ if gem_installed? gem
280
+ output.puts e.inspect
281
+ else
282
+ output.puts "#{bright_red(gem)} not found"
283
+ if prompt("Install the gem?") == "y"
284
+ run "gem-install", gem
285
+ end
286
+ end
287
+
288
+ end # rescue
289
+ end # gems.each
290
+ end
291
+
292
+
293
+ command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |arg|
294
+ gems = Gem.source_index.gems.values.group_by(&:name)
295
+ if arg
296
+ query = Regexp.new(arg, Regexp::IGNORECASE)
297
+ gems = gems.select { |gemname, specs| gemname =~ query }
298
+ end
299
+
300
+ gems.each do |gemname, specs|
301
+ versions = specs.map(&:version).sort.reverse.map(&:to_s)
302
+ versions = ["<bright_green>#{versions.first}</bright_green>"] +
303
+ versions[1..-1].map{|v| "<green>#{v}</green>" }
304
+
305
+ gemname = highlight(gemname, query) if query
306
+ result = "<white>#{gemname} <grey>(#{versions.join ', '})</grey>"
307
+ output.puts colorize(result)
308
+ end
309
+ end
310
+
311
+
312
+ command "whereami", "Show the code context for the session. (whereami <n> shows <n> extra lines of code around the invocation line. Default: 5)" do |num|
236
313
  file = target.eval('__FILE__')
237
314
  line_num = target.eval('__LINE__')
238
315
  klass = target.eval('self.class')
@@ -246,14 +323,14 @@ e.g: gist -d my_method
246
323
  meth_name = meth_name_from_binding(target)
247
324
  meth_name = "N/A" if !meth_name
248
325
 
249
- if file =~ /(\(.*\))|<.*>/ || file == ""
326
+ if file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e"
250
327
  output.puts "Cannot find local context. Did you use `binding.pry` ?"
251
328
  next
252
329
  end
253
-
254
- set_file_and_dir_locals(file)
330
+
331
+ set_file_and_dir_locals(file)
255
332
  output.puts "\n#{bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n"
256
-
333
+
257
334
  # This method inspired by http://rubygems.org/gems/ir_b
258
335
  File.open(file).each_with_index do |line, index|
259
336
  line_n = index + 1
@@ -276,25 +353,24 @@ e.g: gist -d my_method
276
353
  end
277
354
  end
278
355
  end
279
-
356
+
280
357
  command "version", "Show Pry version." do
281
358
  output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
282
359
  end
283
-
284
- command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
360
+
361
+ command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !!@" do
285
362
  str = remove_first_word(opts[:val])
286
363
  throw(:breakout, [0, target.eval(str)])
287
364
  end
288
365
 
289
- alias_command "!@", "exit-all", ""
366
+ alias_command "!!@", "exit-all", ""
290
367
 
291
368
  command "ls", "Show the list of vars and methods in the current scope. Type `ls --help` for more info." do |*args|
292
369
  options = {}
293
-
294
370
  # Set target local to the default -- note that we can set a different target for
295
371
  # ls if we like: e.g ls my_var
296
372
  target = target()
297
-
373
+
298
374
  OptionParser.new do |opts|
299
375
  opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
300
376
  List information about VAR (the current context by default).
@@ -304,7 +380,7 @@ Shows local and instance variables by default.
304
380
  opts.on("-g", "--globals", "Display global variables.") do
305
381
  options[:g] = true
306
382
  end
307
-
383
+
308
384
  opts.on("-c", "--constants", "Display constants.") do
309
385
  options[:c] = true
310
386
  end
@@ -313,15 +389,15 @@ Shows local and instance variables by default.
313
389
  options[:l] = true
314
390
  end
315
391
 
316
- opts.on("-i", "--ivars", "Display instance variables.") do
392
+ opts.on("-i", "--ivars", "Display instance variables.") do
317
393
  options[:i] = true
318
394
  end
319
395
 
320
- opts.on("-k", "--class-vars", "Display class variables.") do
396
+ opts.on("-k", "--class-vars", "Display class variables.") do
321
397
  options[:k] = true
322
- end
398
+ end
323
399
 
324
- opts.on("-m", "--methods", "Display methods (public methods by default).") do
400
+ opts.on("-m", "--methods", "Display methods (public methods by default).") do
325
401
  options[:m] = true
326
402
  end
327
403
 
@@ -329,34 +405,42 @@ Shows local and instance variables by default.
329
405
  options[:M] = true
330
406
  end
331
407
 
332
- opts.on("-P", "--public", "Display public methods (with -m).") do
408
+ opts.on("-P", "--public", "Display public methods (with -m).") do
333
409
  options[:P] = true
334
410
  end
335
411
 
336
- opts.on("-r", "--protected", "Display protected methods (with -m).") do
412
+ opts.on("-r", "--protected", "Display protected methods (with -m).") do
337
413
  options[:r] = true
338
- end
414
+ end
339
415
 
340
- opts.on("-p", "--private", "Display private methods (with -m).") do
416
+ opts.on("-p", "--private", "Display private methods (with -m).") do
341
417
  options[:p] = true
342
418
  end
343
419
 
344
- opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
420
+ opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
345
421
  options[:j] = true
346
- end
422
+ end
347
423
 
348
- opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
424
+ opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
349
425
  options[:s] = true
350
426
  end
351
-
427
+
352
428
  opts.on("-a", "--all", "Display all types of entries.") do
353
429
  options[:a] = true
354
430
  end
355
431
 
356
- opts.on("-v", "--verbose", "Verbose ouput.") do
432
+ opts.on("-v", "--verbose", "Verbose ouput.") do
357
433
  options[:v] = true
358
434
  end
359
435
 
436
+ opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
437
+ options[:f] = true
438
+ end
439
+
440
+ opts.on("--grep REG", "Regular expression to be used.") do |reg|
441
+ options[:grep] = Regexp.new(reg)
442
+ end
443
+
360
444
  opts.on_tail("-h", "--help", "Show this message.") do
361
445
  output.puts opts
362
446
  options[:h] = true
@@ -374,18 +458,21 @@ Shows local and instance variables by default.
374
458
  :l => true,
375
459
  :i => true,
376
460
  :k => true
377
- }) if options.empty? || (options.size == 1 && options[:v])
461
+ }) if options.empty? || (options.size == 1 && options[:v]) || (options.size == 1 && options[:grep])
462
+
463
+ options[:grep] = // if !options[:grep]
464
+
378
465
 
379
466
  # Display public methods by default if -m or -M switch is used.
380
467
  options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r] || options[:j])
381
-
468
+
382
469
  info = {}
383
470
  target_self = target.eval('self')
384
471
 
385
472
  # ensure we have a real boolean and not a `nil` (important when
386
473
  # interpolating in the string)
387
474
  options[:s] = !!options[:s]
388
-
475
+
389
476
  # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
390
477
  i = -1
391
478
 
@@ -400,7 +487,7 @@ Shows local and instance variables by default.
400
487
  end, i += 1] if options[:k] || options[:a]
401
488
 
402
489
  info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
403
-
490
+
404
491
  info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
405
492
 
406
493
  info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
@@ -408,52 +495,77 @@ Shows local and instance variables by default.
408
495
  info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
409
496
 
410
497
  info["just singleton methods"] = [Array(target.eval("methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:j]) || options[:a]
411
-
498
+
412
499
  info["public instance methods"] = [Array(target.eval("public_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:P]) || options[:a])
413
500
 
414
501
  info["protected instance methods"] = [Array(target.eval("protected_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:r]) || options[:a])
415
502
 
416
503
  info["private instance methods"] = [Array(target.eval("private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:p]) || options[:a])
417
-
504
+
418
505
  # dealing with 1.8/1.9 compatibility issues :/
419
506
  csuper = options[:s]
420
507
  if Module.method(:constants).arity == 0
421
508
  csuper = nil
422
509
  end
423
-
510
+
424
511
  info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
425
512
  target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
426
513
 
514
+ text = ""
515
+
427
516
  # verbose output?
428
517
  if options[:v]
429
-
430
518
  # verbose
519
+
431
520
  info.sort_by { |k, v| v.last }.each do |k, v|
432
521
  if !v.first.empty?
433
- output.puts "#{k}:\n--"
522
+ text << "#{k}:\n--\n"
523
+ filtered_list = v.first.grep options[:grep]
434
524
  if Pry.color
435
- output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
525
+ text << CodeRay.scan(Pry.view(filtered_list), :ruby).term + "\n"
436
526
  else
437
- output.puts Pry.view(v.first)
527
+ text << Pry.view(filtered_list) + "\n"
438
528
  end
439
- output.puts
529
+ text << "\n\n"
440
530
  end
441
531
  end
442
532
 
533
+ if !options[:f]
534
+ stagger_output(text)
535
+ else
536
+ output.puts text
537
+ end
538
+
443
539
  # plain
444
540
  else
445
541
  list = info.values.sort_by(&:last).map(&:first).inject(&:+)
542
+ list = list.grep(options[:grep]) if list
446
543
  list.uniq! if list
447
544
  if Pry.color
448
- output.puts CodeRay.scan(Pry.view(list), :ruby).term
545
+ text << CodeRay.scan(Pry.view(list), :ruby).term + "\n"
546
+ else
547
+ text << Pry.view(list) + "\n"
548
+ end
549
+ if !options[:f]
550
+ stagger_output(text)
449
551
  else
450
- output.puts Pry.view(list)
552
+ output.puts text
451
553
  end
452
554
  list
453
555
  end
454
556
  end
455
557
 
456
- command "cat-file", "Show output of file FILE. Type `cat-file --help` for more information." do |*args|
558
+ command "lls", "List local files using 'ls'" do |*args|
559
+ cmd = ".ls"
560
+ cmd << " --color=always" if Pry.color
561
+ run cmd, *args
562
+ end
563
+
564
+ command "lcd", "Change the current (working) directory" do |*args|
565
+ run ".cd", *args
566
+ end
567
+
568
+ command "cat", "Show output of file FILE. Type `cat --help` for more information." do |*args|
457
569
  options= {}
458
570
  file_name = nil
459
571
  start_line = 0
@@ -461,9 +573,9 @@ Shows local and instance variables by default.
461
573
  file_type = nil
462
574
 
463
575
  OptionParser.new do |opts|
464
- opts.banner = %{Usage: cat-file [OPTIONS] FILE
576
+ opts.banner = %{Usage: cat [OPTIONS] FILE
465
577
  Cat a file. Defaults to displaying whole file. Syntax highlights file if type is recognized.
466
- e.g: cat-file hello.rb
578
+ e.g: cat hello.rb
467
579
  --
468
580
  }
469
581
  opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
@@ -482,11 +594,11 @@ e.g: cat-file hello.rb
482
594
  file_type = type.to_sym
483
595
  end
484
596
 
485
- opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
597
+ opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
486
598
  options[:f] = true
487
599
  end
488
600
 
489
- opts.on_tail("-h", "--help", "This message.") do
601
+ opts.on_tail("-h", "--help", "This message.") do
490
602
  output.puts opts
491
603
  options[:h] = true
492
604
  end
@@ -495,7 +607,7 @@ e.g: cat-file hello.rb
495
607
  end
496
608
 
497
609
  next if options[:h]
498
-
610
+
499
611
  if !file_name
500
612
  output.puts "Must provide a file name."
501
613
  next
@@ -516,7 +628,7 @@ e.g: cat-file hello.rb
516
628
  options = {}
517
629
  target = target()
518
630
  file_name = nil
519
-
631
+
520
632
  OptionParser.new do |opts|
521
633
  opts.banner = %{Usage: eval-file [OPTIONS] FILE
522
634
  Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
@@ -528,7 +640,7 @@ e.g: eval-file -c self "hello.rb"
528
640
  target = Pry.binding_for(target.eval(context))
529
641
  end
530
642
 
531
- opts.on_tail("-h", "--help", "This message.") do
643
+ opts.on_tail("-h", "--help", "This message.") do
532
644
  output.puts opts
533
645
  options[:h] = true
534
646
  end
@@ -556,73 +668,57 @@ e.g: eval-file -c self "hello.rb"
556
668
 
557
669
  new_constants = Object.constants - old_constants
558
670
  output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
559
- end
560
-
561
- command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
562
- if !obj
563
- output.puts "Must provide an object to inspect."
564
- next
565
- end
566
-
567
- output.puts Pry.view(target.eval("#{obj}"))
568
671
  end
569
672
 
570
- alias_command "inspect", "cat", ""
571
-
572
673
  command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
573
674
  if !obj
574
675
  output.puts "Must provide an object."
575
676
  next
576
677
  end
577
-
678
+
578
679
  throw(:breakout, opts[:nesting].level) if obj == ".."
579
680
 
580
- if obj == "/"
681
+ if obj == "/"
581
682
  throw(:breakout, 1) if opts[:nesting].level > 0
582
683
  next
583
- end
684
+ end
584
685
 
585
686
  Pry.start target.eval("#{obj}")
586
687
  end
587
688
 
588
689
  command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info. Aliases: \?" do |*args|
589
- options = {}
590
690
  target = target()
591
- meth_name = nil
592
-
593
- OptionParser.new do |opts|
594
- opts.banner = %{Usage: show-doc [OPTIONS] [METH]
691
+
692
+ opts = Slop.parse!(args) do |opts|
693
+ opts.banner %{Usage: show-doc [OPTIONS] [METH]
595
694
  Show the comments above method METH. Tries instance methods first and then methods by default.
596
695
  e.g show-doc hello_method
597
696
  --
598
697
  }
599
- opts.on("-M", "--instance-methods", "Operate on instance methods.") do
600
- options[:M] = true
601
- end
602
-
603
- opts.on("-m", "--methods", "Operate on methods.") do
604
- options[:m] = true
605
- end
606
-
607
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
698
+ opts.on :M, "instance-methods", "Operate on instance methods."
699
+ opts.on :m, :methods, "Operate on methods."
700
+ opts.on :c, :context, "Select object context to run under.", true do |context|
608
701
  target = Pry.binding_for(target.eval(context))
609
702
  end
610
-
611
- opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
612
- options[:f] = true
613
- end
614
-
615
- opts.on_tail("-h", "--help", "This message.") do
703
+ opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
704
+ opts.on :h, :help, "This message." do
616
705
  output.puts opts
617
- options[:h] = true
618
706
  end
619
- end.order(args) do |v|
620
- meth_name = v
621
707
  end
622
708
 
623
- next if options[:h]
709
+ next if opts.help?
710
+
711
+ meth_name = args.shift
712
+ if meth_name
713
+ if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
714
+ context, meth_name = $1, $2
715
+ target = Pry.binding_for(target.eval(context))
716
+ end
717
+ else
718
+ meth_name = meth_name_from_binding(target)
719
+ end
624
720
 
625
- if (meth = get_method_object(meth_name, target, options)).nil?
721
+ if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
626
722
  output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
627
723
  next
628
724
  end
@@ -631,65 +727,55 @@ e.g show-doc hello_method
631
727
  next if !doc
632
728
 
633
729
  next output.puts("No documentation found.") if doc.empty?
634
-
730
+
635
731
  doc = process_comment_markup(doc, code_type)
636
-
732
+
637
733
  output.puts make_header(meth, code_type, doc)
638
734
 
639
- render_output(options[:f], false, doc)
735
+ render_output(opts.flood?, false, doc)
640
736
  doc
641
737
  end
642
738
 
643
739
  alias_command "?", "show-doc", ""
644
740
 
645
741
  command "show-method", "Show the source for METH. Type `show-method --help` for more info. Aliases: $, show-source" do |*args|
646
- options = {}
647
742
  target = target()
648
- meth_name = nil
649
-
650
- OptionParser.new do |opts|
651
- opts.banner = %{Usage: show-method [OPTIONS] [METH]
743
+
744
+ opts = Slop.parse!(args) do |opts|
745
+ opts.banner %{Usage: show-method [OPTIONS] [METH]
652
746
  Show the source for method METH. Tries instance methods first and then methods by default.
653
747
  e.g: show-method hello_method
654
748
  --
655
749
  }
656
- opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
657
- options[:l] = true
658
- end
659
-
660
- opts.on("-M", "--instance-methods", "Operate on instance methods.") do
661
- options[:M] = true
662
- end
663
-
664
- opts.on("-m", "--methods", "Operate on methods.") do
665
- options[:m] = true
666
- end
667
-
668
- opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
669
- options[:f] = true
670
- end
671
-
672
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
750
+ opts.on :l, "line-numbers", "Show line numbers."
751
+ opts.on :M, "instance-methods", "Operate on instance methods."
752
+ opts.on :m, :methods, "Operate on methods."
753
+ opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
754
+ opts.on :c, :context, "Select object context to run under.", true do |context|
673
755
  target = Pry.binding_for(target.eval(context))
674
756
  end
675
-
676
- opts.on_tail("-h", "--help", "This message.") do
757
+ opts.on :h, :help, "This message." do
677
758
  output.puts opts
678
- options[:h] = true
679
759
  end
680
- end.order(args) do |v|
681
- meth_name = v
682
760
  end
683
761
 
684
- next if options[:h]
762
+ next if opts.help?
685
763
 
686
- meth_name = meth_name_from_binding(target) if !meth_name
764
+ meth_name = args.shift
765
+ if meth_name
766
+ if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
767
+ context, meth_name = $1, $2
768
+ target = Pry.binding_for(target.eval(context))
769
+ end
770
+ else
771
+ meth_name = meth_name_from_binding(target)
772
+ end
687
773
 
688
- if (meth = get_method_object(meth_name, target, options)).nil?
774
+ if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
689
775
  output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
690
776
  next
691
777
  end
692
-
778
+
693
779
  code, code_type = code_and_code_type_for(meth)
694
780
  next if !code
695
781
 
@@ -699,11 +785,11 @@ e.g: show-method hello_method
699
785
  end
700
786
 
701
787
  start_line = false
702
- if options[:l]
788
+ if opts.l?
703
789
  start_line = meth.source_location ? meth.source_location.last : 1
704
790
  end
705
-
706
- render_output(options[:f], start_line, code)
791
+
792
+ render_output(opts.flood?, start_line, code)
707
793
  code
708
794
  end
709
795
 
@@ -714,10 +800,10 @@ e.g: show-method hello_method
714
800
  options = {}
715
801
  target = target()
716
802
  command_name = nil
717
-
803
+
718
804
  OptionParser.new do |opts|
719
805
  opts.banner = %{Usage: show-command [OPTIONS] [CMD]
720
- Show the source for command CMD.
806
+ Show the source for command CMD.
721
807
  e.g: show-command show-method
722
808
  --
723
809
  }
@@ -725,11 +811,11 @@ e.g: show-command show-method
725
811
  options[:l] = true
726
812
  end
727
813
 
728
- opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
814
+ opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
729
815
  options[:f] = true
730
816
  end
731
817
 
732
- opts.on_tail("-h", "--help", "This message.") do
818
+ opts.on_tail("-h", "--help", "This message.") do
733
819
  output.puts opts
734
820
  options[:h] = true
735
821
  end
@@ -743,7 +829,7 @@ e.g: show-command show-method
743
829
  output.puts "You must provide a command name."
744
830
  next
745
831
  end
746
-
832
+
747
833
  if commands[command_name]
748
834
  meth = commands[command_name][:action]
749
835
 
@@ -764,7 +850,7 @@ e.g: show-command show-method
764
850
  output.puts "No such command: #{command_name}."
765
851
  end
766
852
  end
767
-
853
+
768
854
  command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
769
855
  break_level = break_level.to_i
770
856
  nesting = opts[:nesting]
@@ -780,7 +866,7 @@ e.g: show-command show-method
780
866
  end
781
867
  end
782
868
 
783
- command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
869
+ command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
784
870
  str = remove_first_word(opts[:val])
785
871
  throw(:breakout, [opts[:nesting].level, target.eval(str)])
786
872
  end
@@ -825,7 +911,7 @@ Wait for the early owl.
825
911
  output.puts text
826
912
  text
827
913
  end
828
-
914
+
829
915
  command "cohen-poem", "" do
830
916
  text = %{
831
917
  --
@@ -843,7 +929,7 @@ and so small between the thin pines
843
929
  on these enormous landscapes,
844
930
  that if you turn your head
845
931
  they are lost for hours.
846
- -- Leonard Cohen
932
+ -- Leonard Cohen
847
933
  }
848
934
  output.puts text
849
935
  text