pry 0.10.4 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +408 -16
  3. data/LICENSE +1 -1
  4. data/README.md +352 -306
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +83 -96
  10. data/lib/pry/code/code_file.rb +37 -26
  11. data/lib/pry/code/code_range.rb +7 -5
  12. data/lib/pry/code/loc.rb +26 -13
  13. data/lib/pry/code.rb +49 -32
  14. data/lib/pry/code_object.rb +53 -28
  15. data/lib/pry/color_printer.rb +46 -35
  16. data/lib/pry/command.rb +197 -369
  17. data/lib/pry/command_set.rb +89 -114
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -72
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -46
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +62 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +48 -23
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +185 -157
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -162
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -149
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -31
  48. data/lib/pry/commands/ls/formatter.rb +42 -36
  49. data/lib/pry/commands/ls/globals.rb +38 -36
  50. data/lib/pry/commands/ls/grep.rb +17 -15
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -28
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -24
  55. data/lib/pry/commands/ls/local_vars.rb +38 -30
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -52
  57. data/lib/pry/commands/ls/methods.rb +49 -51
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -21
  60. data/lib/pry/commands/ls.rb +124 -103
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +92 -82
  63. data/lib/pry/commands/pry_backtrace.rb +22 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -42
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +56 -29
  71. data/lib/pry/commands/shell_mode.rb +22 -18
  72. data/lib/pry/commands/show_doc.rb +80 -70
  73. data/lib/pry/commands/show_info.rb +193 -160
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +110 -42
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -84
  81. data/lib/pry/commands/whereami.rb +155 -146
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +313 -20
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +22 -9
  90. data/lib/pry/editor.rb +53 -33
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -18
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +20 -62
  96. data/lib/pry/helpers/command_helpers.rb +52 -62
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +60 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -85
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +81 -55
  104. data/lib/pry/hooks.rb +60 -110
  105. data/lib/pry/indent.rb +72 -66
  106. data/lib/pry/input_completer.rb +199 -158
  107. data/lib/pry/input_lock.rb +7 -10
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/method/patcher.rb +14 -8
  112. data/lib/pry/method/weird_method_locator.rb +79 -45
  113. data/lib/pry/method.rb +177 -124
  114. data/lib/pry/object_path.rb +37 -28
  115. data/lib/pry/output.rb +102 -16
  116. data/lib/pry/pager.rb +187 -177
  117. data/lib/pry/prompt.rb +213 -25
  118. data/lib/pry/pry_class.rb +106 -98
  119. data/lib/pry/pry_instance.rb +261 -224
  120. data/lib/pry/repl.rb +82 -27
  121. data/lib/pry/repl_file_loader.rb +27 -22
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +27 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +28 -27
  138. data/lib/pry/wrapped_module.rb +66 -57
  139. data/lib/pry.rb +133 -149
  140. metadata +52 -63
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gist.rb +0 -101
  147. data/lib/pry/commands/install_command.rb +0 -53
  148. data/lib/pry/commands/list_prompts.rb +0 -35
  149. data/lib/pry/commands/simple_prompt.rb +0 -22
  150. data/lib/pry/commands.rb +0 -6
  151. data/lib/pry/config/behavior.rb +0 -139
  152. data/lib/pry/config/convenience.rb +0 -25
  153. data/lib/pry/config/default.rb +0 -161
  154. data/lib/pry/history_array.rb +0 -121
  155. data/lib/pry/plugins.rb +0 -103
  156. data/lib/pry/rbx_path.rb +0 -22
  157. data/lib/pry/rubygem.rb +0 -82
  158. data/lib/pry/terminal.rb +0 -79
  159. data/lib/pry/test/helper.rb +0 -170
data/lib/pry/hooks.rb CHANGED
@@ -1,37 +1,33 @@
1
- class Pry
1
+ # frozen_string_literal: true
2
2
 
3
- # Implements a hooks system for Pry. A hook is a callable that is
4
- # associated with an event. A number of events are currently
5
- # provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`.
6
- # A hook must have a name, and is connected with an event by the
7
- # `Pry::Hooks#add_hook` method.
3
+ class Pry
4
+ # Implements a hooks system for Pry. A hook is a callable that is associated
5
+ # with an event. A number of events are currently provided by Pry, these
6
+ # include: `:when_started`, `:before_session`, `:after_session`. A hook must
7
+ # have a name, and is connected with an event by the `Pry::Hooks#add_hook`
8
+ # method.
9
+ #
8
10
  # @example Adding a hook for the `:before_session` event.
9
11
  # Pry.config.hooks.add_hook(:before_session, :say_hi) do
10
12
  # puts "hello"
11
13
  # end
12
14
  class Hooks
15
+ def self.default
16
+ hooks = new
17
+ hooks.add_hook(:before_session, :default) do |_out, _target, pry_instance|
18
+ next if pry_instance.quiet?
13
19
 
14
- # Converts a hash to a `Pry::Hooks` instance. All hooks defined
15
- # this way are anonymous. This functionality is primarily to
16
- # provide backwards-compatibility with the old hash-based hook
17
- # system in Pry versions < 0.9.8
18
- # @param [Hash] hash The hash to convert to `Pry::Hooks`.
19
- # @return [Pry::Hooks] The resulting `Pry::Hooks` instance.
20
- def self.from_hash(hash)
21
- return hash if hash.instance_of?(self)
22
- instance = new
23
- hash.each do |k, v|
24
- instance.add_hook(k, nil, v)
20
+ pry_instance.run_command('whereami --quiet')
25
21
  end
26
- instance
22
+ hooks
27
23
  end
28
24
 
29
25
  def initialize
30
- @hooks = {}
26
+ @hooks = Hash.new { |h, k| h[k] = [] }
31
27
  end
32
28
 
33
- # Ensure that duplicates have their @hooks object
34
- def initialize_copy(orig)
29
+ # Ensure that duplicates have their @hooks object.
30
+ def initialize_copy(_orig)
35
31
  hooks_dup = @hooks.dup
36
32
  @hooks.each do |k, v|
37
33
  hooks_dup[k] = v.dup
@@ -40,63 +36,50 @@ class Pry
40
36
  @hooks = hooks_dup
41
37
  end
42
38
 
43
- def hooks
44
- @hooks
45
- end
46
- protected :hooks
47
-
48
39
  def errors
49
40
  @errors ||= []
50
41
  end
51
42
 
52
43
  # Destructively merge the contents of two `Pry:Hooks` instances.
44
+ #
53
45
  # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
54
- # @return [Pry:Hooks] Returns the receiver.
55
- # @example
56
- # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
57
- # Pry::Hooks.new.merge!(hooks)
46
+ # @return [Pry:Hooks] The receiver.
47
+ # @see #merge
58
48
  def merge!(other)
59
- @hooks.merge!(other.dup.hooks) do |key, v1, v2|
60
- merge_arrays(v1, v2)
61
- end
49
+ @hooks.merge!(other.dup.hooks) do |_key, array, other_array|
50
+ temp_hash = {}
51
+ output = []
62
52
 
63
- self
64
- end
53
+ (array + other_array).reverse_each do |pair|
54
+ temp_hash[pair.first] ||= output.unshift(pair)
55
+ end
65
56
 
66
- def merge_arrays(array1, array2)
67
- uniq_keeping_last(array1 + array2, &:first)
68
- end
69
- private :merge_arrays
57
+ output
58
+ end
70
59
 
71
- def uniq_keeping_last(input, &block)
72
- hash, output = {}, []
73
- input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) }
74
- output
60
+ self
75
61
  end
76
- private :uniq_keeping_last
77
62
 
78
- # Return a new `Pry::Hooks` instance containing a merge of the contents of two `Pry:Hooks` instances,
79
- # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
80
- # @return [Pry::Hooks] The new hash.
81
63
  # @example
82
64
  # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
83
65
  # Pry::Hooks.new.merge(hooks)
66
+ # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
67
+ # @return [Pry::Hooks] a new `Pry::Hooks` instance containing a merge of the
68
+ # contents of two `Pry:Hooks` instances.
84
69
  def merge(other)
85
- self.dup.tap do |v|
70
+ dup.tap do |v|
86
71
  v.merge!(other)
87
72
  end
88
73
  end
89
74
 
90
- # Add a new hook to be executed for the `name` even.
75
+ # Add a new hook to be executed for the `event_name` event.
91
76
  # @param [Symbol] event_name The name of the event.
92
77
  # @param [Symbol] hook_name The name of the hook.
93
78
  # @param [#call] callable The callable.
94
- # @yield The block to use as the callable (if `callable` parameter not provided)
95
- # @return [Pry:Hooks] Returns the receiver.
96
- # @example
97
- # Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
98
- def add_hook(event_name, hook_name, callable=nil, &block)
99
- @hooks[event_name] ||= []
79
+ # @yield The block to use as the callable (if no `callable` provided).
80
+ # @return [Pry:Hooks] The receiver.
81
+ def add_hook(event_name, hook_name, callable = nil, &block)
82
+ event_name = event_name.to_s
100
83
 
101
84
  # do not allow duplicates, but allow multiple `nil` hooks
102
85
  # (anonymous hooks)
@@ -104,12 +87,10 @@ class Pry
104
87
  raise ArgumentError, "Hook with name '#{hook_name}' already defined!"
105
88
  end
106
89
 
107
- if !block && !callable
108
- raise ArgumentError, "Must provide a block or callable."
109
- end
90
+ raise ArgumentError, "Must provide a block or callable." if !block && !callable
110
91
 
111
92
  # ensure we only have one anonymous hook
112
- @hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil?
93
+ @hooks[event_name].delete_if { |h, _k| h.nil? } if hook_name.nil?
113
94
 
114
95
  if block
115
96
  @hooks[event_name] << [hook_name, block]
@@ -124,13 +105,8 @@ class Pry
124
105
  # @param [Symbol] event_name The name of the event.
125
106
  # @param [Array] args The arguments to pass to each hook function.
126
107
  # @return [Object] The return value of the last executed hook.
127
- # @example
128
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
129
- # my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!"
130
108
  def exec_hook(event_name, *args, &block)
131
- @hooks[event_name] ||= []
132
-
133
- @hooks[event_name].map do |hook_name, callable|
109
+ @hooks[event_name.to_s].map do |_hook_name, callable|
134
110
  begin
135
111
  callable.call(*args, &block)
136
112
  rescue RescuableException => e
@@ -140,56 +116,38 @@ class Pry
140
116
  end.last
141
117
  end
142
118
 
143
- # Return the number of hook functions registered for the `event_name` event.
144
119
  # @param [Symbol] event_name The name of the event.
145
120
  # @return [Fixnum] The number of hook functions for `event_name`.
146
- # @example
147
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
148
- # my_hooks.count(:before_session) #=> 1
149
121
  def hook_count(event_name)
150
- @hooks[event_name] ||= []
151
- @hooks[event_name].size
122
+ @hooks[event_name.to_s].size
152
123
  end
153
124
 
154
- # Return a specific hook for a given event.
155
125
  # @param [Symbol] event_name The name of the event.
156
126
  # @param [Symbol] hook_name The name of the hook
157
- # @return [#call] The requested hook.
158
- # @example
159
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
160
- # my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!"
127
+ # @return [#call] a specific hook for a given event.
161
128
  def get_hook(event_name, hook_name)
162
- @hooks[event_name] ||= []
163
- hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name }
129
+ hook = @hooks[event_name.to_s].find do |current_hook_name, _callable|
130
+ current_hook_name == hook_name
131
+ end
164
132
  hook.last if hook
165
133
  end
166
134
 
167
- # Return the hash of hook names / hook functions for a
168
- # given event. (Note that modifying the returned hash does not
169
- # alter the hooks, use add_hook/delete_hook for that).
170
135
  # @param [Symbol] event_name The name of the event.
171
136
  # @return [Hash] The hash of hook names / hook functions.
172
- # @example
173
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
174
- # my_hooks.get_hooks(:before_session) #=> {:say_hi=>#<Proc:0x00000101645e18@(pry):9>}
137
+ # @note Modifying the returned hash does not alter the hooks, use
138
+ # `add_hook`/`delete_hook` for that.
175
139
  def get_hooks(event_name)
176
- @hooks[event_name] ||= []
177
- Hash[@hooks[event_name]]
140
+ Hash[@hooks[event_name.to_s]]
178
141
  end
179
142
 
180
- # Delete a hook for an event.
181
143
  # @param [Symbol] event_name The name of the event.
182
144
  # @param [Symbol] hook_name The name of the hook.
183
145
  # to delete.
184
146
  # @return [#call] The deleted hook.
185
- # @example
186
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
187
- # my_hooks.delete_hook(:before_session, :say_hi)
188
147
  def delete_hook(event_name, hook_name)
189
- @hooks[event_name] ||= []
190
148
  deleted_callable = nil
191
149
 
192
- @hooks[event_name].delete_if do |current_hook_name, callable|
150
+ @hooks[event_name.to_s].delete_if do |current_hook_name, callable|
193
151
  if current_hook_name == hook_name
194
152
  deleted_callable = callable
195
153
  true
@@ -201,30 +159,22 @@ class Pry
201
159
  end
202
160
 
203
161
  # Clear all hooks functions for a given event.
162
+ #
204
163
  # @param [String] event_name The name of the event.
205
- # @example
206
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
207
- # my_hooks.delete_hook(:before_session)
208
- def delete_hooks(event_name)
209
- @hooks[event_name] = []
210
- end
211
-
212
- alias_method :clear, :delete_hooks
213
-
214
- # Remove all events and hooks, clearing out the Pry::Hooks
215
- # instance completely.
216
- # @example
217
- # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
218
- # my_hooks.clear_all
219
- def clear_all
220
- @hooks = {}
164
+ # @return [void]
165
+ def clear_event_hooks(event_name)
166
+ @hooks[event_name.to_s] = []
221
167
  end
222
168
 
223
169
  # @param [Symbol] event_name Name of the event.
224
170
  # @param [Symbol] hook_name Name of the hook.
225
- # @return [Boolean] Whether the hook by the name `hook_name`
171
+ # @return [Boolean] Whether the hook by the name `hook_name`.
226
172
  def hook_exists?(event_name, hook_name)
227
- !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name })
173
+ @hooks[event_name.to_s].map(&:first).include?(hook_name)
228
174
  end
175
+
176
+ protected
177
+
178
+ attr_reader :hooks
229
179
  end
230
180
  end
data/lib/pry/indent.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'coderay'
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Pry
4
4
  ##
@@ -21,35 +21,35 @@ class Pry
21
21
  attr_reader :stack
22
22
 
23
23
  # The amount of spaces to insert for each indent level.
24
- SPACES = ' '
24
+ SPACES = ' '.freeze
25
25
 
26
26
  # Hash containing all the tokens that should increase the indentation
27
27
  # level. The keys of this hash are open tokens, the values the matching
28
28
  # tokens that should prevent a line from being indented if they appear on
29
29
  # the same line.
30
30
  OPEN_TOKENS = {
31
- 'def' => 'end',
32
- 'class' => 'end',
31
+ 'def' => 'end',
32
+ 'class' => 'end',
33
33
  'module' => 'end',
34
- 'do' => 'end',
35
- 'if' => 'end',
34
+ 'do' => 'end',
35
+ 'if' => 'end',
36
36
  'unless' => 'end',
37
- 'while' => 'end',
38
- 'until' => 'end',
39
- 'for' => 'end',
40
- 'case' => 'end',
41
- 'begin' => 'end',
42
- '[' => ']',
43
- '{' => '}',
44
- '(' => ')'
45
- }
37
+ 'while' => 'end',
38
+ 'until' => 'end',
39
+ 'for' => 'end',
40
+ 'case' => 'end',
41
+ 'begin' => 'end',
42
+ '[' => ']',
43
+ '{' => '}',
44
+ '(' => ')'
45
+ }.freeze
46
46
 
47
47
  # Which tokens can either be open tokens, or appear as modifiers on
48
48
  # a single-line.
49
- SINGLELINE_TOKENS = %w(if while until unless rescue)
49
+ SINGLELINE_TOKENS = %w[if while until unless rescue].freeze
50
50
 
51
51
  # Which tokens can be followed by an optional "do" keyword.
52
- OPTIONAL_DO_TOKENS = %w(for while until)
52
+ OPTIONAL_DO_TOKENS = %w[for while until].freeze
53
53
 
54
54
  # Collection of token types that should be ignored. Without this list
55
55
  # keywords such as "class" inside strings would cause the code to be
@@ -58,7 +58,7 @@ class Pry
58
58
  # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0
59
59
  # classifications of "true", "false", and "nil".
60
60
  IGNORE_TOKENS = [:space, :content, :string, :method, :ident,
61
- :constant, :pre_constant, :predefined_constant]
61
+ :constant, :pre_constant, :predefined_constant].freeze
62
62
 
63
63
  # Tokens that indicate the end of a statement (i.e. that, if they appear
64
64
  # directly before an "if" indicates that that if applies to the same line,
@@ -66,12 +66,14 @@ 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.
74
- MIDWAY_TOKENS = %w(when else elsif ensure rescue)
76
+ MIDWAY_TOKENS = %w[when else elsif ensure rescue].freeze
75
77
 
76
78
  # Clean the indentation of a fragment of ruby.
77
79
  #
@@ -99,7 +101,8 @@ class Pry
99
101
  indent.module_nesting
100
102
  end
101
103
 
102
- def initialize
104
+ def initialize(pry_instance = Pry.new)
105
+ @pry_instance = pry_instance
103
106
  reset
104
107
  end
105
108
 
@@ -141,10 +144,11 @@ class Pry
141
144
  prefix = indent_level
142
145
 
143
146
  input.lines.each do |line|
144
-
145
147
  if in_string?
146
148
  tokens = tokenize("#{open_delimiters_line}\n#{line}")
147
- tokens = tokens.drop_while{ |token, type| !(String === token && token.include?("\n")) }
149
+ tokens = tokens.drop_while do |token, _type|
150
+ !(token.is_a?(String) && token.include?("\n"))
151
+ end
148
152
  previously_in_string = true
149
153
  else
150
154
  tokens = tokenize(line)
@@ -153,7 +157,7 @@ class Pry
153
157
 
154
158
  before, after = indentation_delta(tokens)
155
159
 
156
- before.times{ prefix.sub! SPACES, '' }
160
+ before.times { prefix.sub! SPACES, '' }
157
161
  new_prefix = prefix + SPACES * after
158
162
 
159
163
  line = prefix + line.lstrip unless previously_in_string
@@ -165,7 +169,7 @@ class Pry
165
169
 
166
170
  @indent_level = prefix
167
171
 
168
- return output
172
+ output
169
173
  end
170
174
 
171
175
  # Get the indentation for the start of the next line.
@@ -192,7 +196,6 @@ class Pry
192
196
  # @return [Array[Integer]]
193
197
  #
194
198
  def indentation_delta(tokens)
195
-
196
199
  # We need to keep track of whether we've seen a "for" on this line because
197
200
  # if the line ends with "do" then that "do" should be discounted (i.e. we're
198
201
  # only opening one level not two) To do this robustly we want to keep track
@@ -203,29 +206,37 @@ class Pry
203
206
  # When deciding whether an "if" token is the start of a multiline statement,
204
207
  # or just the middle of a single-line if statement, we just look at the
205
208
  # preceding token, which is tracked here.
206
- last_token, last_kind = [nil, nil]
209
+ last_token = nil
210
+ last_kind = nil
207
211
 
208
212
  # delta keeps track of the total difference from the start of each line after
209
213
  # the given token, 0 is just the level at which the current line started for
210
214
  # reference.
211
- remove_before, add_after = [0, 0]
215
+ remove_before = 0
216
+ add_after = 0
212
217
 
213
218
  # If the list of tokens contains a matching closing token the line should
214
219
  # not be indented (and thus we should return true).
215
220
  tokens.each do |token, kind|
216
- is_singleline_if = (SINGLELINE_TOKENS.include?(token)) && end_of_statement?(last_token, last_kind)
221
+ is_singleline_if =
222
+ SINGLELINE_TOKENS.include?(token) && end_of_statement?(last_token, last_kind)
217
223
  is_optional_do = (token == "do" && seen_for_at.include?(add_after - 1))
218
224
 
219
- last_token, last_kind = token, kind unless kind == :space
225
+ unless kind == :space
226
+ last_token = token
227
+ last_kind = kind
228
+ end
220
229
  next if IGNORE_TOKENS.include?(kind)
221
230
 
222
231
  track_module_nesting(token, kind)
223
232
 
224
233
  seen_for_at << add_after if OPTIONAL_DO_TOKENS.include?(token)
225
234
 
235
+ next if is_singleline_if
236
+
226
237
  if kind == :delimiter
227
238
  track_delimiter(token)
228
- elsif OPEN_TOKENS.keys.include?(token) && !is_optional_do && !is_singleline_if
239
+ elsif OPEN_TOKENS.key?(token) && !is_optional_do && !is_singleline_if
229
240
  @stack << token
230
241
  add_after += 1
231
242
  elsif token == OPEN_TOKENS[@stack.last]
@@ -244,20 +255,21 @@ class Pry
244
255
  end
245
256
  end
246
257
 
247
- return [remove_before, add_after]
258
+ [remove_before, add_after]
248
259
  end
249
260
 
250
- # If the code just before an "if" or "while" token on a line looks like the end of a statement,
251
- # then we want to treat that "if" as a singleline, not multiline statement.
261
+ # If the code just before an "if" or "while" token on a line looks like the
262
+ # end of a statement, then we want to treat that "if" as a singleline, not
263
+ # multiline statement.
252
264
  def end_of_statement?(last_token, last_kind)
253
- (last_token =~ /^[)\]}\/]$/ || STATEMENT_END_TOKENS.include?(last_kind))
265
+ (last_token =~ %r{^[)\]\}/]$} || STATEMENT_END_TOKENS.include?(last_kind))
254
266
  end
255
267
 
256
268
  # Are we currently in the middle of a string literal.
257
269
  #
258
- # This is used to determine whether to re-indent a given line, we mustn't re-indent
259
- # within string literals because to do so would actually change the value of the
260
- # String!
270
+ # This is used to determine whether to re-indent a given line, we mustn't
271
+ # re-indent within string literals because to do so would actually change
272
+ # the value of the String!
261
273
  #
262
274
  # @return Boolean
263
275
  def in_string?
@@ -269,16 +281,17 @@ class Pry
269
281
  # @param [String] string The Ruby to lex
270
282
  # @return [Array] An Array of pairs of [token_value, token_type]
271
283
  def tokenize(string)
272
- tokens = CodeRay.scan(string, :ruby)
284
+ tokens = SyntaxHighlighter.tokenize(string)
273
285
  tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens) # Coderay 1.0.0
274
286
  tokens.to_a
275
287
  end
276
288
 
277
289
  # Update the internal state about what kind of strings are open.
278
290
  #
279
- # Most of the complication here comes from the fact that HEREDOCs can be nested. For
280
- # normal strings (which can't be nested) we assume that CodeRay correctly pairs
281
- # open-and-close delimiters so we don't bother checking what they are.
291
+ # Most of the complication here comes from the fact that HEREDOCs can be
292
+ # nested. For normal strings (which can't be nested) we assume that CodeRay
293
+ # correctly pairs open-and-close delimiters so we don't bother checking what
294
+ # they are.
282
295
  #
283
296
  # @param [String] token The token (of type :delimiter)
284
297
  def track_delimiter(token)
@@ -289,11 +302,7 @@ class Pry
289
302
  when @close_heredocs[@heredoc_queue.first]
290
303
  @heredoc_queue.shift
291
304
  else
292
- if @string_start
293
- @string_start = nil
294
- else
295
- @string_start = token
296
- end
305
+ @string_start = @string_start ? nil : token
297
306
  end
298
307
  end
299
308
 
@@ -309,7 +318,7 @@ class Pry
309
318
  #
310
319
  # @return String
311
320
  def open_delimiters_line
312
- "puts #{open_delimiters.join(", ")}"
321
+ "puts #{open_delimiters.join(', ')}"
313
322
  end
314
323
 
315
324
  # Update the internal state relating to module nesting.
@@ -330,7 +339,7 @@ class Pry
330
339
  # @param [String] token a token from Coderay
331
340
  # @param [Symbol] kind the kind of that token
332
341
  def track_module_nesting(token, kind)
333
- if kind == :keyword && (token == "class" || token == "module")
342
+ if kind == :keyword && %w[class module].include?(token)
334
343
  @module_nesting << [token, nil]
335
344
  @awaiting_class = true
336
345
  elsif @awaiting_class
@@ -354,10 +363,8 @@ class Pry
354
363
  #
355
364
  # @param [String] token a token from Coderay
356
365
  # @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
366
+ def track_module_nesting_end(token, kind = :keyword)
367
+ @module_nesting.pop if kind == :keyword && %w[class module].include?(token)
361
368
  end
362
369
 
363
370
  # Return a list of strings which can be used to re-construct the Module.nesting at
@@ -378,25 +385,24 @@ class Pry
378
385
  # the correct indentation. Mostly useful for fixing 'end'.
379
386
  #
380
387
  # @param [String] prompt The user's prompt
381
- # @param [String] code The code the user just typed in.
382
- # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e.,
383
- # the difference in length between the old line and the new one).
384
- # @return [String]
385
- def correct_indentation(prompt, code, overhang=0)
388
+ # @param [String] code The code the user just typed in
389
+ # @param [Integer] overhang The number of characters to erase afterwards (the
390
+ # the difference in length between the old line and the new one)
391
+ #
392
+ # @return [String] correctly indented line
393
+ def correct_indentation(prompt, code, overhang = 0)
386
394
  prompt = prompt.delete("\001\002")
387
395
  line_to_measure = Pry::Helpers::Text.strip_color(prompt) << code
388
396
  whitespace = ' ' * overhang
389
397
 
390
- _, cols = Terminal.screen_size
391
-
392
- cols = cols.to_i
393
- lines = (cols != 0 ? (line_to_measure.length / cols + 1) : 1).to_i
398
+ cols = @pry_instance.output.width
399
+ lines = cols == 0 ? 1 : (line_to_measure.length / cols + 1).to_i
394
400
 
395
- if Pry::Helpers::BaseHelpers.windows_ansi?
396
- move_up = "\e[#{lines}F"
401
+ if Helpers::Platform.windows_ansi?
402
+ move_up = "\e[#{lines}F"
397
403
  move_down = "\e[#{lines}E"
398
404
  else
399
- move_up = "\e[#{lines}A\e[0G"
405
+ move_up = "\e[#{lines}A\e[0G"
400
406
  move_down = "\e[#{lines}B\e[0G"
401
407
  end
402
408