From 580e1ce1ece16fd9fb392641a790ea564dada769 Mon Sep 17 00:00:00 2001 From: John Mair Date: Wed, 13 Apr 2011 17:16:12 +1200 Subject: [PATCH] added new `stat` command to read basic show basic method information. Refactored command_helpers.rb and command_base_helpers.rb, moving some methods up into command_base_helpers. `ls` command now uses a pager. Some headings made 'bold' --- lib/pry/command_base.rb | 6 ++- lib/pry/command_base_helpers.rb | 67 +++++++++++++++++++++++++++++++++ lib/pry/command_helpers.rb | 59 ++--------------------------- lib/pry/commands.rb | 52 ++++++++++++++++++++++++- 4 files changed, 126 insertions(+), 58 deletions(-) diff --git a/lib/pry/command_base.rb b/lib/pry/command_base.rb index a345d7bc..9262da90 100644 --- a/lib/pry/command_base.rb +++ b/lib/pry/command_base.rb @@ -143,10 +143,12 @@ class Pry command_info = opts[:commands] if !cmd - output.puts "\e[1mCommand list:\e[0m\n--" + output.puts + help_text = heading("Command List:") + "\n" command_info.each do |k, data| - output.puts "#{k}".ljust(18) + data[:description] if !data[:description].empty? + help_text << ("#{k}".ljust(18) + data[:description] + "\n") if !data[:description].empty? end + stagger_output(help_text) else if command_info[cmd] output.puts command_info[cmd][:description] diff --git a/lib/pry/command_base_helpers.rb b/lib/pry/command_base_helpers.rb index 6338dc91..de7833c8 100644 --- a/lib/pry/command_base_helpers.rb +++ b/lib/pry/command_base_helpers.rb @@ -36,6 +36,73 @@ class Pry end end + def bold(text) + Pry.color ? "\e[1m#{text}\e[0m" : text + end + + # formatting + def heading(text) + text = "#{text}\n--" + Pry.color ? "\e[1m#{text}\e[0m": text + end + + def page_size + 27 + end + + # a simple pager for systems without `less`. A la windows. + def simple_pager(text) + text_array = text.lines.to_a + text_array.each_slice(page_size) do |chunk| + output.puts chunk.join + break if chunk.size < page_size + if text_array.size > page_size + output.puts "\n --- Press enter to continue ( q to break ) --- " + break if $stdin.gets.chomp == "q" + end + end + end + + # Try to use `less` for paging, if it fails then use simple_pager + def stagger_output(text) + if text.lines.count < page_size + output.puts text + return + end + lesspipe { |less| less.puts text } + rescue Exception + simple_pager(text) + end + + # thanks to epitron for this method + def lesspipe(*args) + if args.any? and args.last.is_a?(Hash) + options = args.pop + else + options = {} + end + + output = args.first if args.any? + + params = [] + params << "-R" unless options[:color] == false + params << "-S" unless options[:wrap] == true + params << "-F" unless options[:always] == true + if options[:tail] == true + params << "+\\>" + $stderr.puts "Seeking to end of stream..." + end + params << "-X" + + IO.popen("less #{params * ' '}", "w") do |less| + if output + less.puts output + else + yield less + end + end + end + end end end diff --git a/lib/pry/command_helpers.rb b/lib/pry/command_helpers.rb index 259652e2..4ba5db39 100644 --- a/lib/pry/command_helpers.rb +++ b/lib/pry/command_helpers.rb @@ -29,28 +29,7 @@ class Pry target.eval("_file_ = $_file_temp") target.eval("_dir_ = $_dir_temp") end - - # a simple pager for systems without `less`. A la windows. - def simple_pager(text) - page_size = 22 - text_array = text.lines.to_a - text_array.each_slice(page_size) do |chunk| - output.puts chunk.join - break if chunk.size < page_size - if text_array.size > page_size - output.puts "\n --- Press enter to continue ( q to break ) --- " - break if $stdin.gets.chomp == "q" - end - end - end - - # Try to use `less` for paging, if it fails then use simple_pager - def stagger_output(text) - lesspipe { |less| less.puts text } - rescue Exception - simple_pager(text) - end - + def add_line_numbers(lines, start_line) line_array = lines.each_line.to_a line_array.each_with_index.map do |line, idx| @@ -64,7 +43,6 @@ class Pry end.join end - # only add line numbers if start_line is not false # if start_line is not false then add line numbers starting with start_line def render_output(should_flood, start_line, doc) if start_line @@ -156,9 +134,9 @@ class Pry num_lines = "Number of lines: #{content.each_line.count}" case code_type when :ruby - "\nFrom #{file} @ line #{line}:\n#{num_lines}\n\n" + "\n#{bold('From:')} #{file} @ line #{line}:\n#{num_lines}\n\n" else - "\nFrom Ruby Core (C Method):\n#{num_lines}\n\n" + "\n#{bold('From:')} Ruby Core (C Method):\n#{num_lines}\n\n" end end @@ -196,7 +174,7 @@ class Pry { [".c", ".h"] => :c, [".cpp", ".hpp", ".cc", ".h", "cxx"] => :cpp, - [".rb", "Rakefile"] => :ruby, + [".rb", "Rakefile", ".irbrc", ".gemspec", ".pryrc"] => :ruby, ".py" => :python, ".diff" => :diff, ".css" => :css, @@ -297,35 +275,6 @@ class Pry code.sub /\A\s*\/\*.*?\*\/\s*/m, '' end - # thanks to epitron for this method - def lesspipe(*args) - if args.any? and args.last.is_a?(Hash) - options = args.pop - else - options = {} - end - - output = args.first if args.any? - - params = [] - params << "-R" unless options[:color] == false - params << "-S" unless options[:wrap] == true - params << "-F" unless options[:always] == true - if options[:tail] == true - params << "+\\>" - $stderr.puts "Seeking to end of stream..." - end - params << "-X" - - IO.popen("less #{params * ' '}", "w") do |less| - if output - less.puts output - else - yield less - end - end - end - end end end diff --git a/lib/pry/commands.rb b/lib/pry/commands.rb index d868a9e7..080da791 100644 --- a/lib/pry/commands.rb +++ b/lib/pry/commands.rb @@ -37,6 +37,56 @@ class Pry run target, ".ri", *args end + command "stat", "View method information and set _file_ and _dir_ locals" do |*args| + options = {} + target = target() + meth_name = nil + + OptionParser.new do |opts| + opts.banner = %{Usage: stat [OPTIONS] [METH] +Show method information for method METH and set _file_ and _dir_ locals. +e.g: stat hello_method +-- +} + opts.on("-M", "--instance-methods", "Operate on instance methods.") do + options[:M] = true + end + + opts.on("-m", "--methods", "Operate on methods.") do + options[:m] = true + end + + opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context| + target = Pry.binding_for(target.eval(context)) + end + + opts.on_tail("-h", "--help", "This message.") do + output.puts opts + options[:h] = true + end + end.order(args) do |v| + meth_name = v + end + + next if options[:h] + + meth_name = meth_name_from_binding(target) if !meth_name + + if (meth = get_method_object(meth_name, target, options)).nil? + output.puts "Invalid method name: #{meth_name}. Type `stat --help` for help" + next + end + + code, code_type = code_and_code_type_for(meth) + next if !code + doc, code_type = doc_and_code_type_for(meth) + + output.puts make_header(meth, code_type, code) + output.puts "Method Language: #{code_type.capitalize}" + output.puts "Method type: #{meth.is_a?(Method) ? "Bound" : "Unbound"}" + output.puts "Comment length: #{doc.empty? ? 'No comment.' : doc.lines.count.to_s + ' lines.'}" + end + command "gist-method", "Gist a method to github.", :requires_gem => "gist" do |*args| options = { } meth_name = nil @@ -175,7 +225,7 @@ e.g: gist -d my_method end set_file_and_dir_locals(file) - output.puts "\nFrom #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n" + output.puts "\n#{bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n" # This method inspired by http://rubygems.org/gems/ir_b File.open(file).each_with_index do |line, index|