pry 0.8.4pre1-i386-mswin32 → 0.9.0-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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