pry 0.10.0.pre2-universal-mswin32

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 (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +25 -0
  4. data/README.md +406 -0
  5. data/bin/pry +16 -0
  6. data/lib/pry.rb +161 -0
  7. data/lib/pry/cli.rb +220 -0
  8. data/lib/pry/code.rb +346 -0
  9. data/lib/pry/code/code_file.rb +103 -0
  10. data/lib/pry/code/code_range.rb +71 -0
  11. data/lib/pry/code/loc.rb +92 -0
  12. data/lib/pry/code_object.rb +172 -0
  13. data/lib/pry/color_printer.rb +55 -0
  14. data/lib/pry/command.rb +692 -0
  15. data/lib/pry/command_set.rb +443 -0
  16. data/lib/pry/commands.rb +6 -0
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +62 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +41 -0
  26. data/lib/pry/commands/change_inspector.rb +27 -0
  27. data/lib/pry/commands/change_prompt.rb +26 -0
  28. data/lib/pry/commands/code_collector.rb +165 -0
  29. data/lib/pry/commands/disable_pry.rb +27 -0
  30. data/lib/pry/commands/disabled_commands.rb +2 -0
  31. data/lib/pry/commands/easter_eggs.rb +112 -0
  32. data/lib/pry/commands/edit.rb +195 -0
  33. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  34. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  35. data/lib/pry/commands/exit.rb +42 -0
  36. data/lib/pry/commands/exit_all.rb +29 -0
  37. data/lib/pry/commands/exit_program.rb +23 -0
  38. data/lib/pry/commands/find_method.rb +193 -0
  39. data/lib/pry/commands/fix_indent.rb +19 -0
  40. data/lib/pry/commands/gem_cd.rb +26 -0
  41. data/lib/pry/commands/gem_install.rb +32 -0
  42. data/lib/pry/commands/gem_list.rb +33 -0
  43. data/lib/pry/commands/gem_open.rb +29 -0
  44. data/lib/pry/commands/gist.rb +101 -0
  45. data/lib/pry/commands/help.rb +164 -0
  46. data/lib/pry/commands/hist.rb +180 -0
  47. data/lib/pry/commands/import_set.rb +22 -0
  48. data/lib/pry/commands/install_command.rb +53 -0
  49. data/lib/pry/commands/jump_to.rb +29 -0
  50. data/lib/pry/commands/list_inspectors.rb +35 -0
  51. data/lib/pry/commands/list_prompts.rb +35 -0
  52. data/lib/pry/commands/ls.rb +114 -0
  53. data/lib/pry/commands/ls/constants.rb +47 -0
  54. data/lib/pry/commands/ls/formatter.rb +49 -0
  55. data/lib/pry/commands/ls/globals.rb +48 -0
  56. data/lib/pry/commands/ls/grep.rb +21 -0
  57. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  58. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  59. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  60. data/lib/pry/commands/ls/local_names.rb +35 -0
  61. data/lib/pry/commands/ls/local_vars.rb +39 -0
  62. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  63. data/lib/pry/commands/ls/methods.rb +57 -0
  64. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  65. data/lib/pry/commands/ls/self_methods.rb +32 -0
  66. data/lib/pry/commands/nesting.rb +25 -0
  67. data/lib/pry/commands/play.rb +103 -0
  68. data/lib/pry/commands/pry_backtrace.rb +25 -0
  69. data/lib/pry/commands/pry_version.rb +17 -0
  70. data/lib/pry/commands/raise_up.rb +32 -0
  71. data/lib/pry/commands/reload_code.rb +62 -0
  72. data/lib/pry/commands/reset.rb +18 -0
  73. data/lib/pry/commands/ri.rb +60 -0
  74. data/lib/pry/commands/save_file.rb +61 -0
  75. data/lib/pry/commands/shell_command.rb +48 -0
  76. data/lib/pry/commands/shell_mode.rb +25 -0
  77. data/lib/pry/commands/show_doc.rb +83 -0
  78. data/lib/pry/commands/show_info.rb +195 -0
  79. data/lib/pry/commands/show_input.rb +17 -0
  80. data/lib/pry/commands/show_source.rb +50 -0
  81. data/lib/pry/commands/simple_prompt.rb +22 -0
  82. data/lib/pry/commands/stat.rb +40 -0
  83. data/lib/pry/commands/switch_to.rb +23 -0
  84. data/lib/pry/commands/toggle_color.rb +24 -0
  85. data/lib/pry/commands/watch_expression.rb +105 -0
  86. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  87. data/lib/pry/commands/whereami.rb +190 -0
  88. data/lib/pry/commands/wtf.rb +57 -0
  89. data/lib/pry/config.rb +24 -0
  90. data/lib/pry/config/behavior.rb +139 -0
  91. data/lib/pry/config/convenience.rb +26 -0
  92. data/lib/pry/config/default.rb +165 -0
  93. data/lib/pry/core_extensions.rb +131 -0
  94. data/lib/pry/editor.rb +133 -0
  95. data/lib/pry/exceptions.rb +77 -0
  96. data/lib/pry/helpers.rb +5 -0
  97. data/lib/pry/helpers/base_helpers.rb +113 -0
  98. data/lib/pry/helpers/command_helpers.rb +156 -0
  99. data/lib/pry/helpers/documentation_helpers.rb +75 -0
  100. data/lib/pry/helpers/options_helpers.rb +27 -0
  101. data/lib/pry/helpers/table.rb +109 -0
  102. data/lib/pry/helpers/text.rb +107 -0
  103. data/lib/pry/history.rb +125 -0
  104. data/lib/pry/history_array.rb +121 -0
  105. data/lib/pry/hooks.rb +230 -0
  106. data/lib/pry/indent.rb +406 -0
  107. data/lib/pry/input_completer.rb +242 -0
  108. data/lib/pry/input_lock.rb +132 -0
  109. data/lib/pry/inspector.rb +27 -0
  110. data/lib/pry/last_exception.rb +61 -0
  111. data/lib/pry/method.rb +546 -0
  112. data/lib/pry/method/disowned.rb +53 -0
  113. data/lib/pry/method/patcher.rb +125 -0
  114. data/lib/pry/method/weird_method_locator.rb +186 -0
  115. data/lib/pry/module_candidate.rb +136 -0
  116. data/lib/pry/object_path.rb +82 -0
  117. data/lib/pry/output.rb +50 -0
  118. data/lib/pry/pager.rb +234 -0
  119. data/lib/pry/plugins.rb +103 -0
  120. data/lib/pry/prompt.rb +26 -0
  121. data/lib/pry/pry_class.rb +375 -0
  122. data/lib/pry/pry_instance.rb +654 -0
  123. data/lib/pry/rbx_path.rb +22 -0
  124. data/lib/pry/repl.rb +202 -0
  125. data/lib/pry/repl_file_loader.rb +74 -0
  126. data/lib/pry/rubygem.rb +82 -0
  127. data/lib/pry/terminal.rb +79 -0
  128. data/lib/pry/test/helper.rb +170 -0
  129. data/lib/pry/version.rb +3 -0
  130. data/lib/pry/wrapped_module.rb +373 -0
  131. metadata +248 -0
@@ -0,0 +1,82 @@
1
+ class Pry
2
+ # `ObjectPath` implements the resolution of "object paths", which are strings
3
+ # that are similar to filesystem paths but meant for traversing Ruby objects.
4
+ # Examples of valid object paths include:
5
+ #
6
+ # x
7
+ # @foo/@bar
8
+ # "string"/upcase
9
+ # Pry/Method
10
+ #
11
+ # Object paths are mostly relevant in the context of the `cd` command.
12
+ # @see https://github.com/pry/pry/wiki/State-navigation
13
+ class ObjectPath
14
+ SPECIAL_TERMS = ["", "::", ".", ".."]
15
+
16
+ # @param [String] path_string The object path expressed as a string.
17
+ # @param [Array<Binding>] current_stack The current state of the binding
18
+ # stack.
19
+ def initialize(path_string, current_stack)
20
+ @path_string = path_string
21
+ @current_stack = current_stack
22
+ end
23
+
24
+ # @return [Array<Binding>] a new stack resulting from applying the given
25
+ # path to the current stack.
26
+ def resolve
27
+ scanner = StringScanner.new(@path_string.strip)
28
+ stack = @current_stack.dup
29
+
30
+ begin
31
+ next_segment = ""
32
+
33
+ loop do
34
+ # Scan for as long as we don't see a slash
35
+ next_segment << scanner.scan(/[^\/]*/)
36
+
37
+ if complete?(next_segment) || scanner.eos?
38
+ scanner.getch # consume the slash
39
+ break
40
+ else
41
+ next_segment << scanner.getch # append the slash
42
+ end
43
+ end
44
+
45
+ case next_segment.chomp
46
+ when ""
47
+ stack = [stack.first]
48
+ when "::"
49
+ stack.push(TOPLEVEL_BINDING)
50
+ when "."
51
+ next
52
+ when ".."
53
+ stack.pop unless stack.size == 1
54
+ else
55
+ stack.push(Pry.binding_for(stack.last.eval(next_segment)))
56
+ end
57
+ rescue RescuableException => e
58
+ return handle_failure(next_segment, e)
59
+ end until scanner.eos?
60
+
61
+ stack
62
+ end
63
+
64
+ private
65
+
66
+ def complete?(segment)
67
+ SPECIAL_TERMS.include?(segment) || Pry::Code.complete_expression?(segment)
68
+ end
69
+
70
+ def handle_failure(context, err)
71
+ msg = [
72
+ "Bad object path: #{@path_string.inspect}",
73
+ "Failed trying to resolve: #{context.inspect}",
74
+ "Exception: #{err.inspect}"
75
+ ].join("\n")
76
+
77
+ raise CommandError.new(msg).tap { |e|
78
+ e.set_backtrace err.backtrace
79
+ }
80
+ end
81
+ end
82
+ end
data/lib/pry/output.rb ADDED
@@ -0,0 +1,50 @@
1
+ class Pry
2
+ class Output
3
+ attr_reader :_pry_
4
+
5
+ def initialize(_pry_)
6
+ @_pry_ = _pry_
7
+ end
8
+
9
+ def puts(*objs)
10
+ return print "\n" if objs.empty?
11
+
12
+ objs.each do |obj|
13
+ if ary = Array.try_convert(obj)
14
+ puts(*ary)
15
+ else
16
+ print "#{obj.to_s.chomp}\n"
17
+ end
18
+ end
19
+
20
+ nil
21
+ end
22
+
23
+ def print(*objs)
24
+ objs.each do |obj|
25
+ _pry_.config.output.print decolorize_maybe(obj.to_s)
26
+ end
27
+
28
+ nil
29
+ end
30
+ alias << print
31
+ alias write print
32
+
33
+ # If _pry_.config.color is currently false, removes ansi escapes from the string.
34
+ def decolorize_maybe(str)
35
+ if _pry_.config.color
36
+ str
37
+ else
38
+ Helpers::Text.strip_color str
39
+ end
40
+ end
41
+
42
+ def method_missing(name, *args, &block)
43
+ _pry_.config.output.send(name, *args, &block)
44
+ end
45
+
46
+ def respond_to_missing?(*a)
47
+ _pry_.config.respond_to?(*a)
48
+ end
49
+ end
50
+ end
data/lib/pry/pager.rb ADDED
@@ -0,0 +1,234 @@
1
+ require 'pry/terminal'
2
+
3
+ # A pager is an `IO`-like object that accepts text and either prints it
4
+ # immediately, prints it one page at a time, or streams it to an external
5
+ # program to print one page at a time.
6
+ class Pry::Pager
7
+ class StopPaging < StandardError
8
+ end
9
+
10
+ attr_reader :_pry_
11
+
12
+ def initialize(_pry_)
13
+ @_pry_ = _pry_
14
+ end
15
+
16
+ # Send the given text through the best available pager (if `Pry.config.pager` is
17
+ # enabled).
18
+ # If you want to send text through in chunks as you generate it, use `open` to
19
+ # get a writable object instead.
20
+ # @param [String] text A piece of text to run through a pager.
21
+ # @param [IO] output (`$stdout`) An object to send output to.
22
+ def page(text)
23
+ open do |pager|
24
+ pager << text
25
+ end
26
+ end
27
+
28
+ # Yields a pager object (`NullPager`, `SimplePager`, or `SystemPager`). All
29
+ # pagers accept output with `#puts`, `#print`, `#write`, and `#<<`.
30
+ # @param [IO] output (`$stdout`) An object to send output to.
31
+ def open
32
+ pager = best_available
33
+ yield pager
34
+ rescue StopPaging
35
+ ensure
36
+ pager.close if pager
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :output
42
+ def enabled?; !!@enabled; end
43
+
44
+ # Return an instance of the "best" available pager class -- `SystemPager` if
45
+ # possible, `SimplePager` if `SystemPager` isn't available, and `NullPager`
46
+ # if the user has disabled paging. All pagers accept output with `#puts`,
47
+ # `#print`, `#write`, and `#<<`. You must call `#close` when you're done
48
+ # writing output to a pager, and you must rescue `Pry::Pager::StopPaging`.
49
+ # These requirements can be avoided by using `.open` instead.
50
+ # @param [#<<] output ($stdout) An object to send output to.
51
+ def best_available
52
+ if !_pry_.config.pager
53
+ NullPager.new(_pry_.output)
54
+ elsif !SystemPager.available? || Pry::Helpers::BaseHelpers.jruby?
55
+ SimplePager.new(_pry_.output)
56
+ else
57
+ SystemPager.new(_pry_.output)
58
+ end
59
+ end
60
+
61
+ # `NullPager` is a "pager" that actually just prints all output as it comes
62
+ # in. Used when `Pry.config.pager` is false.
63
+ class NullPager
64
+ def initialize(out)
65
+ @out = out
66
+ end
67
+
68
+ def puts(str)
69
+ print "#{str.chomp}\n"
70
+ end
71
+
72
+ def print(str)
73
+ write str
74
+ end
75
+ alias << print
76
+
77
+ def write(str)
78
+ @out.write str
79
+ end
80
+
81
+ def close
82
+ end
83
+
84
+ private
85
+
86
+ def height
87
+ @height ||= Pry::Terminal.height!
88
+ end
89
+
90
+ def width
91
+ @width ||= Pry::Terminal.width!
92
+ end
93
+ end
94
+
95
+ # `SimplePager` is a straightforward pure-Ruby pager. We use it on JRuby and
96
+ # when we can't find a usable external pager.
97
+ class SimplePager < NullPager
98
+ def initialize(*)
99
+ super
100
+ @tracker = PageTracker.new(height - 3, width)
101
+ end
102
+
103
+ def write(str)
104
+ str.lines.each do |line|
105
+ @out.print line
106
+ @tracker.record line
107
+
108
+ if @tracker.page?
109
+ @out.print "\n"
110
+ @out.print "\e[0m"
111
+ @out.print "<page break> --- Press enter to continue " \
112
+ "( q<enter> to break ) --- <page break>\n"
113
+ raise StopPaging if Readline.readline("").chomp == "q"
114
+ @tracker.reset
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ # `SystemPager` buffers output until we're pretty sure it's at least a page
121
+ # long, then invokes an external pager and starts streaming output to it. If
122
+ # `#close` is called before then, it just prints out the buffered content.
123
+ class SystemPager < NullPager
124
+ def self.default_pager
125
+ pager = ENV["PAGER"] || ""
126
+
127
+ # Default to less, and make sure less is being passed the correct options
128
+ if pager.strip.empty? or pager =~ /^less\b/
129
+ pager = "less -R -F -X"
130
+ end
131
+
132
+ pager
133
+ end
134
+
135
+ def self.available?
136
+ if @system_pager.nil?
137
+ @system_pager = begin
138
+ pager_executable = default_pager.split(' ').first
139
+ `which #{ pager_executable }`
140
+ rescue
141
+ false
142
+ end
143
+ else
144
+ @system_pager
145
+ end
146
+ end
147
+
148
+ def initialize(*)
149
+ super
150
+ @tracker = PageTracker.new(height, width)
151
+ @buffer = ""
152
+ end
153
+
154
+ def write(str)
155
+ if invoked_pager?
156
+ write_to_pager str
157
+ else
158
+ @tracker.record str
159
+ @buffer << str
160
+
161
+ if @tracker.page?
162
+ write_to_pager @buffer
163
+ end
164
+ end
165
+ rescue Errno::EPIPE
166
+ raise StopPaging
167
+ end
168
+
169
+ def close
170
+ if invoked_pager?
171
+ pager.close
172
+ else
173
+ @out.puts @buffer
174
+ end
175
+ end
176
+
177
+ private
178
+
179
+ def write_to_pager(text)
180
+ pager.write @out.decolorize_maybe(text)
181
+ end
182
+
183
+ def invoked_pager?
184
+ @pager
185
+ end
186
+
187
+ def pager
188
+ @pager ||= IO.popen(self.class.default_pager, 'w')
189
+ end
190
+ end
191
+
192
+ # `PageTracker` tracks output to determine whether it's likely to take up a
193
+ # whole page. This doesn't need to be super precise, but we can use it for
194
+ # `SimplePager` and to avoid invoking the system pager unnecessarily.
195
+ #
196
+ # One simplifying assumption is that we don't need `#page?` to return `true`
197
+ # on the basis of an incomplete line. Long lines should be counted as
198
+ # multiple lines, but we don't have to transition from `false` to `true`
199
+ # until we see a newline.
200
+ class PageTracker
201
+ def initialize(rows, cols)
202
+ @rows, @cols = rows, cols
203
+ reset
204
+ end
205
+
206
+ def record(str)
207
+ str.lines.each do |line|
208
+ if line.end_with? "\n"
209
+ @row += ((@col + line_length(line) - 1) / @cols) + 1
210
+ @col = 0
211
+ else
212
+ @col += line_length(line)
213
+ end
214
+ end
215
+ end
216
+
217
+ def page?
218
+ @row >= @rows
219
+ end
220
+
221
+ def reset
222
+ @row = 0
223
+ @col = 0
224
+ end
225
+
226
+ private
227
+
228
+ # Approximation of the printable length of a given line, without the
229
+ # newline and without ANSI color codes.
230
+ def line_length(line)
231
+ line.chomp.gsub(/\e\[[\d;]*m/, '').length
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,103 @@
1
+ class Pry
2
+ class PluginManager
3
+ PRY_PLUGIN_PREFIX = /^pry-/
4
+
5
+ # Placeholder when no associated gem found, displays warning
6
+ class NoPlugin
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def method_missing(*args)
12
+ warn "Warning: The plugin '#{@name}' was not found! (no gem found)"
13
+ end
14
+ end
15
+
16
+ class Plugin
17
+ attr_accessor :name, :gem_name, :enabled, :spec, :active
18
+
19
+ def initialize(name, gem_name, spec, enabled)
20
+ @name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec
21
+ end
22
+
23
+ # Disable a plugin. (prevents plugin from being loaded, cannot
24
+ # disable an already activated plugin)
25
+ def disable!
26
+ self.enabled = false
27
+ end
28
+
29
+ # Enable a plugin. (does not load it immediately but puts on
30
+ # 'white list' to be loaded)
31
+ def enable!
32
+ self.enabled = true
33
+ end
34
+
35
+ # Load the Command line options defined by this plugin (if they exist)
36
+ def load_cli_options
37
+ cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb")
38
+ require cli_options_file if File.exists?(cli_options_file)
39
+ end
40
+ # Activate the plugin (require the gem - enables/loads the
41
+ # plugin immediately at point of call, even if plugin is
42
+ # disabled)
43
+ # Does not reload plugin if it's already active.
44
+ def activate!
45
+ # Create the configuration object for the plugin.
46
+ Pry.config.send("#{gem_name.gsub('-', '_')}=", Pry::Config.from_hash({}))
47
+
48
+ begin
49
+ require gem_name if !active?
50
+ rescue LoadError => e
51
+ warn "Found plugin #{gem_name}, but could not require '#{gem_name}'"
52
+ warn e
53
+ rescue => e
54
+ warn "require '#{gem_name}' # Failed, saying: #{e}"
55
+ end
56
+
57
+ self.active = true
58
+ self.enabled = true
59
+ end
60
+
61
+ alias active? active
62
+ alias enabled? enabled
63
+ end
64
+
65
+ def initialize
66
+ @plugins = []
67
+ end
68
+
69
+ # Find all installed Pry plugins and store them in an internal array.
70
+ def locate_plugins
71
+ Gem.refresh
72
+ (Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')).each do |gem|
73
+ next if gem.name !~ PRY_PLUGIN_PREFIX
74
+ plugin_name = gem.name.split('-', 2).last
75
+ @plugins << Plugin.new(plugin_name, gem.name, gem, true) if !gem_located?(gem.name)
76
+ end
77
+ @plugins
78
+ end
79
+
80
+ # @return [Hash] A hash with all plugin names (minus the 'pry-') as
81
+ # keys and Plugin objects as values.
82
+ def plugins
83
+ h = Hash.new { |_, key| NoPlugin.new(key) }
84
+ @plugins.each do |plugin|
85
+ h[plugin.name] = plugin
86
+ end
87
+ h
88
+ end
89
+
90
+ # Require all enabled plugins, disabled plugins are skipped.
91
+ def load_plugins
92
+ @plugins.each do |plugin|
93
+ plugin.activate! if plugin.enabled?
94
+ end
95
+ end
96
+
97
+ private
98
+ def gem_located?(gem_name)
99
+ @plugins.any? { |plugin| plugin.gem_name == gem_name }
100
+ end
101
+ end
102
+
103
+ end