pry 0.10.3 → 0.14.2

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 (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +439 -16
  3. data/LICENSE +1 -1
  4. data/README.md +362 -302
  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 +84 -97
  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 +42 -31
  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 +194 -155
  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 +156 -141
  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 +310 -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 +56 -34
  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 +55 -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 +74 -68
  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 +178 -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 -174
  117. data/lib/pry/prompt.rb +213 -25
  118. data/lib/pry/pry_class.rb +119 -98
  119. data/lib/pry/pry_instance.rb +261 -224
  120. data/lib/pry/repl.rb +83 -29
  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 +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
  138. data/lib/pry/wrapped_module.rb +68 -63
  139. data/lib/pry.rb +133 -149
  140. metadata +58 -69
  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
@@ -57,8 +57,8 @@ class Pry
57
57
  #
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
- IGNORE_TOKENS = [:space, :content, :string, :method, :ident,
61
- :constant, :pre_constant, :predefined_constant]
60
+ IGNORE_TOKENS = %i[space content string method ident
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 + %i[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,14 +101,15 @@ 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
 
106
109
  # reset internal state
107
110
  def reset
108
111
  @stack = []
109
- @indent_level = ''
112
+ @indent_level = String.new # rubocop:disable Style/EmptyLiteral
110
113
  @heredoc_queue = []
111
114
  @close_heredocs = {}
112
115
  @string_start = nil
@@ -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