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.
Files changed (65) hide show
  1. data/.gitignore +2 -3
  2. data/CHANGELOG +43 -0
  3. data/README.markdown +3 -1
  4. data/Rakefile +51 -32
  5. data/bin/pry +2 -80
  6. data/lib/pry.rb +33 -26
  7. data/lib/pry/cli.rb +152 -0
  8. data/lib/pry/code.rb +351 -0
  9. data/lib/pry/command.rb +422 -0
  10. data/lib/pry/command_set.rb +259 -129
  11. data/lib/pry/commands.rb +0 -1
  12. data/lib/pry/config.rb +43 -9
  13. data/lib/pry/default_commands/context.rb +109 -92
  14. data/lib/pry/default_commands/documentation.rb +174 -63
  15. data/lib/pry/default_commands/easter_eggs.rb +26 -2
  16. data/lib/pry/default_commands/gems.rb +65 -37
  17. data/lib/pry/default_commands/input.rb +175 -243
  18. data/lib/pry/default_commands/introspection.rb +173 -112
  19. data/lib/pry/default_commands/ls.rb +96 -114
  20. data/lib/pry/default_commands/shell.rb +175 -70
  21. data/lib/pry/helpers/base_helpers.rb +7 -2
  22. data/lib/pry/helpers/command_helpers.rb +71 -77
  23. data/lib/pry/helpers/options_helpers.rb +10 -41
  24. data/lib/pry/helpers/text.rb +24 -4
  25. data/lib/pry/history.rb +55 -17
  26. data/lib/pry/history_array.rb +2 -0
  27. data/lib/pry/hooks.rb +252 -0
  28. data/lib/pry/indent.rb +9 -5
  29. data/lib/pry/method.rb +149 -50
  30. data/lib/pry/plugins.rb +12 -4
  31. data/lib/pry/pry_class.rb +69 -26
  32. data/lib/pry/pry_instance.rb +187 -115
  33. data/lib/pry/version.rb +1 -1
  34. data/lib/pry/wrapped_module.rb +73 -0
  35. data/man/pry.1 +195 -0
  36. data/man/pry.1.html +204 -0
  37. data/man/pry.1.ronn +141 -0
  38. data/pry.gemspec +29 -32
  39. data/test/helper.rb +32 -36
  40. data/test/test_cli.rb +78 -0
  41. data/test/test_code.rb +201 -0
  42. data/test/test_command.rb +327 -0
  43. data/test/test_command_integration.rb +512 -0
  44. data/test/test_command_set.rb +338 -12
  45. data/test/test_completion.rb +1 -1
  46. data/test/test_default_commands.rb +1 -2
  47. data/test/test_default_commands/test_context.rb +27 -5
  48. data/test/test_default_commands/test_documentation.rb +20 -8
  49. data/test/test_default_commands/test_input.rb +84 -45
  50. data/test/test_default_commands/test_introspection.rb +74 -17
  51. data/test/test_default_commands/test_ls.rb +9 -36
  52. data/test/test_default_commands/test_shell.rb +240 -13
  53. data/test/test_hooks.rb +490 -0
  54. data/test/test_indent.rb +2 -0
  55. data/test/test_method.rb +60 -0
  56. data/test/test_pry.rb +29 -904
  57. data/test/test_pry_defaults.rb +380 -0
  58. data/test/test_pry_history.rb +24 -24
  59. data/test/test_syntax_checking.rb +63 -0
  60. data/test/test_wrapped_module.rb +71 -0
  61. metadata +50 -39
  62. data/lib/pry/command_context.rb +0 -53
  63. data/lib/pry/command_processor.rb +0 -181
  64. data/lib/pry/extended_commands/user_command_api.rb +0 -65
  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
- end
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
- command "gem-install", "Install a gem and refresh the gem cache.", :argument_required => true do |gem|
7
- require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
8
- begin
9
- destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir
10
- installer = Gem::DependencyInstaller.new :install_dir => destination
11
- installer.install gem
12
- rescue Errno::EACCES
13
- raise CommandError, "Insufficient permissions to install `#{text.green gem}`."
14
- rescue Gem::GemNotFoundException
15
- raise CommandError, "Gem `#{text.green gem}` not found."
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
- command "gem-cd", "Change working directory to specified gem's directory.", :argument_required => true do |gem|
23
- specs = Gem::Specification.respond_to?(:each) ? Gem::Specification.find_all_by_name(gem) : Gem.source_index.find_name(gem)
24
- spec = specs.sort { |a,b| Gem::Version.new(b.version) <=> Gem::Version.new(a.version) }.first
25
- if spec
26
- Dir.chdir(spec.full_gem_path)
27
- else
28
- raise CommandError, "Gem `#{gem}` not found."
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
- command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |pattern|
33
- pattern = Regexp.new pattern.to_s, Regexp::IGNORECASE
34
- gems = if Gem::Specification.respond_to?(:each)
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
- versions = specs.each_with_index.map do |spec, index|
46
- index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s)
47
- end
38
+ Change the current working directory to that in which the given gem is installed.
39
+ BANNER
48
40
 
49
- output.puts "#{text.default gem} (#{versions.join ', '})"
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
- 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
- output.puts "Input buffer cleared!"
8
- eval_string.replace("")
9
- end
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
- alias_command(/%.?(-?\d+)?(?:\.\.(-?\d+))?/, /amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/)
61
-
62
- command "play", "Play back a string variable or a method or a file as input. Type `play --help` for more information." do |*args|
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
- if opts.m?
82
- meth_name = opts[:m]
83
- meth = get_method_or_raise(meth_name, target, {}, :omit_help)
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
- eval_string << Array(meth.source.each_line.to_a[range]).join
90
- elsif opts.f?
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
- if !File.exists?(file_name)
94
- raise CommandError, "No such file: #{opts[:f]}"
95
- end
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
- text_array = File.readlines(file_name)
98
- range = opts.l? ? one_index_range_or_number(opts[:l]) : (0..-1)
99
- range = (0..-2) if opts.o?
33
+ def process
34
+ start_line_number, end_line_number, replacement_line = *args
100
35
 
101
- _pry_.input_stack << _pry_.input
102
- _pry_.input = StringIO.new(Array(text_array[range]).join)
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
- code = target.eval(args.first)
40
+ replacement_line = "" if !replacement_line
41
+ input_array = eval_string.each_line.to_a
109
42
 
110
- range = opts.l? ? one_index_range_or_number(opts[:l]) : (0..-1)
111
- range = (0..-2) if opts.o?
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
- eval_string << Array(code.each_line.to_a[range]).join
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
- command "hist", "Show and replay Readline history. Type `hist --help` for more info. Aliases: history" do |*args|
120
- # exclude the current command from history.
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
- opt.on :head, 'Display the first N items of history.',
131
- :optional => true,
132
- :as => Integer
63
+ banner <<-BANNER
64
+ Usage: play [OPTIONS] [--help]
133
65
 
134
- opt.on :t, :tail, 'Display the last N items of history.',
135
- :optional => true,
136
- :as => Integer
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
- opt.on :s, :show, 'Show the history corresponding to the history line (or range of lines).',
139
- :optional => true,
140
- :as => Range
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
- opt.on :e, :exclude, 'Exclude pry commands from the history.'
74
+ https://github.com/pry/pry/wiki/User-Input#wiki-Play
75
+ BANNER
143
76
 
144
- opt.on :r, :replay, 'The line (or range of lines) to replay.', true,
145
- :as => Range
77
+ attr_accessor :content
146
78
 
147
- opt.on "save", "Save history to a file. --save [start..end] output.txt. Pry commands are excluded from saved history.", true,
148
- :as => Range
149
-
150
- opt.on :c, :clear, 'Clear the history.', :unless => :grep
79
+ def setup
80
+ self.content = ""
81
+ end
151
82
 
152
- opt.on :h, :help, 'Show this message.', :tail => true, :unless => :grep do
153
- output.puts opt.help
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
- end
156
- next if opts.help?
157
-
158
- if opts.grep?
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
- stagger_output history.compact.join "\n"
173
- next
111
+ def process
112
+ perform_play
113
+ run "show-input" unless _pry_.complete_expression?(eval_string)
174
114
  end
175
115
 
176
- if opts.head?
177
- limit = opts['head'] || 10
178
- list = history.first limit
179
- lines = list.join("\n")
180
- if opts.n?
181
- stagger_output lines
182
- else
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
- if opts.tail?
189
- limit = opts['tail'] || 10
190
- offset = history.size - limit
191
- offset = offset < 0 ? 0 : offset
126
+ def perform_play
127
+ process_non_opt
192
128
 
193
- list = history.last limit
194
- lines = list.join("\n")
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
- if opts.show?
204
- range = opts['show']
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
- next
136
+
137
+ eval_string << self.content
213
138
  end
139
+ end
214
140
 
215
- if opts.exclude?
216
- history.map!.with_index do |element, index|
217
- unless command_processor.valid_command? element
218
- if opts.n?
219
- element
220
- else
221
- "#{text.blue index}: #{element}"
222
- end
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
- if opts.replay?
230
- range = opts['replay']
231
- actions = Array(history[range]).join("\n") + "\n"
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
- if opts.clear?
238
- Pry.history.clear
239
- output.puts 'History cleared.'
240
- next
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
- # FIXME: hack to save history (this must be refactored)
244
- if opts["save"]
245
- file_name = nil
246
- hist_array = nil
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
- case opts["save"]
208
+ def process_save
209
+ case opts[:save]
249
210
  when Range
250
- hist_array = Array(history[opts["save"]])
211
+ @history = @history.between(opts[:save])
251
212
 
252
- if !args.first
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
- hist_array = history
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') do |f|
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 "... history saved."
273
- next
226
+ output.puts "History saved."
274
227
  end
275
228
 
276
- lines = history.join("\n")
277
- if opts.n?
278
- stagger_output lines
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 one_index_range(range)
298
- Range.new(one_index_number(range.begin), one_index_number(range.end))
299
- end
234
+ def process_replay
235
+ @history = @history.between(opts[:r])
300
236
 
301
- def one_index_range_or_number(range_or_number)
302
- case range_or_number
303
- when Range
304
- one_index_range(range_or_number)
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