pry 0.10.pre.1-i386-mingw32 → 0.10.0.pre3-i386-mingw32

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 (214) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +2 -2
  4. data/{README.markdown → README.md} +41 -35
  5. data/lib/pry.rb +82 -139
  6. data/lib/pry/cli.rb +77 -30
  7. data/lib/pry/code.rb +122 -183
  8. data/lib/pry/code/code_file.rb +103 -0
  9. data/lib/pry/code/code_range.rb +71 -0
  10. data/lib/pry/code/loc.rb +92 -0
  11. data/lib/pry/code_object.rb +172 -0
  12. data/lib/pry/color_printer.rb +55 -0
  13. data/lib/pry/command.rb +184 -28
  14. data/lib/pry/command_set.rb +113 -59
  15. data/lib/pry/commands.rb +4 -27
  16. data/lib/pry/commands/amend_line.rb +99 -0
  17. data/lib/pry/commands/bang.rb +20 -0
  18. data/lib/pry/commands/bang_pry.rb +17 -0
  19. data/lib/pry/commands/cat.rb +62 -0
  20. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  21. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  22. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  23. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  24. data/lib/pry/commands/cd.rb +41 -0
  25. data/lib/pry/commands/change_inspector.rb +27 -0
  26. data/lib/pry/commands/change_prompt.rb +26 -0
  27. data/lib/pry/commands/code_collector.rb +165 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/disabled_commands.rb +2 -0
  30. data/lib/pry/commands/easter_eggs.rb +112 -0
  31. data/lib/pry/commands/edit.rb +195 -0
  32. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  33. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  34. data/lib/pry/commands/exit.rb +42 -0
  35. data/lib/pry/commands/exit_all.rb +29 -0
  36. data/lib/pry/commands/exit_program.rb +23 -0
  37. data/lib/pry/commands/find_method.rb +193 -0
  38. data/lib/pry/commands/fix_indent.rb +19 -0
  39. data/lib/pry/commands/gem_cd.rb +26 -0
  40. data/lib/pry/commands/gem_install.rb +32 -0
  41. data/lib/pry/commands/gem_list.rb +33 -0
  42. data/lib/pry/commands/gem_open.rb +29 -0
  43. data/lib/pry/commands/gist.rb +101 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +180 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +53 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/list_inspectors.rb +35 -0
  50. data/lib/pry/commands/list_prompts.rb +35 -0
  51. data/lib/pry/commands/ls.rb +114 -0
  52. data/lib/pry/commands/ls/constants.rb +47 -0
  53. data/lib/pry/commands/ls/formatter.rb +49 -0
  54. data/lib/pry/commands/ls/globals.rb +48 -0
  55. data/lib/pry/commands/ls/grep.rb +21 -0
  56. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  57. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  58. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  59. data/lib/pry/commands/ls/local_names.rb +35 -0
  60. data/lib/pry/commands/ls/local_vars.rb +39 -0
  61. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  62. data/lib/pry/commands/ls/methods.rb +57 -0
  63. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  64. data/lib/pry/commands/ls/self_methods.rb +32 -0
  65. data/lib/pry/commands/nesting.rb +25 -0
  66. data/lib/pry/commands/play.rb +103 -0
  67. data/lib/pry/commands/pry_backtrace.rb +25 -0
  68. data/lib/pry/commands/pry_version.rb +17 -0
  69. data/lib/pry/commands/raise_up.rb +32 -0
  70. data/lib/pry/commands/reload_code.rb +62 -0
  71. data/lib/pry/commands/reset.rb +18 -0
  72. data/lib/pry/commands/ri.rb +60 -0
  73. data/lib/pry/commands/save_file.rb +61 -0
  74. data/lib/pry/commands/shell_command.rb +48 -0
  75. data/lib/pry/commands/shell_mode.rb +25 -0
  76. data/lib/pry/commands/show_doc.rb +83 -0
  77. data/lib/pry/commands/show_info.rb +195 -0
  78. data/lib/pry/commands/show_input.rb +17 -0
  79. data/lib/pry/commands/show_source.rb +50 -0
  80. data/lib/pry/commands/simple_prompt.rb +22 -0
  81. data/lib/pry/commands/stat.rb +40 -0
  82. data/lib/pry/commands/switch_to.rb +23 -0
  83. data/lib/pry/commands/toggle_color.rb +24 -0
  84. data/lib/pry/commands/watch_expression.rb +105 -0
  85. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  86. data/lib/pry/commands/whereami.rb +190 -0
  87. data/lib/pry/commands/wtf.rb +57 -0
  88. data/lib/pry/config.rb +20 -229
  89. data/lib/pry/config/behavior.rb +139 -0
  90. data/lib/pry/config/convenience.rb +26 -0
  91. data/lib/pry/config/default.rb +165 -0
  92. data/lib/pry/core_extensions.rb +59 -38
  93. data/lib/pry/editor.rb +133 -0
  94. data/lib/pry/exceptions.rb +77 -0
  95. data/lib/pry/helpers.rb +1 -0
  96. data/lib/pry/helpers/base_helpers.rb +40 -154
  97. data/lib/pry/helpers/command_helpers.rb +19 -130
  98. data/lib/pry/helpers/documentation_helpers.rb +21 -11
  99. data/lib/pry/helpers/table.rb +109 -0
  100. data/lib/pry/helpers/text.rb +8 -9
  101. data/lib/pry/history.rb +61 -45
  102. data/lib/pry/history_array.rb +11 -1
  103. data/lib/pry/hooks.rb +10 -32
  104. data/lib/pry/indent.rb +110 -38
  105. data/lib/pry/input_completer.rb +242 -0
  106. data/lib/pry/input_lock.rb +132 -0
  107. data/lib/pry/inspector.rb +27 -0
  108. data/lib/pry/last_exception.rb +61 -0
  109. data/lib/pry/method.rb +199 -200
  110. data/lib/pry/method/disowned.rb +53 -0
  111. data/lib/pry/method/patcher.rb +125 -0
  112. data/lib/pry/method/weird_method_locator.rb +186 -0
  113. data/lib/pry/module_candidate.rb +39 -33
  114. data/lib/pry/object_path.rb +82 -0
  115. data/lib/pry/output.rb +50 -0
  116. data/lib/pry/pager.rb +234 -0
  117. data/lib/pry/plugins.rb +4 -3
  118. data/lib/pry/prompt.rb +26 -0
  119. data/lib/pry/pry_class.rb +199 -227
  120. data/lib/pry/pry_instance.rb +344 -403
  121. data/lib/pry/rbx_path.rb +1 -1
  122. data/lib/pry/repl.rb +202 -0
  123. data/lib/pry/repl_file_loader.rb +20 -26
  124. data/lib/pry/rubygem.rb +82 -0
  125. data/lib/pry/terminal.rb +79 -0
  126. data/lib/pry/test/helper.rb +170 -0
  127. data/lib/pry/version.rb +1 -1
  128. data/lib/pry/wrapped_module.rb +133 -48
  129. metadata +132 -197
  130. data/.document +0 -2
  131. data/.gemtest +0 -0
  132. data/.gitignore +0 -16
  133. data/.travis.yml +0 -17
  134. data/.yardopts +0 -1
  135. data/CHANGELOG +0 -387
  136. data/CONTRIBUTORS +0 -36
  137. data/Gemfile +0 -2
  138. data/Rakefile +0 -137
  139. data/TODO +0 -117
  140. data/examples/example_basic.rb +0 -15
  141. data/examples/example_command_override.rb +0 -32
  142. data/examples/example_commands.rb +0 -36
  143. data/examples/example_hooks.rb +0 -9
  144. data/examples/example_image_edit.rb +0 -67
  145. data/examples/example_input.rb +0 -7
  146. data/examples/example_input2.rb +0 -29
  147. data/examples/example_output.rb +0 -11
  148. data/examples/example_print.rb +0 -6
  149. data/examples/example_prompt.rb +0 -9
  150. data/examples/helper.rb +0 -6
  151. data/lib/pry/completion.rb +0 -221
  152. data/lib/pry/custom_completions.rb +0 -6
  153. data/lib/pry/default_commands/cd.rb +0 -81
  154. data/lib/pry/default_commands/commands.rb +0 -62
  155. data/lib/pry/default_commands/context.rb +0 -98
  156. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  157. data/lib/pry/default_commands/editing.rb +0 -420
  158. data/lib/pry/default_commands/find_method.rb +0 -169
  159. data/lib/pry/default_commands/gems.rb +0 -84
  160. data/lib/pry/default_commands/gist.rb +0 -187
  161. data/lib/pry/default_commands/help.rb +0 -127
  162. data/lib/pry/default_commands/hist.rb +0 -120
  163. data/lib/pry/default_commands/input_and_output.rb +0 -306
  164. data/lib/pry/default_commands/introspection.rb +0 -410
  165. data/lib/pry/default_commands/ls.rb +0 -272
  166. data/lib/pry/default_commands/misc.rb +0 -38
  167. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  168. data/lib/pry/default_commands/whereami.rb +0 -92
  169. data/lib/pry/extended_commands/experimental.rb +0 -7
  170. data/lib/pry/rbx_method.rb +0 -13
  171. data/man/pry.1 +0 -195
  172. data/man/pry.1.html +0 -204
  173. data/man/pry.1.ronn +0 -141
  174. data/pry.gemspec +0 -46
  175. data/test/candidate_helper1.rb +0 -11
  176. data/test/candidate_helper2.rb +0 -8
  177. data/test/helper.rb +0 -223
  178. data/test/test_cli.rb +0 -78
  179. data/test/test_code.rb +0 -201
  180. data/test/test_command.rb +0 -712
  181. data/test/test_command_helpers.rb +0 -9
  182. data/test/test_command_integration.rb +0 -668
  183. data/test/test_command_set.rb +0 -610
  184. data/test/test_completion.rb +0 -62
  185. data/test/test_control_d_handler.rb +0 -45
  186. data/test/test_default_commands/example.erb +0 -5
  187. data/test/test_default_commands/test_cd.rb +0 -318
  188. data/test/test_default_commands/test_context.rb +0 -280
  189. data/test/test_default_commands/test_documentation.rb +0 -314
  190. data/test/test_default_commands/test_find_method.rb +0 -50
  191. data/test/test_default_commands/test_gems.rb +0 -18
  192. data/test/test_default_commands/test_help.rb +0 -57
  193. data/test/test_default_commands/test_input.rb +0 -428
  194. data/test/test_default_commands/test_introspection.rb +0 -511
  195. data/test/test_default_commands/test_ls.rb +0 -151
  196. data/test/test_default_commands/test_shell.rb +0 -343
  197. data/test/test_default_commands/test_show_source.rb +0 -432
  198. data/test/test_exception_whitelist.rb +0 -21
  199. data/test/test_history_array.rb +0 -65
  200. data/test/test_hooks.rb +0 -521
  201. data/test/test_indent.rb +0 -277
  202. data/test/test_input_stack.rb +0 -86
  203. data/test/test_method.rb +0 -401
  204. data/test/test_pry.rb +0 -463
  205. data/test/test_pry_defaults.rb +0 -419
  206. data/test/test_pry_history.rb +0 -84
  207. data/test/test_pry_output.rb +0 -41
  208. data/test/test_sticky_locals.rb +0 -155
  209. data/test/test_syntax_checking.rb +0 -65
  210. data/test/test_wrapped_module.rb +0 -174
  211. data/test/testrc +0 -2
  212. data/test/testrcbad +0 -2
  213. data/wiki/Customizing-pry.md +0 -397
  214. data/wiki/Home.md +0 -4
@@ -1,6 +1,6 @@
1
1
  class Pry
2
2
  # A history array is an array to which you can only add elements. Older
3
- # entries are removed progressively, so that the aray never contains more than
3
+ # entries are removed progressively, so that the array never contains more than
4
4
  # N elements.
5
5
  #
6
6
  # History arrays are used by Pry to store the output of the last commands.
@@ -89,6 +89,16 @@ class Pry
89
89
  ((@count - size)...@count).map { |n| @hash[n] }
90
90
  end
91
91
 
92
+ # Returns [Hash] copy of the internal @hash history
93
+ def to_h
94
+ @hash.dup
95
+ end
96
+
97
+ def pop!
98
+ @hash.delete @count - 1
99
+ @count -= 1
100
+ end
101
+
92
102
  def inspect
93
103
  "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>"
94
104
  end
data/lib/pry/hooks.rb CHANGED
@@ -18,11 +18,11 @@ class Pry
18
18
  # @param [Hash] hash The hash to convert to `Pry::Hooks`.
19
19
  # @return [Pry::Hooks] The resulting `Pry::Hooks` instance.
20
20
  def self.from_hash(hash)
21
+ return hash if hash.instance_of?(self)
21
22
  instance = new
22
23
  hash.each do |k, v|
23
24
  instance.add_hook(k, nil, v)
24
25
  end
25
-
26
26
  instance
27
27
  end
28
28
 
@@ -49,22 +49,6 @@ class Pry
49
49
  @errors ||= []
50
50
  end
51
51
 
52
- # FIXME:
53
- # This is a hack to alert people of the new API.
54
- def [](event_name)
55
- warn "`Pry.hooks[]` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
56
-
57
- get_hook(event_name, nil)
58
- end
59
-
60
- # FIXME:
61
- # This is a hack to alert people of the new API.
62
- def []=(event_name, callable)
63
- warn "`Pry.hooks[]=` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
64
-
65
- add_hook(event_name, nil, callable)
66
- end
67
-
68
52
  # Destructively merge the contents of two `Pry:Hooks` instances.
69
53
  # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
70
54
  # @return [Pry:Hooks] Returns the receiver.
@@ -146,18 +130,14 @@ class Pry
146
130
  def exec_hook(event_name, *args, &block)
147
131
  @hooks[event_name] ||= []
148
132
 
149
- # silence warnings to get rid of 1.8's "warning: multiple values
150
- # for a block parameter" warnings
151
- Pry::Helpers::BaseHelpers.silence_warnings do
152
- @hooks[event_name].map do |hook_name, callable|
153
- begin
154
- callable.call(*args, &block)
155
- rescue RescuableException => e
156
- errors << e
157
- e
158
- end
159
- end.last
160
- end
133
+ @hooks[event_name].map do |hook_name, callable|
134
+ begin
135
+ callable.call(*args, &block)
136
+ rescue RescuableException => e
137
+ errors << e
138
+ e
139
+ end
140
+ end.last
161
141
  end
162
142
 
163
143
  # Return the number of hook functions registered for the `event_name` event.
@@ -244,9 +224,7 @@ class Pry
244
224
  # @param [Symbol] hook_name Name of the hook.
245
225
  # @return [Boolean] Whether the hook by the name `hook_name`
246
226
  def hook_exists?(event_name, hook_name)
247
- !!@hooks[event_name].find { |name, _| name == hook_name }
227
+ !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name })
248
228
  end
249
- private :hook_exists?
250
-
251
229
  end
252
230
  end
data/lib/pry/indent.rb CHANGED
@@ -1,12 +1,6 @@
1
1
  require 'coderay'
2
2
 
3
3
  class Pry
4
- # Load io-console if possible, so that we can use $stdout.winsize.
5
- begin
6
- require 'io/console'
7
- rescue LoadError
8
- end
9
-
10
4
  ##
11
5
  # Pry::Indent is a class that can be used to indent a number of lines
12
6
  # containing Ruby code similar as to how IRB does it (but better). The class
@@ -17,9 +11,15 @@ class Pry
17
11
  class Indent
18
12
  include Helpers::BaseHelpers
19
13
 
20
- # String containing the spaces to be inserted before the next line.
14
+ # Raised if {#module_nesting} would not work.
15
+ class UnparseableNestingError < StandardError; end
16
+
17
+ # @return [String] String containing the spaces to be inserted before the next line.
21
18
  attr_reader :indent_level
22
19
 
20
+ # @return [Array<String>] The stack of open tokens.
21
+ attr_reader :stack
22
+
23
23
  # The amount of spaces to insert for each indent level.
24
24
  SPACES = ' '
25
25
 
@@ -48,6 +48,9 @@ class Pry
48
48
  # a single-line.
49
49
  SINGLELINE_TOKENS = %w(if while until unless rescue)
50
50
 
51
+ # Which tokens can be followed by an optional "do" keyword.
52
+ OPTIONAL_DO_TOKENS = %w(for while until)
53
+
51
54
  # Collection of token types that should be ignored. Without this list
52
55
  # keywords such as "class" inside strings would cause the code to be
53
56
  # indented incorrectly.
@@ -70,6 +73,32 @@ class Pry
70
73
  # don't affect the surrounding code.
71
74
  MIDWAY_TOKENS = %w(when else elsif ensure rescue)
72
75
 
76
+ # Clean the indentation of a fragment of ruby.
77
+ #
78
+ # @param [String] str
79
+ # @return [String]
80
+ def self.indent(str)
81
+ new.indent(str)
82
+ end
83
+
84
+ # Get the module nesting at the given point in the given string.
85
+ #
86
+ # NOTE If the line specified contains a method definition, then the nesting
87
+ # at the start of the method definition is used. Otherwise the nesting from
88
+ # the end of the line is used.
89
+ #
90
+ # @param [String] str The ruby code to analyze
91
+ # @param [Fixnum] line_number The line number (starting from 1)
92
+ # @return [Array<String>]
93
+ def self.nesting_at(str, line_number)
94
+ indent = new
95
+ lines = str.split("\n")
96
+ n = line_number - 1
97
+ to_indent = lines[0...n] << (lines[n] || "").split("def").first(1)
98
+ indent.indent(to_indent.join("\n") << "\n")
99
+ indent.module_nesting
100
+ end
101
+
73
102
  def initialize
74
103
  reset
75
104
  end
@@ -81,6 +110,8 @@ class Pry
81
110
  @heredoc_queue = []
82
111
  @close_heredocs = {}
83
112
  @string_start = nil
113
+ @awaiting_class = false
114
+ @module_nesting = []
84
115
  self
85
116
  end
86
117
 
@@ -126,7 +157,6 @@ class Pry
126
157
  new_prefix = prefix + SPACES * after
127
158
 
128
159
  line = prefix + line.lstrip unless previously_in_string
129
- line = line.rstrip + "\n" unless in_string?
130
160
 
131
161
  output += line
132
162
 
@@ -135,7 +165,7 @@ class Pry
135
165
 
136
166
  @indent_level = prefix
137
167
 
138
- return output.gsub(/\s+$/, '')
168
+ return output
139
169
  end
140
170
 
141
171
  # Get the indentation for the start of the next line.
@@ -189,7 +219,9 @@ class Pry
189
219
  last_token, last_kind = token, kind unless kind == :space
190
220
  next if IGNORE_TOKENS.include?(kind)
191
221
 
192
- seen_for_at << add_after if token == "for"
222
+ track_module_nesting(token, kind)
223
+
224
+ seen_for_at << add_after if OPTIONAL_DO_TOKENS.include?(token)
193
225
 
194
226
  if kind == :delimiter
195
227
  track_delimiter(token)
@@ -197,7 +229,8 @@ class Pry
197
229
  @stack << token
198
230
  add_after += 1
199
231
  elsif token == OPEN_TOKENS[@stack.last]
200
- @stack.pop
232
+ popped = @stack.pop
233
+ track_module_nesting_end(popped)
201
234
  if add_after == 0
202
235
  remove_before += 1
203
236
  else
@@ -279,6 +312,68 @@ class Pry
279
312
  "puts #{open_delimiters.join(", ")}"
280
313
  end
281
314
 
315
+ # Update the internal state relating to module nesting.
316
+ #
317
+ # It's responsible for adding to the @module_nesting array, which looks
318
+ # something like:
319
+ #
320
+ # [ ["class", "Foo"], ["module", "Bar::Baz"], ["class <<", "self"] ]
321
+ #
322
+ # A nil value in the @module_nesting array happens in two places: either
323
+ # when @awaiting_class is true and we're still waiting for the string to
324
+ # fill that space, or when a parse was rejected.
325
+ #
326
+ # At the moment this function is quite restricted about what formats it will
327
+ # parse, for example we disallow expressions after the class keyword. This
328
+ # could maybe be improved in the future.
329
+ #
330
+ # @param [String] token a token from Coderay
331
+ # @param [Symbol] kind the kind of that token
332
+ def track_module_nesting(token, kind)
333
+ if kind == :keyword && (token == "class" || token == "module")
334
+ @module_nesting << [token, nil]
335
+ @awaiting_class = true
336
+ elsif @awaiting_class
337
+ if kind == :operator && token == "<<" && @module_nesting.last[0] == "class"
338
+ @module_nesting.last[0] = "class <<"
339
+ @awaiting_class = true
340
+ elsif kind == :class && token =~ /\A(self|[A-Z:][A-Za-z0-9_:]*)\z/
341
+ @module_nesting.last[1] = token if kind == :class
342
+ @awaiting_class = false
343
+ else
344
+ # leave @module_nesting[-1]
345
+ @awaiting_class = false
346
+ end
347
+ end
348
+ end
349
+
350
+ # Update the internal state relating to module nesting on 'end'.
351
+ #
352
+ # If the current 'end' pairs up with a class or a module then we should
353
+ # pop an array off of @module_nesting
354
+ #
355
+ # @param [String] token a token from Coderay
356
+ # @param [Symbol] kind the kind of that token
357
+ def track_module_nesting_end(token, kind=:keyword)
358
+ if kind == :keyword && (token == "class" || token == "module")
359
+ @module_nesting.pop
360
+ end
361
+ end
362
+
363
+ # Return a list of strings which can be used to re-construct the Module.nesting at
364
+ # the current point in the file.
365
+ #
366
+ # Returns nil if the syntax of the file was not recognizable.
367
+ #
368
+ # @return [Array<String>]
369
+ def module_nesting
370
+ @module_nesting.map do |(kind, token)|
371
+ raise UnparseableNestingError, @module_nesting.inspect if token.nil?
372
+
373
+ "#{kind} #{token}"
374
+ end
375
+ end
376
+
282
377
  # Return a string which, when printed, will rewrite the previous line with
283
378
  # the correct indentation. Mostly useful for fixing 'end'.
284
379
  #
@@ -288,13 +383,14 @@ class Pry
288
383
  # the difference in length between the old line and the new one).
289
384
  # @return [String]
290
385
  def correct_indentation(prompt, code, overhang=0)
291
- full_line = prompt + code
386
+ prompt = prompt.delete("\001\002")
387
+ line_to_measure = Pry::Helpers::Text.strip_color(prompt) << code
292
388
  whitespace = ' ' * overhang
293
389
 
294
- _, cols = screen_size
390
+ _, cols = Terminal.screen_size
295
391
 
296
392
  cols = cols.to_i
297
- lines = cols != 0 ? (full_line.length / cols + 1) : 1
393
+ lines = (cols != 0 ? (line_to_measure.length / cols + 1) : 1).to_i
298
394
 
299
395
  if Pry::Helpers::BaseHelpers.windows_ansi?
300
396
  move_up = "\e[#{lines}F"
@@ -306,29 +402,5 @@ class Pry
306
402
 
307
403
  "#{move_up}#{prompt}#{colorize_code(code)}#{whitespace}#{move_down}"
308
404
  end
309
-
310
- # Return a pair of [rows, columns] which gives the size of the window.
311
- #
312
- # If the window size cannot be determined, return nil.
313
- def screen_size
314
- [
315
- # io/console adds a winsize method to IO streams.
316
- $stdout.tty? && $stdout.respond_to?(:winsize) && $stdout.winsize,
317
-
318
- # Some readlines also provides get_screen_size.
319
- Readline.respond_to?(:get_screen_size) && Readline.get_screen_size,
320
-
321
- # Otherwise try to use the environment (this may be out of date due
322
- # to window resizing, but it's better than nothing).
323
- [ENV["ROWS"], ENV["COLUMNS"],
324
-
325
- # If the user is running within ansicon, then use the screen size
326
- # that it reports (same caveats apply as with ROWS and COLUMNS)
327
- ENV['ANSICON'] =~ /\((.*)x(.*)\)/ && [$2, $1]
328
- ]
329
- ].detect do |(_, cols)|
330
- cols.to_i > 0
331
- end
332
- end
333
405
  end
334
406
  end
@@ -0,0 +1,242 @@
1
+ # taken from irb
2
+ # Implements tab completion for Readline in Pry
3
+ class Pry::InputCompleter
4
+ NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
5
+ ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/
6
+ SYMBOL_REGEXP = /^(:[^:.]*)$/
7
+ SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/
8
+ REGEX_REGEXP = /^(\/[^\/]*\/)\.([^.]*)$/
9
+ PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/
10
+ TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/
11
+ CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/
12
+ CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/
13
+ HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
14
+ GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/
15
+ VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/
16
+
17
+ ReservedWords = [
18
+ "BEGIN", "END",
19
+ "alias", "and",
20
+ "begin", "break",
21
+ "case", "class",
22
+ "def", "defined", "do",
23
+ "else", "elsif", "end", "ensure",
24
+ "false", "for",
25
+ "if", "in",
26
+ "module",
27
+ "next", "nil", "not",
28
+ "or",
29
+ "redo", "rescue", "retry", "return",
30
+ "self", "super",
31
+ "then", "true",
32
+ "undef", "unless", "until",
33
+ "when", "while",
34
+ "yield" ]
35
+
36
+ Operators = [
37
+ "%", "&", "*", "**", "+", "-", "/",
38
+ "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
39
+ "[]", "[]=", "^", "!", "!=", "!~"
40
+ ]
41
+
42
+ WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{("
43
+
44
+ def initialize(input, pry = nil)
45
+ @pry = pry
46
+ @input = input
47
+ @input.basic_word_break_characters = WORD_ESCAPE_STR if @input.respond_to?(:basic_word_break_characters=)
48
+ @input.completion_append_character = nil if @input.respond_to?(:completion_append_character=)
49
+ end
50
+
51
+ #
52
+ # Return a new completion proc for use by Readline.
53
+ #
54
+ def call(str, options = {})
55
+ custom_completions = options[:custom_completions] || []
56
+ # if there are multiple contexts e.g. cd 1/2/3
57
+ # get new target for 1/2 and find candidates for 3
58
+ path, input = build_path(str)
59
+
60
+ if path.call.empty?
61
+ target = options[:target]
62
+ else
63
+ # Assume the user is tab-completing the 'cd' command
64
+ begin
65
+ target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
66
+ # but if that doesn't work, assume they're doing division with no spaces
67
+ rescue Pry::CommandError
68
+ target = options[:target]
69
+ end
70
+ end
71
+
72
+ begin
73
+ bind = target
74
+ # Complete stdlib symbols
75
+ case input
76
+ when REGEX_REGEXP # Regexp
77
+ receiver = $1
78
+ message = Regexp.quote($2)
79
+ candidates = Regexp.instance_methods.collect(&:to_s)
80
+ select_message(path, receiver, message, candidates)
81
+ when ARRAY_REGEXP # Array
82
+ receiver = $1
83
+ message = Regexp.quote($2)
84
+ candidates = Array.instance_methods.collect(&:to_s)
85
+ select_message(path, receiver, message, candidates)
86
+ when PROC_OR_HASH_REGEXP # Proc or Hash
87
+ receiver = $1
88
+ message = Regexp.quote($2)
89
+ candidates = Proc.instance_methods.collect(&:to_s)
90
+ candidates |= Hash.instance_methods.collect(&:to_s)
91
+ select_message(path, receiver, message, candidates)
92
+ when SYMBOL_REGEXP # Symbol
93
+ if Symbol.respond_to?(:all_symbols)
94
+ sym = Regexp.quote($1)
95
+ candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name}
96
+ candidates.grep(/^#{sym}/)
97
+ else
98
+ []
99
+ end
100
+ when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods
101
+ receiver = $1
102
+ candidates = Object.constants.collect(&:to_s)
103
+ candidates.grep(/^#{receiver}/).collect{|e| "::" << e}
104
+ when CONSTANT_REGEXP # Constant
105
+ message = $1
106
+ begin
107
+ context = target.eval("self")
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)
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
163
+ begin
164
+ candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
165
+ rescue Pry::RescuableException
166
+ candidates = []
167
+ 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)
202
+
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)
208
+ end
209
+ rescue Pry::RescuableException
210
+ []
211
+ end
212
+ end
213
+
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
222
+ end
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
239
+ end
240
+ return path, input
241
+ end
242
+ end