pry 0.9.7.4-i386-mswin32 → 0.9.8-i386-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.
- data/.gitignore +2 -3
- data/CHANGELOG +43 -0
- data/README.markdown +3 -1
- data/Rakefile +51 -32
- data/bin/pry +2 -80
- data/lib/pry.rb +33 -26
- data/lib/pry/cli.rb +152 -0
- data/lib/pry/code.rb +351 -0
- data/lib/pry/command.rb +422 -0
- data/lib/pry/command_set.rb +259 -129
- data/lib/pry/commands.rb +0 -1
- data/lib/pry/config.rb +43 -9
- data/lib/pry/default_commands/context.rb +109 -92
- data/lib/pry/default_commands/documentation.rb +174 -63
- data/lib/pry/default_commands/easter_eggs.rb +26 -2
- data/lib/pry/default_commands/gems.rb +65 -37
- data/lib/pry/default_commands/input.rb +175 -243
- data/lib/pry/default_commands/introspection.rb +173 -112
- data/lib/pry/default_commands/ls.rb +96 -114
- data/lib/pry/default_commands/shell.rb +175 -70
- data/lib/pry/helpers/base_helpers.rb +7 -2
- data/lib/pry/helpers/command_helpers.rb +71 -77
- data/lib/pry/helpers/options_helpers.rb +10 -41
- data/lib/pry/helpers/text.rb +24 -4
- data/lib/pry/history.rb +55 -17
- data/lib/pry/history_array.rb +2 -0
- data/lib/pry/hooks.rb +252 -0
- data/lib/pry/indent.rb +9 -5
- data/lib/pry/method.rb +149 -50
- data/lib/pry/plugins.rb +12 -4
- data/lib/pry/pry_class.rb +69 -26
- data/lib/pry/pry_instance.rb +187 -115
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +73 -0
- data/man/pry.1 +195 -0
- data/man/pry.1.html +204 -0
- data/man/pry.1.ronn +141 -0
- data/pry.gemspec +29 -32
- data/test/helper.rb +32 -36
- data/test/test_cli.rb +78 -0
- data/test/test_code.rb +201 -0
- data/test/test_command.rb +327 -0
- data/test/test_command_integration.rb +512 -0
- data/test/test_command_set.rb +338 -12
- data/test/test_completion.rb +1 -1
- data/test/test_default_commands.rb +1 -2
- data/test/test_default_commands/test_context.rb +27 -5
- data/test/test_default_commands/test_documentation.rb +20 -8
- data/test/test_default_commands/test_input.rb +84 -45
- data/test/test_default_commands/test_introspection.rb +74 -17
- data/test/test_default_commands/test_ls.rb +9 -36
- data/test/test_default_commands/test_shell.rb +240 -13
- data/test/test_hooks.rb +490 -0
- data/test/test_indent.rb +2 -0
- data/test/test_method.rb +60 -0
- data/test/test_pry.rb +29 -904
- data/test/test_pry_defaults.rb +380 -0
- data/test/test_pry_history.rb +24 -24
- data/test/test_syntax_checking.rb +63 -0
- data/test/test_wrapped_module.rb +71 -0
- metadata +50 -39
- data/lib/pry/command_context.rb +0 -53
- data/lib/pry/command_processor.rb +0 -181
- data/lib/pry/extended_commands/user_command_api.rb +0 -65
- data/test/test_command_processor.rb +0 -176
data/lib/pry/commands.rb
CHANGED
data/lib/pry/config.rb
CHANGED
@@ -33,8 +33,8 @@ class Pry
|
|
33
33
|
attr_accessor :exception_whitelist
|
34
34
|
|
35
35
|
# @return [Fixnum] The number of lines of context to show before and after
|
36
|
-
#
|
37
|
-
attr_accessor :
|
36
|
+
# exceptions, etc.
|
37
|
+
attr_accessor :default_window_size
|
38
38
|
|
39
39
|
# Get/Set the Hash that defines Pry hooks used by default by all Pry
|
40
40
|
# instances.
|
@@ -42,7 +42,19 @@ class Pry
|
|
42
42
|
# @example
|
43
43
|
# Pry.hooks :before_session => proc { puts "hello" },
|
44
44
|
# :after_session => proc { puts "goodbye" }
|
45
|
-
|
45
|
+
attr_reader :hooks
|
46
|
+
|
47
|
+
# FIXME:
|
48
|
+
# This is a hack to alert people of the new API.
|
49
|
+
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
50
|
+
def hooks=(v)
|
51
|
+
if v.is_a?(Hash)
|
52
|
+
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
53
|
+
@hooks = Pry::Hooks.from_hash(v)
|
54
|
+
else
|
55
|
+
@hooks = v
|
56
|
+
end
|
57
|
+
end
|
46
58
|
|
47
59
|
# Get/Set the stack of input objects that a Pry instance switches
|
48
60
|
# to when its current input object encounters EOF.
|
@@ -98,14 +110,20 @@ class Pry
|
|
98
110
|
# @return [Boolean]
|
99
111
|
attr_accessor :disable_auto_reload
|
100
112
|
|
113
|
+
# Determines whether Pry should trap SIGINT and cause it to raise an
|
114
|
+
# Interrupt exception. This is only useful on jruby, MRI does this
|
115
|
+
# for us.
|
116
|
+
# @return [Boolean]
|
117
|
+
attr_accessor :should_trap_interrupts
|
118
|
+
|
101
119
|
# Config option for history.
|
102
|
-
# sub-options include
|
103
|
-
#
|
120
|
+
# sub-options include history.file, history.load, and history.save
|
121
|
+
# history.file is the file to save/load history to, e.g
|
104
122
|
# Pry.config.history.file = "~/.pry_history".
|
105
|
-
#
|
106
|
-
# loaded from
|
107
|
-
#
|
108
|
-
# saved to
|
123
|
+
# history.should_load is a boolean that determines whether history will be
|
124
|
+
# loaded from history.file at session start.
|
125
|
+
# history.should_save is a boolean that determines whether history will be
|
126
|
+
# saved to history.file at session end.
|
109
127
|
# @return [OpenStruct]
|
110
128
|
attr_accessor :history
|
111
129
|
|
@@ -138,6 +156,22 @@ class Pry
|
|
138
156
|
# @return [Boolean] Whether or not indentation should be corrected
|
139
157
|
# after hitting enter. This feature is not supported by all terminals.
|
140
158
|
attr_accessor :correct_indent
|
159
|
+
|
160
|
+
# @return [Boolean] Whether or not a warning will be displayed when
|
161
|
+
# a command name collides with a method/local in the current context.
|
162
|
+
attr_accessor :collision_warning
|
163
|
+
|
164
|
+
|
165
|
+
# Config option for gist.
|
166
|
+
# sub-options include `gist.inspecter`,
|
167
|
+
# `gist.inspecter` is a callable that defines how the expression output
|
168
|
+
# will be displayed when using the `gist -i` command.
|
169
|
+
# @example Pretty inspect output
|
170
|
+
# Pry.config.gist.inspecter = proc { |v| v.pretty_inspect }
|
171
|
+
# @example Regular inspect
|
172
|
+
# Pry.config.gist.inspecter = proc &:inspect
|
173
|
+
# @return [OpenStruct]
|
174
|
+
attr_accessor :gist
|
141
175
|
end
|
142
176
|
end
|
143
177
|
|
@@ -6,45 +6,56 @@ class Pry
|
|
6
6
|
Context = Pry::CommandSet.new do
|
7
7
|
import Ls
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
9
|
+
create_command "cd" do
|
10
|
+
description "Move into a new context (object or scope). Type `cd --help` for more information."
|
11
|
+
|
12
|
+
banner <<-BANNER
|
13
|
+
Usage: cd [OPTIONS] [--help]
|
14
|
+
|
15
|
+
Move into new context (object or scope). As in unix shells use
|
16
|
+
`cd ..` to go back and `cd /` to return to Pry top-level).
|
17
|
+
Complex syntax (e.g cd ../@x/y) also supported.
|
18
|
+
|
19
|
+
e.g: `cd @x`
|
20
|
+
e.g: `cd ..
|
21
|
+
e.g: `cd /`
|
22
|
+
|
23
|
+
https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope
|
24
|
+
BANNER
|
25
|
+
|
26
|
+
def process
|
27
|
+
path = arg_string.split(/\//)
|
28
|
+
stack = _pry_.binding_stack.dup
|
29
|
+
|
30
|
+
# special case when we only get a single "/", return to root
|
31
|
+
stack = [stack.first] if path.empty?
|
32
|
+
|
33
|
+
path.each do |context|
|
34
|
+
begin
|
35
|
+
case context.chomp
|
36
|
+
when ""
|
37
|
+
stack = [stack.first]
|
38
|
+
when "::"
|
39
|
+
stack.push(TOPLEVEL_BINDING)
|
40
|
+
when "."
|
41
|
+
next
|
42
|
+
when ".."
|
43
|
+
unless stack.size == 1
|
44
|
+
stack.pop
|
45
|
+
end
|
30
46
|
else
|
31
|
-
stack.
|
47
|
+
stack.push(Pry.binding_for(stack.last.eval(context)))
|
32
48
|
end
|
33
|
-
else
|
34
|
-
stack.push(Pry.binding_for(stack.last.eval(context)))
|
35
|
-
end
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
50
|
+
rescue RescuableException => e
|
51
|
+
output.puts "Bad object path: #{arg_string.chomp}. Failed trying to resolve: #{context}"
|
52
|
+
output.puts e.inspect
|
53
|
+
return
|
54
|
+
end
|
42
55
|
end
|
43
|
-
end
|
44
56
|
|
45
|
-
|
46
|
-
|
47
|
-
_pry_.binding_stack = stack
|
57
|
+
_pry_.binding_stack = stack
|
58
|
+
end
|
48
59
|
end
|
49
60
|
|
50
61
|
command "switch-to", "Start a new sub-session on a binding in the current stack (numbered by nesting)." do |selection|
|
@@ -95,21 +106,47 @@ class Pry
|
|
95
106
|
|
96
107
|
alias_command "!!@", "exit-all"
|
97
108
|
|
98
|
-
|
99
|
-
|
100
|
-
|
109
|
+
create_command "exit" do
|
110
|
+
description "Pop the previous binding (does NOT exit program). Type `exit --help` for more information. Aliases: quit"
|
111
|
+
|
112
|
+
banner <<-BANNER
|
113
|
+
Usage: exit [OPTIONS] [--help]
|
114
|
+
Aliases: quit
|
115
|
+
|
116
|
+
It can be useful to exit a context with a user-provided value. For
|
117
|
+
instance an exit value can be used to determine program flow.
|
118
|
+
|
119
|
+
e.g: `exit "pry this"`
|
120
|
+
e.g: `exit`
|
121
|
+
|
122
|
+
https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value
|
123
|
+
BANNER
|
124
|
+
|
125
|
+
command_options(
|
126
|
+
:keep_retval => true
|
127
|
+
)
|
128
|
+
|
129
|
+
def process
|
130
|
+
if _pry_.binding_stack.one?
|
131
|
+
# when breaking out of top-level then behave like `exit-all`
|
132
|
+
process_exit_all
|
133
|
+
else
|
134
|
+
# otherwise just pop a binding and return user supplied value
|
135
|
+
process_pop_and_return
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def process_exit_all
|
101
140
|
_pry_.binding_stack.clear
|
102
141
|
throw(:breakout, target.eval(arg_string))
|
103
|
-
|
104
|
-
|
142
|
+
end
|
143
|
+
|
144
|
+
def process_pop_and_return
|
105
145
|
popped_object = _pry_.binding_stack.pop.eval('self')
|
106
146
|
|
107
|
-
# return a user-specified value if given
|
108
|
-
|
109
|
-
|
110
|
-
else
|
111
|
-
popped_object
|
112
|
-
end
|
147
|
+
# return a user-specified value if given otherwise return the object
|
148
|
+
return target.eval(arg_string) unless arg_string.empty?
|
149
|
+
popped_object
|
113
150
|
end
|
114
151
|
end
|
115
152
|
|
@@ -127,64 +164,44 @@ class Pry
|
|
127
164
|
target.pry
|
128
165
|
end
|
129
166
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
klass = target.eval('self.class')
|
167
|
+
create_command "pry-backtrace", "Show the backtrace for the Pry session." do
|
168
|
+
banner <<-BANNER
|
169
|
+
Usage: pry-backtrace [OPTIONS] [--help]
|
134
170
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
i_num = 5
|
139
|
-
end
|
171
|
+
Show the backtrace for the position in the code where Pry was started. This can be used to
|
172
|
+
infer the behavior of the program immediately before it entered Pry, just like the backtrace
|
173
|
+
property of an exception.
|
140
174
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
175
|
+
(NOTE: if you are looking for the backtrace of the most recent exception raised,
|
176
|
+
just type: `_ex_.backtrace` instead, see https://github.com/pry/pry/wiki/Special-Locals)
|
177
|
+
|
178
|
+
e.g: pry-backtrace
|
179
|
+
BANNER
|
180
|
+
|
181
|
+
def process
|
182
|
+
output.puts "\n#{text.bold('Backtrace:')}\n--\n"
|
183
|
+
stagger_output _pry_.backtrace.join("\n")
|
145
184
|
end
|
185
|
+
end
|
186
|
+
|
187
|
+
command "whereami", "Show the code context for the session. (whereami <n> shows <n> extra lines of code around the invocation line. Default: 5)" do |num|
|
188
|
+
file = target.eval('__FILE__')
|
189
|
+
line_num = target.eval('__LINE__')
|
190
|
+
i_num = num ? num.to_i : 5
|
146
191
|
|
147
192
|
if file != Pry.eval_path && (file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e")
|
148
193
|
raise CommandError, "Cannot find local context. Did you use `binding.pry`?"
|
149
194
|
end
|
150
195
|
|
151
196
|
set_file_and_dir_locals(file)
|
152
|
-
output.puts "\n#{text.bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n"
|
153
197
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
unless File.readable?(file)
|
158
|
-
raise CommandError, "Cannot open #{file.inspect} for reading."
|
159
|
-
end
|
160
|
-
f = File.open(file)
|
161
|
-
end
|
198
|
+
method = Pry::Method.from_binding(target)
|
199
|
+
method_description = method ? " in #{method.name_with_owner}" : ""
|
200
|
+
output.puts "\n#{text.bold('From:')} #{file} @ line #{line_num}#{method_description}:\n\n"
|
162
201
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
line_n = index + 1
|
167
|
-
next unless line_n > (line_num - i_num - 1)
|
168
|
-
break if line_n > (line_num + i_num)
|
169
|
-
if line_n == line_num
|
170
|
-
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
171
|
-
if Pry.color
|
172
|
-
code = CodeRay.scan(code, :ruby).term
|
173
|
-
end
|
174
|
-
output.puts code
|
175
|
-
code
|
176
|
-
else
|
177
|
-
code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
|
178
|
-
if Pry.color
|
179
|
-
code = CodeRay.scan(code, :ruby).term
|
180
|
-
end
|
181
|
-
output.puts code
|
182
|
-
code
|
183
|
-
end
|
184
|
-
end
|
185
|
-
ensure
|
186
|
-
f.close if f.respond_to?(:close)
|
187
|
-
end
|
202
|
+
code = Pry::Code.from_file(file).around(line_num, i_num)
|
203
|
+
output.puts code.with_line_numbers.with_marker(line_num)
|
204
|
+
output.puts
|
188
205
|
end
|
189
206
|
|
190
207
|
end
|
@@ -3,96 +3,207 @@ class Pry
|
|
3
3
|
|
4
4
|
Documentation = Pry::CommandSet.new do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
create_command "ri", "View ri documentation. e.g `ri Array#each`" do
|
7
|
+
banner <<-BANNER
|
8
|
+
Usage: ri [spec]
|
9
|
+
e.g. ri Array#each
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
opt.banner unindent <<-USAGE
|
13
|
-
Usage: show-doc [OPTIONS] [METH]
|
14
|
-
Show the comments above method METH. Tries instance methods first and then methods by default.
|
15
|
-
e.g show-doc hello_method
|
16
|
-
USAGE
|
11
|
+
Relies on the ri executable being available. See also: show-doc.
|
12
|
+
BANNER
|
17
13
|
|
14
|
+
def process
|
15
|
+
run ".ri", *args
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
create_command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info. Aliases: \?", :shellwords => false do |*args|
|
20
|
+
banner <<-BANNER
|
21
|
+
Usage: show-doc [OPTIONS] [METH]
|
22
|
+
Show the comments above method METH. Tries instance methods first and then methods by default.
|
23
|
+
e.g show-doc hello_method
|
24
|
+
BANNER
|
25
|
+
|
26
|
+
def options(opt)
|
27
|
+
method_options(opt)
|
28
|
+
opt.on :l, "line-numbers", "Show line numbers."
|
29
|
+
opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)."
|
18
30
|
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
19
31
|
end
|
20
32
|
|
21
|
-
|
33
|
+
def process
|
34
|
+
meth = method_object
|
35
|
+
raise Pry::CommandError, "No documentation found." if meth.doc.nil? || meth.doc.empty?
|
36
|
+
|
37
|
+
doc = process_comment_markup(meth.doc, meth.source_type)
|
38
|
+
output.puts make_header(meth, doc)
|
39
|
+
output.puts "#{text.bold("Owner:")} #{meth.owner || "N/A"}"
|
40
|
+
output.puts "#{text.bold("Visibility:")} #{meth.visibility}"
|
41
|
+
output.puts "#{text.bold("Signature:")} #{meth.signature}"
|
42
|
+
output.puts
|
43
|
+
|
44
|
+
if opts.present?(:b) || opts.present?(:l)
|
45
|
+
doc = Code.new(doc, start_line, :text).
|
46
|
+
with_line_numbers(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
render_output(doc, opts)
|
50
|
+
end
|
51
|
+
|
52
|
+
def start_line
|
53
|
+
if opts.present?(:'base-one')
|
54
|
+
1
|
55
|
+
else
|
56
|
+
(method_object.source_line - method_object.doc.lines.count) || 1
|
57
|
+
end
|
58
|
+
end
|
22
59
|
|
23
|
-
doc = process_comment_markup(meth.doc, meth.source_type)
|
24
|
-
output.puts make_header(meth, doc)
|
25
|
-
output.puts "#{text.bold("Owner:")} #{meth.owner || "N/A"}"
|
26
|
-
output.puts "#{text.bold("Visibility:")} #{meth.visibility}"
|
27
|
-
output.puts "#{text.bold("Signature:")} #{meth.signature}"
|
28
|
-
output.puts
|
29
|
-
render_output(opts.flood?, false, doc)
|
30
60
|
end
|
31
61
|
|
32
62
|
alias_command "?", "show-doc"
|
33
63
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
opts, meth = parse_options!(args, :method_object) do |opt|
|
38
|
-
opt.banner unindent <<-USAGE
|
64
|
+
create_command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info.", :shellwords => false do |*args|
|
65
|
+
banner <<-BANNER
|
39
66
|
Usage: stat [OPTIONS] [METH]
|
40
67
|
Show method information for method METH and set _file_ and _dir_ locals.
|
41
68
|
e.g: stat hello_method
|
42
|
-
|
69
|
+
BANNER
|
70
|
+
|
71
|
+
def options(opt)
|
72
|
+
method_options(opt)
|
43
73
|
end
|
44
74
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
75
|
+
def process
|
76
|
+
meth = method_object
|
77
|
+
output.puts unindent <<-EOS
|
78
|
+
Method Information:
|
79
|
+
--
|
80
|
+
Name: #{meth.name}
|
81
|
+
Owner: #{meth.owner ? meth.owner : "Unknown"}
|
82
|
+
Visibility: #{meth.visibility}
|
83
|
+
Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"}
|
84
|
+
Arity: #{meth.arity}
|
85
|
+
Method Signature: #{meth.signature}
|
86
|
+
Source Location: #{meth.source_location ? meth.source_location.join(":") : "Not found."}
|
87
|
+
EOS
|
88
|
+
end
|
56
89
|
end
|
57
90
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
91
|
+
create_command "gist", "Gist a method or expression history to github. Type `gist --help` for more info.", :requires_gem => "gist", :shellwords => false do
|
92
|
+
banner <<-USAGE
|
93
|
+
Usage: gist [OPTIONS] [METH]
|
94
|
+
Gist method (doc or source) or input expression to github.
|
95
|
+
Ensure the `gist` gem is properly working before use. http://github.com/defunkt/gist for instructions.
|
96
|
+
e.g: gist -m my_method
|
97
|
+
e.g: gist -d my_method
|
98
|
+
e.g: gist -i 1..10
|
99
|
+
e.g: gist -c show-method
|
100
|
+
e.g: gist -m hello_world --lines 2..-2
|
101
|
+
USAGE
|
102
|
+
|
103
|
+
attr_accessor :content
|
104
|
+
attr_accessor :code_type
|
105
|
+
|
106
|
+
def setup
|
107
|
+
require 'gist'
|
108
|
+
self.content = ""
|
109
|
+
self.code_type = :ruby
|
110
|
+
end
|
62
111
|
|
63
|
-
|
64
|
-
opt.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
112
|
+
def options(opt)
|
113
|
+
opt.on :m, :method, "Gist a method's source.", true do |meth_name|
|
114
|
+
meth = get_method_or_raise(meth_name, target, {})
|
115
|
+
self.content << meth.source
|
116
|
+
self.code_type = meth.source_type
|
117
|
+
end
|
118
|
+
opt.on :d, :doc, "Gist a method's documentation.", true do |meth_name|
|
119
|
+
meth = get_method_or_raise(meth_name, target, {})
|
120
|
+
text.no_color do
|
121
|
+
self.content << process_comment_markup(meth.doc, self.code_type)
|
122
|
+
end
|
123
|
+
self.code_type = :plain
|
124
|
+
end
|
125
|
+
opt.on :c, :command, "Gist a command's source.", true do |command_name|
|
126
|
+
command = find_command(command_name)
|
127
|
+
block = Pry::Method.new(find_command(command_name).block)
|
128
|
+
self.content << block.source
|
129
|
+
end
|
130
|
+
opt.on :f, :file, "Gist a file.", true do |file|
|
131
|
+
self.content << File.read(File.expand_path(file))
|
132
|
+
end
|
133
|
+
opt.on :p, :public, "Create a public gist (default: false)", :default => false
|
134
|
+
opt.on :l, :lines, "Only gist a subset of lines.", :optional => true, :as => Range, :default => 1..-1
|
135
|
+
opt.on :i, :in, "Gist entries from Pry's input expression history. Takes an index or range.", :optional => true,
|
136
|
+
:as => Range, :default => -5..-1 do |range|
|
137
|
+
range = convert_to_range(range)
|
138
|
+
input_expressions = _pry_.input_array[range] || []
|
139
|
+
Array(input_expressions).each_with_index do |code, index|
|
140
|
+
corrected_index = index + range.first
|
141
|
+
if code && code != ""
|
142
|
+
self.content << code
|
143
|
+
if code !~ /;\Z/
|
144
|
+
self.content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
71
150
|
|
72
|
-
|
73
|
-
|
151
|
+
def process
|
152
|
+
perform_gist
|
74
153
|
end
|
75
154
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
155
|
+
def perform_gist
|
156
|
+
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
|
157
|
+
|
158
|
+
if self.content =~ /\A\s*\z/
|
159
|
+
raise CommandError, "Found no code to gist."
|
160
|
+
end
|
161
|
+
|
162
|
+
# prevent Gist from exiting the session on error
|
163
|
+
begin
|
164
|
+
extname = opts.present?(:file) ? ".#{gist_file_extension(opts[:f])}" : ".#{type_map[self.code_type]}"
|
165
|
+
|
166
|
+
if opts.present?(:lines)
|
167
|
+
self.content = restrict_to_lines(content, opts[:l])
|
168
|
+
end
|
83
169
|
|
84
|
-
|
85
|
-
|
170
|
+
link = Gist.write([:extension => extname,
|
171
|
+
:input => self.content],
|
172
|
+
!opts[:p])
|
173
|
+
rescue SystemExit
|
174
|
+
end
|
175
|
+
|
176
|
+
if link
|
177
|
+
Gist.copy(link)
|
178
|
+
output.puts "Gist created at #{link} and added to clipboard."
|
86
179
|
end
|
87
|
-
code_type = :plain
|
88
180
|
end
|
89
181
|
|
90
|
-
|
91
|
-
|
92
|
-
|
182
|
+
def gist_file_extension(file_name)
|
183
|
+
file_name.split(".").last
|
184
|
+
end
|
93
185
|
|
94
|
-
|
186
|
+
def convert_to_range(n)
|
187
|
+
if !n.is_a?(Range)
|
188
|
+
(n..n)
|
189
|
+
else
|
190
|
+
n
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def comment_expression_result_for_gist(result)
|
195
|
+
content = ""
|
196
|
+
result.lines.each_with_index do |line, index|
|
197
|
+
if index == 0
|
198
|
+
content << "# => #{line}"
|
199
|
+
else
|
200
|
+
content << "# #{line}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
content
|
204
|
+
end
|
95
205
|
end
|
96
206
|
end
|
97
207
|
end
|
98
208
|
end
|
209
|
+
|