From cc15c7622a88d4338cc3729cfc9a2aa1176287b8 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 03:13:00 +1200 Subject: [PATCH 1/9] Added clean task as prerequisite to gems task --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 9d4dd528..05aca9e9 100644 --- a/Rakefile +++ b/Rakefile @@ -90,7 +90,7 @@ end desc "build all platform gems at once" -task :gems => [:rmgems, "ruby:gem", "jruby:gem", "mswin32:gem", "mingw32:gem"] +task :gems => [:clean, :rmgems, "ruby:gem", "jruby:gem", "mswin32:gem", "mingw32:gem"] desc "remove all platform gems" task :rmgems => ["ruby:clobber_package"] From 4fc757ece1dad0ccd4cbf70187a514495523b26d Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 03:19:55 +1200 Subject: [PATCH 2/9] extracted is_a_dynamically_defined_method? from check_for_dynamically_defined_method --- lib/pry/command_helpers.rb | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/pry/command_helpers.rb b/lib/pry/command_helpers.rb index fba0618f..c5d383db 100644 --- a/lib/pry/command_helpers.rb +++ b/lib/pry/command_helpers.rb @@ -56,9 +56,28 @@ class Pry end end - def check_for_dynamically_defined_method(meth) + def editor_with_start_line(line_number) + case Pry.editor + when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/ + "#{Pry.editor} +#{line_number}" + when /^mate/ + "#{Pry.editor} -l#{line_number}" + else + if RUBY_PLATFORM =~ /mswin|mingw/ + Pry.editor + else + "#{Pry.editor} +#{line_number}" + end + end + end + + def is_a_dynamically_defined_method?(meth) file, _ = meth.source_location - if file =~ /(\(.*\))|<.*>/ + !!(file =~ /(\(.*\))|<.*>/) + end + + def check_for_dynamically_defined_method(meth) + if is_a_dynamically_defined_method?(meth) raise "Cannot retrieve source for dynamically defined method." end end From 477a25ae210f24e72b29da8215257b7ae6982b0f Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 03:21:42 +1200 Subject: [PATCH 3/9] added Pry.editor option for use by the edit-method command --- lib/pry/pry_class.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 052739d3..31a5997b 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -98,6 +98,11 @@ class Pry # Set to true if the pry-doc extension is loaded. # @return [Boolean] attr_accessor :has_pry_doc + + # The default editor to use. Defaults to $EDITOR or nano if + # $EDITOR is not defined. + # @return [String] + attr_accessor :editor end # Load the rc files given in the `Pry::RC_FILES` array. @@ -216,6 +221,7 @@ class Pry @should_load_rc = true @rc_loaded = false @cli = false + @editor = ENV['EDITOR'] ? ENV['EDITOR'] : "nano" end self.reset_defaults From 021ed2bb599d7ec05cfabdf2a0b342eeae2c8de9 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 03:23:42 +1200 Subject: [PATCH 4/9] added edit-method command, enables you to edit a method in an editor using the Pry.editor. Editor opens at line of method --- lib/pry/commands.rb | 51 +++++++++++++++++++++++++++++++++++++++++++++ test/test.rb | 6 ++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/lib/pry/commands.rb b/lib/pry/commands.rb index 287ec730..1aafb7bf 100644 --- a/lib/pry/commands.rb +++ b/lib/pry/commands.rb @@ -50,6 +50,57 @@ class Pry Pry.active_instance.input = StringIO.new(actions) end + command "edit-method", "Edit a method. Type `edit-method --help` for more info." do |*args| + target = target() + + opts = Slop.parse!(args) do |opts| + opts.banner %{Usage: edit-method [OPTIONS] [METH] +Edit the method METH in an editor. +Ensure #{bold("Pry.editor")} is set to your editor of choice. +e.g: edit-method hello_method +-- +} + opts.on :M, "instance-methods", "Operate on instance methods." + opts.on :m, :methods, "Operate on methods." + opts.on "no-reload", "Do not automatically reload the method's file after editting." + opts.on :c, :context, "Select object context to run under.", true do |context| + target = Pry.binding_for(target.eval(context)) + end + opts.on :h, :help, "This message." do + output.puts opts + end + end + + next if opts.help? + + meth_name = args.shift + if meth_name + if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context? + context, meth_name = $1, $2 + target = Pry.binding_for(target.eval(context)) + end + else + meth_name = meth_name_from_binding(target) + end + + if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil? + output.puts "Invalid method name: #{meth_name}." + next + end + + next output.puts "Error: No editor set!\nEnsure that #{bold("Pry.editor")} is set to your editor of choice." if !Pry.editor + + if is_a_c_method?(meth) + output.puts "Error: Can't edit a C method." + elsif is_a_dynamically_defined_method?(meth) + output.puts "Error: Can't edit an eval method." + else + file, line = meth.source_location + run ".#{editor_with_start_line(line)}", file + load file if !opts["no-reload"] + end + end + command "exit-program", "End the current program. Aliases: quit-program, !!!" do exit end diff --git a/test/test.rb b/test/test.rb index ecaecede..fa4fd662 100644 --- a/test/test.rb +++ b/test/test.rb @@ -1,8 +1,10 @@ direc = File.dirname(__FILE__) +$LOAD_PATH.unshift "#{direc}/../lib" + require 'rubygems' require 'bacon' -require "#{direc}/../lib/pry" +require "pry" require "#{direc}/test_helper" puts "Ruby Version #{RUBY_VERSION}" @@ -73,7 +75,7 @@ describe Pry do pry_tester.rep(o) str_output.string.should == "" end - + it 'should suppress output if input ends in a ";" (multi-line)' do o = Object.new From 9ba396bb5443b2053543c0f196642e016a4176a3 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 04:17:20 +1200 Subject: [PATCH 5/9] version 0.8.3, added edit-method and updated documention for edit-method --- README.markdown | 96 ++++++++++++++++++++++++++------------------ lib/pry/pry_class.rb | 10 ++++- lib/pry/version.rb | 2 +- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/README.markdown b/README.markdown index 55000c65..a15505b1 100644 --- a/README.markdown +++ b/README.markdown @@ -11,6 +11,7 @@ these include: * Source code browsing (including core C source with the pry-doc gem) * Documentation browsing * Live help system +* Open methods in editors (`edit-method Class#method`) * Syntax highlighting * Command shell integration (start editors, run git, and rake from within Pry) * Gist integration @@ -126,16 +127,16 @@ code: # test.rb require 'pry' - + class A def hello() puts "hello world!" end end - + a = A.new - + # start a REPL session binding.pry - + # program resumes here (after pry session) puts "program resumes here." @@ -169,8 +170,8 @@ using the normal `#{}` string interpolation syntax. In the code below we're going to switch to `shell-mode` and edit the `.pryrc` file in the home directory. We'll then cat its contents and reload the file. - - pry(main)> shell-mode + + pry(main)> shell-mode pry main:/home/john/ruby/projects/pry $ .cd ~ pry main:/home/john $ .emacsclient .pryrc pry main:/home/john $ .cat .pryrc @@ -179,7 +180,7 @@ reload the file. end pry main:/home/john $ load ".pryrc" => true - pry main:/home/john $ hello_world + pry main:/home/john $ hello_world hello world! We can also interpolate Ruby code into the shell. In the @@ -189,7 +190,7 @@ current directory and count the number of lines in that file with pry main:/home/john $ .cat #{Dir['*.*'].sample} | wc -l 44 - + ### Code Browsing #### show-method @@ -206,37 +207,37 @@ include line numbers in the output. In the following example we will enter the `Pry` class, list the instance methods beginning with 're' and display the source code for the `rep` method: - + pry(main)> cd Pry pry(Pry):1> ls -M --grep ^re [:re, :readline, :rep, :repl, :repl_epilogue, :repl_prologue, :retrieve_line] pry(Pry):1> show-method rep -l - + From: /home/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 143: Number of lines: 6 - + 143: def rep(target=TOPLEVEL_BINDING) 144: target = Pry.binding_for(target) 145: result = re(target) - 146: + 146: 147: show_result(result) if should_print? 148: end Note that we can also view C methods (from Ruby Core) using the `pry-doc` gem; we also show off the alternate syntax for `show-method`: - + pry(main)> show-method Array#select - + From: array.c in Ruby Core (C Method): Number of lines: 15 - + static VALUE rb_ary_select(VALUE ary) { VALUE result; long i; - + RETURN_ENUMERATOR(ary, 0, 0); result = rb_ary_new2(RARRAY_LEN(ary)); for (i = 0; i < RARRAY_LEN(ary); i++) { @@ -259,14 +260,14 @@ commands to do such things as change directory into the directory containing the file, open the file in an editor, display the file using `cat`, and so on. In the following example we wil use Pry to fix a bug in a method: - + pry(main)> greet "john" hello johnhow are you?=> nil pry(main)> show-method greet - + From: /Users/john/ruby/play/bug.rb @ line 2: Number of lines: 4 - + def greet(name) print "hello #{name}" print "how are you?" @@ -278,10 +279,10 @@ In the following example we wil use Pry to fix a bug in a method: how are you? => nil pry(main)> show-method greet - + From: /Users/john/ruby/play/bug.rb @ line 2: Number of lines: 4 - + def greet(name) puts "hello #{name}" puts "how are you?" @@ -317,10 +318,10 @@ documentation for the `try_activate` method: pry(main)> cd Gem pry(Gem):1> show-doc try_activate - + From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems.rb @ line 201: Number of lines: 3 - + Try to activate a gem containing path. Returns true if activation succeeded or wasn't needed because it was already activated. Returns false if it can't find the path in a gem. @@ -334,14 +335,14 @@ We can also use `ri` in the normal way: ------------------------------------------------------------------------ Calls _block_ once for each element in _self_, passing that element as a parameter. - + a = [ "a", "b", "c" ] a.each {|x| print x, " -- " } - + produces: - + a -- b -- c -- - + ### History @@ -353,7 +354,7 @@ history can be replayed. In the example below we will enter a few lines in a Pry session and then view history; we will then replay one of those lines: - + pry(main)> hist 0: hist -h 1: ls @@ -362,10 +363,10 @@ then view history; we will then replay one of those lines: 4: x = rand 5: hist pry(main)> hist --replay 3 - + From: io.c in Ruby Core (C Method): Number of lines: 8 - + static VALUE rb_f_puts(int argc, VALUE *argv, VALUE recv) { @@ -374,7 +375,7 @@ then view history; we will then replay one of those lines: } return rb_funcall2(rb_stdout, rb_intern("puts"), argc, argv); } - + In the next example we will replay a range of lines in history. Note that we replay to a point where a class definition is still open and so we can continue to add instance methods to the class: @@ -397,7 +398,7 @@ we can continue to add instance methods to the class: pry(main)> Also note that in the above the line `Hello.new.goodbye_world;` ends -with a semi-colon which causes expression evaluation output to be suppressed. +with a semi-colon which causes expression evaluation output to be suppressed. ### Gist integration @@ -405,12 +406,31 @@ If the `gist` gem is installed then method source or documentation can be gisted `gist-method` command. The `gist-method` command accepts the same two syntaxes as `show-method`. In the example below we will gist the C source code for the `Symbol#to_proc` method to github: - + pry(main)> gist-method Symbol#to_proc https://gist.github.com/5332c38afc46d902ce46 - pry(main)> - -You can see the actual gist generated here: https://gist.github.com/5332c38afc46d902ce46 + pry(main)> + +You can see the actual gist generated here: [https://gist.github.com/5332c38afc46d902ce46](https://gist.github.com/5332c38afc46d902ce46) + +### Edit methods + +You can use `edit-method Class#method` or `edit-method my_method` +(if the method is in scope) to open a method for editing directly in +your favorite editor. Pry has knowledge of a few different editors and +will attempt to open the file at the line the method is defined. + +You can set the editor to use by assigning to the `Pry.editor=` +accessor. `Pry.editor` will default to `$EDITOR` or failing that will +use `nano` as the backup default. The file that is edited will be +automatically reloaded after exiting the editor - reloading can be +suppressed by passing the --no-reload option to `edit-method` + +In the example below we will set our default editor to "emacsclient" +and open the `Pry#repl` method for editing: + + pry(main)> Pry.editor = "emacsclient" + pry(main)> edit-method Pry#repl ### Live Help System @@ -471,7 +491,7 @@ invoke any of these methods directly depending on exactly what aspect of the fun limitation in JRuby's regex). * Tab completion is currently a bit broken/limited this will have a major overhaul in a future version. - + ### Syntax Highlighting Syntax highlighting is on by default in Pry. You can toggle it on and @@ -497,7 +517,7 @@ features, see the `examples/` directory. ### Customizing Pry -Pry allows a large degree of customization. +Pry allows a large degree of customization. [Read how to customize Pry here.](http://rdoc.info/github/banister/pry/master/file/wiki/Customizing-pry.md) diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 31a5997b..0876db2e 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -206,6 +206,14 @@ class Pry end end + def self.default_editor_for_platform + if RUBY_PLATFORM =~ /mswin|mingw/ + ENV['EDITOR'] ? ENV['EDITOR'] : "notepad" + else + ENV['EDITOR'] ? ENV['EDITOR'] : "nano" + end + end + # Set all the configurable options back to their default values def self.reset_defaults @input = Readline @@ -221,7 +229,7 @@ class Pry @should_load_rc = true @rc_loaded = false @cli = false - @editor = ENV['EDITOR'] ? ENV['EDITOR'] : "nano" + @editor = default_editor_for_platform end self.reset_defaults diff --git a/lib/pry/version.rb b/lib/pry/version.rb index 04a72e50..b3913cd9 100644 --- a/lib/pry/version.rb +++ b/lib/pry/version.rb @@ -1,3 +1,3 @@ class Pry - VERSION = "0.8.2" + VERSION = "0.8.3" end From f6f7e818f48b494bf05ec02dfebcca76952bc941 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 04:33:10 +1200 Subject: [PATCH 6/9] updated docs, fixed unicode error --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index a15505b1..f1e59cf4 100644 --- a/README.markdown +++ b/README.markdown @@ -424,7 +424,7 @@ You can set the editor to use by assigning to the `Pry.editor=` accessor. `Pry.editor` will default to `$EDITOR` or failing that will use `nano` as the backup default. The file that is edited will be automatically reloaded after exiting the editor - reloading can be -suppressed by passing the --no-reload option to `edit-method` +suppressed by passing the `--no-reload` option to `edit-method` In the example below we will set our default editor to "emacsclient" and open the `Pry#repl` method for editing: From db5d5825e31cc116d8b54e2c6bf7eaa8f1fe38e7 Mon Sep 17 00:00:00 2001 From: John Mair Date: Tue, 26 Apr 2011 05:11:07 +1200 Subject: [PATCH 7/9] fixed encoding issue in readme --- README.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index f1e59cf4..5be14331 100644 --- a/README.markdown +++ b/README.markdown @@ -420,7 +420,7 @@ You can use `edit-method Class#method` or `edit-method my_method` your favorite editor. Pry has knowledge of a few different editors and will attempt to open the file at the line the method is defined. -You can set the editor to use by assigning to the `Pry.editor=` +You can set the editor to use by assigning to the `Pry.editor` accessor. `Pry.editor` will default to `$EDITOR` or failing that will use `nano` as the backup default. The file that is edited will be automatically reloaded after exiting the editor - reloading can be @@ -432,7 +432,6 @@ and open the `Pry#repl` method for editing: pry(main)> Pry.editor = "emacsclient" pry(main)> edit-method Pry#repl - ### Live Help System Many other commands are available in Pry; to see the full list type From 55fd3b831d9215612b6401584f3a0242f4103ac9 Mon Sep 17 00:00:00 2001 From: John Mair Date: Thu, 28 Apr 2011 01:32:02 +1200 Subject: [PATCH 8/9] added info on using pry as rails 3 console to README --- README.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.markdown b/README.markdown index 5be14331..acb163f6 100644 --- a/README.markdown +++ b/README.markdown @@ -441,6 +441,11 @@ help that can be accessed via typing `command_name --help`. A command will typically say in its description if the `--help` option is avaiable. +### Use Pry as your Rails 3 Console + +This is currently a hack, but follow the gist kindly provided by +MyArtChannel: (https://gist.github.com/941174)[https://gist.github.com/941174] + ### Other Features and limitations From fde297e05be5c8e338688a89511df9693e9606b0 Mon Sep 17 00:00:00 2001 From: John Mair Date: Thu, 28 Apr 2011 02:04:45 +1200 Subject: [PATCH 9/9] hopefully fixed rubydoc issue --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index acb163f6..f8bcfd0f 100644 --- a/README.markdown +++ b/README.markdown @@ -444,7 +444,7 @@ avaiable. ### Use Pry as your Rails 3 Console This is currently a hack, but follow the gist kindly provided by -MyArtChannel: (https://gist.github.com/941174)[https://gist.github.com/941174] +MyArtChannel: [https://gist.github.com/941174](https://gist.github.com/941174) ### Other Features and limitations