pry 0.9.7.4-i386-mingw32 → 0.9.8-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -8,7 +8,7 @@ class Pry
|
|
8
8
|
run "show-input"
|
9
9
|
end
|
10
10
|
|
11
|
-
command "get-naked" "" do
|
11
|
+
command "get-naked", "" do
|
12
12
|
text = %{
|
13
13
|
--
|
14
14
|
We dont have to take our clothes off to have a good time.
|
@@ -60,8 +60,32 @@ they are lost for hours.
|
|
60
60
|
text
|
61
61
|
end
|
62
62
|
|
63
|
+
command "test-ansi", "" do
|
64
|
+
prev_color = Pry.color
|
65
|
+
Pry.color = true
|
63
66
|
|
64
|
-
|
67
|
+
picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s| text.red(s) }
|
68
|
+
____ _______________________
|
69
|
+
/ \ | A W G |
|
70
|
+
/ O O \ | N I O N ! |
|
71
|
+
| | | S S R I ! |
|
72
|
+
\ \__/ / __| I K ! |
|
73
|
+
\____/ \________________________|
|
74
|
+
EOS
|
75
|
+
|
76
|
+
if defined?(Win32::Console)
|
77
|
+
move_up = proc { |n| "\e[#{n}F" }
|
78
|
+
else
|
79
|
+
move_up = proc { |n| "\e[#{n}A\e[0G" }
|
80
|
+
end
|
81
|
+
|
82
|
+
output.puts "\n" * 6
|
83
|
+
output.puts picture.lines.map(&:chomp).reverse.join(move_up[1])
|
84
|
+
output.puts "\n" * 6
|
85
|
+
output.puts "** ENV['TERM'] is #{ENV['TERM']} **\n\n"
|
65
86
|
|
87
|
+
Pry.color = prev_color
|
88
|
+
end
|
89
|
+
end
|
66
90
|
end
|
67
91
|
end
|
@@ -3,53 +3,81 @@ class Pry
|
|
3
3
|
|
4
4
|
Gems = Pry::CommandSet.new do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
else
|
17
|
-
Gem.refresh
|
18
|
-
output.puts "Gem `#{text.green gem}` installed."
|
6
|
+
create_command "gem-install", "Install a gem and refresh the gem cache.", :argument_required => true do |gem|
|
7
|
+
|
8
|
+
banner <<-BANNER
|
9
|
+
Usage: gem-install GEM_NAME
|
10
|
+
|
11
|
+
Installs the given gem and refreshes the gem cache so that you can immediately 'require GEM_FILE'
|
12
|
+
BANNER
|
13
|
+
|
14
|
+
def setup
|
15
|
+
require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
|
19
16
|
end
|
20
|
-
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
def process(gem)
|
19
|
+
begin
|
20
|
+
destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir
|
21
|
+
installer = Gem::DependencyInstaller.new :install_dir => destination
|
22
|
+
installer.install gem
|
23
|
+
rescue Errno::EACCES
|
24
|
+
raise CommandError, "Insufficient permissions to install `#{text.green gem}`."
|
25
|
+
rescue Gem::GemNotFoundException
|
26
|
+
raise CommandError, "Gem `#{text.green gem}` not found."
|
27
|
+
else
|
28
|
+
Gem.refresh
|
29
|
+
output.puts "Gem `#{text.green gem}` installed."
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
Gem::Specification.select{|spec| spec.name =~ pattern }.group_by(&:name)
|
36
|
-
else
|
37
|
-
Gem.source_index.gems.values.group_by(&:name).select { |gemname, specs| gemname =~ pattern }
|
38
|
-
end
|
39
|
-
|
40
|
-
gems.each do |gem, specs|
|
41
|
-
specs.sort! do |a,b|
|
42
|
-
Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
|
43
|
-
end
|
34
|
+
create_command "gem-cd", "Change working directory to specified gem's directory.", :argument_required => true do |gem|
|
35
|
+
banner <<-BANNER
|
36
|
+
Usage: gem-cd GEM_NAME
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
38
|
+
Change the current working directory to that in which the given gem is installed.
|
39
|
+
BANNER
|
48
40
|
|
49
|
-
|
41
|
+
def process(gem)
|
42
|
+
specs = Gem::Specification.respond_to?(:each) ? Gem::Specification.find_all_by_name(gem) : Gem.source_index.find_name(gem)
|
43
|
+
spec = specs.sort { |a,b| Gem::Version.new(b.version) <=> Gem::Version.new(a.version) }.first
|
44
|
+
if spec
|
45
|
+
Dir.chdir(spec.full_gem_path)
|
46
|
+
output.puts(Dir.pwd)
|
47
|
+
else
|
48
|
+
raise CommandError, "Gem `#{gem}` not found."
|
49
|
+
end
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
create_command "gem-list", "List and search installed gems." do |pattern|
|
54
|
+
banner <<-BANNER
|
55
|
+
Usage: gem-list [REGEX]
|
56
|
+
|
57
|
+
List all installed gems, when a regex is provided, limit the output to those that
|
58
|
+
match the regex.
|
59
|
+
BANNER
|
60
|
+
|
61
|
+
def process(pattern=nil)
|
62
|
+
gems = if Gem::Specification.respond_to?(:each)
|
63
|
+
Gem::Specification.select{|spec| spec.name =~ pattern }.group_by(&:name)
|
64
|
+
else
|
65
|
+
Gem.source_index.gems.values.group_by(&:name).select { |gemname, specs| gemname =~ pattern }
|
66
|
+
end
|
67
|
+
|
68
|
+
gems.each do |gem, specs|
|
69
|
+
specs.sort! do |a,b|
|
70
|
+
Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
|
71
|
+
end
|
72
|
+
|
73
|
+
versions = specs.each_with_index.map do |spec, index|
|
74
|
+
index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
output.puts "#{text.default gem} (#{versions.join ', '})"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
53
81
|
end
|
54
82
|
end
|
55
83
|
end
|
@@ -3,313 +3,245 @@ class Pry
|
|
3
3
|
|
4
4
|
Input = Pry::CommandSet.new do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
end
|
14
|
-
|
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 unindent <<-USAGE
|
21
|
-
Amend a line of input in multi-line mode. `amend-line N`, where the N in `amend-line N` represents line to replace.
|
22
|
-
|
23
|
-
Can also specify a range of lines using `amend-line N..M` syntax. Passing '!' as replacement content deletes the line(s) instead. Aliases: %N
|
24
|
-
e.g amend-line 1 puts 'hello world! # replace line 1'
|
25
|
-
e.g amend-line 1..4 ! # delete lines 1..4
|
26
|
-
e.g amend-line 3 >puts 'goodbye' # insert before line 3
|
27
|
-
e.g amend-line puts 'hello again' # no line number modifies immediately preceding line
|
28
|
-
USAGE
|
29
|
-
|
30
|
-
opt.on :h, :help, "This message." do
|
31
|
-
output.puts opt
|
32
|
-
end
|
6
|
+
create_command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop.", :use_prefix => false do
|
7
|
+
def process
|
8
|
+
output.puts "Input buffer cleared!"
|
9
|
+
eval_string.replace("")
|
33
10
|
end
|
34
|
-
|
35
|
-
next if opts.h?
|
36
|
-
|
37
|
-
if eval_string.empty?
|
38
|
-
raise CommandError, "No input to amend."
|
39
|
-
end
|
40
|
-
|
41
|
-
replacement_line = "" if !replacement_line
|
42
|
-
input_array = eval_string.each_line.to_a
|
43
|
-
|
44
|
-
end_line_number = start_line_number.to_i if !end_line_number
|
45
|
-
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
|
46
|
-
|
47
|
-
# delete selected lines if replacement line is '!'
|
48
|
-
if arg_string == "!"
|
49
|
-
input_array.slice!(line_range)
|
50
|
-
elsif arg_string.start_with?(">")
|
51
|
-
insert_slot = Array(line_range).first
|
52
|
-
input_array.insert(insert_slot, arg_string[1..-1] + "\n")
|
53
|
-
else
|
54
|
-
input_array[line_range] = arg_string + "\n"
|
55
|
-
end
|
56
|
-
eval_string.replace input_array.join
|
57
|
-
run "show-input"
|
58
11
|
end
|
59
12
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
opts = Slop.parse!(args) do |opt|
|
64
|
-
opt.banner unindent <<-USAGE
|
65
|
-
Usage: play [OPTIONS] [--help]
|
66
|
-
Default action (no options) is to play the provided string variable
|
67
|
-
e.g `play _in_[20] --lines 1..3`
|
68
|
-
e.g `play -m Pry#repl --lines 1..-1`
|
69
|
-
e.g `play -f Rakefile --lines 5`
|
70
|
-
USAGE
|
71
|
-
|
72
|
-
opt.on :l, :lines, 'The line (or range of lines) to replay.', true, :as => Range
|
73
|
-
opt.on :m, :method, 'Play a method.', true
|
74
|
-
opt.on :f, "file", 'The file to replay in context.', true
|
75
|
-
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.'
|
76
|
-
opt.on :h, :help, "This message." do
|
77
|
-
output.puts opt
|
78
|
-
end
|
13
|
+
create_command "show-input", "Show the contents of the input buffer for the current multi-line expression." do
|
14
|
+
def process
|
15
|
+
output.puts Code.new(eval_string).with_line_numbers
|
79
16
|
end
|
17
|
+
end
|
80
18
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
next unless meth.source
|
85
|
-
|
86
|
-
range = opts.l? ? one_index_range_or_number(opts[:l]) : (0..-1)
|
87
|
-
range = (0..-2) if opts.o?
|
19
|
+
create_command(/amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/) do
|
20
|
+
description "Amend a line of input in multi-line mode. Type `amend-line --help` for more information."
|
21
|
+
command_options :interpolate => false, :listing => "amend-line"
|
88
22
|
|
89
|
-
|
90
|
-
|
91
|
-
file_name = File.expand_path(opts[:f])
|
23
|
+
banner <<-'BANNER'
|
24
|
+
Amend a line of input in multi-line mode. `amend-line N`, where the N in `amend-line N` represents line to replace.
|
92
25
|
|
93
|
-
|
94
|
-
|
95
|
-
|
26
|
+
Can also specify a range of lines using `amend-line N..M` syntax. Passing '!' as replacement content deletes the line(s) instead.
|
27
|
+
e.g amend-line 1 puts 'hello world! # replace line 1'
|
28
|
+
e.g amend-line 1..4 ! # delete lines 1..4
|
29
|
+
e.g amend-line 3 >puts 'goodbye' # insert before line 3
|
30
|
+
e.g amend-line puts 'hello again' # no line number modifies immediately preceding line
|
31
|
+
BANNER
|
96
32
|
|
97
|
-
|
98
|
-
|
99
|
-
range = (0..-2) if opts.o?
|
33
|
+
def process
|
34
|
+
start_line_number, end_line_number, replacement_line = *args
|
100
35
|
|
101
|
-
|
102
|
-
|
103
|
-
else
|
104
|
-
if !args.first
|
105
|
-
raise CommandError, "No input to play command."
|
36
|
+
if eval_string.empty?
|
37
|
+
raise CommandError, "No input to amend."
|
106
38
|
end
|
107
39
|
|
108
|
-
|
40
|
+
replacement_line = "" if !replacement_line
|
41
|
+
input_array = eval_string.each_line.to_a
|
109
42
|
|
110
|
-
|
111
|
-
|
43
|
+
end_line_number = start_line_number.to_i if !end_line_number
|
44
|
+
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
|
112
45
|
|
113
|
-
|
46
|
+
# delete selected lines if replacement line is '!'
|
47
|
+
if arg_string == "!"
|
48
|
+
input_array.slice!(line_range)
|
49
|
+
elsif arg_string.start_with?(">")
|
50
|
+
insert_slot = Array(line_range).first
|
51
|
+
input_array.insert(insert_slot, arg_string[1..-1] + "\n")
|
52
|
+
else
|
53
|
+
input_array[line_range] = arg_string + "\n"
|
54
|
+
end
|
55
|
+
eval_string.replace input_array.join
|
56
|
+
run "show-input"
|
114
57
|
end
|
115
|
-
|
116
|
-
run "show-input" if !_pry_.valid_expression?(eval_string)
|
117
58
|
end
|
118
59
|
|
119
|
-
|
120
|
-
|
121
|
-
history = Pry.history.to_a[0..-2]
|
122
|
-
|
123
|
-
opts = Slop.parse!(args) do |opt|
|
124
|
-
opt.banner "Usage: hist [--replay START..END] [--clear] [--grep PATTERN] [--head N] [--tail N] [--help] [--save [START..END] file.txt]\n"
|
125
|
-
|
126
|
-
opt.on :n, 'no-numbers', 'Omit line numbers.'
|
127
|
-
|
128
|
-
opt.on :g, :grep, 'A pattern to match against the history.', true
|
60
|
+
create_command "play" do
|
61
|
+
description "Play back a string variable or a method or a file as input. Type `play --help` for more information."
|
129
62
|
|
130
|
-
|
131
|
-
|
132
|
-
:as => Integer
|
63
|
+
banner <<-BANNER
|
64
|
+
Usage: play [OPTIONS] [--help]
|
133
65
|
|
134
|
-
|
135
|
-
|
136
|
-
|
66
|
+
The play command enables you to replay code from files and methods as
|
67
|
+
if they were entered directly in the Pry REPL. Default action (no
|
68
|
+
options) is to play the provided string variable
|
137
69
|
|
138
|
-
|
139
|
-
|
140
|
-
|
70
|
+
e.g: `play -i 20 --lines 1..3`
|
71
|
+
e.g: `play -m Pry#repl --lines 1..-1`
|
72
|
+
e.g: `play -f Rakefile --lines 5`
|
141
73
|
|
142
|
-
|
74
|
+
https://github.com/pry/pry/wiki/User-Input#wiki-Play
|
75
|
+
BANNER
|
143
76
|
|
144
|
-
|
145
|
-
:as => Range
|
77
|
+
attr_accessor :content
|
146
78
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
opt.on :c, :clear, 'Clear the history.', :unless => :grep
|
79
|
+
def setup
|
80
|
+
self.content = ""
|
81
|
+
end
|
151
82
|
|
152
|
-
|
153
|
-
|
83
|
+
def options(opt)
|
84
|
+
opt.on :m, :method, "Play a method's source.", true do |meth_name|
|
85
|
+
meth = get_method_or_raise(meth_name, target, {})
|
86
|
+
self.content << meth.source
|
154
87
|
end
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
pattern = Regexp.new(arg_string.strip.split(/ /, 2).last.strip)
|
160
|
-
history.pop
|
161
|
-
|
162
|
-
history.map!.with_index do |element, index|
|
163
|
-
if element =~ pattern
|
164
|
-
if opts.n?
|
165
|
-
element
|
166
|
-
else
|
167
|
-
"#{text.blue index}: #{element}"
|
168
|
-
end
|
88
|
+
opt.on :d, :doc, "Play a method's documentation.", true do |meth_name|
|
89
|
+
meth = get_method_or_raise(meth_name, target, {})
|
90
|
+
text.no_color do
|
91
|
+
self.content << process_comment_markup(meth.doc, :ruby)
|
169
92
|
end
|
170
93
|
end
|
94
|
+
opt.on :c, :command, "Play a command's source.", true do |command_name|
|
95
|
+
command = find_command(command_name)
|
96
|
+
block = Pry::Method.new(find_command(command_name).block)
|
97
|
+
self.content << block.source
|
98
|
+
end
|
99
|
+
opt.on :f, :file, "Play a file.", true do |file|
|
100
|
+
self.content << File.read(File.expand_path(file))
|
101
|
+
end
|
102
|
+
opt.on :l, :lines, "Only play a subset of lines.", :optional => true, :as => Range, :default => 1..-1
|
103
|
+
opt.on :i, :in, "Play entries from Pry's input expression history. Takes an index or range.", :optional => true,
|
104
|
+
:as => Range, :default => -5..-1 do |range|
|
105
|
+
input_expressions = _pry_.input_array[range] || []
|
106
|
+
Array(input_expressions).each { |v| self.content << v }
|
107
|
+
end
|
108
|
+
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.'
|
109
|
+
end
|
171
110
|
|
172
|
-
|
173
|
-
|
111
|
+
def process
|
112
|
+
perform_play
|
113
|
+
run "show-input" unless _pry_.complete_expression?(eval_string)
|
174
114
|
end
|
175
115
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
stagger_output text.with_line_numbers(lines, 0)
|
116
|
+
def process_non_opt
|
117
|
+
args.each do |arg|
|
118
|
+
begin
|
119
|
+
self.content << target.eval(arg)
|
120
|
+
rescue Pry::RescuableException
|
121
|
+
raise CommandError, "Prblem when evaling #{arg}."
|
122
|
+
end
|
184
123
|
end
|
185
|
-
next
|
186
124
|
end
|
187
125
|
|
188
|
-
|
189
|
-
|
190
|
-
offset = history.size - limit
|
191
|
-
offset = offset < 0 ? 0 : offset
|
126
|
+
def perform_play
|
127
|
+
process_non_opt
|
192
128
|
|
193
|
-
|
194
|
-
|
195
|
-
if opts.n?
|
196
|
-
stagger_output lines
|
197
|
-
else
|
198
|
-
stagger_output text.with_line_numbers(lines, offset)
|
129
|
+
if opts.present?(:lines)
|
130
|
+
self.content = restrict_to_lines(self.content, opts[:l])
|
199
131
|
end
|
200
|
-
next
|
201
|
-
end
|
202
132
|
|
203
|
-
|
204
|
-
|
205
|
-
start_line = range.is_a?(Range) ? range.first : range
|
206
|
-
lines = Array(history[range]).join("\n")
|
207
|
-
if opts.n?
|
208
|
-
stagger_output lines
|
209
|
-
else
|
210
|
-
stagger_output text.with_line_numbers(lines, start_line)
|
133
|
+
if opts.present?(:open)
|
134
|
+
self.content = restrict_to_lines(self.content, 1..-2)
|
211
135
|
end
|
212
|
-
|
136
|
+
|
137
|
+
eval_string << self.content
|
213
138
|
end
|
139
|
+
end
|
214
140
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
141
|
+
create_command "hist", "Show and replay Readline history. Aliases: history" do
|
142
|
+
banner <<-USAGE
|
143
|
+
Usage: hist
|
144
|
+
hist --head N
|
145
|
+
hist --tail N
|
146
|
+
hist --show START..END
|
147
|
+
hist --grep PATTERN
|
148
|
+
hist --clear
|
149
|
+
hist --replay START..END
|
150
|
+
hist --save [START..END] FILE
|
151
|
+
USAGE
|
152
|
+
|
153
|
+
def options(opt)
|
154
|
+
opt.on :H, :head, "Display the first N items.", :optional => true, :as => Integer
|
155
|
+
opt.on :T, :tail, "Display the last N items.", :optional => true, :as => Integer
|
156
|
+
opt.on :s, :show, "Show the given range of lines.", :optional => true, :as => Range
|
157
|
+
opt.on :G, :grep, "Show lines matching the given pattern.", true, :as => String
|
158
|
+
opt.on :c, :clear, "Clear the current session's history."
|
159
|
+
opt.on :r, :replay, "Replay a line or range of lines.", true, :as => Range
|
160
|
+
opt.on :save, "Save history to a file.", true, :as => Range
|
161
|
+
|
162
|
+
opt.on :e, :'exclude-pry', "Exclude Pry commands from the history."
|
163
|
+
opt.on :n, :'no-numbers', "Omit line numbers."
|
164
|
+
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
165
|
+
end
|
166
|
+
|
167
|
+
def process
|
168
|
+
@history = Pry::Code(Pry.history.to_a)
|
169
|
+
|
170
|
+
@history = case
|
171
|
+
when opts.present?(:head)
|
172
|
+
@history.between(1, opts[:head] || 10)
|
173
|
+
when opts.present?(:tail)
|
174
|
+
@history.between(-(opts[:tail] || 10), -1)
|
175
|
+
when opts.present?(:show)
|
176
|
+
@history.between(opts[:show])
|
177
|
+
else
|
178
|
+
@history
|
223
179
|
end
|
180
|
+
|
181
|
+
if opts.present?(:grep)
|
182
|
+
@history = @history.grep(opts[:grep])
|
224
183
|
end
|
225
|
-
stagger_output history.compact.join "\n"
|
226
|
-
next
|
227
|
-
end
|
228
184
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
_pry_.input_stack << _pry_.input
|
233
|
-
_pry_.input = StringIO.new(actions)
|
234
|
-
next
|
235
|
-
end
|
185
|
+
if opts.present?(:'exclude-pry')
|
186
|
+
@history = @history.select { |l, ln| !command_set.valid_command?(l) }
|
187
|
+
end
|
236
188
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
189
|
+
if opts.present?(:save)
|
190
|
+
process_save
|
191
|
+
elsif opts.present?(:clear)
|
192
|
+
process_clear
|
193
|
+
elsif opts.present?(:replay)
|
194
|
+
process_replay
|
195
|
+
else
|
196
|
+
process_display
|
197
|
+
end
|
241
198
|
end
|
242
199
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
200
|
+
def process_display
|
201
|
+
unless opts.present?(:'no-numbers')
|
202
|
+
@history = @history.with_line_numbers
|
203
|
+
end
|
204
|
+
|
205
|
+
render_output(@history, opts)
|
206
|
+
end
|
247
207
|
|
248
|
-
|
208
|
+
def process_save
|
209
|
+
case opts[:save]
|
249
210
|
when Range
|
250
|
-
|
211
|
+
@history = @history.between(opts[:save])
|
251
212
|
|
252
|
-
|
213
|
+
unless args.first
|
253
214
|
raise CommandError, "Must provide a file name."
|
254
215
|
end
|
255
216
|
|
256
217
|
file_name = File.expand_path(args.first)
|
257
218
|
when String
|
258
|
-
|
259
|
-
file_name = File.expand_path(opts["save"])
|
219
|
+
file_name = File.expand_path(opts[:save])
|
260
220
|
end
|
261
221
|
|
262
|
-
output.puts "Saving history in #{file_name}
|
263
|
-
# exclude pry commands
|
264
|
-
hist_array.reject! do |element|
|
265
|
-
command_processor.valid_command?(element)
|
266
|
-
end
|
222
|
+
output.puts "Saving history in #{file_name}..."
|
267
223
|
|
268
|
-
File.open(file_name, 'w')
|
269
|
-
f.write hist_array.join("\n")
|
270
|
-
end
|
224
|
+
File.open(file_name, 'w') { |f| f.write(@history.to_s) }
|
271
225
|
|
272
|
-
output.puts "
|
273
|
-
next
|
226
|
+
output.puts "History saved."
|
274
227
|
end
|
275
228
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
else
|
280
|
-
stagger_output text.with_line_numbers(lines, 0)
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
alias_command "history", "hist"
|
285
|
-
|
286
|
-
helpers do
|
287
|
-
def one_index_number(line_number)
|
288
|
-
if line_number > 0
|
289
|
-
line_number - 1
|
290
|
-
elsif line_number < 0
|
291
|
-
line_number
|
292
|
-
else
|
293
|
-
line_number
|
294
|
-
end
|
229
|
+
def process_clear
|
230
|
+
Pry.history.clear
|
231
|
+
output.puts "History cleared."
|
295
232
|
end
|
296
233
|
|
297
|
-
def
|
298
|
-
|
299
|
-
end
|
234
|
+
def process_replay
|
235
|
+
@history = @history.between(opts[:r])
|
300
236
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
else
|
306
|
-
one_index_number(range_or_number)
|
307
|
-
end
|
237
|
+
_pry_.input_stack.push _pry_.input
|
238
|
+
_pry_.input = StringIO.new(@history.raw)
|
239
|
+
# eval_string << "#{@history.raw}\n"
|
240
|
+
# run "show-input" unless _pry_.complete_expression?(eval_string)
|
308
241
|
end
|
309
|
-
|
310
242
|
end
|
311
243
|
|
244
|
+
alias_command "history", "hist"
|
312
245
|
end
|
313
|
-
|
314
246
|
end
|
315
247
|
end
|