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/core_extensions.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
4
|
# @return [Array] Code of the method used when implementing Pry's
|
3
5
|
# __binding__, along with line indication to be used with instance_eval (and
|
4
6
|
# friends).
|
5
7
|
#
|
6
8
|
# @see Object#__binding__
|
7
|
-
BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1]
|
9
|
+
BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1].freeze
|
8
10
|
# Get a binding with 'self' set to self, and no locals.
|
9
11
|
#
|
10
12
|
# The default definee is determined by the context in which the
|
@@ -38,8 +40,8 @@ class Object
|
|
38
40
|
# end
|
39
41
|
# my_method()
|
40
42
|
# @see Pry.start
|
41
|
-
def pry(object=nil, hash={})
|
42
|
-
if object.nil? || Hash === object
|
43
|
+
def pry(object = nil, hash = {})
|
44
|
+
if object.nil? || Hash === object # rubocop:disable Style/CaseEquality
|
43
45
|
Pry.start(self, object || {})
|
44
46
|
else
|
45
47
|
Pry.start(object, hash)
|
@@ -68,15 +70,26 @@ class Object
|
|
68
70
|
def __binding__
|
69
71
|
# If you ever feel like changing this method, be careful about variables
|
70
72
|
# that you use. They shouldn't be inserted into the binding that will
|
71
|
-
# eventually be
|
73
|
+
# eventually be returned.
|
72
74
|
|
73
75
|
# When you're cd'd into a class, methods you define should be added to it.
|
74
76
|
if is_a?(Module)
|
77
|
+
# A special case, for JRuby.
|
78
|
+
# Module.new.class_eval("binding") has different behaviour than CRuby,
|
79
|
+
# where this is not needed: class_eval("binding") vs class_eval{binding}.
|
80
|
+
# Using a block works around the difference of behaviour on JRuby.
|
81
|
+
# The scope is clear of local variables. Don't add any.
|
82
|
+
#
|
83
|
+
# This fixes the following two spec failures, at https://travis-ci.org/pry/pry/jobs/274470002
|
84
|
+
# 1) ./spec/pry_spec.rb:360:in `block in (root)'
|
85
|
+
# 2) ./spec/pry_spec.rb:366:in `block in (root)'
|
86
|
+
return class_eval { binding } if Pry::Helpers::Platform.jruby? && name.nil?
|
87
|
+
|
75
88
|
# class_eval sets both self and the default definee to this class.
|
76
|
-
return class_eval
|
89
|
+
return class_eval("binding", __FILE__, __LINE__)
|
77
90
|
end
|
78
91
|
|
79
|
-
unless
|
92
|
+
unless self.class.method_defined?(:__pry__)
|
80
93
|
# The easiest way to check whether an object has a working singleton class
|
81
94
|
# is to try and define a method on it. (just checking for the presence of
|
82
95
|
# the singleton class gives false positives for `true` and `false`).
|
@@ -84,14 +97,14 @@ class Object
|
|
84
97
|
# it has the nice property that we can memoize this check.
|
85
98
|
begin
|
86
99
|
# instance_eval sets the default definee to the object's singleton class
|
87
|
-
instance_eval
|
100
|
+
instance_eval(*Pry::BINDING_METHOD_IMPL)
|
88
101
|
|
89
102
|
# If we can't define methods on the Object's singleton_class. Then we fall
|
90
103
|
# back to setting the default definee to be the Object's class. That seems
|
91
104
|
# nicer than having a REPL in which you can't define methods.
|
92
|
-
rescue TypeError
|
105
|
+
rescue TypeError, Pry::FrozenObjectException
|
93
106
|
# class_eval sets the default definee to self.class
|
94
|
-
self.class.class_eval
|
107
|
+
self.class.class_eval(*Pry::BINDING_METHOD_IMPL)
|
95
108
|
end
|
96
109
|
end
|
97
110
|
|
@@ -99,23 +112,33 @@ class Object
|
|
99
112
|
end
|
100
113
|
end
|
101
114
|
|
102
|
-
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
class BasicObject
|
116
|
+
# Return a binding object for the receiver.
|
117
|
+
#
|
118
|
+
# The `self` of the binding is set to the current object, and it contains no
|
119
|
+
# local variables.
|
120
|
+
#
|
121
|
+
# The default definee (http://yugui.jp/articles/846) is set such that new
|
122
|
+
# methods defined will be added to the singleton class of the BasicObject.
|
123
|
+
#
|
124
|
+
# @return [Binding]
|
125
|
+
def __binding__
|
126
|
+
# BasicObjects don't have respond_to?, so we just define the method
|
127
|
+
# every time. As they also don't have `.freeze`, this call won't
|
128
|
+
# fail as it can for normal Objects.
|
129
|
+
(class << self; self; end).class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
|
130
|
+
# Get a binding with 'self' set to self, and no locals.
|
131
|
+
#
|
132
|
+
# The default definee is determined by the context in which the
|
133
|
+
# definition is eval'd.
|
134
|
+
#
|
135
|
+
# Please don't call this method directly, see {__binding__}.
|
136
|
+
#
|
137
|
+
# @return [Binding]
|
138
|
+
def __pry__
|
139
|
+
::Kernel.binding
|
140
|
+
end
|
141
|
+
METHOD
|
142
|
+
__pry__
|
120
143
|
end
|
121
144
|
end
|
data/lib/pry/editor.rb
CHANGED
@@ -1,129 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
|
1
5
|
class Pry
|
2
6
|
class Editor
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def edit_tempfile_with_content(initial_content, line=1)
|
8
|
-
temp_file do |f|
|
9
|
-
f.puts(initial_content)
|
10
|
-
f.flush
|
11
|
-
f.close(false)
|
12
|
-
invoke_editor(f.path, line, true)
|
13
|
-
File.read(f.path)
|
14
|
-
end
|
7
|
+
def self.default
|
8
|
+
if (visual = Pry::Env['VISUAL'])
|
9
|
+
return visual
|
15
10
|
end
|
16
11
|
|
17
|
-
|
18
|
-
|
12
|
+
if (editor = Pry::Env['EDITOR'])
|
13
|
+
return editor
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
return nil unless editor_invocation
|
16
|
+
return 'notepad' if Helpers::Platform.windows?
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
open_editor(editor_invocation)
|
27
|
-
end
|
18
|
+
%w[editor nano vi].find do |editor_exe|
|
19
|
+
Kernel.system("which #{editor_exe} > /dev/null 2>&1")
|
28
20
|
end
|
21
|
+
end
|
29
22
|
|
30
|
-
|
23
|
+
include Pry::Helpers::CommandHelpers
|
31
24
|
|
32
|
-
|
33
|
-
# all the flags we want as well as the file and line number we
|
34
|
-
# want to open at.
|
35
|
-
def build_editor_invocation_string(file, line, blocking)
|
25
|
+
attr_reader :pry_instance
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
else
|
41
|
-
sanitized_file = if windows?
|
42
|
-
file.gsub(/\//, '\\')
|
43
|
-
else
|
44
|
-
Shellwords.escape(file)
|
45
|
-
end
|
27
|
+
def initialize(pry_instance)
|
28
|
+
@pry_instance = pry_instance
|
29
|
+
end
|
46
30
|
|
47
|
-
|
48
|
-
|
31
|
+
def edit_tempfile_with_content(initial_content, line = 1)
|
32
|
+
temp_file do |f|
|
33
|
+
f.puts(initial_content)
|
34
|
+
f.flush
|
35
|
+
f.close(false)
|
36
|
+
invoke_editor(f.path, line, true)
|
37
|
+
File.read(f.path)
|
49
38
|
end
|
39
|
+
end
|
50
40
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# ensure the editor is always interactive
|
56
|
-
system(editor_invocation) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
|
41
|
+
def invoke_editor(file, line, blocking = true)
|
42
|
+
unless pry_instance.config.editor
|
43
|
+
raise CommandError,
|
44
|
+
"Please set Pry.config.editor or export $VISUAL or $EDITOR"
|
57
45
|
end
|
58
46
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
rescue FFI::NotFoundError
|
67
|
-
system(editor_invocation)
|
68
|
-
end
|
47
|
+
editor_invocation = build_editor_invocation_string(file, line, blocking)
|
48
|
+
return nil unless editor_invocation
|
49
|
+
|
50
|
+
if Helpers::Platform.jruby?
|
51
|
+
open_editor_on_jruby(editor_invocation)
|
52
|
+
else
|
53
|
+
open_editor(editor_invocation)
|
69
54
|
end
|
55
|
+
end
|
70
56
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
57
|
+
# Generate the string that's used to start the editor. This includes
|
58
|
+
# all the flags we want as well as the file and line number we
|
59
|
+
# want to open at.
|
60
|
+
def build_editor_invocation_string(file, line, blocking)
|
61
|
+
if pry_instance.config.editor.respond_to?(:call)
|
62
|
+
args = [file, line, blocking][0...(pry_instance.config.editor.arity)]
|
63
|
+
pry_instance.config.editor.call(*args)
|
64
|
+
else
|
65
|
+
sanitized_file = Helpers::Platform.windows? ? file : Shellwords.escape(file)
|
66
|
+
editor = pry_instance.config.editor
|
67
|
+
flag = blocking_flag_for_editor(blocking)
|
68
|
+
start_line = start_line_syntax_for_editor(sanitized_file, line)
|
69
|
+
"#{editor} #{flag} #{start_line}"
|
85
70
|
end
|
71
|
+
end
|
86
72
|
|
87
|
-
|
88
|
-
# and moving to a particular line within that file
|
89
|
-
def start_line_syntax_for_editor(file_name, line_number)
|
90
|
-
# special case for 1st line
|
91
|
-
return file_name if line_number <= 1
|
73
|
+
private
|
92
74
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
"
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
75
|
+
# Start the editor running, using the calculated invocation string
|
76
|
+
def open_editor(editor_invocation)
|
77
|
+
# Note we dont want to use Pry.config.system here as that
|
78
|
+
# may be invoked non-interactively (i.e via Open4), whereas we want to
|
79
|
+
# ensure the editor is always interactive
|
80
|
+
system(*Shellwords.split(editor_invocation)) ||
|
81
|
+
raise(
|
82
|
+
CommandError,
|
83
|
+
"`#{editor_invocation}` gave exit status: #{$CHILD_STATUS.exitstatus}"
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
# We need JRuby specific code here cos just shelling out using
|
88
|
+
# system() appears to be pretty broken :/
|
89
|
+
def open_editor_on_jruby(editor_invocation)
|
90
|
+
require 'spoon'
|
91
|
+
pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
|
92
|
+
Process.waitpid(pid)
|
93
|
+
rescue FFI::NotFoundError
|
94
|
+
system(editor_invocation)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Some editors that run outside the terminal allow you to control whether or
|
98
|
+
# not to block the process from which they were launched (in this case, Pry).
|
99
|
+
# For those editors, return the flag that produces the desired behavior.
|
100
|
+
def blocking_flag_for_editor(blocking)
|
101
|
+
case editor_name
|
102
|
+
when /^emacsclient/
|
103
|
+
'--no-wait' unless blocking
|
104
|
+
when /^[gm]vim/
|
105
|
+
'--nofork' if blocking
|
106
|
+
when /^jedit/
|
107
|
+
'-wait' if blocking
|
108
|
+
when /^mate/, /^subl/, /^redcar/, /^code/
|
109
|
+
'-w' if blocking
|
111
110
|
end
|
111
|
+
end
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
113
|
+
# Return the syntax for a given editor for starting the editor
|
114
|
+
# and moving to a particular line within that file
|
115
|
+
def start_line_syntax_for_editor(file_name, line_number)
|
116
|
+
# special case for 1st line
|
117
|
+
return file_name if line_number <= 1
|
118
|
+
|
119
|
+
case editor_name
|
120
|
+
when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
|
121
|
+
"+#{line_number} #{file_name}"
|
122
|
+
when /^mate/, /^geany/
|
123
|
+
"-l #{line_number} #{file_name}"
|
124
|
+
when /^code/
|
125
|
+
"-g #{file_name}:#{line_number}"
|
126
|
+
when /^subl/
|
127
|
+
"#{file_name}:#{line_number}"
|
128
|
+
when /^uedit32/
|
129
|
+
"#{file_name}/#{line_number}"
|
130
|
+
when /^jedit/
|
131
|
+
"#{file_name} +line:#{line_number}"
|
132
|
+
when /^redcar/
|
133
|
+
"-l#{line_number} #{file_name}"
|
134
|
+
else
|
135
|
+
if Helpers::Platform.windows?
|
136
|
+
file_name.to_s
|
137
|
+
else
|
138
|
+
"+#{line_number} #{file_name}"
|
139
|
+
end
|
125
140
|
end
|
141
|
+
end
|
126
142
|
|
143
|
+
# Get the name of the binary that Pry.config.editor points to.
|
144
|
+
#
|
145
|
+
# This is useful for deciding which flags we pass to the editor as
|
146
|
+
# we can just use the program's name and ignore any absolute paths.
|
147
|
+
#
|
148
|
+
# @example
|
149
|
+
# Pry.config.editor="/home/conrad/bin/textmate -w"
|
150
|
+
# editor_name
|
151
|
+
# # => textmate
|
152
|
+
#
|
153
|
+
def editor_name
|
154
|
+
File.basename(pry_instance.config.editor).split(" ").first
|
127
155
|
end
|
128
156
|
end
|
129
157
|
end
|
data/lib/pry/env.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
# Env is a helper module to work with environment variables.
|
5
|
+
#
|
6
|
+
# @since v0.13.0
|
7
|
+
# @api private
|
8
|
+
module Env
|
9
|
+
def self.[](key)
|
10
|
+
return unless ENV.key?(key)
|
11
|
+
|
12
|
+
value = ENV[key]
|
13
|
+
return if value == ''
|
14
|
+
|
15
|
+
value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
# @api private
|
5
|
+
# @since v0.13.0
|
6
|
+
module ExceptionHandler
|
7
|
+
class << self
|
8
|
+
# Will only show the first line of the backtrace.
|
9
|
+
def handle_exception(output, exception, _pry_instance)
|
10
|
+
if exception.is_a?(UserError) && exception.is_a?(SyntaxError)
|
11
|
+
output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}"
|
12
|
+
else
|
13
|
+
output.puts standard_error_text_for(exception)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def standard_error_text_for(exception)
|
20
|
+
text = exception_text(exception)
|
21
|
+
return text unless exception.respond_to?(:cause)
|
22
|
+
|
23
|
+
cause = exception.cause
|
24
|
+
while cause
|
25
|
+
text += cause_text(cause)
|
26
|
+
cause = cause.cause
|
27
|
+
end
|
28
|
+
|
29
|
+
text
|
30
|
+
end
|
31
|
+
|
32
|
+
def exception_text(exception)
|
33
|
+
"#{exception.class}: #{exception.message}\n" \
|
34
|
+
"from #{exception.backtrace.first}\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def cause_text(cause)
|
38
|
+
"Caused by #{cause.class}: #{cause}\n" \
|
39
|
+
"from #{cause.backtrace.first}\n"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
# As a REPL, we often want to catch any unexpected exceptions that may have
|
5
|
+
# been raised; however we don't want to go overboard and prevent the user
|
6
|
+
# from exiting Pry when they want to.
|
7
|
+
module RescuableException
|
8
|
+
def self.===(exception)
|
9
|
+
case exception
|
10
|
+
# Catch when the user hits ^C (Interrupt < SignalException), and assume
|
11
|
+
# that they just wanted to stop the in-progress command (just like bash
|
12
|
+
# etc.)
|
13
|
+
when Interrupt
|
14
|
+
true
|
15
|
+
# Don't catch signals (particularly not SIGTERM) as these are unlikely
|
16
|
+
# to be intended for pry itself. We should also make sure that
|
17
|
+
# Kernel#exit works.
|
18
|
+
when *Pry.config.unrescued_exceptions
|
19
|
+
false
|
20
|
+
# All other exceptions will be caught.
|
21
|
+
else
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Catches SecurityErrors if $SAFE is set
|
28
|
+
module TooSafeException
|
29
|
+
def self.===(exception)
|
30
|
+
if Pry::HAS_SAFE_LEVEL
|
31
|
+
$SAFE > 0 && exception.is_a?(SecurityError)
|
32
|
+
else
|
33
|
+
exception.is_a?(SecurityError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error
|
39
|
+
# in a more user-friendly manner. This should be used when the exception
|
40
|
+
# happens within Pry itself as a direct consequence of the user typing
|
41
|
+
# something wrong.
|
42
|
+
#
|
43
|
+
# This allows us to distinguish between the user typing:
|
44
|
+
#
|
45
|
+
# pry(main)> def )
|
46
|
+
# SyntaxError: unexpected )
|
47
|
+
#
|
48
|
+
# pry(main)> method_that_evals("def )")
|
49
|
+
# SyntaxError: (eval):1: syntax error, unexpected ')'
|
50
|
+
# from ./a.rb:2 in `eval'
|
51
|
+
module UserError; end
|
52
|
+
|
53
|
+
# When we try to get a binding for an object, we try to define a method on
|
54
|
+
# that Object's singleton class. This doesn't work for "frozen" Object's, and
|
55
|
+
# the exception is just a vanilla RuntimeError.
|
56
|
+
module FrozenObjectException
|
57
|
+
def self.===(exception)
|
58
|
+
[
|
59
|
+
"can't modify frozen class/module",
|
60
|
+
"can't modify frozen Class",
|
61
|
+
"can't modify frozen object"
|
62
|
+
].include?(exception.message)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# CommandErrors are caught by the REPL loop and displayed to the user. They
|
67
|
+
# indicate an exceptional condition that's fatal to the current command.
|
68
|
+
class CommandError < StandardError; end
|
69
|
+
class MethodNotFound < CommandError; end
|
70
|
+
|
71
|
+
# indicates obsolete API
|
72
|
+
class ObsoleteError < StandardError; end
|
73
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pry
|
4
|
+
module Forwardable
|
5
|
+
require 'forwardable'
|
6
|
+
include ::Forwardable
|
7
|
+
|
8
|
+
#
|
9
|
+
# Since Ruby 2.4, Forwardable will print a warning when
|
10
|
+
# calling a method that is private on a delegate, and
|
11
|
+
# in the future it could be an error: https://bugs.ruby-lang.org/issues/12782#note-3
|
12
|
+
#
|
13
|
+
# That's why we revert to a custom implementation for delegating one
|
14
|
+
# private method to another.
|
15
|
+
#
|
16
|
+
def def_private_delegators(target, *private_delegates)
|
17
|
+
private_delegates.each do |private_delegate|
|
18
|
+
define_method(private_delegate) do |*a, &b|
|
19
|
+
instance_variable_get(target).__send__(private_delegate, *a, &b)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class_eval do
|
23
|
+
private(*private_delegates) # rubocop:disable Style/AccessModifierDeclarations
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|