pry 0.9.0pre3-i386-mingw32 → 0.9.1-i386-mingw32

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/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.6.0")
26
- s.add_dependency("method_source",">=0.4.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}-#{spec.version}.gemspec", "w") do |f|
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", "jruby:gem", "mswin32:gem", "mingw32: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
- if Pry.color
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, binding)[0])
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
- # reevaluated in.
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] && (command_regex =~ interp_val)
60
- val.replace interp_val
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].strip
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
@@ -22,8 +22,5 @@ class Pry
22
22
  import DefaultCommands::Shell
23
23
  import DefaultCommands::Introspection
24
24
  import DefaultCommands::EasterEggs
25
-
26
- # Helpers::CommandHelpers.try_to_load_pry_doc
27
-
28
25
  end
29
26
  end
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.load is a boolean that determines whether history will be
78
+ # hist.should_load is a boolean that determines whether history will be
79
79
  # loaded from hist.file at session start.
80
- # hist.save is a boolean that determines whether history will be
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 _out_
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
 
@@ -67,6 +67,7 @@ class Pry
67
67
  alias_command "!!@", "exit-all", ""
68
68
 
69
69
  command "exit-program", "End the current program. Aliases: quit-program, !!!" do
70
+ Pry.active_instance.save_history if Pry.config.history.should_save
70
71
  exit
71
72
  end
72
73
 
@@ -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
- code, code_type = code_and_code_type_for(meth)
77
- next if !code
78
- doc, code_type = doc_and_code_type_for(meth)
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 make_header(meth, code_type, code)
81
- output.puts text.bold("Method Name: ") + meth_name
82
- output.puts text.bold("Method Owner: ") + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
83
- output.puts text.bold("Method Language: ") + code_type.to_s.capitalize
84
- output.puts text.bold("Method Type: ") + (meth.is_a?(Method) ? "Bound" : "Unbound")
85
- output.puts text.bold("Method Arity: ") + meth.arity.to_s
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 text.bold("Method Parameters: ") + meth.parameters.group_by(&:first).
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
- output.puts text.bold("Comment length: ") + (doc.empty? ? 'No comment.' : (doc.lines.count.to_s + ' lines.'))
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 eval_string" do
12
- render_output(false, 0, Pry.color ? CodeRay.scan(eval_string, :ruby).term : eval_string)
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-?(\d+)?/, "Experimental amend-line, where the N in amend-line-N represents line to replace. Aliases: %N",
16
- :interpolate => false, :listing => "amend-line-N") do |line_number, replacement_line|
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
- line_num = line_number ? line_number.to_i : input_array.size - 1
20
- input_array[line_num] = arg_string + "\n"
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(/%(\d+)?/, /amend-line-?(\d+)?/, "")
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
- Slop.parse(args) do |opt|
28
- history = Readline::HISTORY.to_a
29
- opt.banner "Usage: hist [--replay START..END] [--clear] [--grep PATTERN] [--head N] [--tail N] [--help]\n"
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(/ /)[1]
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', :optional => true, :as => Integer do |limit|
45
- unless opt.grep?
46
- limit ||= 10
47
- list = history.first limit
48
- lines = text.with_line_numbers list.join("\n"), 0
49
- stagger_output lines
50
- end
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', :optional => true, :as => Integer do |limit|
54
- unless opt.grep?
55
- limit ||= 10
56
- offset = history.size-limit
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
- list = history.last limit
60
- lines = text.with_line_numbers list.join("\n"), offset
61
- stagger_output lines
62
- end
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).', true, :as => Range do |range|
66
- unless opt.grep?
67
- start_line = range.is_a?(Range) ? range.first : range
68
- lines = text.with_line_numbers Array(history[range]).join("\n"), start_line
69
- stagger_output lines
70
- end
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
- unless opt.grep?
75
- history.map!.with_index do |element, index|
76
- unless command_processor.valid_command? element
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.', true, :as => Range do |range|
85
- unless opt.grep?
86
- actions = Array(history[range]).join("\n") + "\n"
87
- Pry.active_instance.input = StringIO.new(actions)
88
- end
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 :c, :clear, 'Clear the history' do
92
- unless opt.grep?
93
- Readline::HISTORY.shift until Readline::HISTORY.empty?
94
- output.puts 'History cleared.'
95
- end
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
- unless opt.grep?
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