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
@@ -1,196 +1,205 @@
1
- class Pry
2
- class Command::Whereami < Pry::ClassCommand
3
-
4
- def initialize(*)
5
- super
1
+ # frozen_string_literal: true
6
2
 
7
- @method_code = nil
8
- end
3
+ require 'method_source'
9
4
 
10
- class << self
11
- attr_accessor :method_size_cutoff
12
- end
5
+ class Pry
6
+ class Command
7
+ class Whereami < Pry::ClassCommand
8
+ def initialize(*)
9
+ super
13
10
 
14
- @method_size_cutoff = 30
11
+ @method_code = nil
12
+ end
15
13
 
16
- match 'whereami'
17
- description 'Show code surrounding the current context.'
18
- group 'Context'
14
+ class << self
15
+ attr_accessor :method_size_cutoff
16
+ end
19
17
 
20
- banner <<-'BANNER'
21
- Usage: whereami [-qn] [LINES]
18
+ @method_size_cutoff = 30
22
19
 
23
- Describe the current location. If you use `binding.pry` inside a method then
24
- whereami will print out the source for that method.
20
+ match 'whereami'
21
+ description 'Show code surrounding the current context.'
22
+ group 'Context'
25
23
 
26
- If a number is passed, then LINES lines before and after the current line will be
27
- shown instead of the method itself.
24
+ banner <<-'BANNER'
25
+ Usage: whereami [-qn] [LINES]
28
26
 
29
- The `-q` flag can be used to suppress error messages in the case that there's
30
- no code to show. This is used by pry in the default before_session hook to show
31
- you when you arrive at a `binding.pry`.
27
+ Describe the current location. If you use `binding.pry` inside a method then
28
+ whereami will print out the source for that method.
32
29
 
33
- The `-n` flag can be used to hide line numbers so that code can be copy/pasted
34
- effectively.
30
+ If a number is passed, then LINES lines before and after the current line will be
31
+ shown instead of the method itself.
35
32
 
36
- When pry was started on an Object and there is no associated method, whereami
37
- will instead output a brief description of the current object.
38
- BANNER
33
+ The `-q` flag can be used to suppress error messages in the case that there's
34
+ no code to show. This is used by pry in the default before_session hook to show
35
+ you when you arrive at a `binding.pry`.
39
36
 
40
- def setup
41
- @file = expand_path(target.eval('__FILE__'))
42
- @line = target.eval('__LINE__')
43
- @method = Pry::Method.from_binding(target)
44
- end
37
+ The `-n` flag can be used to hide line numbers so that code can be copy/pasted
38
+ effectively.
45
39
 
46
- def options(opt)
47
- opt.on :q, :quiet, "Don't display anything in case of an error"
48
- opt.on :n, :"no-line-numbers", "Do not display line numbers"
49
- opt.on :m, :"method", "Show the complete source for the current method."
50
- opt.on :c, :"class", "Show the complete source for the current class or module."
51
- opt.on :f, :"file", "Show the complete source for the current file."
52
- end
40
+ When pry was started on an Object and there is no associated method, whereami
41
+ will instead output a brief description of the current object.
42
+ BANNER
53
43
 
54
- def code
55
- @code ||= if opts.present?(:m)
56
- method_code or raise CommandError, "Cannot find method code."
57
- elsif opts.present?(:c)
58
- class_code or raise CommandError, "Cannot find class code."
59
- elsif opts.present?(:f)
60
- Pry::Code.from_file(@file)
61
- elsif args.any?
62
- code_window
63
- else
64
- default_code
65
- end
66
- end
44
+ def setup
45
+ if target.respond_to?(:source_location)
46
+ file, @line = target.source_location
47
+ @file = expand_path(file)
48
+ else
49
+ @file = expand_path(target.eval('__FILE__'))
50
+ @line = target.eval('__LINE__')
51
+ end
52
+ @method = Pry::Method.from_binding(target)
53
+ end
67
54
 
68
- def code?
69
- !!code
70
- rescue MethodSource::SourceNotFoundError
71
- false
72
- end
55
+ def options(opt)
56
+ opt.on :q, :quiet, "Don't display anything in case of an error"
57
+ opt.on :n, :"no-line-numbers", "Do not display line numbers"
58
+ opt.on :m, :method, "Show the complete source for the current method."
59
+ opt.on :c, :class, "Show the complete source for the current class or module."
60
+ opt.on :f, :file, "Show the complete source for the current file."
61
+ end
73
62
 
74
- def bad_option_combination?
75
- [opts.present?(:m), opts.present?(:f),
76
- opts.present?(:c), args.any?].count(true) > 1
77
- end
63
+ def code
64
+ @code ||= if opts.present?(:m)
65
+ method_code || raise(CommandError, "Cannot find method code.")
66
+ elsif opts.present?(:c)
67
+ class_code || raise(CommandError, "Cannot find class code.")
68
+ elsif opts.present?(:f)
69
+ Pry::Code.from_file(@file)
70
+ elsif args.any?
71
+ code_window
72
+ else
73
+ default_code
74
+ end
75
+ end
78
76
 
79
- def location
80
- "#{@file} @ line #{@line} #{@method && @method.name_with_owner}"
81
- end
77
+ def code?
78
+ !!code
79
+ rescue MethodSource::SourceNotFoundError
80
+ false
81
+ end
82
82
 
83
- def process
84
- if bad_option_combination?
85
- raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
83
+ def bad_option_combination?
84
+ [opts.present?(:m), opts.present?(:f),
85
+ opts.present?(:c), args.any?].count(true) > 1
86
86
  end
87
87
 
88
- if nothing_to_do?
89
- return
90
- elsif internal_binding?(target)
91
- handle_internal_binding
92
- return
88
+ def location
89
+ "#{@file}:#{@line} #{@method && @method.name_with_owner}"
93
90
  end
94
91
 
95
- set_file_and_dir_locals(@file)
92
+ def process
93
+ if bad_option_combination?
94
+ raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
95
+ end
96
96
 
97
- out = "\n#{text.bold('From:')} #{location}:\n\n" <<
98
- code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted << "\n"
97
+ return if nothing_to_do?
99
98
 
100
- _pry_.pager.page out
101
- end
99
+ if internal_binding?(target)
100
+ handle_internal_binding
101
+ return
102
+ end
102
103
 
103
- private
104
+ set_file_and_dir_locals(@file)
104
105
 
105
- def nothing_to_do?
106
- opts.quiet? && (internal_binding?(target) || !code?)
107
- end
106
+ pretty_code = code.with_line_numbers(use_line_numbers?)
107
+ .with_marker(marker)
108
+ .highlighted
109
+ pry_instance.pager.page(
110
+ "\n#{bold('From:')} #{location}:\n\n" + pretty_code + "\n"
111
+ )
112
+ end
108
113
 
109
- def use_line_numbers?
110
- !opts.present?(:n)
111
- end
114
+ private
112
115
 
113
- def marker
114
- !opts.present?(:n) && @line
115
- end
116
+ def nothing_to_do?
117
+ opts.quiet? && (internal_binding?(target) || !code?)
118
+ end
116
119
 
117
- def top_level?
118
- target_self == Pry.main
119
- end
120
+ def use_line_numbers?
121
+ !opts.present?(:n)
122
+ end
120
123
 
121
- def handle_internal_binding
122
- if top_level?
123
- output.puts "At the top level."
124
- else
125
- output.puts "Inside #{Pry.view_clip(target_self)}."
124
+ def marker
125
+ !opts.present?(:n) && @line
126
126
  end
127
- end
128
127
 
129
- def small_method?
130
- @method.source_range.count < self.class.method_size_cutoff
131
- end
128
+ def top_level?
129
+ target_self == Pry.main
130
+ end
132
131
 
133
- def default_code
134
- if method_code && small_method?
135
- method_code
136
- else
137
- code_window
132
+ def handle_internal_binding
133
+ if top_level?
134
+ output.puts "At the top level."
135
+ else
136
+ output.puts "Inside #{Pry.view_clip(target_self)}."
137
+ end
138
138
  end
139
- end
140
139
 
141
- def code_window
142
- Pry::Code.from_file(@file).around(@line, window_size)
143
- end
140
+ def small_method?
141
+ @method.source_range.count < self.class.method_size_cutoff
142
+ end
144
143
 
145
- def method_code
146
- return @method_code if @method_code
144
+ def default_code
145
+ if method_code && small_method?
146
+ method_code
147
+ else
148
+ code_window
149
+ end
150
+ end
147
151
 
148
- if valid_method?
149
- @method_code = Pry::Code.from_method(@method)
152
+ def code_window
153
+ Pry::Code.from_file(@file).around(@line, window_size)
150
154
  end
151
- end
152
155
 
153
- # This either returns the `target_self`
154
- # or it returns the class of `target_self` if `target_self` is not a class.
155
- # @return [Pry::WrappedModule]
156
- def target_class
157
- target_self.is_a?(Module) ? Pry::WrappedModule(target_self) :
158
- Pry::WrappedModule(target_self.class)
159
- end
156
+ def method_code
157
+ return @method_code if @method_code
160
158
 
161
- def class_code
162
- return @class_code if @class_code
159
+ @method_code = Pry::Code.from_method(@method) if valid_method?
160
+ end
163
161
 
164
- mod = @method ? Pry::WrappedModule(@method.owner) : target_class
162
+ # This either returns the `target_self`
163
+ # or it returns the class of `target_self` if `target_self` is not a class.
164
+ # @return [Pry::WrappedModule]
165
+ def target_class
166
+ return Pry::WrappedModule(target_self) if target_self.is_a?(Module)
165
167
 
166
- idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
167
- @class_code = idx && Pry::Code.from_module(mod, idx)
168
- end
168
+ Pry::WrappedModule(target_self.class)
169
+ end
169
170
 
170
- def valid_method?
171
- @method && @method.source? && expand_path(@method.source_file) == @file &&
172
- @method.source_range.include?(@line)
173
- end
171
+ def class_code
172
+ @class_code ||=
173
+ begin
174
+ mod = @method ? Pry::WrappedModule(@method.owner) : target_class
175
+ idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
176
+ idx && Pry::Code.from_module(mod, idx)
177
+ end
178
+ end
174
179
 
175
- def expand_path(f)
176
- return if !f
180
+ def valid_method?
181
+ @method && @method.source? && expand_path(@method.source_file) == @file &&
182
+ @method.source_range.include?(@line)
183
+ end
184
+
185
+ def expand_path(filename)
186
+ return unless filename
187
+ return filename if Pry.eval_path == filename
177
188
 
178
- if Pry.eval_path == f
179
- f
180
- else
181
- File.expand_path(f)
189
+ File.expand_path(filename)
182
190
  end
183
- end
184
191
 
185
- def window_size
186
- if args.empty?
187
- _pry_.config.default_window_size
188
- else
189
- args.first.to_i
192
+ def window_size
193
+ if args.empty?
194
+ pry_instance.config.default_window_size
195
+ else
196
+ args.first.to_i
197
+ end
190
198
  end
191
199
  end
192
- end
193
200
 
194
- Pry::Commands.add_command(Pry::Command::Whereami)
195
- Pry::Commands.alias_command '@', 'whereami'
201
+ Pry::Commands.add_command(Pry::Command::Whereami)
202
+ Pry::Commands.alias_command '@', 'whereami'
203
+ Pry::Commands.alias_command(/whereami[!?]+/, 'whereami')
204
+ end
196
205
  end
@@ -1,57 +1,95 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::Wtf < Pry::ClassCommand
3
- match(/wtf([?!]*)/)
4
- group 'Context'
5
- description 'Show the backtrace of the most recent exception.'
6
- options :listing => 'wtf?'
4
+ class Command
5
+ class Wtf < Pry::ClassCommand
6
+ match(/wtf([?!]*)/)
7
+ group 'Context'
8
+ description 'Show the backtrace of the most recent exception.'
9
+ options listing: 'wtf?'
7
10
 
8
- banner <<-'BANNER'
9
- Usage: wtf[?|!]
11
+ banner <<-'BANNER'
12
+ Usage: wtf[?|!]
10
13
 
11
- Show's a few lines of the backtrace of the most recent exception (also available
12
- as `_ex_.backtrace`). If you want to see more lines, add more question marks or
13
- exclamation marks.
14
+ Shows a few lines of the backtrace of the most recent exception (also available
15
+ as `_ex_.backtrace`). If you want to see more lines, add more question marks or
16
+ exclamation marks.
14
17
 
15
- wtf?
16
- wtf?!???!?!?
18
+ wtf?
19
+ wtf?!???!?!?
17
20
 
18
- # To see the entire backtrace, pass the `-v` or `--verbose` flag.
19
- wtf -v
20
- BANNER
21
+ # To see the entire backtrace, pass the `-v` or `--verbose` flag.
22
+ wtf -v
23
+ BANNER
21
24
 
22
- def options(opt)
23
- opt.on :v, :verbose, "Show the full backtrace"
24
- end
25
+ RUBY_FRAME_PATTERN = /\A(?<file>(.+)):(?<line>(\d+))/.freeze
26
+
27
+ def options(opt)
28
+ opt.on :v, :verbose, "Show the full backtrace"
29
+ opt.on :c, :code, "Show code corresponding to the backtrace frame"
30
+ end
25
31
 
26
- def process
27
- raise Pry::CommandError, "No most-recent exception" unless exception
32
+ def process
33
+ unless pry_instance.last_exception
34
+ raise Pry::CommandError, "No most-recent exception"
35
+ end
28
36
 
29
- output.puts "#{text.bold('Exception:')} #{exception.class}: #{exception}\n--"
30
- if opts.verbose?
31
- output.puts with_line_numbers(backtrace)
32
- else
33
- output.puts with_line_numbers(backtrace.first(size_of_backtrace))
37
+ text = ''.dup
38
+ unwind_exceptions.each_with_index do |exception, i|
39
+ title = (i == 0 ? 'Exception' : 'Caused by')
40
+ text << format_header(title, exception)
41
+ text << format_backtrace(exception.backtrace)
42
+ end
43
+ output.puts(text)
34
44
  end
35
- end
36
45
 
37
- private
46
+ private
38
47
 
39
- def exception
40
- _pry_.last_exception
41
- end
48
+ def unwind_exceptions
49
+ exception_list = []
50
+ exception = pry_instance.last_exception
42
51
 
43
- def with_line_numbers(bt)
44
- Pry::Code.new(bt, 0, :text).with_line_numbers.to_s
45
- end
52
+ while exception
53
+ exception_list << exception
54
+ exception = (exception.cause if exception.respond_to?(:cause))
55
+ end
46
56
 
47
- def backtrace
48
- exception.backtrace
49
- end
57
+ exception_list
58
+ end
59
+
60
+ def format_header(title, exception)
61
+ "#{bold(title + ':')} #{exception.class}: #{exception}\n--\n"
62
+ end
50
63
 
51
- def size_of_backtrace
52
- [captures[0].size, 0.5].max * 10
64
+ def format_backtrace(backtrace)
65
+ lines = trim_backtrace(backtrace).map do |frame|
66
+ next frame unless opts.code?
67
+
68
+ match = frame.match(RUBY_FRAME_PATTERN)
69
+ code = read_line(match[:file], match[:line].to_i)
70
+ [bold(frame), code].join("\n")
71
+ end
72
+
73
+ Pry::Code.new(lines.compact, 0, :text).with_line_numbers.to_s
74
+ end
75
+
76
+ def trim_backtrace(backtrace)
77
+ return backtrace if opts.verbose?
78
+
79
+ size_of_backtrace = [captures[0].size, 0.5].max * 10
80
+ backtrace.first(size_of_backtrace)
81
+ end
82
+
83
+ def read_line(file, line)
84
+ File.open(file, 'r') do |f|
85
+ (line - 1).times { f.gets }
86
+ f.gets
87
+ end
88
+ rescue Errno::ENOENT
89
+ nil
90
+ end
53
91
  end
54
- end
55
92
 
56
- Pry::Commands.add_command(Pry::Command::Wtf)
93
+ Pry::Commands.add_command(Pry::Command::Wtf)
94
+ end
57
95
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Config
5
+ # Attributable provides the ability to create "attribute"
6
+ # accessors. Attribute accessors create a standard "attr_writer" and a
7
+ # customised "attr_reader". This reader is Proc-aware (lazy).
8
+ #
9
+ # @since v0.13.0
10
+ # @api private
11
+ module Attributable
12
+ def attribute(attr_name)
13
+ define_method(attr_name) do
14
+ value = Config::Value.new(instance_variable_get("@#{attr_name}"))
15
+ value.call
16
+ end
17
+
18
+ attr_writer(attr_name)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Config
5
+ # LazyValue is a Proc (block) wrapper. It is meant to be used as a
6
+ # configuration value. Subsequent `#call` calls always evaluate the given
7
+ # block.
8
+ #
9
+ # @example
10
+ # num = 19
11
+ # value = Pry::Config::LazyValue.new { num += 1 }
12
+ # value.foo # => 20
13
+ # value.foo # => 21
14
+ # value.foo # => 22
15
+ #
16
+ # @api private
17
+ # @since v0.13.0
18
+ # @see Pry::Config::MemoizedValue
19
+ class LazyValue
20
+ def initialize(&block)
21
+ @block = block
22
+ end
23
+
24
+ def call
25
+ @block.call
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Config
5
+ # MemoizedValue is a Proc (block) wrapper. It is meant to be used as a
6
+ # configuration value. Subsequent `#call` calls return the same memoized
7
+ # result.
8
+ #
9
+ # @example
10
+ # num = 19
11
+ # value = Pry::Config::MemoizedValue.new { num += 1 }
12
+ # value.call # => 20
13
+ # value.call # => 20
14
+ # value.call # => 20
15
+ #
16
+ # @api private
17
+ # @since v0.13.0
18
+ # @see Pry::Config::LazyValue
19
+ class MemoizedValue
20
+ def initialize(&block)
21
+ @block = block
22
+ @called = false
23
+ @call = nil
24
+ end
25
+
26
+ def call
27
+ return @call if @called
28
+
29
+ @called = true
30
+ @call = @block.call
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Config
5
+ # Value holds a value for the given attribute and decides how it should
6
+ # be read. Procs get called, other values are returned as is.
7
+ #
8
+ # @since v0.13.0
9
+ # @api private
10
+ class Value
11
+ def initialize(value)
12
+ @value = value
13
+ end
14
+
15
+ def call
16
+ unless [Config::MemoizedValue, Config::LazyValue].include?(@value.class)
17
+ return @value
18
+ end
19
+
20
+ @value.call
21
+ end
22
+ end
23
+ end
24
+ end