pry 0.10.4 → 0.11.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -18
  3. data/LICENSE +1 -1
  4. data/README.md +28 -26
  5. data/bin/pry +3 -7
  6. data/lib/pry.rb +3 -2
  7. data/lib/pry/basic_object.rb +6 -0
  8. data/lib/pry/cli.rb +39 -34
  9. data/lib/pry/code.rb +6 -1
  10. data/lib/pry/code/code_file.rb +8 -2
  11. data/lib/pry/code_object.rb +23 -0
  12. data/lib/pry/color_printer.rb +11 -8
  13. data/lib/pry/command.rb +40 -16
  14. data/lib/pry/command_set.rb +9 -2
  15. data/lib/pry/commands/cat/exception_formatter.rb +11 -10
  16. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  17. data/lib/pry/commands/code_collector.rb +16 -14
  18. data/lib/pry/commands/easter_eggs.rb +9 -9
  19. data/lib/pry/commands/edit.rb +6 -2
  20. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  21. data/lib/pry/commands/find_method.rb +1 -1
  22. data/lib/pry/commands/gem_open.rb +1 -1
  23. data/lib/pry/commands/gem_readme.rb +25 -0
  24. data/lib/pry/commands/gem_search.rb +40 -0
  25. data/lib/pry/commands/hist.rb +2 -2
  26. data/lib/pry/commands/jump_to.rb +7 -7
  27. data/lib/pry/commands/ls/formatter.rb +1 -0
  28. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  29. data/lib/pry/commands/ls/self_methods.rb +2 -0
  30. data/lib/pry/commands/play.rb +2 -2
  31. data/lib/pry/commands/reload_code.rb +2 -2
  32. data/lib/pry/commands/ri.rb +4 -0
  33. data/lib/pry/commands/shell_command.rb +34 -8
  34. data/lib/pry/commands/show_info.rb +10 -2
  35. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  36. data/lib/pry/commands/whereami.rb +6 -6
  37. data/lib/pry/config.rb +3 -16
  38. data/lib/pry/config/behavior.rb +139 -49
  39. data/lib/pry/config/default.rb +21 -33
  40. data/lib/pry/config/lazy.rb +25 -0
  41. data/lib/pry/editor.rb +1 -1
  42. data/lib/pry/exceptions.rb +1 -1
  43. data/lib/pry/helpers/base_helpers.rb +6 -10
  44. data/lib/pry/helpers/documentation_helpers.rb +1 -0
  45. data/lib/pry/helpers/options_helpers.rb +1 -1
  46. data/lib/pry/helpers/text.rb +69 -76
  47. data/lib/pry/history.rb +22 -1
  48. data/lib/pry/history_array.rb +1 -1
  49. data/lib/pry/hooks.rb +48 -107
  50. data/lib/pry/indent.rb +6 -2
  51. data/lib/pry/input_completer.rb +118 -118
  52. data/lib/pry/method.rb +13 -13
  53. data/lib/pry/method/disowned.rb +1 -0
  54. data/lib/pry/method/patcher.rb +0 -3
  55. data/lib/pry/output.rb +37 -38
  56. data/lib/pry/pager.rb +11 -8
  57. data/lib/pry/plugins.rb +20 -5
  58. data/lib/pry/pry_class.rb +29 -3
  59. data/lib/pry/pry_instance.rb +8 -6
  60. data/lib/pry/repl.rb +37 -5
  61. data/lib/pry/repl_file_loader.rb +1 -1
  62. data/lib/pry/rubygem.rb +3 -1
  63. data/lib/pry/slop.rb +661 -0
  64. data/lib/pry/slop/LICENSE +20 -0
  65. data/lib/pry/slop/commands.rb +196 -0
  66. data/lib/pry/slop/option.rb +208 -0
  67. data/lib/pry/terminal.rb +16 -5
  68. data/lib/pry/test/helper.rb +11 -2
  69. data/lib/pry/version.rb +1 -1
  70. data/lib/pry/wrapped_module.rb +5 -5
  71. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +2 -4
  72. metadata +14 -20
@@ -66,8 +66,10 @@ class Pry
66
66
  #
67
67
  # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively
68
68
  # classifications of "super", "next", "return", etc.
69
- STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword,
70
- :delimiter, :reserved]
69
+ STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float,
70
+ :keyword, :delimiter, :reserved,
71
+ :instance_variable,
72
+ :class_variable, :global_variable]
71
73
 
72
74
  # Collection of tokens that should appear dedented even though they
73
75
  # don't affect the surrounding code.
@@ -223,6 +225,8 @@ class Pry
223
225
 
224
226
  seen_for_at << add_after if OPTIONAL_DO_TOKENS.include?(token)
225
227
 
228
+ next if is_singleline_if
229
+
226
230
  if kind == :delimiter
227
231
  track_delimiter(token)
228
232
  elsif OPEN_TOKENS.keys.include?(token) && !is_optional_do && !is_singleline_if
@@ -106,137 +106,137 @@ class Pry::InputCompleter
106
106
  begin
107
107
  context = target.eval("self")
108
108
  context = context.class unless context.respond_to? :constants
109
- candidates = context.constants.collect(&:to_s)
110
- rescue
111
- candidates = []
112
- end
113
- candidates = candidates.grep(/^#{message}/).collect(&path)
114
- when CONSTANT_OR_METHOD_REGEXP # Constant or class methods
115
- receiver = $1
116
- message = Regexp.quote($2)
117
- begin
118
- candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
119
- candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
120
- rescue Pry::RescuableException
121
- candidates = []
122
- end
123
- candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
124
- when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol
125
- receiver = $1
126
- message = Regexp.quote($2)
127
- candidates = Symbol.instance_methods.collect(&:to_s)
128
- select_message(path, receiver, message, candidates)
129
- when NUMERIC_REGEXP
130
- # Numeric
131
- receiver = $1
132
- message = Regexp.quote($5)
133
- begin
134
- candidates = eval(receiver, bind).methods.collect(&:to_s)
135
- rescue Pry::RescuableException
136
- candidates = []
137
- end
138
- select_message(path, receiver, message, candidates)
139
- when HEX_REGEXP
140
- # Numeric(0xFFFF)
141
- receiver = $1
142
- message = Regexp.quote($2)
109
+ candidates = context.constants.collect(&:to_s)
110
+ rescue
111
+ candidates = []
112
+ end
113
+ candidates = candidates.grep(/^#{message}/).collect(&path)
114
+ when CONSTANT_OR_METHOD_REGEXP # Constant or class methods
115
+ receiver = $1
116
+ message = Regexp.quote($2)
117
+ begin
118
+ candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
119
+ candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
120
+ rescue Pry::RescuableException
121
+ candidates = []
122
+ end
123
+ candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
124
+ when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol
125
+ receiver = $1
126
+ message = Regexp.quote($2)
127
+ candidates = Symbol.instance_methods.collect(&:to_s)
128
+ select_message(path, receiver, message, candidates)
129
+ when NUMERIC_REGEXP
130
+ # Numeric
131
+ receiver = $1
132
+ message = Regexp.quote($5)
133
+ begin
134
+ candidates = eval(receiver, bind).methods.collect(&:to_s)
135
+ rescue Pry::RescuableException
136
+ candidates = []
137
+ end
138
+ select_message(path, receiver, message, candidates)
139
+ when HEX_REGEXP
140
+ # Numeric(0xFFFF)
141
+ receiver = $1
142
+ message = Regexp.quote($2)
143
+ begin
144
+ candidates = eval(receiver, bind).methods.collect(&:to_s)
145
+ rescue Pry::RescuableException
146
+ candidates = []
147
+ end
148
+ select_message(path, receiver, message, candidates)
149
+ when GLOBALVARIABLE_REGEXP # global
150
+ regmessage = Regexp.new(Regexp.quote($1))
151
+ candidates = global_variables.collect(&:to_s).grep(regmessage)
152
+ when VARIABLE_REGEXP # variable
153
+ receiver = $1
154
+ message = Regexp.quote($2)
155
+
156
+ gv = eval("global_variables", bind).collect(&:to_s)
157
+ lv = eval("local_variables", bind).collect(&:to_s)
158
+ cv = eval("self.class.constants", bind).collect(&:to_s)
159
+
160
+ if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
161
+ # foo.func and foo is local var. OR
162
+ # Foo::Bar.func
143
163
  begin
144
- candidates = eval(receiver, bind).methods.collect(&:to_s)
164
+ candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
145
165
  rescue Pry::RescuableException
146
166
  candidates = []
147
167
  end
148
- select_message(path, receiver, message, candidates)
149
- when GLOBALVARIABLE_REGEXP # global
150
- regmessage = Regexp.new(Regexp.quote($1))
151
- candidates = global_variables.collect(&:to_s).grep(regmessage)
152
- when VARIABLE_REGEXP # variable
153
- receiver = $1
154
- message = Regexp.quote($2)
155
-
156
- gv = eval("global_variables", bind).collect(&:to_s)
157
- lv = eval("local_variables", bind).collect(&:to_s)
158
- cv = eval("self.class.constants", bind).collect(&:to_s)
159
-
160
- if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
161
- # foo.func and foo is local var. OR
162
- # Foo::Bar.func
168
+ else
169
+ # func1.func2
170
+ candidates = []
171
+ ObjectSpace.each_object(Module){|m|
163
172
  begin
164
- candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
173
+ name = m.name.to_s
165
174
  rescue Pry::RescuableException
166
- candidates = []
175
+ name = ""
167
176
  end
168
- else
169
- # func1.func2
170
- candidates = []
171
- ObjectSpace.each_object(Module){|m|
172
- begin
173
- name = m.name.to_s
174
- rescue Pry::RescuableException
175
- name = ""
176
- end
177
- next if name != "IRB::Context" and
178
- /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
179
-
180
- # jruby doesn't always provide #instance_methods() on each
181
- # object.
182
- if m.respond_to?(:instance_methods)
183
- candidates.concat m.instance_methods(false).collect(&:to_s)
184
- end
185
- }
186
- candidates.sort!
187
- candidates.uniq!
188
- end
189
- select_message(path, receiver, message, candidates)
190
- when /^\.([^.]*)$/
191
- # Unknown(maybe String)
192
- receiver = ""
193
- message = Regexp.quote($1)
194
- candidates = String.instance_methods(true).collect(&:to_s)
195
- select_message(path, receiver, message, candidates)
196
- else
197
- candidates = eval(
198
- "methods | private_methods | local_variables | " \
199
- "self.class.constants | instance_variables",
200
- bind
201
- ).collect(&:to_s)
177
+ next if name != "IRB::Context" and
178
+ /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
202
179
 
203
- if eval("respond_to?(:class_variables)", bind)
204
- candidates += eval("class_variables", bind).collect(&:to_s)
205
- end
206
- candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/)
207
- candidates.collect(&path)
180
+ # jruby doesn't always provide #instance_methods() on each
181
+ # object.
182
+ if m.respond_to?(:instance_methods)
183
+ candidates.concat m.instance_methods(false).collect(&:to_s)
184
+ end
185
+ }
186
+ candidates.sort!
187
+ candidates.uniq!
208
188
  end
209
- rescue Pry::RescuableException
210
- []
211
- end
212
- end
189
+ select_message(path, receiver, message, candidates)
190
+ when /^\.([^.]*)$/
191
+ # Unknown(maybe String)
192
+ receiver = ""
193
+ message = Regexp.quote($1)
194
+ candidates = String.instance_methods(true).collect(&:to_s)
195
+ select_message(path, receiver, message, candidates)
196
+ else
197
+ candidates = eval(
198
+ "methods | private_methods | local_variables | " \
199
+ "self.class.constants | instance_variables",
200
+ bind
201
+ ).collect(&:to_s)
213
202
 
214
- def select_message(path, receiver, message, candidates)
215
- candidates.grep(/^#{message}/).collect { |e|
216
- case e
217
- when /^[a-zA-Z_]/
218
- path.call(receiver + "." << e)
219
- when /^[0-9]/
220
- when *Operators
221
- #receiver + " " << e
203
+ if eval("respond_to?(:class_variables)", bind)
204
+ candidates += eval("class_variables", bind).collect(&:to_s)
222
205
  end
223
- }.compact
206
+ candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/)
207
+ candidates.collect(&path)
208
+ end
209
+ rescue Pry::RescuableException
210
+ []
224
211
  end
212
+ end
225
213
 
226
- # build_path seperates the input into two parts: path and input.
227
- # input is the partial string that should be completed
228
- # path is a proc that takes an input and builds a full path.
229
- def build_path(input)
230
- # check to see if the input is a regex
231
- return proc {|i| i.to_s }, input if input[/\/\./]
232
- trailing_slash = input.end_with?('/')
233
- contexts = input.chomp('/').split(/\//)
234
- input = contexts[-1]
235
- path = proc do |i|
236
- p = contexts[0..-2].push(i).join('/')
237
- p += '/' if trailing_slash && !i.nil?
238
- p
214
+ def select_message(path, receiver, message, candidates)
215
+ candidates.grep(/^#{message}/).collect { |e|
216
+ case e
217
+ when /^[a-zA-Z_]/
218
+ path.call(receiver + "." << e)
219
+ when /^[0-9]/
220
+ when *Operators
221
+ #receiver + " " << e
239
222
  end
240
- return path, input
223
+ }.compact
224
+ end
225
+
226
+ # build_path seperates the input into two parts: path and input.
227
+ # input is the partial string that should be completed
228
+ # path is a proc that takes an input and builds a full path.
229
+ def build_path(input)
230
+ # check to see if the input is a regex
231
+ return proc {|i| i.to_s }, input if input[/\/\./]
232
+ trailing_slash = input.end_with?('/')
233
+ contexts = input.chomp('/').split(/\//)
234
+ input = contexts[-1]
235
+ path = proc do |i|
236
+ p = contexts[0..-2].push(i).join('/')
237
+ p += '/' if trailing_slash && !i.nil?
238
+ p
241
239
  end
240
+ return path, input
241
+ end
242
242
  end
@@ -140,11 +140,11 @@ class Pry
140
140
  # @param [Boolean] include_super Whether to include methods from ancestors.
141
141
  # @return [Array[Pry::Method]]
142
142
  def all_from_class(klass, include_super=true)
143
- %w(public protected private).map do |visibility|
143
+ %w(public protected private).flat_map do |visibility|
144
144
  safe_send(klass, :"#{visibility}_instance_methods", include_super).map do |method_name|
145
145
  new(safe_send(klass, :instance_method, method_name), :visibility => visibility.to_sym)
146
146
  end
147
- end.flatten(1)
147
+ end
148
148
  end
149
149
 
150
150
  #
@@ -163,7 +163,7 @@ class Pry
163
163
 
164
164
  #
165
165
  # @deprecated
166
- # please use {#all_from_obj} instead.
166
+ # please use {all_from_obj} instead.
167
167
  # the `method_type` argument is ignored.
168
168
  #
169
169
  def all_from_common(obj, method_type = nil, include_super=true)
@@ -212,9 +212,9 @@ class Pry
212
212
  # the lowest copy will be returned.
213
213
  def singleton_class_resolution_order(klass)
214
214
  ancestors = Pry::Method.safe_send(klass, :ancestors)
215
- resolution_order = ancestors.grep(Class).map do |anc|
215
+ resolution_order = ancestors.grep(Class).flat_map do |anc|
216
216
  [singleton_class_of(anc), *singleton_class_of(anc).included_modules]
217
- end.flatten(1)
217
+ end
218
218
 
219
219
  resolution_order.reverse.uniq.reverse - Class.included_modules
220
220
  end
@@ -359,13 +359,13 @@ class Pry
359
359
  # Paraphrased from `awesome_print` gem.
360
360
  def signature
361
361
  if respond_to?(:parameters)
362
- args = parameters.inject([]) do |arr, (type, name)|
363
- name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
364
- arr << case type
365
- when :req then name.to_s
366
- when :opt then "#{name}=?"
367
- when :rest then "*#{name}"
368
- when :block then "&#{name}"
362
+ args = parameters.inject([]) do |arr, (typ, nam)|
363
+ nam ||= (typ == :block ? 'block' : "arg#{arr.size + 1}")
364
+ arr << case typ
365
+ when :req then nam.to_s
366
+ when :opt then "#{nam}=?"
367
+ when :rest then "*#{nam}"
368
+ when :block then "&#{nam}"
369
369
  else '?'
370
370
  end
371
371
  end
@@ -484,7 +484,7 @@ class Pry
484
484
  else
485
485
  fail_msg = "Cannot locate this method: #{name}."
486
486
  if mri?
487
- fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.'
487
+ fail_msg += " Invoke the 'gem-install pry-doc' Pry command to get access to Ruby Core documentation.\n"
488
488
  end
489
489
  raise CommandError, fail_msg
490
490
  end
@@ -22,6 +22,7 @@ class Pry
22
22
  # @param [String] method_name
23
23
  def initialize(receiver, method_name, binding=nil)
24
24
  @receiver, @name = receiver, method_name
25
+ @method = nil
25
26
  end
26
27
 
27
28
  # Is the method undefined? (aka `Disowned`)
@@ -42,9 +42,6 @@ class Pry
42
42
  # transation we make that not happen, which means that alias_method_chains, etc.
43
43
  # continue to work.
44
44
  #
45
- # @param [String] meth_name The method name before aliasing
46
- # @param [Module] target The owner of the method
47
-
48
45
  def with_method_transaction
49
46
  temp_name = "__pry_#{method.original_name}__"
50
47
  method = self.method
@@ -1,50 +1,49 @@
1
- class Pry
2
- class Output
3
- attr_reader :_pry_
1
+ class Pry::Output
2
+ attr_reader :_pry_
4
3
 
5
- def initialize(_pry_)
6
- @_pry_ = _pry_
7
- end
8
-
9
- def puts(*objs)
10
- return print "\n" if objs.empty?
4
+ def initialize(_pry_)
5
+ @_pry_ = _pry_
6
+ @boxed_io = _pry_.config.output
7
+ end
11
8
 
12
- objs.each do |obj|
13
- if ary = Array.try_convert(obj)
14
- puts(*ary)
15
- else
16
- print "#{obj.to_s.chomp}\n"
17
- end
9
+ def puts(*objs)
10
+ return print "\n" if objs.empty?
11
+ objs.each do |obj|
12
+ if ary = Array.try_convert(obj)
13
+ puts(*ary)
14
+ else
15
+ print "#{obj.to_s.chomp}\n"
18
16
  end
19
-
20
- nil
21
17
  end
18
+ nil
19
+ end
22
20
 
23
- def print(*objs)
24
- objs.each do |obj|
25
- _pry_.config.output.print decolorize_maybe(obj.to_s)
26
- end
27
-
28
- nil
21
+ def print(*objs)
22
+ objs.each do |obj|
23
+ @boxed_io.print decolorize_maybe(obj.to_s)
29
24
  end
30
- alias << print
31
- alias write print
25
+ nil
26
+ end
27
+ alias << print
28
+ alias write print
32
29
 
33
- # If _pry_.config.color is currently false, removes ansi escapes from the string.
34
- def decolorize_maybe(str)
35
- if _pry_.config.color
36
- str
37
- else
38
- Helpers::Text.strip_color str
39
- end
40
- end
30
+ def tty?
31
+ @boxed_io.respond_to?(:tty?) and @boxed_io.tty?
32
+ end
41
33
 
42
- def method_missing(name, *args, &block)
43
- _pry_.config.output.send(name, *args, &block)
44
- end
34
+ def method_missing(name, *args, &block)
35
+ @boxed_io.__send__(name, *args, &block)
36
+ end
37
+
38
+ def respond_to_missing?(*a)
39
+ @boxed_io.respond_to?(*a)
40
+ end
45
41
 
46
- def respond_to_missing?(*a)
47
- _pry_.config.respond_to?(*a)
42
+ def decolorize_maybe(str)
43
+ if _pry_.config.color
44
+ str
45
+ else
46
+ Pry::Helpers::Text.strip_color str
48
47
  end
49
48
  end
50
49
  end
@@ -14,11 +14,12 @@ class Pry::Pager
14
14
  end
15
15
 
16
16
  # Send the given text through the best available pager (if `Pry.config.pager` is
17
- # enabled).
18
- # If you want to send text through in chunks as you generate it, use `open` to
19
- # get a writable object instead.
20
- # @param [String] text A piece of text to run through a pager.
21
- # @param [IO] output (`$stdout`) An object to send output to.
17
+ # enabled). If you want to send text through in chunks as you generate it, use `open`
18
+ # to get a writable object instead.
19
+ #
20
+ # @param [String] text
21
+ # Text to run through a pager.
22
+ #
22
23
  def page(text)
23
24
  open do |pager|
24
25
  pager << text
@@ -27,7 +28,6 @@ class Pry::Pager
27
28
 
28
29
  # Yields a pager object (`NullPager`, `SimplePager`, or `SystemPager`). All
29
30
  # pagers accept output with `#puts`, `#print`, `#write`, and `#<<`.
30
- # @param [IO] output (`$stdout`) An object to send output to.
31
31
  def open
32
32
  pager = best_available
33
33
  yield pager
@@ -48,7 +48,6 @@ class Pry::Pager
48
48
  # `#print`, `#write`, and `#<<`. You must call `#close` when you're done
49
49
  # writing output to a pager, and you must rescue `Pry::Pager::StopPaging`.
50
50
  # These requirements can be avoided by using `.open` instead.
51
- # @param [#<<] output ($stdout) An object to send output to.
52
51
  def best_available
53
52
  if !_pry_.config.pager
54
53
  NullPager.new(_pry_.output)
@@ -139,7 +138,11 @@ class Pry::Pager
139
138
  if @system_pager.nil?
140
139
  @system_pager = begin
141
140
  pager_executable = default_pager.split(' ').first
142
- `which #{pager_executable}`
141
+ if Pry::Helpers::BaseHelpers.windows? || Pry::Helpers::BaseHelpers.windows_ansi?
142
+ `where #{pager_executable}`
143
+ else
144
+ `which #{pager_executable}`
145
+ end
143
146
  $?.success?
144
147
  rescue
145
148
  false