pry 0.9.12.2 → 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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1141 -0
- data/LICENSE +2 -2
- data/README.md +466 -0
- data/bin/pry +4 -7
- data/lib/pry/basic_object.rb +10 -0
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +97 -92
- data/lib/pry/code/code_file.rb +114 -0
- data/lib/pry/code/code_range.rb +7 -4
- data/lib/pry/code/loc.rb +27 -14
- data/lib/pry/code.rb +62 -90
- data/lib/pry/code_object.rb +83 -39
- data/lib/pry/color_printer.rb +66 -0
- data/lib/pry/command.rb +202 -371
- data/lib/pry/command_set.rb +151 -133
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -82
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +85 -73
- data/lib/pry/commands/cat/file_formatter.rb +56 -63
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cat.rb +64 -47
- data/lib/pry/commands/cd.rb +42 -26
- data/lib/pry/commands/change_inspector.rb +34 -0
- data/lib/pry/commands/change_prompt.rb +51 -0
- data/lib/pry/commands/clear_screen.rb +20 -0
- data/lib/pry/commands/code_collector.rb +148 -131
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +23 -34
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +33 -24
- data/lib/pry/commands/edit.rb +183 -167
- data/lib/pry/commands/exit.rb +40 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -17
- data/lib/pry/commands/find_method.rb +167 -167
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +153 -132
- data/lib/pry/commands/import_set.rb +20 -15
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +42 -0
- data/lib/pry/commands/ls/constants.rb +75 -0
- data/lib/pry/commands/ls/formatter.rb +55 -0
- data/lib/pry/commands/ls/globals.rb +50 -0
- data/lib/pry/commands/ls/grep.rb +23 -0
- data/lib/pry/commands/ls/instance_vars.rb +40 -0
- data/lib/pry/commands/ls/interrogatable.rb +24 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +55 -0
- data/lib/pry/commands/ls/local_names.rb +37 -0
- data/lib/pry/commands/ls/local_vars.rb +47 -0
- data/lib/pry/commands/ls/ls_entity.rb +65 -0
- data/lib/pry/commands/ls/methods.rb +55 -0
- data/lib/pry/commands/ls/methods_helper.rb +50 -0
- data/lib/pry/commands/ls/self_methods.rb +34 -0
- data/lib/pry/commands/ls.rb +100 -303
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +93 -49
- data/lib/pry/commands/pry_backtrace.rb +22 -18
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +33 -27
- data/lib/pry/commands/reload_code.rb +57 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +57 -38
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +66 -34
- data/lib/pry/commands/shell_mode.rb +22 -20
- data/lib/pry/commands/show_doc.rb +80 -65
- data/lib/pry/commands/show_info.rb +193 -159
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +113 -33
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +21 -13
- data/lib/pry/commands/watch_expression/expression.rb +43 -0
- data/lib/pry/commands/watch_expression.rb +110 -0
- data/lib/pry/commands/whereami.rb +157 -134
- data/lib/pry/commands/wtf.rb +78 -40
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/config.rb +290 -220
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +50 -27
- data/lib/pry/editor.rb +130 -102
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +73 -0
- data/lib/pry/forwardable.rb +27 -0
- data/lib/pry/helpers/base_helpers.rb +22 -151
- data/lib/pry/helpers/command_helpers.rb +55 -63
- data/lib/pry/helpers/documentation_helpers.rb +21 -13
- data/lib/pry/helpers/options_helpers.rb +15 -8
- data/lib/pry/helpers/platform.rb +55 -0
- data/lib/pry/helpers/table.rb +44 -32
- data/lib/pry/helpers/text.rb +96 -86
- data/lib/pry/helpers.rb +3 -0
- data/lib/pry/history.rb +101 -70
- data/lib/pry/hooks.rb +67 -137
- data/lib/pry/indent.rb +79 -73
- data/lib/pry/input_completer.rb +283 -0
- data/lib/pry/input_lock.rb +129 -0
- data/lib/pry/inspector.rb +39 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method/disowned.rb +19 -5
- data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +51 -42
- data/lib/pry/method/weird_method_locator.rb +80 -44
- data/lib/pry/method.rb +225 -176
- data/lib/pry/object_path.rb +91 -0
- data/lib/pry/output.rb +136 -0
- data/lib/pry/pager.rb +227 -68
- data/lib/pry/prompt.rb +214 -0
- data/lib/pry/pry_class.rb +216 -289
- data/lib/pry/pry_instance.rb +438 -500
- data/lib/pry/repl.rb +256 -0
- data/lib/pry/repl_file_loader.rb +34 -35
- data/lib/pry/ring.rb +89 -0
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +190 -0
- data/lib/pry/slop/option.rb +210 -0
- data/lib/pry/slop.rb +672 -0
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable/evalable.rb +24 -0
- data/lib/pry/testable/mockable.rb +22 -0
- data/lib/pry/testable/pry_tester.rb +88 -0
- data/lib/pry/testable/utility.rb +34 -0
- data/lib/pry/testable/variables.rb +52 -0
- data/lib/pry/testable.rb +68 -0
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +20 -0
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +36 -43
- data/lib/pry/wrapped_module.rb +102 -103
- data/lib/pry.rb +135 -261
- metadata +94 -283
- data/.document +0 -2
- data/.gitignore +0 -16
- data/.travis.yml +0 -21
- data/.yardopts +0 -1
- data/CHANGELOG +0 -534
- data/CONTRIBUTORS +0 -55
- data/Gemfile +0 -9
- data/Guardfile +0 -62
- data/README.markdown +0 -400
- data/Rakefile +0 -140
- data/TODO +0 -117
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -29
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gist.rb +0 -102
- data/lib/pry/commands/install_command.rb +0 -51
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/completion.rb +0 -304
- data/lib/pry/custom_completions.rb +0 -6
- data/lib/pry/history_array.rb +0 -116
- data/lib/pry/plugins.rb +0 -103
- data/lib/pry/rbx_method.rb +0 -13
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/rubygem.rb +0 -74
- data/lib/pry/terminal.rb +0 -78
- data/lib/pry/test/helper.rb +0 -185
- data/man/pry.1 +0 -195
- data/man/pry.1.html +0 -204
- data/man/pry.1.ronn +0 -141
- data/pry.gemspec +0 -30
- data/spec/Procfile +0 -3
- data/spec/cli_spec.rb +0 -78
- data/spec/code_object_spec.rb +0 -277
- data/spec/code_spec.rb +0 -219
- data/spec/command_helpers_spec.rb +0 -29
- data/spec/command_integration_spec.rb +0 -644
- data/spec/command_set_spec.rb +0 -627
- data/spec/command_spec.rb +0 -821
- data/spec/commands/amend_line_spec.rb +0 -247
- data/spec/commands/bang_spec.rb +0 -19
- data/spec/commands/cat_spec.rb +0 -164
- data/spec/commands/cd_spec.rb +0 -250
- data/spec/commands/disable_pry_spec.rb +0 -25
- data/spec/commands/edit_spec.rb +0 -727
- data/spec/commands/exit_all_spec.rb +0 -34
- data/spec/commands/exit_program_spec.rb +0 -19
- data/spec/commands/exit_spec.rb +0 -34
- data/spec/commands/find_method_spec.rb +0 -70
- data/spec/commands/gem_list_spec.rb +0 -26
- data/spec/commands/gist_spec.rb +0 -79
- data/spec/commands/help_spec.rb +0 -56
- data/spec/commands/hist_spec.rb +0 -181
- data/spec/commands/jump_to_spec.rb +0 -15
- data/spec/commands/ls_spec.rb +0 -181
- data/spec/commands/play_spec.rb +0 -140
- data/spec/commands/raise_up_spec.rb +0 -56
- data/spec/commands/save_file_spec.rb +0 -177
- data/spec/commands/show_doc_spec.rb +0 -510
- data/spec/commands/show_input_spec.rb +0 -17
- data/spec/commands/show_source_spec.rb +0 -782
- data/spec/commands/whereami_spec.rb +0 -203
- data/spec/completion_spec.rb +0 -239
- data/spec/control_d_handler_spec.rb +0 -58
- data/spec/documentation_helper_spec.rb +0 -73
- data/spec/editor_spec.rb +0 -79
- data/spec/exception_whitelist_spec.rb +0 -21
- data/spec/fixtures/candidate_helper1.rb +0 -11
- data/spec/fixtures/candidate_helper2.rb +0 -8
- data/spec/fixtures/example.erb +0 -5
- data/spec/fixtures/example_nesting.rb +0 -33
- data/spec/fixtures/show_source_doc_examples.rb +0 -15
- data/spec/fixtures/testrc +0 -2
- data/spec/fixtures/testrcbad +0 -2
- data/spec/fixtures/whereami_helper.rb +0 -6
- data/spec/helper.rb +0 -34
- data/spec/helpers/bacon.rb +0 -86
- data/spec/helpers/mock_pry.rb +0 -43
- data/spec/helpers/table_spec.rb +0 -105
- data/spec/history_array_spec.rb +0 -67
- data/spec/hooks_spec.rb +0 -522
- data/spec/indent_spec.rb +0 -301
- data/spec/input_stack_spec.rb +0 -90
- data/spec/method_spec.rb +0 -482
- data/spec/prompt_spec.rb +0 -60
- data/spec/pry_defaults_spec.rb +0 -419
- data/spec/pry_history_spec.rb +0 -99
- data/spec/pry_output_spec.rb +0 -95
- data/spec/pry_spec.rb +0 -504
- data/spec/run_command_spec.rb +0 -25
- data/spec/sticky_locals_spec.rb +0 -157
- data/spec/syntax_checking_spec.rb +0 -81
- data/spec/wrapped_module_spec.rb +0 -261
- data/wiki/Customizing-pry.md +0 -397
- data/wiki/Home.md +0 -4
data/lib/pry/repl.rb
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
class REPL
|
5
|
+
extend Pry::Forwardable
|
6
|
+
def_delegators :@pry, :input, :output
|
7
|
+
|
8
|
+
# @return [Pry] The instance of {Pry} that the user is controlling.
|
9
|
+
attr_accessor :pry
|
10
|
+
|
11
|
+
# Instantiate a new {Pry} instance with the given options, then start a
|
12
|
+
# {REPL} instance wrapping it.
|
13
|
+
# @option options See {Pry#initialize}
|
14
|
+
def self.start(options)
|
15
|
+
new(Pry.new(options)).start
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create an instance of {REPL} wrapping the given {Pry}.
|
19
|
+
# @param [Pry] pry The instance of {Pry} that this {REPL} will control.
|
20
|
+
# @param [Hash] options Options for this {REPL} instance.
|
21
|
+
# @option options [Object] :target The initial target of the session.
|
22
|
+
def initialize(pry, options = {})
|
23
|
+
@pry = pry
|
24
|
+
@indent = Pry::Indent.new(pry)
|
25
|
+
|
26
|
+
@readline_output = nil
|
27
|
+
|
28
|
+
@pry.push_binding options[:target] if options[:target]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Start the read-eval-print loop.
|
32
|
+
# @return [Object?] If the session throws `:breakout`, return the value
|
33
|
+
# thrown with it.
|
34
|
+
# @raise [Exception] If the session throws `:raise_up`, raise the exception
|
35
|
+
# thrown with it.
|
36
|
+
def start
|
37
|
+
prologue
|
38
|
+
Pry::InputLock.for(:all).with_ownership { repl }
|
39
|
+
ensure
|
40
|
+
epilogue
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Set up the repl session.
|
46
|
+
# @return [void]
|
47
|
+
def prologue
|
48
|
+
pry.exec_hook :before_session, pry.output, pry.current_binding, pry
|
49
|
+
|
50
|
+
return unless pry.config.correct_indent
|
51
|
+
|
52
|
+
# Clear the line before starting Pry. This fixes issue #566.
|
53
|
+
output.print(Helpers::Platform.windows_ansi? ? "\e[0F" : "\e[0G")
|
54
|
+
end
|
55
|
+
|
56
|
+
# The actual read-eval-print loop.
|
57
|
+
#
|
58
|
+
# The {REPL} instance is responsible for reading and looping, whereas the
|
59
|
+
# {Pry} instance is responsible for evaluating user input and printing
|
60
|
+
# return values and command output.
|
61
|
+
#
|
62
|
+
# @return [Object?] If the session throws `:breakout`, return the value
|
63
|
+
# thrown with it.
|
64
|
+
# @raise [Exception] If the session throws `:raise_up`, raise the exception
|
65
|
+
# thrown with it.
|
66
|
+
def repl
|
67
|
+
loop do
|
68
|
+
case val = read
|
69
|
+
when :control_c
|
70
|
+
output.puts ""
|
71
|
+
pry.reset_eval_string
|
72
|
+
when :no_more_input
|
73
|
+
output.puts "" if output.tty?
|
74
|
+
break
|
75
|
+
else
|
76
|
+
output.puts "" if val.nil? && output.tty?
|
77
|
+
return pry.exit_value unless pry.eval(val)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Clean up after the repl session.
|
83
|
+
# @return [void]
|
84
|
+
def epilogue
|
85
|
+
pry.exec_hook :after_session, pry.output, pry.current_binding, pry
|
86
|
+
end
|
87
|
+
|
88
|
+
# Read a line of input from the user.
|
89
|
+
# @return [String] The line entered by the user.
|
90
|
+
# @return [nil] On `<Ctrl-D>`.
|
91
|
+
# @return [:control_c] On `<Ctrl+C>`.
|
92
|
+
# @return [:no_more_input] On EOF.
|
93
|
+
def read
|
94
|
+
@indent.reset if pry.eval_string.empty?
|
95
|
+
current_prompt = pry.select_prompt
|
96
|
+
indentation = pry.config.auto_indent ? @indent.current_prefix : ''
|
97
|
+
|
98
|
+
val = read_line("#{current_prompt}#{indentation}")
|
99
|
+
|
100
|
+
# Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
|
101
|
+
return val unless val.is_a?(String)
|
102
|
+
|
103
|
+
if pry.config.auto_indent
|
104
|
+
original_val = "#{indentation}#{val}"
|
105
|
+
indented_val = @indent.indent(val)
|
106
|
+
|
107
|
+
if output.tty? &&
|
108
|
+
pry.config.correct_indent &&
|
109
|
+
Pry::Helpers::BaseHelpers.use_ansi_codes?
|
110
|
+
output.print @indent.correct_indentation(
|
111
|
+
current_prompt,
|
112
|
+
indented_val,
|
113
|
+
calculate_overhang(current_prompt, original_val, indented_val)
|
114
|
+
)
|
115
|
+
output.flush
|
116
|
+
end
|
117
|
+
else
|
118
|
+
indented_val = val
|
119
|
+
end
|
120
|
+
|
121
|
+
indented_val
|
122
|
+
end
|
123
|
+
|
124
|
+
# Manage switching of input objects on encountering `EOFError`s.
|
125
|
+
# @return [Object] Whatever the given block returns.
|
126
|
+
# @return [:no_more_input] Indicates that no more input can be read.
|
127
|
+
def handle_read_errors
|
128
|
+
should_retry = true
|
129
|
+
exception_count = 0
|
130
|
+
|
131
|
+
begin
|
132
|
+
yield
|
133
|
+
rescue EOFError
|
134
|
+
pry.config.input = Pry.config.input
|
135
|
+
unless should_retry
|
136
|
+
output.puts "Error: Pry ran out of things to read from! " \
|
137
|
+
"Attempting to break out of REPL."
|
138
|
+
return :no_more_input
|
139
|
+
end
|
140
|
+
should_retry = false
|
141
|
+
retry
|
142
|
+
|
143
|
+
# Handle <Ctrl+C> like Bash: empty the current input buffer, but don't
|
144
|
+
# quit.
|
145
|
+
rescue Interrupt
|
146
|
+
return :control_c
|
147
|
+
|
148
|
+
# If we get a random error when trying to read a line we don't want to
|
149
|
+
# automatically retry, as the user will see a lot of error messages
|
150
|
+
# scroll past and be unable to do anything about it.
|
151
|
+
rescue RescuableException => e
|
152
|
+
puts "Error: #{e.message}"
|
153
|
+
output.puts e.backtrace
|
154
|
+
exception_count += 1
|
155
|
+
retry if exception_count < 5
|
156
|
+
puts "FATAL: Pry failed to get user input using `#{input}`."
|
157
|
+
puts "To fix this you may be able to pass input and output file " \
|
158
|
+
"descriptors to pry directly. e.g."
|
159
|
+
puts " Pry.config.input = STDIN"
|
160
|
+
puts " Pry.config.output = STDOUT"
|
161
|
+
puts " binding.pry"
|
162
|
+
return :no_more_input
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns the next line of input to be sent to the {Pry} instance.
|
167
|
+
# @param [String] current_prompt The prompt to use for input.
|
168
|
+
# @return [String?] The next line of input, or `nil` on <Ctrl-D>.
|
169
|
+
def read_line(current_prompt)
|
170
|
+
handle_read_errors do
|
171
|
+
if coolline_available?
|
172
|
+
input.completion_proc = proc do |cool|
|
173
|
+
completions = @pry.complete cool.completed_word
|
174
|
+
completions.compact
|
175
|
+
end
|
176
|
+
elsif input.respond_to? :completion_proc=
|
177
|
+
input.completion_proc = proc do |inp|
|
178
|
+
@pry.complete inp
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
if readline_available?
|
183
|
+
set_readline_output
|
184
|
+
input_readline(current_prompt, false) # false since we'll add it manually
|
185
|
+
elsif coolline_available?
|
186
|
+
input_readline(current_prompt)
|
187
|
+
elsif input.method(:readline).arity == 1
|
188
|
+
input_readline(current_prompt)
|
189
|
+
else
|
190
|
+
input_readline
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def input_readline(*args)
|
196
|
+
Pry::InputLock.for(:all).interruptible_region do
|
197
|
+
input.readline(*args)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def readline_available?
|
202
|
+
defined?(Readline) && input == Readline
|
203
|
+
end
|
204
|
+
|
205
|
+
def coolline_available?
|
206
|
+
defined?(Coolline) && input.is_a?(Coolline)
|
207
|
+
end
|
208
|
+
|
209
|
+
# If `$stdout` is not a tty, it's probably a pipe.
|
210
|
+
# @example
|
211
|
+
# # `piping?` returns `false`
|
212
|
+
# % pry
|
213
|
+
# [1] pry(main)
|
214
|
+
#
|
215
|
+
# # `piping?` returns `true`
|
216
|
+
# % pry | tee log
|
217
|
+
def piping?
|
218
|
+
return false unless $stdout.respond_to?(:tty?)
|
219
|
+
|
220
|
+
!$stdout.tty? && $stdin.tty? && !Helpers::Platform.windows?
|
221
|
+
end
|
222
|
+
|
223
|
+
# @return [void]
|
224
|
+
def set_readline_output
|
225
|
+
return if @readline_output
|
226
|
+
|
227
|
+
@readline_output = (Readline.output = Pry.config.output) if piping?
|
228
|
+
end
|
229
|
+
|
230
|
+
# Calculates correct overhang for current line. Supports vi Readline
|
231
|
+
# mode and its indicators such as "(ins)" or "(cmd)".
|
232
|
+
#
|
233
|
+
# @return [Integer]
|
234
|
+
# @note This doesn't calculate overhang for Readline's emacs mode with an
|
235
|
+
# indicator because emacs is the default mode and it doesn't use
|
236
|
+
# indicators in 99% of cases.
|
237
|
+
def calculate_overhang(current_prompt, original_val, indented_val)
|
238
|
+
overhang = original_val.length - indented_val.length
|
239
|
+
|
240
|
+
if readline_available? && Readline.respond_to?(:vi_editing_mode?)
|
241
|
+
begin
|
242
|
+
# rb-readline doesn't support this method:
|
243
|
+
# https://github.com/ConnorAtherton/rb-readline/issues/152
|
244
|
+
if Readline.vi_editing_mode?
|
245
|
+
overhang = output.width - current_prompt.size - indented_val.size
|
246
|
+
end
|
247
|
+
rescue NotImplementedError
|
248
|
+
# VI editing mode is unsupported on JRuby.
|
249
|
+
# https://github.com/pry/pry/issues/1840
|
250
|
+
nil
|
251
|
+
end
|
252
|
+
end
|
253
|
+
[0, overhang].max
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
data/lib/pry/repl_file_loader.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class Pry
|
3
4
|
# A class to manage the loading of files through the REPL loop.
|
4
5
|
# This is an interesting trick as it processes your file as if it
|
5
6
|
# was user input in an interactive session. As a result, all Pry
|
@@ -13,31 +14,44 @@ class Pry
|
|
13
14
|
class REPLFileLoader
|
14
15
|
def initialize(file_name)
|
15
16
|
full_name = File.expand_path(file_name)
|
16
|
-
raise
|
17
|
+
raise "No such file: #{full_name}" unless File.exist?(full_name)
|
17
18
|
|
18
|
-
|
19
|
+
define_additional_commands
|
20
|
+
@content = File.read(full_name)
|
19
21
|
end
|
20
22
|
|
21
23
|
# Switch to interactive mode, i.e take input from the user
|
22
24
|
# and use the regular print and exception handlers.
|
23
|
-
# @param [Pry]
|
24
|
-
def interactive_mode(
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
# @param [Pry] pry_instance the Pry instance to make interactive.
|
26
|
+
def interactive_mode(pry_instance)
|
27
|
+
pry_instance.config.input = Pry.config.input
|
28
|
+
pry_instance.config.print = Pry.config.print
|
29
|
+
pry_instance.config.exception_handler = Pry.config.exception_handler
|
30
|
+
Pry::REPL.new(pry_instance).start
|
28
31
|
end
|
29
32
|
|
30
33
|
# Switch to non-interactive mode. Essentially
|
31
34
|
# this means there is no result output
|
32
35
|
# and that the session becomes interactive when an exception is encountered.
|
33
|
-
# @param [Pry]
|
34
|
-
def non_interactive_mode(
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
# @param [Pry] pry_instance the Pry instance to make non-interactive.
|
37
|
+
def non_interactive_mode(pry_instance, content)
|
38
|
+
pry_instance.print = proc {}
|
39
|
+
pry_instance.exception_handler = proc do |o, _e, p|
|
40
|
+
p.run_command "cat --ex"
|
38
41
|
o.puts "...exception encountered, going interactive!"
|
39
|
-
interactive_mode(
|
42
|
+
interactive_mode(pry_instance)
|
40
43
|
end
|
44
|
+
|
45
|
+
content.lines.each do |line|
|
46
|
+
break unless pry_instance.eval line, generated: true
|
47
|
+
end
|
48
|
+
|
49
|
+
return if pry_instance.eval_string.empty?
|
50
|
+
|
51
|
+
pry_instance.output.puts(
|
52
|
+
"#{pry_instance.eval_string}...exception encountered, going interactive!"
|
53
|
+
)
|
54
|
+
interactive_mode(pry_instance)
|
41
55
|
end
|
42
56
|
|
43
57
|
# Define a few extra commands useful for flipping back & forth
|
@@ -46,35 +60,20 @@ class Pry
|
|
46
60
|
s = self
|
47
61
|
|
48
62
|
Pry::Commands.command "make-interactive", "Make the session interactive" do
|
49
|
-
|
50
|
-
s.interactive_mode(_pry_)
|
63
|
+
s.interactive_mode(pry_instance)
|
51
64
|
end
|
52
65
|
|
53
|
-
Pry::Commands.command
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
Pry::Commands.command "load-file", "Load another file through the repl" do |file_name|
|
59
|
-
content = StringIO.new(File.read(File.expand_path(file_name)))
|
60
|
-
_pry_.input_stack.push(_pry_.input)
|
61
|
-
_pry_.input = content
|
66
|
+
Pry::Commands.command(
|
67
|
+
"load-file", "Load another file through the repl"
|
68
|
+
) do |file_name|
|
69
|
+
s.non_interactive_mode(pry_instance, File.read(File.expand_path(file_name)))
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
65
73
|
# Actually load the file through the REPL by setting file content
|
66
74
|
# as the REPL input stream.
|
67
75
|
def load
|
68
|
-
Pry.
|
69
|
-
define_additional_commands
|
70
|
-
|
71
|
-
Pry.config.hooks.add_hook(:when_started, :start_non_interactively) do |o, t, _pry_|
|
72
|
-
non_interactive_mode(_pry_)
|
73
|
-
end
|
74
|
-
|
75
|
-
Pry.start(Pry.toplevel_binding,
|
76
|
-
:input => @content,
|
77
|
-
:input_stack => [StringIO.new("exit-all\n")])
|
76
|
+
non_interactive_mode(Pry.new, @content)
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
data/lib/pry/ring.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
# A ring is a thread-safe fixed-capacity array to which you can only add
|
5
|
+
# elements. Older entries are overwritten as you add new elements, so that the
|
6
|
+
# ring can never contain more than `max_size` elemens.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# ring = Pry::Ring.new(3)
|
10
|
+
# ring << 1 << 2 << 3
|
11
|
+
# ring.to_a #=> [1, 2, 3]
|
12
|
+
# ring << 4
|
13
|
+
# ring.to_a #=> [2, 3, 4]
|
14
|
+
#
|
15
|
+
# ring[0] #=> 2
|
16
|
+
# ring[-1] #=> 4
|
17
|
+
# ring.clear
|
18
|
+
# ring[0] #=> nil
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
# @since v0.12.0
|
22
|
+
class Ring
|
23
|
+
# @return [Integer] maximum buffer size
|
24
|
+
attr_reader :max_size
|
25
|
+
|
26
|
+
# @return [Integer] how many objects were added during the lifetime of the
|
27
|
+
# ring
|
28
|
+
attr_reader :count
|
29
|
+
alias size count
|
30
|
+
|
31
|
+
# @param [Integer] max_size Maximum buffer size. The buffer will start
|
32
|
+
# overwriting elements once its reaches its maximum capacity
|
33
|
+
def initialize(max_size)
|
34
|
+
@max_size = max_size
|
35
|
+
@mutex = Mutex.new
|
36
|
+
clear
|
37
|
+
end
|
38
|
+
|
39
|
+
# Push `value` to the current index.
|
40
|
+
#
|
41
|
+
# @param [Object] value
|
42
|
+
# @return [self]
|
43
|
+
def <<(value)
|
44
|
+
@mutex.synchronize do
|
45
|
+
@buffer[count % max_size] = value
|
46
|
+
@count += 1
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Read the value stored at `index`.
|
52
|
+
#
|
53
|
+
# @param [Integer, Range] index The element (if Integer) or elements
|
54
|
+
# (if Range) associated with `index`
|
55
|
+
# @return [Object, Array<Object>, nil] element(s) at `index`, `nil` if none
|
56
|
+
# exist
|
57
|
+
def [](index)
|
58
|
+
@mutex.synchronize do
|
59
|
+
return @buffer[index] if count <= max_size
|
60
|
+
return @buffer[(count + index) % max_size] if index.is_a?(Integer)
|
61
|
+
|
62
|
+
transpose_buffer_tail[index]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Array<Object>] the buffer as unwinded array
|
67
|
+
def to_a
|
68
|
+
return @buffer.dup if count <= max_size
|
69
|
+
|
70
|
+
transpose_buffer_tail
|
71
|
+
end
|
72
|
+
|
73
|
+
# Clear the buffer and reset count.
|
74
|
+
# @return [void]
|
75
|
+
def clear
|
76
|
+
@mutex.synchronize do
|
77
|
+
@buffer = []
|
78
|
+
@count = 0
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def transpose_buffer_tail
|
85
|
+
tail = @buffer.slice(count % max_size, @buffer.size)
|
86
|
+
tail.concat @buffer.slice(0, count % max_size)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Lee Jarvis
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
class Slop
|
5
|
+
class Commands
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
attr_reader :config, :commands, :arguments
|
9
|
+
attr_writer :banner
|
10
|
+
|
11
|
+
# Create a new instance of Slop::Commands and optionally build
|
12
|
+
# Slop instances via a block. Any configuration options used in
|
13
|
+
# this method will be the default configuration options sent to
|
14
|
+
# each Slop object created.
|
15
|
+
#
|
16
|
+
# config - An optional configuration Hash.
|
17
|
+
# block - Optional block used to define commands.
|
18
|
+
#
|
19
|
+
# Examples:
|
20
|
+
#
|
21
|
+
# commands = Slop::Commands.new do
|
22
|
+
# on :new do
|
23
|
+
# on '-o', '--outdir=', 'The output directory'
|
24
|
+
# on '-v', '--verbose', 'Enable verbose mode'
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# on :generate do
|
28
|
+
# on '--assets', 'Generate assets', :default => true
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# global do
|
32
|
+
# on '-D', '--debug', 'Enable debug mode', :default => false
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# commands[:new].class #=> Slop
|
37
|
+
# commands.parse
|
38
|
+
#
|
39
|
+
def initialize(config = {}, &block)
|
40
|
+
@config = config
|
41
|
+
@commands = {}
|
42
|
+
@banner = nil
|
43
|
+
@triggered_command = nil
|
44
|
+
|
45
|
+
warn "[DEPRECATED] Slop::Commands is deprecated and will be removed in "\
|
46
|
+
"Slop version 4. Check out http://injekt.github.com/slop/#commands for "\
|
47
|
+
"a new implementation of commands."
|
48
|
+
|
49
|
+
return unless block_given?
|
50
|
+
|
51
|
+
block.arity == 1 ? yield(self) : instance_eval(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Optionally set the banner for this command help output.
|
55
|
+
#
|
56
|
+
# banner - The String text to set the banner.
|
57
|
+
#
|
58
|
+
# Returns the String banner if one is set.
|
59
|
+
def banner(banner = nil)
|
60
|
+
@banner = banner if banner
|
61
|
+
@banner
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add a Slop instance for a specific command.
|
65
|
+
#
|
66
|
+
# command - A String or Symbol key used to identify this command.
|
67
|
+
# config - A Hash of configuration options to pass to Slop.
|
68
|
+
# block - An optional block used to pass options to Slop.
|
69
|
+
#
|
70
|
+
# Returns the newly created Slop instance mapped to command.
|
71
|
+
def on(command, config = {}, &block)
|
72
|
+
commands[command.to_s] = Slop.new(@config.merge(config), &block)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Add a Slop instance used when no other commands exist.
|
76
|
+
#
|
77
|
+
# config - A Hash of configuration options to pass to Slop.
|
78
|
+
# block - An optional block used to pass options to Slop.
|
79
|
+
#
|
80
|
+
# Returns the newly created Slop instance mapped to default.
|
81
|
+
def default(config = {}, &block)
|
82
|
+
on('default', config, &block)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Add a global Slop instance.
|
86
|
+
#
|
87
|
+
# config - A Hash of configuration options to pass to Slop.
|
88
|
+
# block - An optional block used to pass options to Slop.
|
89
|
+
#
|
90
|
+
# Returns the newly created Slop instance mapped to global.
|
91
|
+
def global(config = {}, &block)
|
92
|
+
on('global', config, &block)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Fetch the instance of Slop tied to a command.
|
96
|
+
#
|
97
|
+
# key - The String or Symbol key used to locate this command.
|
98
|
+
#
|
99
|
+
# Returns the Slop instance if this key is found, nil otherwise.
|
100
|
+
def [](key)
|
101
|
+
commands[key.to_s]
|
102
|
+
end
|
103
|
+
alias get []
|
104
|
+
|
105
|
+
# Check for a command presence.
|
106
|
+
#
|
107
|
+
# Examples:
|
108
|
+
#
|
109
|
+
# cmds.parse %w( foo )
|
110
|
+
# cmds.present?(:foo) #=> true
|
111
|
+
# cmds.present?(:bar) #=> false
|
112
|
+
#
|
113
|
+
# Returns true if the given key is present in the parsed arguments.
|
114
|
+
def present?(key)
|
115
|
+
key.to_s == @triggered_command
|
116
|
+
end
|
117
|
+
|
118
|
+
# Enumerable interface.
|
119
|
+
def each(&block)
|
120
|
+
@commands.each(&block)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Parse a list of items.
|
124
|
+
#
|
125
|
+
# items - The Array of items to parse.
|
126
|
+
#
|
127
|
+
# Returns the original Array of items.
|
128
|
+
def parse(items = ARGV)
|
129
|
+
parse! items.dup
|
130
|
+
items
|
131
|
+
end
|
132
|
+
|
133
|
+
# Parse a list of items, removing any options or option arguments found.
|
134
|
+
#
|
135
|
+
# items - The Array of items to parse.
|
136
|
+
#
|
137
|
+
# Returns the original Array of items with options removed.
|
138
|
+
def parse!(items = ARGV)
|
139
|
+
if (opts = commands[items[0].to_s])
|
140
|
+
@triggered_command = items.shift
|
141
|
+
execute_arguments! items
|
142
|
+
opts.parse! items
|
143
|
+
elsif (opts = commands['default'])
|
144
|
+
opts.parse! items
|
145
|
+
elsif config[:strict] && items[0]
|
146
|
+
raise InvalidCommandError, "Unknown command `#{items[0]}`"
|
147
|
+
end
|
148
|
+
execute_global_opts! items
|
149
|
+
items
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns a nested Hash with Slop options and values. See Slop#to_hash.
|
153
|
+
def to_hash
|
154
|
+
Hash[commands.map { |k, v| [k.to_sym, v.to_hash] }]
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns the help String.
|
158
|
+
def to_s
|
159
|
+
defaults = commands.delete('default')
|
160
|
+
globals = commands.delete('global')
|
161
|
+
helps = commands.reject { |_, v| v.options.none? }
|
162
|
+
helps['Global options'] = globals.to_s if globals && globals.options.any?
|
163
|
+
helps['Other options'] = defaults.to_s if defaults && defaults.options.any?
|
164
|
+
banner = @banner ? "#{@banner}\n" : ""
|
165
|
+
banner + helps.map { |key, opts| " #{key}\n#{opts}" }.join("\n\n")
|
166
|
+
end
|
167
|
+
alias help to_s
|
168
|
+
|
169
|
+
# Returns the inspection String.
|
170
|
+
def inspect
|
171
|
+
"#<Slop::Commands #{config.inspect} #{commands.values.map(&:inspect)}>"
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
# Returns nothing.
|
177
|
+
def execute_arguments!(items)
|
178
|
+
@arguments = items.take_while { |arg| !arg.start_with?('-') }
|
179
|
+
items.shift @arguments.size
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns nothing.
|
183
|
+
def execute_global_opts!(items)
|
184
|
+
return unless (global_opts = commands['global'])
|
185
|
+
|
186
|
+
global_opts.parse!(items)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|