Skip to content

Instantly share code, notes, and snippets.

@zhandao
Last active November 10, 2023 05:44
Show Gist options
  • Save zhandao/2b3f85b1a2803ba281bff1893962cb81 to your computer and use it in GitHub Desktop.
Save zhandao/2b3f85b1a2803ba281bff1893962cb81 to your computer and use it in GitHub Desktop.
[Ruby] my Pry settings and useful commands (.pryrc)

Find histories

# separate history file into current project
Pry.config.history_file = ".pry_history"

# @usage
#   hist User.first
#   hist User.first 3
#   hist User.first 3 5
Pry::Commands.block_command "hist", "find history" do |keyword, limit, show_lines|
  histories = File.readlines(Pry.config.history_file)
  show_lines = (show_lines || 1).to_i
  found = [ ]
  while found.size < (limit&.to_i || 2)
    index = histories.index { _1[keyword] && !_1["hist "] }
    break if index.nil?

    (found << "#{histories[index..(index+show_lines-1)].join}\n").uniq!
    histories.delete_at(index)
  end

  output.puts
  found.each { output.puts Pry.Code(_1).highlighted }
end

Trace method call (searchable)

# @usage
#   trace instantiate | { User.first.posts }
#   trace instantiate true | { User.first.posts }
#   trace @ | { User.first.posts }
#   trace ! | { User.first.posts }
Pry::Commands.block_command "trace", "method call tracing", takes_block: true do |*args|
  step  = 0
  trace =
    if args.first == "@" # only show file name
      last = ""
      TracePoint.new(:call) do |tp|
        path = tp.path.sub(%r{.*/.rvm/(gems|rubies)/ruby-[^/]*}, "~")
        path.gsub!("active_record", "active_record".red)
        step += 1

        output.puts "#{step.to_s.red} #{path}" unless path == last
        last = path
      end
    elsif args.first == "!" # only show uniq file name
      traces = [ ]
      TracePoint.new(:call) do |tp|
        path = tp.path.sub(%r{.*/.rvm/(gems|rubies)/ruby-[^/]*}, "~")
        path.gsub!("active_record", "active_record".red)
        step += 1

        output.puts "#{step.to_s.red} #{path}" if traces.exclude?(path)
        traces << path
      end
    else # all / search
      last6 = [ ]
      search, show_unsearched = args
      TracePoint.new(:call) do |tp|
        path = tp.path.sub(%r{.*/.rvm/(gems|rubies)/ruby-[^/]*}, "~")
        path.gsub!("active_record", "active_record".red)
        step += 1

        curr = "#{path}:#{tp.lineno} #{tp.method_id.to_s.green.bold}"
        if search.present? && curr.match?(search)
          curr = curr.colorize background: :yellow if show_unsearched
        elsif search.present? && !show_unsearched
          next
        end

        if last6.include?(curr)
          next if last6.last(3).all?("  ...")
          output.puts "  ..."
          last6 << "  ..."
        else
          output.puts "#{step.to_s.red} #{curr}"
          last6 << curr
        end
        last6 = last6[1..] if last6.size > 6
      end
    end

  trace.enable
  command_block.call
  trace.disable
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment