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
@@ -1,190 +1,205 @@
1
- class Pry
2
- class Command::Whereami < Pry::ClassCommand
1
+ # frozen_string_literal: true
3
2
 
4
- class << self
5
- attr_accessor :method_size_cutoff
6
- end
3
+ require 'method_source'
7
4
 
8
- @method_size_cutoff = 30
5
+ class Pry
6
+ class Command
7
+ class Whereami < Pry::ClassCommand
8
+ def initialize(*)
9
+ super
9
10
 
10
- match 'whereami'
11
- description 'Show code surrounding the current context.'
12
- group 'Context'
11
+ @method_code = nil
12
+ end
13
13
 
14
- banner <<-'BANNER'
15
- Usage: whereami [-qn] [LINES]
14
+ class << self
15
+ attr_accessor :method_size_cutoff
16
+ end
16
17
 
17
- Describe the current location. If you use `binding.pry` inside a method then
18
- whereami will print out the source for that method.
18
+ @method_size_cutoff = 30
19
19
 
20
- If a number is passed, then LINES lines before and after the current line will be
21
- shown instead of the method itself.
20
+ match 'whereami'
21
+ description 'Show code surrounding the current context.'
22
+ group 'Context'
22
23
 
23
- The `-q` flag can be used to suppress error messages in the case that there's
24
- no code to show. This is used by pry in the default before_session hook to show
25
- you when you arrive at a `binding.pry`.
24
+ banner <<-'BANNER'
25
+ Usage: whereami [-qn] [LINES]
26
26
 
27
- The `-n` flag can be used to hide line numbers so that code can be copy/pasted
28
- effectively.
27
+ Describe the current location. If you use `binding.pry` inside a method then
28
+ whereami will print out the source for that method.
29
29
 
30
- When pry was started on an Object and there is no associated method, whereami
31
- will instead output a brief description of the current object.
32
- BANNER
30
+ If a number is passed, then LINES lines before and after the current line will be
31
+ shown instead of the method itself.
33
32
 
34
- def setup
35
- @file = expand_path(target.eval('__FILE__'))
36
- @line = target.eval('__LINE__')
37
- @method = Pry::Method.from_binding(target)
38
- end
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 options(opt)
41
- opt.on :q, :quiet, "Don't display anything in case of an error"
42
- opt.on :n, :"no-line-numbers", "Do not display line numbers"
43
- opt.on :m, :"method", "Show the complete source for the current method."
44
- opt.on :c, :"class", "Show the complete source for the current class or module."
45
- opt.on :f, :"file", "Show the complete source for the current file."
46
- end
37
+ The `-n` flag can be used to hide line numbers so that code can be copy/pasted
38
+ effectively.
47
39
 
48
- def code
49
- @code ||= if opts.present?(:m)
50
- method_code or raise CommandError, "Cannot find method code."
51
- elsif opts.present?(:c)
52
- class_code or raise CommandError, "Cannot find class code."
53
- elsif opts.present?(:f)
54
- Pry::Code.from_file(@file)
55
- elsif args.any?
56
- code_window
57
- else
58
- default_code
59
- end
60
- 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
61
43
 
62
- def code?
63
- !!code
64
- rescue MethodSource::SourceNotFoundError
65
- false
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 bad_option_combination?
69
- [opts.present?(:m), opts.present?(:f),
70
- opts.present?(:c), args.any?].count(true) > 1
71
- 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
72
62
 
73
- def location
74
- "#{@file} @ line #{@line} #{@method && @method.name_with_owner}"
75
- 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
76
76
 
77
- def process
78
- if bad_option_combination?
79
- raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
77
+ def code?
78
+ !!code
79
+ rescue MethodSource::SourceNotFoundError
80
+ false
80
81
  end
81
82
 
82
- if nothing_to_do?
83
- return
84
- elsif internal_binding?(target)
85
- handle_internal_binding
86
- return
83
+ def bad_option_combination?
84
+ [opts.present?(:m), opts.present?(:f),
85
+ opts.present?(:c), args.any?].count(true) > 1
87
86
  end
88
87
 
89
- set_file_and_dir_locals(@file)
88
+ def location
89
+ "#{@file}:#{@line} #{@method && @method.name_with_owner}"
90
+ end
90
91
 
91
- out = "\n#{text.bold('From:')} #{location}:\n\n" <<
92
- code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted << "\n"
92
+ def process
93
+ if bad_option_combination?
94
+ raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
95
+ end
93
96
 
94
- _pry_.pager.page out
95
- end
97
+ return if nothing_to_do?
96
98
 
97
- private
99
+ if internal_binding?(target)
100
+ handle_internal_binding
101
+ return
102
+ end
98
103
 
99
- def nothing_to_do?
100
- opts.quiet? && (internal_binding?(target) || !code?)
101
- end
104
+ set_file_and_dir_locals(@file)
102
105
 
103
- def use_line_numbers?
104
- !opts.present?(:n)
105
- 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
106
113
 
107
- def marker
108
- !opts.present?(:n) && @line
109
- end
114
+ private
110
115
 
111
- def top_level?
112
- target_self == Pry.main
113
- end
116
+ def nothing_to_do?
117
+ opts.quiet? && (internal_binding?(target) || !code?)
118
+ end
114
119
 
115
- def handle_internal_binding
116
- if top_level?
117
- output.puts "At the top level."
118
- else
119
- output.puts "Inside #{Pry.view_clip(target_self)}."
120
+ def use_line_numbers?
121
+ !opts.present?(:n)
120
122
  end
121
- end
122
123
 
123
- def small_method?
124
- @method.source_range.count < self.class.method_size_cutoff
125
- end
124
+ def marker
125
+ !opts.present?(:n) && @line
126
+ end
126
127
 
127
- def default_code
128
- if method_code && small_method?
129
- method_code
130
- else
131
- code_window
128
+ def top_level?
129
+ target_self == Pry.main
132
130
  end
133
- end
134
131
 
135
- def code_window
136
- Pry::Code.from_file(@file).around(@line, window_size)
137
- end
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
+ end
138
139
 
139
- def method_code
140
- return @method_code if @method_code
140
+ def small_method?
141
+ @method.source_range.count < self.class.method_size_cutoff
142
+ end
141
143
 
142
- if valid_method?
143
- @method_code = Pry::Code.from_method(@method)
144
+ def default_code
145
+ if method_code && small_method?
146
+ method_code
147
+ else
148
+ code_window
149
+ end
144
150
  end
145
- end
146
151
 
147
- # This either returns the `target_self`
148
- # or it returns the class of `target_self` if `target_self` is not a class.
149
- # @return [Pry::WrappedModule]
150
- def target_class
151
- target_self.is_a?(Module) ? Pry::WrappedModule(target_self) :
152
- Pry::WrappedModule(target_self.class)
153
- end
152
+ def code_window
153
+ Pry::Code.from_file(@file).around(@line, window_size)
154
+ end
155
+
156
+ def method_code
157
+ return @method_code if @method_code
154
158
 
155
- def class_code
156
- return @class_code if @class_code
159
+ @method_code = Pry::Code.from_method(@method) if valid_method?
160
+ end
157
161
 
158
- 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)
159
167
 
160
- idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
161
- @class_code = idx && Pry::Code.from_module(mod, idx)
162
- end
168
+ Pry::WrappedModule(target_self.class)
169
+ end
163
170
 
164
- def valid_method?
165
- @method && @method.source? && expand_path(@method.source_file) == @file &&
166
- @method.source_range.include?(@line)
167
- 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
168
179
 
169
- def expand_path(f)
170
- 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
171
188
 
172
- if Pry.eval_path == f
173
- f
174
- else
175
- File.expand_path(f)
189
+ File.expand_path(filename)
176
190
  end
177
- end
178
191
 
179
- def window_size
180
- if args.empty?
181
- _pry_.config.default_window_size
182
- else
183
- 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
184
198
  end
185
199
  end
186
- end
187
200
 
188
- Pry::Commands.add_command(Pry::Command::Whereami)
189
- 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
190
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