pry 0.9.0pre3 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +25 -6
- data/README.markdown +10 -3
- data/Rakefile +6 -17
- data/bin/pry +11 -0
- data/lib/pry.rb +3 -7
- data/lib/pry/command_processor.rb +19 -7
- data/lib/pry/commands.rb +0 -3
- data/lib/pry/config.rb +7 -3
- data/lib/pry/default_commands/context.rb +1 -0
- data/lib/pry/default_commands/documentation.rb +32 -14
- data/lib/pry/default_commands/input.rb +186 -54
- data/lib/pry/default_commands/introspection.rb +59 -13
- data/lib/pry/default_commands/ls.rb +21 -7
- data/lib/pry/extended_commands/experimental.rb +0 -31
- data/lib/pry/extended_commands/user_command_api.rb +1 -1
- data/lib/pry/helpers/base_helpers.rb +9 -1
- data/lib/pry/plugins.rb +4 -4
- data/lib/pry/pry_class.rb +4 -3
- data/lib/pry/pry_instance.rb +11 -4
- data/lib/pry/version.rb +1 -1
- data/pry.gemspec +45 -0
- data/test/helper.rb +2 -2
- data/test/test_command_processor.rb +73 -1
- data/test/test_default_commands/test_input.rb +172 -2
- data/test/test_default_commands/test_introspection.rb +9 -0
- data/test/test_pry.rb +26 -0
- metadata +8 -7
data/CHANGELOG
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
17/6/2011 version 0.9.0
|
2
|
+
* plugin system
|
3
|
+
* regex commands
|
4
|
+
* show-method works on methods defined in REPL
|
5
|
+
* new command system/API
|
6
|
+
* rubinius core support
|
7
|
+
* inp/out special locals
|
8
|
+
* _ex_ backtrace navigation object (_ex_.line, _ex_.file)
|
9
|
+
* readline history saving/loading
|
10
|
+
* prompt stack
|
11
|
+
* more hooks
|
12
|
+
* amend-line
|
13
|
+
* play
|
14
|
+
* show-input
|
15
|
+
* edit
|
16
|
+
* much more comprehensive test suite
|
17
|
+
* support for new and old rubygems API
|
18
|
+
* changed -s behaviour of ls (now excludes Object methods)
|
19
|
+
|
1
20
|
26/3/2011 version 0.7.6.1
|
2
21
|
* added slightly better support for YARD
|
3
22
|
* now @param and @return tags are colored green and markdown `code` is syntax highlighted using coderay
|
@@ -24,11 +43,11 @@
|
|
24
43
|
* --color mode for pry commandline
|
25
44
|
* clean up requires (put them all in one place)
|
26
45
|
* simple-prompt command and toggle-color commandd.
|
27
|
-
|
46
|
+
|
28
47
|
28/2/2011 version 0.6.3
|
29
48
|
* Using MethodSource 0.3.4 so 1.8 show-method support provided
|
30
49
|
* `Set` class added to list of classes that are inspected
|
31
|
-
|
50
|
+
|
32
51
|
26/2/2011 version 0.6.1
|
33
52
|
* !@ command alias for exit_all
|
34
53
|
* `cd /` for breaking out to pry top level (jump-to 0)
|
@@ -40,11 +59,11 @@
|
|
40
59
|
22/2/2011 version 0.5.8
|
41
60
|
* Added -c (context) option to show-doc, show-methods and eval-file
|
42
61
|
* Fixed up ordering issue of -c and -r parameters to command line pry
|
43
|
-
|
62
|
+
|
44
63
|
21/2/2011 version 0.5.7
|
45
64
|
* Added pry executable, auto-loads .pryrc in user's home directory, if it
|
46
65
|
exists.
|
47
|
-
|
66
|
+
|
48
67
|
19/2/2011 version 0.5.5
|
49
68
|
* Added Pry.run_command
|
50
69
|
* More useful error messages
|
@@ -65,7 +84,7 @@
|
|
65
84
|
* Get rid of ls_method and ls_imethods (subsumed by more powerful ls)
|
66
85
|
* Get rid of show_idoc and show_imethod
|
67
86
|
* Add special eval-file command that evals target file in current context
|
68
|
-
|
87
|
+
|
69
88
|
27/1/2011 version 0.4.5
|
70
89
|
* fixed show_method (though fragile as it references __binding_impl__
|
71
90
|
directly, making a name change to that method difficult
|
@@ -99,4 +118,4 @@
|
|
99
118
|
* now rescuing SyntaxError as well as Racc::Parser error in valid_expression?
|
100
119
|
8/12/2010 version 0.1.0
|
101
120
|
* release!
|
102
|
-
|
121
|
+
|
data/README.markdown
CHANGED
@@ -4,6 +4,15 @@
|
|
4
4
|
|
5
5
|
_Get to the code_
|
6
6
|
|
7
|
+
## These docs are now out of date for the 0.9.0 release.
|
8
|
+
|
9
|
+
** New documentation will be available shortly, please see the CHANGELOG and Pry's own livehelp system for information in the meantime.
|
10
|
+
|
11
|
+
Also note that JRuby is not yet supported in this release, but will be soon.
|
12
|
+
|
13
|
+
Thanks **
|
14
|
+
|
15
|
+
|
7
16
|
Pry is a powerful alternative to the standard IRB shell for Ruby. It is
|
8
17
|
written from scratch to provide a number of advanced features, some of
|
9
18
|
these include:
|
@@ -549,8 +558,6 @@ Problems or questions contact me at [github](http://github.com/banister)
|
|
549
558
|
The Pry team consists of:
|
550
559
|
|
551
560
|
* [banisterfiend](http://github.com/banister)
|
552
|
-
* [epitron](http://github.com/epitron)
|
553
561
|
* [injekt](http://github.com/injekt)
|
554
562
|
* [Mon_Ouie](http://github.com/mon-ouie)
|
555
|
-
|
556
|
-
|
563
|
+
* [Rob Gleeson](https://github.com/robgleeson)
|
data/Rakefile
CHANGED
@@ -22,12 +22,13 @@ def apply_spec_defaults(s)
|
|
22
22
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
23
23
|
s.add_dependency("ruby_parser",">=2.0.5")
|
24
24
|
s.add_dependency("coderay",">=0.9.8")
|
25
|
-
s.add_dependency("slop","~>1.
|
26
|
-
s.add_dependency("method_source",">=0.
|
25
|
+
s.add_dependency("slop","~>1.9.0")
|
26
|
+
s.add_dependency("method_source",">=0.6.0")
|
27
27
|
s.add_development_dependency("bacon",">=1.1.0")
|
28
28
|
s.add_development_dependency("open4", "~>1.0.1")
|
29
29
|
end
|
30
30
|
|
31
|
+
desc "Run tests"
|
31
32
|
task :test do
|
32
33
|
sh "bacon -Itest -rubygems -a"
|
33
34
|
end
|
@@ -52,10 +53,10 @@ namespace :ruby do
|
|
52
53
|
pkg.need_zip = false
|
53
54
|
pkg.need_tar = false
|
54
55
|
end
|
55
|
-
|
56
|
+
|
56
57
|
desc "Generate gemspec file"
|
57
58
|
task :gemspec do
|
58
|
-
File.open("#{spec.name}
|
59
|
+
File.open("#{spec.name}.gemspec", "w") do |f|
|
59
60
|
f << spec.to_ruby
|
60
61
|
end
|
61
62
|
end
|
@@ -76,20 +77,8 @@ end
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
|
-
namespace :jruby do
|
80
|
-
spec = Gem::Specification.new do |s|
|
81
|
-
apply_spec_defaults(s)
|
82
|
-
s.platform = "java"
|
83
|
-
end
|
84
|
-
|
85
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
86
|
-
pkg.need_zip = false
|
87
|
-
pkg.need_tar = false
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
80
|
desc "build all platform gems at once"
|
92
|
-
task :gems => [:clean, :rmgems, "ruby:gem", "
|
81
|
+
task :gems => [:clean, :rmgems, "ruby:gem", "mswin32:gem", "mingw32:gem"]
|
93
82
|
|
94
83
|
desc "remove all platform gems"
|
95
84
|
task :rmgems => ["ruby:clobber_package"]
|
data/bin/pry
CHANGED
@@ -39,6 +39,8 @@ See: `https://github.com/banister` for more information.
|
|
39
39
|
Pry.config.plugins.enabled = false
|
40
40
|
end
|
41
41
|
|
42
|
+
on "installed-plugins", "List installed plugins."
|
43
|
+
|
42
44
|
on "simple-prompt", "Enable simple prompt mode" do
|
43
45
|
Pry.prompt = Pry::SIMPLE_PROMPT
|
44
46
|
end
|
@@ -63,6 +65,15 @@ See: `https://github.com/banister` for more information.
|
|
63
65
|
)
|
64
66
|
end
|
65
67
|
|
68
|
+
if opts["installed-plugins"]
|
69
|
+
puts "Installed Plugins:"
|
70
|
+
puts "--"
|
71
|
+
Pry.locate_plugins.each do |plugin|
|
72
|
+
puts "#{plugin.name}".ljust(18) + plugin.spec.summary
|
73
|
+
end
|
74
|
+
exit
|
75
|
+
end
|
76
|
+
|
66
77
|
# invoked via cli
|
67
78
|
Pry.cli = true
|
68
79
|
|
data/lib/pry.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# MIT License
|
3
3
|
|
4
4
|
require 'pp'
|
5
|
-
|
5
|
+
require 'pry/helpers/base_helpers'
|
6
6
|
class Pry
|
7
7
|
# The default hooks - display messages when beginning and ending Pry sessions.
|
8
8
|
DEFAULT_HOOKS = {
|
@@ -20,11 +20,7 @@ class Pry
|
|
20
20
|
|
21
21
|
# The default prints
|
22
22
|
DEFAULT_PRINT = proc do |output, value|
|
23
|
-
|
24
|
-
output.puts "=> #{CodeRay.scan(value.pretty_inspect, :ruby).term}"
|
25
|
-
else
|
26
|
-
output.puts "=> #{Pry.view(value)}"
|
27
|
-
end
|
23
|
+
Helpers::BaseHelpers.stagger_output("=> #{Helpers::BaseHelpers.colorize_code(value.pretty_inspect)}", output)
|
28
24
|
end
|
29
25
|
|
30
26
|
# Will only show the first line of the backtrace
|
@@ -53,7 +49,7 @@ class Pry
|
|
53
49
|
]
|
54
50
|
|
55
51
|
# A simple prompt - doesn't display target or nesting level
|
56
|
-
SIMPLE_PROMPT = [proc { ">> " }, proc { "
|
52
|
+
SIMPLE_PROMPT = [proc { ">> " }, proc { " | " }]
|
57
53
|
|
58
54
|
SHELL_PROMPT = [
|
59
55
|
proc { |target_self, _| "pry #{Pry.view_clip(target_self)}:#{Dir.pwd} $ " },
|
@@ -14,9 +14,11 @@ class Pry
|
|
14
14
|
|
15
15
|
# Is the string a valid command?
|
16
16
|
# @param [String] val The string passed in from the Pry prompt.
|
17
|
+
# @param [Binding] target The context where the string should be
|
18
|
+
# interpolated in.
|
17
19
|
# @return [Boolean] Whether the string is a valid command.
|
18
|
-
def valid_command?(val)
|
19
|
-
!!(command_matched(val,
|
20
|
+
def valid_command?(val, target=binding)
|
21
|
+
!!(command_matched(val, target)[0])
|
20
22
|
end
|
21
23
|
|
22
24
|
# Convert the object to a form that can be interpolated into a
|
@@ -34,7 +36,7 @@ class Pry
|
|
34
36
|
# Revaluate the string (str) and perform interpolation.
|
35
37
|
# @param [String] str The string to reevaluate with interpolation.
|
36
38
|
# @param [Binding] target The context where the string should be
|
37
|
-
#
|
39
|
+
# interpolated in.
|
38
40
|
# @return [String] The reevaluated string with interpolations
|
39
41
|
# applied (if any).
|
40
42
|
def interpolate_string(str, target)
|
@@ -53,11 +55,18 @@ class Pry
|
|
53
55
|
def command_matched(val, target)
|
54
56
|
_, cmd_data = commands.commands.find do |name, data|
|
55
57
|
|
56
|
-
interp_val = interpolate_string(val, target)
|
57
58
|
command_regex = /^#{convert_to_regex(name)}(?!\S)/
|
58
59
|
|
59
|
-
if data.options[:interpolate]
|
60
|
-
|
60
|
+
if data.options[:interpolate]
|
61
|
+
# If interpolation fails then the command cannot be matched,
|
62
|
+
# so early exit.
|
63
|
+
begin
|
64
|
+
interp_val = interpolate_string(val, target)
|
65
|
+
rescue NameError
|
66
|
+
next
|
67
|
+
end
|
68
|
+
|
69
|
+
val.replace interp_val if command_regex =~ interp_val
|
61
70
|
else
|
62
71
|
command_regex =~ val
|
63
72
|
end
|
@@ -80,7 +89,10 @@ class Pry
|
|
80
89
|
# no command was matched, so return to caller
|
81
90
|
command, captures, pos = command_matched(val, target)
|
82
91
|
return if !command
|
83
|
-
arg_string = val[pos..-1]
|
92
|
+
arg_string = val[pos..-1]
|
93
|
+
|
94
|
+
# remove the one leading space if it exists
|
95
|
+
arg_string.slice!(0) if arg_string.start_with?(" ")
|
84
96
|
|
85
97
|
args = arg_string ? Shellwords.shellwords(arg_string) : []
|
86
98
|
|
data/lib/pry/commands.rb
CHANGED
data/lib/pry/config.rb
CHANGED
@@ -75,9 +75,9 @@ class Pry
|
|
75
75
|
# sub-options include hist.file, hist.load, and hist.save
|
76
76
|
# hist.file is the file to save/load history too, e.g
|
77
77
|
# Pry.config.history.file = "~/.pry_history".
|
78
|
-
# hist.
|
78
|
+
# hist.should_load is a boolean that determines whether history will be
|
79
79
|
# loaded from hist.file at session start.
|
80
|
-
# hist.
|
80
|
+
# hist.should_save is a boolean that determines whether history will be
|
81
81
|
# saved to hist.file at session end.
|
82
82
|
# @return [OpenStruct]
|
83
83
|
attr_accessor :history
|
@@ -89,8 +89,12 @@ class Pry
|
|
89
89
|
# @return [OpenStruct]
|
90
90
|
attr_accessor :plugins
|
91
91
|
|
92
|
-
# @return [Integer] Amount of results that will be stored into
|
92
|
+
# @return [Integer] Amount of results that will be stored into out
|
93
93
|
attr_accessor :memory_size
|
94
|
+
|
95
|
+
# @return [Boolean] Whether or not evalation results (`=>`) are sent
|
96
|
+
# through a pager.
|
97
|
+
attr_accessor :result_pager
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
@@ -40,13 +40,16 @@ class Pry
|
|
40
40
|
next output.puts("No documentation found.") if doc.empty?
|
41
41
|
doc = process_comment_markup(doc, code_type)
|
42
42
|
output.puts make_header(meth, code_type, doc)
|
43
|
+
if meth.respond_to?(:parameters)
|
44
|
+
output.puts "#{text.bold("signature")}: #{signature_for(meth)}"
|
45
|
+
output.puts
|
46
|
+
end
|
43
47
|
render_output(opts.flood?, false, doc)
|
44
48
|
doc
|
45
49
|
end
|
46
50
|
|
47
51
|
alias_command "?", "show-doc", ""
|
48
52
|
|
49
|
-
|
50
53
|
command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
|
51
54
|
target = target()
|
52
55
|
|
@@ -73,23 +76,21 @@ class Pry
|
|
73
76
|
next
|
74
77
|
end
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
+
if !is_a_c_method?(meth) && !is_a_dynamically_defined_method?(meth)
|
80
|
+
set_file_and_dir_locals(path_line_for(meth).first)
|
81
|
+
end
|
79
82
|
|
80
|
-
output.puts
|
81
|
-
output.puts
|
82
|
-
output.puts
|
83
|
-
output.puts
|
84
|
-
output.puts
|
85
|
-
output.puts
|
83
|
+
output.puts "Method Information:"
|
84
|
+
output.puts "--"
|
85
|
+
output.puts "Name: " + meth_name
|
86
|
+
output.puts "Owner: " + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
|
87
|
+
output.puts "Type: " + (meth.is_a?(Method) ? "Bound" : "Unbound")
|
88
|
+
output.puts "Arity: " + meth.arity.to_s
|
86
89
|
|
87
|
-
name_map = { :req => "Required:", :opt => "Optional:", :rest => "Rest:" }
|
88
90
|
if meth.respond_to?(:parameters)
|
89
|
-
output.puts
|
90
|
-
map { |k, v| "#{name_map[k]} #{v.map { |kk, vv| vv ? vv.to_s : "noname" }.join(", ")}" }.join(". ")
|
91
|
+
output.puts "Method Signature: " + signature_for(meth)
|
91
92
|
end
|
92
|
-
|
93
|
+
|
93
94
|
end
|
94
95
|
|
95
96
|
command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
|
@@ -140,6 +141,23 @@ class Pry
|
|
140
141
|
output.puts "Gist created at #{link}"
|
141
142
|
end
|
142
143
|
|
144
|
+
helpers do
|
145
|
+
def signature_for(meth)
|
146
|
+
param_strings = []
|
147
|
+
meth.parameters.each do |kind, name|
|
148
|
+
case kind
|
149
|
+
when :req
|
150
|
+
param_strings << name
|
151
|
+
when :opt
|
152
|
+
param_strings << "#{name}=?"
|
153
|
+
when :rest
|
154
|
+
param_strings << "*#{name}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
"#{meth.name}(#{param_strings.join(", ")})"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
143
161
|
end
|
144
162
|
|
145
163
|
end
|
@@ -8,28 +8,101 @@ class Pry
|
|
8
8
|
eval_string.replace("")
|
9
9
|
end
|
10
10
|
|
11
|
-
command "show-input", "Show the current
|
12
|
-
render_output(false,
|
11
|
+
command "show-input", "Show the contents of the input buffer for the current multi-line expression." do
|
12
|
+
render_output(false, 1, Pry.color ? CodeRay.scan(eval_string, :ruby).term : eval_string)
|
13
13
|
end
|
14
14
|
|
15
|
-
command(/amend-line
|
16
|
-
|
15
|
+
command(/amend-line.?(-?\d+)?(?:\.\.(-?\d+))?/, "Amend a line of input in multi-line mode. Type `amend-line --help` for more information. Aliases %",
|
16
|
+
:interpolate => false, :listing => "amend-line") do |*args|
|
17
|
+
start_line_number, end_line_number, replacement_line = *args
|
18
|
+
|
19
|
+
opts = Slop.parse!(args.compact) do |opt|
|
20
|
+
opt.banner %{Amend a line of input in multi-line mode. `amend-line N`, where the N in `amend-line N` represents line to replace.
|
21
|
+
|
22
|
+
Can also specify a range of lines using `amend-line N..M` syntax. Passing '!' as replacement content deletes the line(s) instead. Aliases: %N
|
23
|
+
e.g amend-line 1 puts 'hello world! # replace line 1'
|
24
|
+
e.g amend-line 1..4 ! # delete lines 1..4
|
25
|
+
e.g amend-line 3 >puts 'goodbye' # insert before line 3
|
26
|
+
e.g amend-line puts 'hello again' # no line number modifies immediately preceding line
|
27
|
+
}
|
28
|
+
opt.on :h, :help, "This message." do
|
29
|
+
output.puts opt
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
next if opts.h?
|
34
|
+
next output.puts "No input to amend." if eval_string.empty?
|
35
|
+
|
17
36
|
replacement_line = "" if !replacement_line
|
18
37
|
input_array = eval_string.each_line.to_a
|
19
|
-
|
20
|
-
|
38
|
+
|
39
|
+
end_line_number = start_line_number.to_i if !end_line_number
|
40
|
+
line_range = start_line_number ? (one_index_number(start_line_number.to_i)..one_index_number(end_line_number.to_i)) : input_array.size - 1
|
41
|
+
|
42
|
+
# delete selected lines if replacement line is '!'
|
43
|
+
if arg_string == "!"
|
44
|
+
input_array.slice!(line_range)
|
45
|
+
elsif arg_string.start_with?(">")
|
46
|
+
insert_slot = Array(line_range).first
|
47
|
+
input_array.insert(insert_slot, arg_string[1..-1] + "\n")
|
48
|
+
else
|
49
|
+
input_array[line_range] = arg_string + "\n"
|
50
|
+
end
|
21
51
|
eval_string.replace input_array.join
|
52
|
+
run "show-input"
|
22
53
|
end
|
23
54
|
|
24
|
-
alias_command(
|
55
|
+
alias_command(/%.?(-?\d+)?(?:\.\.(-?\d+))?/, /amend-line.?(-?\d+)?(?:\.\.(-?\d+))?/, "")
|
56
|
+
|
57
|
+
command "play", "Play back a string or a method or a file as input. Type `play --help` for more information." do |*args|
|
58
|
+
opts = Slop.parse!(args) do |opt|
|
59
|
+
opt.banner "Usage: play [OPTIONS] [--help]\nDefault action (no options) is to play the provided string\ne.g `play puts 'hello world'` #=> \"hello world\"\ne.g `play -m Pry#repl --lines 1..-1`\ne.g `play -f Rakefile --lines 5`\n"
|
60
|
+
|
61
|
+
opt.on :l, :lines, 'The line (or range of lines) to replay.', true, :as => Range
|
62
|
+
opt.on :m, :method, 'Play a method.', true
|
63
|
+
opt.on :f, "file", 'The line (or range of lines) to replay.', true
|
64
|
+
opt.on :o, "open", 'When used with the -m switch, it plays the entire method except the last line, leaving the method definition "open". `amend-line` can then be used to modify the method.'
|
65
|
+
opt.on :h, :help, "This message." do
|
66
|
+
output.puts opt
|
67
|
+
end
|
68
|
+
|
69
|
+
opt.on_noopts { Pry.active_instance.input = StringIO.new(arg_string) }
|
70
|
+
end
|
71
|
+
|
72
|
+
if opts.m?
|
73
|
+
meth_name = opts[:m]
|
74
|
+
if (meth = get_method_object(meth_name, target, {})).nil?
|
75
|
+
output.puts "Invalid method name: #{meth_name}."
|
76
|
+
next
|
77
|
+
end
|
78
|
+
code, code_type = code_and_code_type_for(meth)
|
79
|
+
next if !code
|
80
|
+
|
81
|
+
range = opts.l? ? one_index_range_or_number(opts[:l]) : (0..-1)
|
82
|
+
range = (0..-2) if opts.o?
|
83
|
+
|
84
|
+
Pry.active_instance.input = StringIO.new(Array(code.each_line.to_a[range]).join)
|
85
|
+
end
|
86
|
+
|
87
|
+
if opts.f?
|
88
|
+
file_name = File.expand_path(opts[:f])
|
89
|
+
next output.puts "No such file: #{opts[:f]}" if !File.exists?(file_name)
|
90
|
+
text_array = File.readlines(file_name)
|
91
|
+
range = opts.l? ? one_index_range_or_number(opts[:l]) : (0..-1)
|
92
|
+
range = (0..-2) if opts.o?
|
93
|
+
|
94
|
+
Pry.active_instance.input = StringIO.new(Array(text_array[range]).join)
|
95
|
+
end
|
96
|
+
end
|
25
97
|
|
26
98
|
command "hist", "Show and replay Readline history. Type `hist --help` for more info." do |*args|
|
27
|
-
|
28
|
-
|
29
|
-
|
99
|
+
history = Readline::HISTORY.to_a
|
100
|
+
|
101
|
+
opts = Slop.parse!(args) do |opt|
|
102
|
+
opt.banner "Usage: hist [--replay START..END] [--clear] [--grep PATTERN] [--head N] [--tail N] [--help] [--save [START..END] file.txt]\n"
|
30
103
|
|
31
104
|
opt.on :g, :grep, 'A pattern to match against the history.', true do |pattern|
|
32
|
-
pattern = Regexp.new arg_string.split(/
|
105
|
+
pattern = Regexp.new arg_string.strip.split(/ /, 2).last.strip
|
33
106
|
history.pop
|
34
107
|
|
35
108
|
history.map!.with_index do |element, index|
|
@@ -41,64 +114,67 @@ class Pry
|
|
41
114
|
stagger_output history.compact.join "\n"
|
42
115
|
end
|
43
116
|
|
44
|
-
opt.on :head, 'Display the first N items of history',
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
117
|
+
opt.on :head, 'Display the first N items of history',
|
118
|
+
:optional => true,
|
119
|
+
:as => Integer,
|
120
|
+
:unless => :grep do |limit|
|
121
|
+
|
122
|
+
limit ||= 10
|
123
|
+
list = history.first limit
|
124
|
+
lines = text.with_line_numbers list.join("\n"), 0
|
125
|
+
stagger_output lines
|
51
126
|
end
|
52
127
|
|
53
|
-
opt.on :t, :tail, 'Display the last N items of history',
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
offset = offset < 0 ? 0 : offset
|
128
|
+
opt.on :t, :tail, 'Display the last N items of history',
|
129
|
+
:optional => true,
|
130
|
+
:as => Integer,
|
131
|
+
:unless => :grep do |limit|
|
58
132
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
133
|
+
limit ||= 10
|
134
|
+
offset = history.size-limit
|
135
|
+
offset = offset < 0 ? 0 : offset
|
136
|
+
|
137
|
+
list = history.last limit
|
138
|
+
lines = text.with_line_numbers list.join("\n"), offset
|
139
|
+
stagger_output lines
|
63
140
|
end
|
64
141
|
|
65
|
-
opt.on :s, :show, 'Show the history corresponding to the history line (or range of lines).',
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
142
|
+
opt.on :s, :show, 'Show the history corresponding to the history line (or range of lines).',
|
143
|
+
true,
|
144
|
+
:as => Range,
|
145
|
+
:unless => :grep do |range|
|
146
|
+
|
147
|
+
start_line = range.is_a?(Range) ? range.first : range
|
148
|
+
lines = text.with_line_numbers Array(history[range]).join("\n"), start_line
|
149
|
+
stagger_output lines
|
71
150
|
end
|
72
151
|
|
73
|
-
opt.on :e, :exclude, 'Exclude pry commands from the history.' do
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
"#{text.blue index}: #{element}"
|
78
|
-
end
|
152
|
+
opt.on :e, :exclude, 'Exclude pry commands from the history.', :unless => :grep do
|
153
|
+
history.map!.with_index do |element, index|
|
154
|
+
unless command_processor.valid_command? element
|
155
|
+
"#{text.blue index}: #{element}"
|
79
156
|
end
|
80
|
-
stagger_output history.compact.join "\n"
|
81
157
|
end
|
158
|
+
stagger_output history.compact.join "\n"
|
82
159
|
end
|
83
160
|
|
84
|
-
opt.on :r, :replay, 'The line (or range of lines) to replay.',
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
161
|
+
opt.on :r, :replay, 'The line (or range of lines) to replay.',
|
162
|
+
true,
|
163
|
+
:as => Range,
|
164
|
+
:unless => :grep do |range|
|
165
|
+
actions = Array(history[range]).join("\n") + "\n"
|
166
|
+
Pry.active_instance.input = StringIO.new(actions)
|
89
167
|
end
|
90
168
|
|
91
|
-
opt.on
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
169
|
+
opt.on "save", "Save history to a file. --save [start..end] output.txt. Pry commands are excluded from saved history.", true, :as => Range
|
170
|
+
|
171
|
+
opt.on :c, :clear, 'Clear the history', :unless => :grep do
|
172
|
+
Readline::HISTORY.shift until Readline::HISTORY.empty?
|
173
|
+
output.puts 'History cleared.'
|
96
174
|
end
|
97
175
|
|
98
|
-
opt.on :h, :help, 'Show this message.', :tail => true do
|
99
|
-
|
100
|
-
output.puts opt.help
|
101
|
-
end
|
176
|
+
opt.on :h, :help, 'Show this message.', :tail => true, :unless => :grep do
|
177
|
+
output.puts opt.help
|
102
178
|
end
|
103
179
|
|
104
180
|
opt.on_empty do
|
@@ -106,6 +182,62 @@ class Pry
|
|
106
182
|
stagger_output lines
|
107
183
|
end
|
108
184
|
end
|
185
|
+
|
186
|
+
# FIXME: hack to save history (this must be refactored)
|
187
|
+
if opts["save"]
|
188
|
+
file_name = nil
|
189
|
+
hist_array = nil
|
190
|
+
|
191
|
+
case opts["save"]
|
192
|
+
when Range
|
193
|
+
hist_array = Array(history[opts["save"]])
|
194
|
+
next output.puts "Must provide a file name." if !args.first
|
195
|
+
file_name = File.expand_path(args.first)
|
196
|
+
when String
|
197
|
+
hist_array = history
|
198
|
+
file_name = File.expand_path(opts["save"])
|
199
|
+
end
|
200
|
+
|
201
|
+
output.puts "Saving history in #{file_name} ..."
|
202
|
+
# exclude pry commands
|
203
|
+
hist_array.reject! do |element|
|
204
|
+
command_processor.valid_command?(element)
|
205
|
+
end
|
206
|
+
|
207
|
+
File.open(file_name, 'w') do |f|
|
208
|
+
f.write hist_array.join("\n")
|
209
|
+
end
|
210
|
+
|
211
|
+
output.puts "... history saved."
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
helpers do
|
218
|
+
def one_index_number(line_number)
|
219
|
+
if line_number > 0
|
220
|
+
line_number - 1
|
221
|
+
elsif line_number < 0
|
222
|
+
line_number
|
223
|
+
else
|
224
|
+
line_number
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def one_index_range(range)
|
229
|
+
Range.new(one_index_number(range.begin), one_index_number(range.end))
|
230
|
+
end
|
231
|
+
|
232
|
+
def one_index_range_or_number(range_or_number)
|
233
|
+
case range_or_number
|
234
|
+
when Range
|
235
|
+
one_index_range(range_or_number)
|
236
|
+
else
|
237
|
+
one_index_number(range_or_number)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
109
241
|
end
|
110
242
|
|
111
243
|
end
|