Skip to content
This repository
Browse code

first commit

  • Loading branch information...
commit 3601caa6203917f2a8df0d683f35a451310eccbe 0 parents
John Mair authored November 12, 2011
0  .gemtest
No changes.
7  .gitignore
... ...
@@ -0,0 +1,7 @@
  1
+Makefile
  2
+*.so
  3
+*.o
  4
+*.def
  5
+doc/
  6
+pkg/
  7
+.yardoc/
1  .yardopts
... ...
@@ -0,0 +1 @@
  1
+--markup markdown
0  CHANGELOG
No changes.
25  LICENSE
... ...
@@ -0,0 +1,25 @@
  1
+License
  2
+-------
  3
+
  4
+(The MIT License) 
  5
+
  6
+Copyright (c) 2011 John Mair (banisterfiend)
  7
+
  8
+Permission is hereby granted, free of charge, to any person obtaining
  9
+a copy of this software and associated documentation files (the
  10
+'Software'), to deal in the Software without restriction, including
  11
+without limitation the rights to use, copy, modify, merge, publish,
  12
+distribute, sublicense, and/or sell copies of the Software, and to
  13
+permit persons to whom the Software is furnished to do so, subject to
  14
+the following conditions:
  15
+
  16
+The above copyright notice and this permission notice shall be
  17
+included in all copies or substantial portions of the Software.
  18
+
  19
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  20
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  22
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56  README.md
Source Rendered
... ...
@@ -0,0 +1,56 @@
  1
+pry-stack_explore
  2
+===========
  3
+
  4
+(C) John Mair (banisterfiend) 2011
  5
+
  6
+FIXME: _tagline_
  7
+
  8
+FIXME: _description goes here_
  9
+
  10
+* Install the [gem](https://rubygems.org/gems/pry-stack_explore): `gem install pry-stack_explore`
  11
+* Read the [documentation](http://rdoc.info/github/banister/pry-stack_explore/master/file/README.md)
  12
+* See the [source code](http://github.com/banister/pry-stack_explore)
  13
+
  14
+Example: Example description
  15
+--------
  16
+
  17
+Example preamble
  18
+
  19
+    puts "example code"
  20
+
  21
+Features and limitations
  22
+-------------------------
  23
+
  24
+Feature List Preamble
  25
+
  26
+Contact
  27
+-------
  28
+
  29
+Problems or questions contact me at [github](http://github.com/banister)
  30
+
  31
+
  32
+License
  33
+-------
  34
+
  35
+(The MIT License) 
  36
+
  37
+Copyright (c) 2011 John Mair (banisterfiend)
  38
+
  39
+Permission is hereby granted, free of charge, to any person obtaining
  40
+a copy of this software and associated documentation files (the
  41
+'Software'), to deal in the Software without restriction, including
  42
+without limitation the rights to use, copy, modify, merge, publish,
  43
+distribute, sublicense, and/or sell copies of the Software, and to
  44
+permit persons to whom the Software is furnished to do so, subject to
  45
+the following conditions:
  46
+
  47
+The above copyright notice and this permission notice shall be
  48
+included in all copies or substantial portions of the Software.
  49
+
  50
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  51
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  52
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  53
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  54
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  55
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  56
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68  Rakefile
... ...
@@ -0,0 +1,68 @@
  1
+$:.unshift 'lib'
  2
+
  3
+dlext = Config::CONFIG['DLEXT']
  4
+direc = File.dirname(__FILE__)
  5
+
  6
+PROJECT_NAME = "pry-stack_explorer"
  7
+
  8
+require 'rake/clean'
  9
+require 'rake/gempackagetask'
  10
+require "#{PROJECT_NAME}/version"
  11
+
  12
+CLOBBER.include("**/*~", "**/*#*", "**/*.log")
  13
+CLEAN.include("**/*#*", "**/*#*.*", "**/*_flymake*.*", "**/*_flymake",
  14
+              "**/*.rbc", "**/.#*.*")
  15
+
  16
+def apply_spec_defaults(s)
  17
+  s.name = PROJECT_NAME
  18
+  s.summary = "Walk the stack in a Pry session"
  19
+  s.version = PryStackExplorer::VERSION
  20
+  s.date = Time.now.strftime '%Y-%m-%d'
  21
+  s.author = "John Mair (banisterfiend)"
  22
+  s.email = 'jrmair@gmail.com'
  23
+  s.description = s.summary
  24
+  s.require_path = 'lib'
  25
+  s.add_dependency("binding_of_caller","~>0.5.0")
  26
+  s.add_development_dependency("bacon","~>1.1.0")
  27
+  s.homepage = "https://github.com/banister"
  28
+  s.files = Dir["lib/**/*.rb", "test/*.rb", "CHANGELOG", "README.md", "Rakefile"]
  29
+end
  30
+
  31
+desc "run pry with plugin enabled"
  32
+task :pry do
  33
+  exec("pry -I#{direc}/lib/ -r #{direc}/lib/#{PROJECT_NAME}")
  34
+end
  35
+
  36
+desc "run tests"
  37
+task :test do
  38
+  sh "bacon -Itest -rubygems -a"
  39
+end
  40
+
  41
+namespace :ruby do
  42
+  spec = Gem::Specification.new do |s|
  43
+    apply_spec_defaults(s)
  44
+    s.platform = Gem::Platform::RUBY
  45
+  end
  46
+
  47
+  Rake::GemPackageTask.new(spec) do |pkg|
  48
+    pkg.need_zip = false
  49
+    pkg.need_tar = false
  50
+  end
  51
+end
  52
+
  53
+desc "build all platform gems at once"
  54
+task :gems => [:clean, :rmgems, "ruby:gem"]
  55
+
  56
+desc "remove all platform gems"
  57
+task :rmgems => ["ruby:clobber_package"]
  58
+
  59
+desc "build and push latest gems"
  60
+task :pushgems => :gems do
  61
+  chdir("#{File.dirname(__FILE__)}/pkg") do
  62
+    Dir["*.gem"].each do |gemfile|
  63
+      sh "gem push #{gemfile}"
  64
+    end
  65
+  end
  66
+end
  67
+
  68
+
121  lib/pry-stack_explorer.rb
... ...
@@ -0,0 +1,121 @@
  1
+# pry-stack_explorer.rb
  2
+# (C) John Mair (banisterfiend); MIT license
  3
+
  4
+require "pry-stack_explorer/version"
  5
+require "pry"
  6
+require "binding_of_caller"
  7
+
  8
+module PryStackExplorer
  9
+
  10
+  def self.bindings_equal?(b1, b2)
  11
+    (b1.eval('self') == b2.eval('self')) &&
  12
+      (b1.eval('local_variables').map { |v| b1.eval("#{v}") } ==
  13
+       b2.eval('local_variables').map { |v| b2.eval("#{v}") }) &&
  14
+      (b1.eval('__method__') == b2.eval('__method__'))
  15
+  end
  16
+
  17
+  def self.frame_manager
  18
+    Thread.current[:__pry_frame_manager__]
  19
+  end
  20
+
  21
+  def self.frame_manager=(obj)
  22
+    Thread.current[:__pry_frame_manager__] = obj
  23
+  end
  24
+
  25
+  class FrameManager
  26
+    attr_reader   :pry_instance
  27
+    attr_reader   :binding_index
  28
+    attr_accessor :bindings
  29
+
  30
+    def initialize(bindings)
  31
+      @bindings      = bindings
  32
+      @binding_index = 0
  33
+    end
  34
+
  35
+    def change_binding_to(index, pry_instance)
  36
+      if index > bindings.size - 1
  37
+        pry_instance.output.puts "Warning: At top of stack, cannot go further!"
  38
+      elsif index < 0
  39
+        pry_instance.output.puts "Warning: At bottom of stack, cannot go further!"
  40
+      else
  41
+        @binding_index = index
  42
+        pry_instance.binding_stack[-1] = bindings[binding_index]
  43
+
  44
+        pry_instance.run_command "whereami"
  45
+      end
  46
+    end
  47
+  end
  48
+
  49
+  StackCommands = Pry::CommandSet.new do
  50
+    command "up", "Go up to the caller's context" do |inc_str|
  51
+      inc = inc_str.nil? ? 1 : inc_str.to_i
  52
+
  53
+      binding_index = PryStackExplorer.frame_manager.binding_index
  54
+      PryStackExplorer.frame_manager.change_binding_to binding_index + inc, _pry_
  55
+    end
  56
+
  57
+    command "down", "Go down to the callee's context." do |inc_str|
  58
+      inc = inc_str.nil? ? 1 : inc_str.to_i
  59
+
  60
+      binding_index = PryStackExplorer.frame_manager.binding_index
  61
+      PryStackExplorer.frame_manager.change_binding_to binding_index - inc, _pry_
  62
+    end
  63
+
  64
+    command "frame", "Switch to a particular frame." do |frame_num|
  65
+      PryStackExplorer.frame_manager.change_binding_to frame_num.to_i, _pry_
  66
+    end
  67
+
  68
+    command "frame-type", "Display current frame type." do
  69
+      bindex = PryStackExplorer.frame_manager.binding_index
  70
+      output.puts PryStackExplorer.frame_manager.bindings[bindex].frame_type
  71
+    end
  72
+  end
  73
+end
  74
+
  75
+class << Pry
  76
+  alias_method :PSE_old_start, :start
  77
+  def start(target, *args, &block)
  78
+    target = Pry.binding_for(target)
  79
+
  80
+    # we need to know how many frames to skip depending on whether we
  81
+    # were invoked with Pry.start or Object#pry
  82
+    if binding.of_caller(1).eval('__method__') == :pry
  83
+      drop_number = 2
  84
+    else
  85
+      drop_number = 1
  86
+    end
  87
+
  88
+    bindings = binding.callers.drop(drop_number)
  89
+
  90
+    # Use the binding returned by #of_caller if possible (as we get
  91
+    # access to frame_type).
  92
+    # Otherwise stick to the given binding (target).
  93
+    if !PryStackExplorer.bindings_equal?(target, bindings.first)
  94
+      bindings.shift
  95
+      bindings.unshift(target)
  96
+    end
  97
+
  98
+    PryStackExplorer.frame_manager = PryStackExplorer::FrameManager.new(bindings)
  99
+
  100
+    PSE_old_start(bindings.first)
  101
+  end
  102
+end
  103
+
  104
+Pry.config.commands.import PryStackExplorer::StackCommands
  105
+
  106
+Pry.config.commands.alias_command "__old_whereami__", "whereami", ""
  107
+
  108
+# monkey-patch the whereami command to show some frame information,
  109
+# useful for navigating stack.
  110
+Pry.config.commands.command "whereami", "Show the code context for the session. (whereami <n> shows <n> extra lines of code around the invocation line. Default: 5)" do |num|
  111
+  if PryStackExplorer.frame_manager
  112
+    bindings      = PryStackExplorer.frame_manager.bindings
  113
+    binding_index = PryStackExplorer.frame_manager.binding_index
  114
+
  115
+    output.puts "\n"
  116
+    output.puts "#{Pry::Helpers::Text.bold('Frame number:')} #{binding_index}/#{bindings.size - 1}"
  117
+    output.puts "#{Pry::Helpers::Text.bold('Frame type:')} #{bindings[binding_index].frame_type}" rescue nil
  118
+  end
  119
+
  120
+  run "__old_whereami__", num
  121
+end
3  lib/pry-stack_explorer/version.rb
... ...
@@ -0,0 +1,3 @@
  1
+module PryStackExplorer
  2
+  VERSION = "0.1.0pre1"
  3
+end
12  test/test.rb
... ...
@@ -0,0 +1,12 @@
  1
+direc = File.dirname(__FILE__)
  2
+
  3
+require 'rubygems'
  4
+require "#{direc}/../lib/pry-stack_explorer"
  5
+require 'bacon'
  6
+
  7
+puts "Testing pry-stack_explorer version #{PryStackExplorer::VERSION}..."
  8
+puts "Ruby version: #{RUBY_VERSION}"
  9
+
  10
+describe PryStackExplorer do
  11
+end
  12
+
14  tester.rb
... ...
@@ -0,0 +1,14 @@
  1
+def a
  2
+  x = 20
  3
+  b
  4
+end
  5
+
  6
+def b
  7
+  x = 30
  8
+  c
  9
+end
  10
+
  11
+def c
  12
+  u = 50
  13
+  binding.pry
  14
+end

0 notes on commit 3601caa

Please sign in to comment.
Something went wrong with that request. Please try again.