pry 0.8.4pre1-i386-mswin32 → 0.9.0-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 (60) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG +25 -6
  3. data/README.markdown +11 -4
  4. data/Rakefile +15 -19
  5. data/TODO +28 -2
  6. data/bin/pry +28 -11
  7. data/examples/example_basic.rb +2 -4
  8. data/examples/example_command_override.rb +2 -5
  9. data/examples/example_commands.rb +1 -4
  10. data/examples/example_hooks.rb +2 -5
  11. data/examples/example_image_edit.rb +4 -8
  12. data/examples/example_input.rb +1 -4
  13. data/examples/example_input2.rb +1 -4
  14. data/examples/example_output.rb +1 -4
  15. data/examples/example_print.rb +2 -5
  16. data/examples/example_prompt.rb +2 -5
  17. data/examples/helper.rb +6 -0
  18. data/lib/pry.rb +59 -3
  19. data/lib/pry/command_context.rb +10 -9
  20. data/lib/pry/command_processor.rb +51 -73
  21. data/lib/pry/command_set.rb +79 -28
  22. data/lib/pry/commands.rb +9 -123
  23. data/lib/pry/completion.rb +30 -29
  24. data/lib/pry/config.rb +100 -0
  25. data/lib/pry/default_commands/basic.rb +37 -0
  26. data/lib/pry/default_commands/context.rb +16 -15
  27. data/lib/pry/default_commands/documentation.rb +73 -54
  28. data/lib/pry/default_commands/easter_eggs.rb +1 -20
  29. data/lib/pry/default_commands/gems.rb +31 -40
  30. data/lib/pry/default_commands/input.rb +223 -15
  31. data/lib/pry/default_commands/introspection.rb +108 -73
  32. data/lib/pry/default_commands/ls.rb +25 -11
  33. data/lib/pry/default_commands/shell.rb +29 -39
  34. data/lib/pry/extended_commands/experimental.rb +17 -0
  35. data/lib/pry/extended_commands/user_command_api.rb +22 -0
  36. data/lib/pry/helpers.rb +1 -0
  37. data/lib/pry/helpers/base_helpers.rb +15 -104
  38. data/lib/pry/helpers/command_helpers.rb +96 -59
  39. data/lib/pry/helpers/text.rb +83 -0
  40. data/lib/pry/history_array.rb +105 -0
  41. data/lib/pry/plugins.rb +79 -0
  42. data/lib/pry/pry_class.rb +102 -114
  43. data/lib/pry/pry_instance.rb +123 -55
  44. data/lib/pry/version.rb +1 -1
  45. data/pry.gemspec +45 -0
  46. data/test/helper.rb +57 -7
  47. data/test/test_command_processor.rb +205 -0
  48. data/test/{test_commandset.rb → test_command_set.rb} +18 -12
  49. data/test/test_default_commands.rb +59 -0
  50. data/test/test_default_commands/test_context.rb +64 -0
  51. data/test/test_default_commands/test_documentation.rb +31 -0
  52. data/test/test_default_commands/test_gems.rb +14 -0
  53. data/test/test_default_commands/test_input.rb +327 -0
  54. data/test/test_default_commands/test_introspection.rb +155 -0
  55. data/test/test_history_array.rb +65 -0
  56. data/test/test_pry.rb +548 -313
  57. metadata +48 -15
  58. data/lib/pry/hooks.rb +0 -17
  59. data/lib/pry/print.rb +0 -16
  60. data/lib/pry/prompts.rb +0 -31
@@ -1,26 +1,7 @@
1
1
  class Pry
2
2
  module DefaultCommands
3
3
 
4
- EasterEggs = Pry::CommandSet.new :easter_eggs do
5
-
6
- command "game", "" do |highest|
7
- highest = highest ? highest.to_i : 100
8
- num = rand(highest)
9
- output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
10
- count = 0
11
- while(true)
12
- count += 1
13
- str = Readline.readline("game > ", true)
14
- break if str == "." || !str
15
- val = str.to_i
16
- output.puts "Too large!" if val > num
17
- output.puts "Too small!" if val < num
18
- if val == num
19
- output.puts "Well done! You guessed right! It took you #{count} guesses."
20
- break
21
- end
22
- end
23
- end
4
+ EasterEggs = Pry::CommandSet.new do
24
5
 
25
6
  command "east-coker", "" do
26
7
  text = %{
@@ -1,56 +1,47 @@
1
1
  class Pry
2
2
  module DefaultCommands
3
3
 
4
- Gems = Pry::CommandSet.new :gems do
5
-
6
- command "gem-install", "Install a gem and refresh the gem cache." do |gem_name|
7
- gem_home = Gem.instance_variable_get(:@gem_home)
8
- output.puts "Attempting to install gem: #{bold(gem_name)}"
4
+ Gems = Pry::CommandSet.new do
9
5
 
6
+ command "gem-install", "Install a gem and refresh the gem cache.", :argument_required => true do |gem|
10
7
  begin
11
- if File.writable?(gem_home)
12
- Gem::DependencyInstaller.new.install(gem_name)
13
- output.puts "Gem #{bold(gem_name)} successfully installed."
14
- else
15
- if system("sudo gem install #{gem_name}")
16
- output.puts "Gem #{bold(gem_name)} successfully installed."
17
- else
18
- output.puts "Gem #{bold(gem_name)} could not be installed."
19
- next
20
- end
21
- end
8
+ destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir
9
+ installer = Gem::DependencyInstaller.new :install_dir => destination
10
+ installer.install gem
11
+ rescue Errno::EACCES
12
+ output.puts "Insufficient permissions to install `#{text.green gem}`"
22
13
  rescue Gem::GemNotFoundException
23
- output.puts "Required Gem: #{bold(gem_name)} not found."
24
- next
14
+ output.puts "Gem `#{text.green gem}` not found."
15
+ else
16
+ Gem.refresh
17
+ output.puts "Gem `#{text.green gem}` installed."
25
18
  end
26
-
27
- Gem.refresh
28
- output.puts "Refreshed gem cache."
29
19
  end
30
20
 
31
- command "gem-cd", "Change working directory to specified gem's directory." do |gem_name|
32
- require 'rubygems'
33
- gem_spec = Gem.source_index.find_name(gem_name).first
34
- next output.puts("Gem `#{gem_name}` not found.") if !gem_spec
35
- Dir.chdir(File.expand_path(gem_spec.full_gem_path))
21
+ command "gem-cd", "Change working directory to specified gem's directory.", :argument_required => true do |gem|
22
+ specs = Gem::Specification.respond_to?(:each) ? Gem::Specification.find_all_by_name(gem) : Gem.source_index.find_name(gem)
23
+ spec = specs.sort { |a,b| Gem::Version.new(b.version) <=> Gem::Version.new(a.version) }.first
24
+ spec ? Dir.chdir(spec.full_gem_path) : output.puts("Gem `#{gem}` not found.")
36
25
  end
37
26
 
27
+ command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |pattern|
28
+ pattern = Regexp.new pattern.to_s, Regexp::IGNORECASE
29
+ gems = if Gem::Specification.respond_to?(:each)
30
+ Gem::Specification.select{|spec| spec.name =~ pattern }.group_by(&:name)
31
+ else
32
+ Gem.source_index.gems.values.group_by(&:name).select { |gemname, specs| gemname =~ pattern }
33
+ end
34
+
35
+ gems.each do |gem, specs|
36
+ specs.sort! do |a,b|
37
+ Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
38
+ end
38
39
 
39
- command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |arg|
40
- gems = Gem.source_index.gems.values.group_by(&:name)
41
- if arg
42
- query = Regexp.new(arg, Regexp::IGNORECASE)
43
- gems = gems.select { |gemname, specs| gemname =~ query }
44
- end
45
-
46
- gems.each do |gemname, specs|
47
- versions = specs.map(&:version).sort.reverse.map(&:to_s)
48
- versions = ["<bright_green>#{versions.first}</bright_green>"] +
49
- versions[1..-1].map{|v| "<green>#{v}</green>" }
40
+ versions = specs.each_with_index.map do |spec, index|
41
+ index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s)
42
+ end
50
43
 
51
- gemname = highlight(gemname, query) if query
52
- result = "<white>#{gemname} <grey>(#{versions.join ', '})</grey>"
53
- output.puts colorize(result)
44
+ output.puts "#{text.white gem} (#{versions.join ', '})"
54
45
  end
55
46
  end
56
47
 
@@ -1,37 +1,245 @@
1
1
  class Pry
2
2
  module DefaultCommands
3
3
 
4
- Input = Pry::CommandSet.new :input do
4
+ Input = Pry::CommandSet.new do
5
5
 
6
6
  command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
7
7
  output.puts "Input buffer cleared!"
8
- opts[:eval_string].clear
8
+ eval_string.replace("")
9
9
  end
10
10
 
11
- command "hist", "Show and replay Readline history. When given no args history is displayed.\nType `hist --help` for more info." do |*args|
12
- hist_array = Readline::HISTORY.to_a
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 %{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
+
36
+ replacement_line = "" if !replacement_line
37
+ input_array = eval_string.each_line.to_a
13
38
 
14
- if args.empty?
15
- text = add_line_numbers(hist_array.join("\n"), 0)
16
- stagger_output(text)
17
- next
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"
18
50
  end
51
+ eval_string.replace input_array.join
52
+ run "show-input"
53
+ end
54
+
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
97
+
98
+ command "hist", "Show and replay Readline history. Type `hist --help` for more info." do |*args|
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"
103
+
104
+ opt.on :g, :grep, 'A pattern to match against the history.', true do |pattern|
105
+ pattern = Regexp.new arg_string.strip.split(/ /, 2).last.strip
106
+ history.pop
107
+
108
+ history.map!.with_index do |element, index|
109
+ if element =~ pattern
110
+ "#{text.blue index}: #{element}"
111
+ end
112
+ end
113
+
114
+ stagger_output history.compact.join "\n"
115
+ end
116
+
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
126
+ end
19
127
 
20
- opts = Slop.parse(args) do |opt|
21
- opt.banner "Usage: hist [--replay START..END]\nView and replay history\nWhen given no args, history is displayed.\ne.g hist --replay 2..8"
22
- opt.on :r, :replay, 'The line (or range of lines) to replay.', true, :as => Range
23
- opt.on :h, :help, 'Show this message.', :tail => true do
128
+ opt.on :t, :tail, 'Display the last N items of history',
129
+ :optional => true,
130
+ :as => Integer,
131
+ :unless => :grep do |limit|
132
+
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
140
+ end
141
+
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
150
+ end
151
+
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}"
156
+ end
157
+ end
158
+ stagger_output history.compact.join "\n"
159
+ end
160
+
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)
167
+ end
168
+
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.'
174
+ end
175
+
176
+ opt.on :h, :help, 'Show this message.', :tail => true, :unless => :grep do
24
177
  output.puts opt.help
25
178
  end
179
+
180
+ opt.on_empty do
181
+ lines = text.with_line_numbers history.join("\n"), 0
182
+ stagger_output lines
183
+ end
26
184
  end
27
185
 
28
- next if opts.h?
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
29
213
 
30
- actions = Array(hist_array[opts[:replay]]).join("\n") + "\n"
31
- Pry.active_instance.input = StringIO.new(actions)
32
214
  end
33
215
 
34
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
+
241
+ end
242
+
35
243
  end
36
244
 
37
245
  end
@@ -1,26 +1,27 @@
1
1
  class Pry
2
2
  module DefaultCommands
3
3
 
4
- Introspection = Pry::CommandSet.new :introspection do
4
+ Introspection = Pry::CommandSet.new do
5
5
 
6
6
  command "show-method", "Show the source for METH. Type `show-method --help` for more info. Aliases: $, show-source" do |*args|
7
7
  target = target()
8
8
 
9
- opts = Slop.parse!(args) do |opts|
10
- opts.banner %{Usage: show-method [OPTIONS] [METH]
11
- Show the source for method METH. Tries instance methods first and then methods by default.
12
- e.g: show-method hello_method
13
- --
14
- }
15
- opts.on :l, "line-numbers", "Show line numbers."
16
- opts.on :M, "instance-methods", "Operate on instance methods."
17
- opts.on :m, :methods, "Operate on methods."
18
- opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
19
- opts.on :c, :context, "Select object context to run under.", true do |context|
9
+ opts = Slop.parse!(args) do |opt|
10
+ opt.banner "Usage: show-method [OPTIONS] [METH]\n" \
11
+ "Show the source for method METH. Tries instance methods first and then methods by default.\n" \
12
+ "e.g: show-method hello_method"
13
+
14
+ opt.on :l, "line-numbers", "Show line numbers."
15
+ opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)."
16
+
17
+ opt.on :M, "instance-methods", "Operate on instance methods."
18
+ opt.on :m, :methods, "Operate on methods."
19
+ opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
20
+ opt.on :c, :context, "Select object context to run under.", true do |context|
20
21
  target = Pry.binding_for(target.eval(context))
21
22
  end
22
- opts.on :h, :help, "This message." do
23
- output.puts opts
23
+ opt.on :h, :help, "This message." do
24
+ output.puts opt
24
25
  end
25
26
  end
26
27
 
@@ -45,6 +46,9 @@ e.g: show-method hello_method
45
46
  start_line = meth.source_location ? meth.source_location.last : 1
46
47
  end
47
48
 
49
+ start_line = opts.b? ? 1 : start_line
50
+
51
+
48
52
  render_output(opts.flood?, start_line, code)
49
53
  code
50
54
  end
@@ -53,79 +57,103 @@ e.g: show-method hello_method
53
57
  alias_command "$", "show-method", ""
54
58
 
55
59
  command "show-command", "Show the source for CMD. Type `show-command --help` for more info." do |*args|
56
- options = {}
57
60
  target = target()
58
- command_name = nil
59
-
60
- OptionParser.new do |opts|
61
- opts.banner = %{Usage: show-command [OPTIONS] [CMD]
62
- Show the source for command CMD.
63
- e.g: show-command show-method
64
- --
65
- }
66
- opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
67
- options[:l] = true
68
- end
69
61
 
70
- opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
71
- options[:f] = true
72
- end
62
+ opts = Slop.parse!(args) do |opt|
63
+ opt.banner = "Usage: show-command [OPTIONS] [CMD]\n" \
64
+ "Show the source for command CMD.\n" \
65
+ "e.g: show-command show-method"
73
66
 
74
- opts.on_tail("-h", "--help", "This message.") do
75
- output.puts opts
76
- options[:h] = true
67
+ opt.on :l, "line-numbers", "Show line numbers."
68
+ opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
69
+ opt.on :h, :help, "This message." do
70
+ output.puts opt
77
71
  end
78
- end.order(args) do |v|
79
- command_name = v
80
72
  end
81
73
 
82
- next if options[:h]
74
+ next if opts.help?
83
75
 
76
+ command_name = args.shift
84
77
  if !command_name
85
78
  output.puts "You must provide a command name."
86
79
  next
87
80
  end
88
81
 
89
- if commands[command_name]
90
- meth = commands[command_name].block
82
+ if find_command(command_name)
83
+ block = find_command(command_name).block
91
84
 
92
- code = strip_leading_whitespace(meth.source)
93
- file, line = meth.source_location
94
- set_file_and_dir_locals(file)
95
- check_for_dynamically_defined_method(meth)
85
+ code, _ = code_and_code_type_for(block)
86
+ next if !code
96
87
 
97
- output.puts make_header(meth, :ruby, code)
88
+ output.puts make_header(block, :ruby, code)
98
89
 
99
90
  if Pry.color
100
91
  code = CodeRay.scan(code, :ruby).term
101
92
  end
102
93
 
103
- render_output(options[:f], options[:l] ? meth.source_location.last : false, code)
94
+ start_line = false
95
+ if opts.l?
96
+ start_line = block.source_location ? block.source_location.last : 1
97
+ end
98
+
99
+ render_output(opts.flood?, opts.l? ? block.source_location.last : false, code)
104
100
  code
105
101
  else
106
102
  output.puts "No such command: #{command_name}."
107
103
  end
108
104
  end
109
105
 
106
+ command "edit", "Invoke the default editor on a file. Type `edit --help` for more info" do |*args|
107
+ opts = Slop.parse!(args) do |opt|
108
+ opt.banner "Usage: edit [OPTIONS] [FILE]\n" \
109
+ "Edit the method FILE in an editor.\n" \
110
+ "Ensure #{text.bold("Pry.editor")} is set to your editor of choice.\n" \
111
+ "e.g: edit sample.rb"
112
+
113
+ opt.on :r, "reload", "Eval file content after editing (using `load`)"
114
+ opt.on :p, "play", "Use the pry `play` command to eval the file content after editing (instead of the `load` method)."
115
+ opt.on :l, "line", "Specify line number to jump to in file", true, :as => Integer
116
+ opt.on :h, :help, "This message." do
117
+ output.puts opt
118
+ end
119
+ end
120
+ next if opts.h?
121
+
122
+ next output.puts("Need to specify a file.") if !args.first
123
+ file_name = File.expand_path(args.first)
124
+
125
+ invoke_editor(file_name, opts[:l].to_i)
126
+ set_file_and_dir_locals(file_name)
127
+
128
+ if opts[:r]
129
+ silence_warnings do
130
+ load file_name
131
+ end
132
+ elsif opts[:p]
133
+ silence_warnings do
134
+ Pry.active_instance.input = StringIO.new(File.readlines(file_name).join)
135
+ end
136
+ end
137
+ end
138
+
110
139
  command "edit-method", "Edit a method. Type `edit-method --help` for more info." do |*args|
111
140
  target = target()
112
141
 
113
- opts = Slop.parse!(args) do |opts|
114
- opts.banner %{Usage: edit-method [OPTIONS] [METH]
115
- Edit the method METH in an editor.
116
- Ensure #{bold("Pry.editor")} is set to your editor of choice.
117
- e.g: edit-method hello_method
118
- --
119
- }
120
- opts.on :M, "instance-methods", "Operate on instance methods."
121
- opts.on :m, :methods, "Operate on methods."
122
- opts.on "no-reload", "Do not automatically reload the method's file after editting."
123
- opts.on :n, "no-jump", "Do not fast forward editor to first line of method."
124
- opts.on :c, :context, "Select object context to run under.", true do |context|
142
+ opts = Slop.parse!(args) do |opt|
143
+ opt.banner "Usage: edit-method [OPTIONS] [METH]\n" \
144
+ "Edit the method METH in an editor.\n" \
145
+ "Ensure #{text.bold("Pry.editor")} is set to your editor of choice.\n" \
146
+ "e.g: edit-method hello_method"
147
+
148
+ opt.on :M, "instance-methods", "Operate on instance methods."
149
+ opt.on :m, :methods, "Operate on methods."
150
+ opt.on :n, "no-reload", "Do not automatically reload the method's file after editting."
151
+ opt.on "no-jump", "Do not fast forward editor to first line of method."
152
+ opt.on :c, :context, "Select object context to run under.", true do |context|
125
153
  target = Pry.binding_for(target.eval(context))
126
154
  end
127
- opts.on :h, :help, "This message." do
128
- output.puts opts
155
+ opt.on :h, :help, "This message." do
156
+ output.puts opt
129
157
  end
130
158
  end
131
159
 
@@ -137,7 +165,7 @@ e.g: edit-method hello_method
137
165
  next
138
166
  end
139
167
 
140
- next output.puts "Error: No editor set!\nEnsure that #{bold("Pry.editor")} is set to your editor of choice." if !Pry.editor
168
+ next output.puts "Error: No editor set!\nEnsure that #{text.bold("Pry.editor")} is set to your editor of choice." if !Pry.editor
141
169
 
142
170
  if is_a_c_method?(meth)
143
171
  output.puts "Error: Can't edit a C method."
@@ -146,38 +174,45 @@ e.g: edit-method hello_method
146
174
 
147
175
  # editor is invoked here
148
176
  else
149
- file, line = meth.source_location
177
+ file, line = path_line_for(meth)
150
178
  set_file_and_dir_locals(file)
151
179
 
180
+ invoke_editor(file, opts["no-jump"] ? 0 : line)
181
+ silence_warnings do
182
+ load file if !opts.n?
183
+ end
184
+ end
185
+ end
186
+
187
+ helpers do
188
+
189
+ def invoke_editor(file, line)
152
190
  if Pry.editor.respond_to?(:call)
153
191
  editor_invocation = Pry.editor.call(file, line)
154
192
  else
155
- # only use start line if -n option is not used
156
- start_line_syntax = opts.n? ? "" : start_line_for_editor(line)
157
- editor_invocation = "#{Pry.editor} #{start_line_syntax} #{file}"
193
+ editor_invocation = "#{Pry.editor} #{start_line_syntax_for_editor(file, line)}"
158
194
  end
159
195
 
160
196
  run ".#{editor_invocation}"
161
- silence_warnings do
162
- load file if !opts["no-reload"]
163
- end
164
197
  end
165
- end
166
198
 
199
+ def start_line_syntax_for_editor(file_name, line_number)
200
+ file_name.gsub!(/\//, '\\') if RUBY_PLATFORM =~ /mswin|mingw/
167
201
 
168
- helpers do
169
-
170
- def start_line_for_editor(line_number)
171
202
  case Pry.editor
172
203
  when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
173
- "+#{line_number}"
204
+ "+#{line_number} #{file_name}"
174
205
  when /^mate/, /^geany/
175
- "-l #{line_number}"
206
+ "-l #{line_number} #{file_name}"
207
+ when /^uedit32/
208
+ "#{file_name}/#{line_number}"
209
+ when /^jedit/
210
+ "#{file_name} +#{line_number}"
176
211
  else
177
212
  if RUBY_PLATFORM =~ /mswin|mingw/
178
- ""
213
+ "#{file_name}"
179
214
  else
180
- "+#{line_number}"
215
+ "+#{line_number} #{file_name}"
181
216
  end
182
217
  end
183
218
  end