pry 0.9.8.4-i386-mswin32 → 0.9.9-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.
Files changed (46) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG +26 -0
  3. data/README.markdown +3 -3
  4. data/lib/pry.rb +9 -1
  5. data/lib/pry/code.rb +93 -0
  6. data/lib/pry/command.rb +35 -22
  7. data/lib/pry/command_set.rb +97 -67
  8. data/lib/pry/config.rb +63 -10
  9. data/lib/pry/core_extensions.rb +24 -18
  10. data/lib/pry/default_commands/context.rb +72 -12
  11. data/lib/pry/default_commands/easter_eggs.rb +4 -0
  12. data/lib/pry/default_commands/editing.rb +43 -15
  13. data/lib/pry/default_commands/find_method.rb +171 -0
  14. data/lib/pry/default_commands/hist.rb +10 -6
  15. data/lib/pry/default_commands/introspection.rb +183 -30
  16. data/lib/pry/default_commands/ls.rb +77 -7
  17. data/lib/pry/default_commands/misc.rb +1 -0
  18. data/lib/pry/default_commands/navigating_pry.rb +1 -8
  19. data/lib/pry/helpers/base_helpers.rb +10 -2
  20. data/lib/pry/helpers/command_helpers.rb +23 -40
  21. data/lib/pry/helpers/documentation_helpers.rb +65 -0
  22. data/lib/pry/indent.rb +17 -4
  23. data/lib/pry/method.rb +61 -45
  24. data/lib/pry/pry_class.rb +9 -3
  25. data/lib/pry/pry_instance.rb +99 -65
  26. data/lib/pry/rbx_method.rb +2 -9
  27. data/lib/pry/version.rb +1 -1
  28. data/lib/pry/wrapped_module.rb +236 -1
  29. data/pry.gemspec +5 -5
  30. data/test/helper.rb +22 -0
  31. data/test/test_command.rb +29 -0
  32. data/test/test_command_integration.rb +193 -10
  33. data/test/test_command_set.rb +82 -17
  34. data/test/test_default_commands/test_cd.rb +16 -0
  35. data/test/test_default_commands/test_context.rb +61 -0
  36. data/test/test_default_commands/test_documentation.rb +163 -43
  37. data/test/test_default_commands/test_find_method.rb +42 -0
  38. data/test/test_default_commands/test_input.rb +32 -0
  39. data/test/test_default_commands/test_introspection.rb +50 -197
  40. data/test/test_default_commands/test_ls.rb +22 -0
  41. data/test/test_default_commands/test_show_source.rb +306 -0
  42. data/test/test_pry.rb +3 -3
  43. data/test/test_pry_defaults.rb +21 -0
  44. data/test/test_sticky_locals.rb +81 -1
  45. data/test/test_syntax_checking.rb +7 -6
  46. metadata +24 -16
@@ -1,6 +1,7 @@
1
1
  class Pry
2
2
  module DefaultCommands
3
3
  Misc = Pry::CommandSet.new do
4
+
4
5
  command "toggle-color", "Toggle syntax highlighting." do
5
6
  Pry.color = !Pry.color
6
7
  output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
@@ -72,19 +72,13 @@ class Pry
72
72
 
73
73
  def process
74
74
  if _pry_.binding_stack.one?
75
- # when breaking out of top-level then behave like `exit-all`
76
- process_exit_all
75
+ _pry_.run_command "exit-all #{arg_string}"
77
76
  else
78
77
  # otherwise just pop a binding and return user supplied value
79
78
  process_pop_and_return
80
79
  end
81
80
  end
82
81
 
83
- def process_exit_all
84
- _pry_.binding_stack.clear
85
- throw(:breakout, target.eval(arg_string))
86
- end
87
-
88
82
  def process_pop_and_return
89
83
  popped_object = _pry_.binding_stack.pop.eval('self')
90
84
 
@@ -111,4 +105,3 @@ class Pry
111
105
  end
112
106
  end
113
107
  end
114
-
@@ -110,6 +110,14 @@ class Pry
110
110
  RbConfig::CONFIG['ruby_install_name'] == 'rbx'
111
111
  end
112
112
 
113
+ def mri_18?
114
+ RUBY_VERSION =~ /1.8/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby'
115
+ end
116
+
117
+ def mri_19?
118
+ RUBY_VERSION =~ /1.9/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby'
119
+ end
120
+
113
121
  # a simple pager for systems without `less`. A la windows.
114
122
  def simple_pager(text, output=output())
115
123
  text_array = text.lines.to_a
@@ -138,7 +146,7 @@ class Pry
138
146
  # Sys.
139
147
  $stdout
140
148
  end
141
-
149
+
142
150
  if text.lines.count < page_size || !Pry.pager
143
151
  out.puts text
144
152
  return
@@ -151,7 +159,7 @@ class Pry
151
159
  lesspipe { |less| less.puts text }
152
160
  end
153
161
  rescue Errno::ENOENT
154
- simple_pager(text, output)
162
+ simple_pager(text, out)
155
163
  rescue Errno::EPIPE
156
164
  end
157
165
 
@@ -77,48 +77,13 @@ class Pry
77
77
  header << "#{Pry::Helpers::Text.bold("Number of lines:")} #{content.each_line.count.to_s}\n"
78
78
  end
79
79
 
80
- def process_rdoc(comment, code_type)
81
- comment = comment.dup
82
- comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
83
- gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[1m#{$1}\e[0m": $1 }.
84
- gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[1m#{$1}\e[0m" : $1 }.
85
- gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
86
- gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
87
- gsub(/`(?:\s*\n)?(.*?)\s*`/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }
88
- end
89
-
90
- def process_yardoc_tag(comment, tag)
91
- in_tag_block = nil
92
- comment.lines.map do |v|
93
- if in_tag_block && v !~ /^\S/
94
- Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
95
- elsif in_tag_block
96
- in_tag_block = false
97
- v
98
- else
99
- in_tag_block = true if v =~ /^@#{tag}/
100
- v
101
- end
102
- end.join
103
- end
104
-
105
- def process_yardoc(comment)
106
- yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
107
- "deprecate", "example"]
108
- (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
109
- gsub(/^@(#{yard_tags.join("|")})/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 }
110
- end
111
-
112
- def process_comment_markup(comment, code_type)
113
- process_yardoc process_rdoc(comment, code_type)
114
- end
115
-
116
- def invoke_editor(file, line)
117
- raise CommandError, "Please set Pry.config.editor or export $EDITOR" unless Pry.config.editor
80
+ def invoke_editor(file, line, reloading)
81
+ raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless Pry.config.editor
118
82
  if Pry.config.editor.respond_to?(:call)
119
- editor_invocation = Pry.config.editor.call(file, line)
83
+ args = [file, line, reloading][0...(Pry.config.editor.arity)]
84
+ editor_invocation = Pry.config.editor.call(*args)
120
85
  else
121
- editor_invocation = "#{Pry.config.editor} #{start_line_syntax_for_editor(file, line)}"
86
+ editor_invocation = "#{Pry.config.editor} #{blocking_flag_for_editor(reloading)} #{start_line_syntax_for_editor(file, line)}"
122
87
  end
123
88
  return nil unless editor_invocation
124
89
 
@@ -138,6 +103,22 @@ class Pry
138
103
  end
139
104
  end
140
105
 
106
+ # Some editors that run outside the terminal allow you to control whether or
107
+ # not to block the process from which they were launched (in this case, Pry).
108
+ # For those editors, return the flag that produces the desired behavior.
109
+ def blocking_flag_for_editor(block)
110
+ case Pry.config.editor
111
+ when /^emacsclient/
112
+ '--no-wait' unless block
113
+ when /^[gm]vim/
114
+ '--nofork' if block
115
+ when /^jedit/
116
+ '-wait' if block
117
+ when /^mate/, /^subl/
118
+ '-w' if block
119
+ end
120
+ end
121
+
141
122
  # Return the syntax for a given editor for starting the editor
142
123
  # and moving to a particular line within that file
143
124
  def start_line_syntax_for_editor(file_name, line_number)
@@ -153,6 +134,8 @@ class Pry
153
134
  "+#{line_number} #{file_name}"
154
135
  when /^mate/, /^geany/
155
136
  "-l #{line_number} #{file_name}"
137
+ when /^subl/
138
+ "#{file_name}:#{line_number}"
156
139
  when /^uedit32/
157
140
  "#{file_name}/#{line_number}"
158
141
  when /^jedit/
@@ -0,0 +1,65 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ # This class contains methods useful for extracting
5
+ # documentation from methods and classes.
6
+ module DocumentationHelpers
7
+ def process_rdoc(comment, code_type)
8
+ comment = comment.dup
9
+ comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
10
+ gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[1m#{$1}\e[0m": $1 }.
11
+ gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[1m#{$1}\e[0m" : $1 }.
12
+ gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
13
+ gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
14
+ gsub(/`(?:\s*\n)?(.*?)\s*`/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }
15
+ end
16
+
17
+ def process_yardoc_tag(comment, tag)
18
+ in_tag_block = nil
19
+ comment.lines.map do |v|
20
+ if in_tag_block && v !~ /^\S/
21
+ Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
22
+ elsif in_tag_block
23
+ in_tag_block = false
24
+ v
25
+ else
26
+ in_tag_block = true if v =~ /^@#{tag}/
27
+ v
28
+ end
29
+ end.join
30
+ end
31
+
32
+ def process_yardoc(comment)
33
+ yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
34
+ "deprecate", "example"]
35
+ (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
36
+ gsub(/^@(#{yard_tags.join("|")})/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 }
37
+ end
38
+
39
+ def process_comment_markup(comment, code_type)
40
+ process_yardoc process_rdoc(comment, code_type)
41
+ end
42
+
43
+ # @param [String] code
44
+ # @return [String]
45
+ def strip_comments_from_c_code(code)
46
+ code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
47
+ end
48
+
49
+ # @param [String] comment
50
+ # @return [String]
51
+ def strip_leading_hash_and_whitespace_from_ruby_comments(comment)
52
+ comment = comment.dup
53
+ comment.gsub!(/\A\#+?$/, '')
54
+ comment.gsub!(/^\s*#/, '')
55
+ strip_leading_whitespace(comment)
56
+ end
57
+
58
+ # @param [String] text
59
+ # @return [String]
60
+ def strip_leading_whitespace(text)
61
+ Pry::Helpers::CommandHelpers.unindent(text)
62
+ end
63
+ end
64
+ end
65
+ end
data/lib/pry/indent.rb CHANGED
@@ -1,6 +1,14 @@
1
1
  require 'coderay'
2
2
 
3
3
  class Pry
4
+ begin
5
+ require 'io/console'
6
+ rescue LoadError
7
+ IO_CONSOLE_AVAILABLE = false
8
+ else
9
+ IO_CONSOLE_AVAILABLE = true
10
+ end
11
+
4
12
  ##
5
13
  # Pry::Indent is a class that can be used to indent a number of lines
6
14
  # containing Ruby code similar as to how IRB does it (but better). The class
@@ -187,12 +195,17 @@ class Pry
187
195
  # Return a string which, when printed, will rewrite the previous line with
188
196
  # the correct indentation. Mostly useful for fixing 'end'.
189
197
  #
190
- # @param [String] full_line The full line of input, including the prompt.
198
+ # @param [String] prompt The user's prompt
199
+ # @param [String] code The code the user just typed in.
191
200
  # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e.,
192
201
  # the difference in length between the old line and the new one).
193
202
  # @return [String]
194
- def correct_indentation(full_line, overhang=0)
195
- if Readline.respond_to?(:get_screen_size)
203
+ def correct_indentation(prompt, code, overhang=0)
204
+ full_line = prompt + code
205
+ if IO_CONSOLE_AVAILABLE && $stdout.tty?
206
+ _, cols = $stdout.winsize
207
+ lines = full_line.length / cols + 1
208
+ elsif Readline.respond_to?(:get_screen_size)
196
209
  _, cols = Readline.get_screen_size
197
210
  lines = full_line.length / cols + 1
198
211
  elsif ENV['COLUMNS'] && ENV['COLUMNS'] != ''
@@ -211,7 +224,7 @@ class Pry
211
224
  end
212
225
  whitespace = ' ' * overhang
213
226
 
214
- "#{move_up}#{full_line}#{whitespace}#{move_down}"
227
+ "#{move_up}#{prompt}#{CodeRay.scan(code, :ruby).term}#{whitespace}#{move_down}"
215
228
  end
216
229
  end
217
230
  end
data/lib/pry/method.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'pry/helpers/documentation_helpers'
3
+
2
4
  class Pry
3
5
  class << self
4
6
  # If the given object is a `Pry::Method`, return it unaltered. If it's
@@ -12,8 +14,11 @@ class Pry
12
14
  end
13
15
  end
14
16
 
17
+ # This class wraps the normal `Method` and `UnboundMethod` classes
18
+ # to provide extra functionality useful to Pry.
15
19
  class Method
16
20
  include RbxMethod if Helpers::BaseHelpers.rbx?
21
+ include Helpers::DocumentationHelpers
17
22
 
18
23
  class << self
19
24
  # Given a string representing a method name and optionally a binding to
@@ -62,7 +67,7 @@ class Pry
62
67
  nil
63
68
  else
64
69
  method = begin
65
- new(b.eval("method(#{meth_name.to_s.inspect})"))
70
+ new(b.eval("Object.instance_method(:method).bind(self).call(#{meth_name.to_s.inspect})"))
66
71
  rescue NameError, NoMethodError
67
72
  Disowned.new(b.eval('self'), meth_name.to_s)
68
73
  end
@@ -126,16 +131,18 @@ class Pry
126
131
 
127
132
  # Get all of the instance methods of a `Class` or `Module`
128
133
  # @param [Class,Module] klass
134
+ # @param [Boolean] include_super Whether to include methods from ancestors.
129
135
  # @return [Array[Pry::Method]]
130
- def all_from_class(klass)
131
- all_from_common(klass, :instance_method)
136
+ def all_from_class(klass, include_super=true)
137
+ all_from_common(klass, :instance_method, include_super)
132
138
  end
133
139
 
134
140
  # Get all of the methods on an `Object`
135
141
  # @param [Object] obj
142
+ # @param [Boolean] include_super Whether to include methods from ancestors.
136
143
  # @return [Array[Pry::Method]]
137
- def all_from_obj(obj)
138
- all_from_common(obj, :method)
144
+ def all_from_obj(obj, include_super=true)
145
+ all_from_common(obj, :method, include_super)
139
146
  end
140
147
 
141
148
  # Get every `Class` and `Module`, in order, that will be checked when looking
@@ -168,9 +175,9 @@ class Pry
168
175
  # If method_type is :method, obj can be any `Object`
169
176
  #
170
177
  # N.B. we pre-cache the visibility here to avoid O(N²) behaviour in "ls".
171
- def all_from_common(obj, method_type)
178
+ def all_from_common(obj, method_type, include_super=true)
172
179
  %w(public protected private).map do |visibility|
173
- safe_send(obj, :"#{visibility}_#{method_type}s").map do |method_name|
180
+ safe_send(obj, :"#{visibility}_#{method_type}s", include_super).map do |method_name|
174
181
  new(safe_send(obj, method_type, method_name), :visibility => visibility.to_sym)
175
182
  end
176
183
  end.flatten(1)
@@ -183,6 +190,7 @@ class Pry
183
190
  def safe_send(obj, method, *args, &block)
184
191
  (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block)
185
192
  end
193
+ public :safe_send
186
194
 
187
195
  # Get the singleton classes of superclasses that could define methods on
188
196
  # the given class object, and any modules they include.
@@ -239,21 +247,21 @@ class Pry
239
247
  # @return [String, nil] The source code of the method, or `nil` if it's unavailable.
240
248
  def source
241
249
  @source ||= case source_type
242
- when :c
243
- info = pry_doc_info
244
- if info and info.source
245
- code = strip_comments_from_c_code(info.source)
246
- end
247
- when :ruby
248
- if Helpers::BaseHelpers.rbx? && core?
249
- code = core_code
250
- elsif pry_method?
251
- code = Pry.new(:input => StringIO.new(Pry.line_buffer[source_line..-1].join), :prompt => proc {""}, :hooks => Pry::Hooks.new).r
252
- else
253
- code = @method.source
254
- end
255
- strip_leading_whitespace(code)
256
- end
250
+ when :c
251
+ info = pry_doc_info
252
+ if info and info.source
253
+ code = strip_comments_from_c_code(info.source)
254
+ end
255
+ when :ruby
256
+ if Helpers::BaseHelpers.rbx? && !pry_method?
257
+ code = core_code
258
+ elsif pry_method?
259
+ code = Pry::Code.retrieve_complete_expression_from(Pry.line_buffer[source_line..-1])
260
+ else
261
+ code = @method.source
262
+ end
263
+ strip_leading_whitespace(code)
264
+ end
257
265
  end
258
266
 
259
267
  # @return [String, nil] The documentation for the method, or `nil` if it's
@@ -265,10 +273,12 @@ class Pry
265
273
  info = pry_doc_info
266
274
  info.docstring if info
267
275
  when :ruby
268
- if Helpers::BaseHelpers.rbx? && core?
269
- strip_leading_hash_and_whitespace_from_ruby_comments(core_doc)
276
+ if Helpers::BaseHelpers.rbx? && !pry_method?
277
+ strip_leading_hash_and_whitespace_from_ruby_comments(core_doc)
270
278
  elsif pry_method?
271
- raise CommandError, "Can't view doc for a REPL-defined method."
279
+ # raise CommandError, "Can't view doc for a REPL-defined
280
+ # method."
281
+ strip_leading_hash_and_whitespace_from_ruby_comments(doc_for_pry_method)
272
282
  else
273
283
  strip_leading_hash_and_whitespace_from_ruby_comments(@method.comment)
274
284
  end
@@ -281,6 +291,15 @@ class Pry
281
291
  source_location.nil? ? :c : :ruby
282
292
  end
283
293
 
294
+ def source_location
295
+ if @method.source_location && Helpers::BaseHelpers.rbx?
296
+ file, line = @method.source_location
297
+ [RbxPath.convert_path_to_full(file), line]
298
+ else
299
+ @method.source_location
300
+ end
301
+ end
302
+
284
303
  # @return [String, nil] The name of the file the method is defined in, or
285
304
  # `nil` if the filename is unavailable.
286
305
  def source_file
@@ -303,7 +322,7 @@ class Pry
303
322
  # @return [Range, nil] The range of lines in `source_file` which contain
304
323
  # the method's definition, or `nil` if that information is unavailable.
305
324
  def source_range
306
- source_location.nil? ? nil : (source_line)...(source_line + source.lines.count)
325
+ source_location.nil? ? nil : (source_line)..(source_line + source.lines.count - 1)
307
326
  end
308
327
 
309
328
  # @return [Symbol] The visibility of the method. May be `:public`,
@@ -382,7 +401,7 @@ class Pry
382
401
  # @return [Boolean]
383
402
  def ==(obj)
384
403
  if obj.is_a? Pry::Method
385
- super
404
+ obj == @method
386
405
  else
387
406
  @method == obj
388
407
  end
@@ -411,31 +430,28 @@ class Pry
411
430
  # @raise [CommandError] Raises when the method can't be found or `pry-doc` isn't installed.
412
431
  def pry_doc_info
413
432
  if Pry.config.has_pry_doc
414
- Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}."
433
+ Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
415
434
  else
416
435
  raise CommandError, "Cannot locate this method: #{name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
417
436
  end
418
437
  end
419
438
 
420
- # @param [String] code
421
- # @return [String]
422
- def strip_comments_from_c_code(code)
423
- code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
424
- end
439
+ # FIXME: a very similar method to this exists on WrappedModule: extract_doc_for_candidate
440
+ def doc_for_pry_method
441
+ _, line = source_location
425
442
 
426
- # @param [String] comment
427
- # @return [String]
428
- def strip_leading_hash_and_whitespace_from_ruby_comments(comment)
429
- comment = comment.dup
430
- comment.gsub!(/\A\#+?$/, '')
431
- comment.gsub!(/^\s*#/, '')
432
- strip_leading_whitespace(comment)
433
- end
443
+ buffer = ""
444
+ Pry.line_buffer[0..(line - 1)].each do |line|
445
+ # Add any line that is a valid ruby comment,
446
+ # but clear as soon as we hit a non comment line.
447
+ if (line =~ /^\s*#/) || (line =~ /^\s*$/)
448
+ buffer << line.lstrip
449
+ else
450
+ buffer.replace("")
451
+ end
452
+ end
434
453
 
435
- # @param [String] text
436
- # @return [String]
437
- def strip_leading_whitespace(text)
438
- Pry::Helpers::CommandHelpers.unindent(text)
454
+ buffer
439
455
  end
440
456
 
441
457
  # @param [Class,Module] the ancestors to investigate