code_buddy 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -1,4 +1,10 @@
1
1
  pkg/*
2
2
  *.gem
3
3
  .bundle
4
+ bundler
5
+ cache
4
6
  *.swp
7
+ *~
8
+ Gemfile.lock
9
+ example_trace
10
+ tmp
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in code_buddy.gemspec
4
4
  gemspec
5
+
6
+
7
+ group :test, :cucumber do
8
+ gem 'rails'
9
+ end
@@ -0,0 +1,10 @@
1
+ ## Code Buddy release history
2
+
3
+ ### 0.0.7 / 2011-01-04
4
+
5
+ [full changelog](https://github.com/patshaughnessy/code_buddy/compare/v0.0.6...v0.0.7)
6
+
7
+ * Bug fix: Handles stack traces from haml files
8
+ * 'e' opens an editor to current file (mvim and mate only based on EDITOR environment variable)
9
+ * 'h' show/hide code window
10
+ * Added some cucumber features so we know it works
data/Rakefile CHANGED
@@ -3,8 +3,13 @@ Bundler::GemHelper.install_tasks
3
3
 
4
4
  require 'rspec/core'
5
5
  require 'rspec/core/rake_task'
6
+ require 'cucumber/rake/task'
7
+
6
8
  RSpec::Core::RakeTask.new(:spec) do |spec|
7
9
  spec.pattern = FileList['spec/**/*_spec.rb']
8
10
  end
9
11
 
10
- task :default => :spec
12
+ task :default => [:spec, :cucumber]
13
+
14
+ Cucumber::Rake::Task.new(:cucumber)
15
+
@@ -27,5 +27,8 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'rake', '~> 0.8.7'
28
28
  s.add_development_dependency 'rspec', '~> 2.2.0'
29
29
  s.add_development_dependency 'mocha', '~> 0.9.10'
30
-
30
+ s.add_development_dependency 'cucumber', '~> 0.9.4'
31
+ s.add_development_dependency 'aruba', '~> 0.2.2'
32
+ # s.add_development_dependency 'capybara'
33
+ # s.add_development_dependency 'akephalos'
31
34
  end
@@ -0,0 +1,21 @@
1
+ Feature: Make sure CodeBuddy works with a Rails3 app
2
+
3
+ @announce
4
+ Scenario: See a stack trace with links
5
+ Given I have created a new Rails 2 app "new_rails2_app" with code_buddy
6
+ And I run "script/generate scaffold user"
7
+ And I overwrite "app/views/users/index.html.erb" with:
8
+ """
9
+ <%= raise 'oops' %>
10
+ """
11
+ And I run "rake db:migrate"
12
+ And I run "cp ../../../features/templates/rails_exception.feature.template features/rails_exception.feature"
13
+ And I am pending
14
+ And I run "rake cucumber"
15
+ Then it should pass with:
16
+ """
17
+ 1 scenario (1 passed)
18
+ 4 steps (4 passed)
19
+ """
20
+
21
+
@@ -0,0 +1,21 @@
1
+ Feature: Make sure CodeBuddy works with a Rails3 app
2
+
3
+ @announce
4
+ Scenario: See a stack trace with links
5
+ Given I have created a new Rails 3 app "new_rails3_app" with code_buddy
6
+ And I run "rails generate scaffold users"
7
+ And I overwrite "app/views/users/index.html.erb" with:
8
+ """
9
+ <%= raise 'oops' %>
10
+ """
11
+ And I run "rake db:migrate"
12
+ And I enable show_exceptions in "config/environments/test.rb"
13
+ And I run "cp ../../../features/templates/rails_exception.feature.template features/rails_exception.feature"
14
+ And I run "bundle exec rake cucumber -v"
15
+ Then it should pass with:
16
+ """
17
+ 1 scenario (1 passed)
18
+ 4 steps (4 passed)
19
+ """
20
+
21
+
@@ -0,0 +1,15 @@
1
+ Feature: Make sure CodeBuddy works when started as a sinatra app
2
+
3
+ @announce
4
+ Scenario: See a stack trace with links
5
+ Given I have created a test harness "sinatra_testing" for sinatra
6
+ And I run "cp ../../../features/templates/sinatra_homepage.feature.template features/sinatra_homepage.feature"
7
+ And I run "cp ../../../features/templates/sinatra_paths.rb.template features/support/paths.rb"
8
+ And I run "cucumber ."
9
+ Then it should pass with:
10
+ """
11
+ 1 scenario (1 passed)
12
+ 2 steps (2 passed)
13
+ """
14
+
15
+
@@ -0,0 +1,68 @@
1
+ Given /^I have created a new Rails 3 app "([^"]*)" with code_buddy$/ do |app_name|
2
+ steps <<-STEPS
3
+ Given I successfully run "rails new #{app_name}"
4
+ And I cd to "#{app_name}"
5
+ And I append to "Gemfile" with:
6
+ """
7
+ gem 'rspec'
8
+ # gem 'akephalos', :git => 'https://github.com/thoughtbot/akephalos.git'
9
+ gem "cucumber-rails"
10
+ gem "capybara", '~> 0.3.8'
11
+ gem 'code_buddy', :path=>File.expand_path("../../../..", __FILE__)
12
+ """
13
+ And I run "bundle install"
14
+ And I run "rails generate cucumber:install"
15
+ And I run "rake db:migrate"
16
+ STEPS
17
+ end
18
+
19
+ Given /^I have created a new Rails 2 app "([^"]*)" with code_buddy$/ do |app_name|
20
+ steps <<-STEPS
21
+ Given I run "gem install rails --version '=2.3.10'"
22
+ And I successfully run "rails _2.3.10_ #{app_name}"
23
+ And I cd to "#{app_name}"
24
+ And I replace "# Specify gems that this application depends on and have them installed with rake gems:install" in "config/environment.rb" with:
25
+ """
26
+ # Specify gems that this application depends on and have them installed with rake gems:install
27
+ config.gem 'code_buddy'
28
+ config.middleware.use "CodeBuddy::ShowApp"
29
+
30
+ """
31
+ And I run "mkdir vendor/gems"
32
+ And I run "ln -s #{File.expand_path("../../..", __FILE__)} vendor/gems/code_buddy-#{CodeBuddy::VERSION}"
33
+ And I run "script/generate cucumber"
34
+ And I run "rake db:migrate"
35
+ STEPS
36
+ end
37
+
38
+
39
+ Given /^I have created a test harness "([^"]*)" for sinatra$/ do |app_name|
40
+ steps <<-STEPS
41
+ Given I run "gem install cucumber-sinatra"
42
+ And I successfully run "mkdir #{app_name}"
43
+ And I cd to "#{app_name}"
44
+ And I run "cucumber-sinatra init CodeBuddy::App ../../../spec/spec_helper.rb"
45
+ STEPS
46
+ # And I run "cp #{File.expand_path("../templates/sinatra_env.rb.template", __FILE__)} features/support/env.rb"
47
+ end
48
+
49
+ Given /^I enable show_exceptions in "([^"]*)"$/ do |file_name|
50
+ # Given %Q[I replace "config.action_dispatch.show_exceptions = false" in "#{file_name}"], pystring #Cucumber::Ast::PyString.parse('config.action_dispatch.show_exceptions = true')
51
+ cmd = "sed s/'config.action_dispatch.show_exceptions = false'/'config.action_dispatch.show_exceptions = true'/ #{file_name}"
52
+ run_simple(cmd)
53
+ create_file(file_name, stdout_from(cmd), true)
54
+ end
55
+
56
+ Given /^I replace "([^"]*)" in "([^"]*)" with:$/ do |marker, file_name, new_text|
57
+ file = File.readlines(File.join(current_dir, file_name))
58
+ new_content = file.map do |line|
59
+ if line =~ Regexp.new(marker)
60
+ new_text
61
+ else
62
+ line
63
+ end
64
+ end
65
+ create_file(file_name, new_content, true)
66
+ end
67
+
68
+
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/expectations'
4
+ require 'aruba/cucumber'
5
+
6
+ Before do
7
+ unset_bundler_env_vars
8
+ end
9
+
@@ -0,0 +1,8 @@
1
+ Feature: Ensure CodeBuddy creates links in a Rails app
2
+
3
+ @allow-rescue
4
+ Scenario: Clicking on a line of a stack trace on the exception page
5
+ When I go to the users page
6
+ Then I should see "app/views/users/index.html.erb:1"
7
+ And I follow "app/views/users/index.html.erb:1"
8
+ Then I should see "CodeBuddySee your Ruby stack come alive"
@@ -0,0 +1,22 @@
1
+ # Some minor edits after being
2
+ # Generated by cucumber-sinatra. (Wed Dec 22 13:32:12 -0500 2010)
3
+
4
+ ENV['RACK_ENV'] = 'test'
5
+
6
+ require File.join(File.dirname(__FILE__), '..', '..', '../../spec/spec_helper.rb')
7
+
8
+ require 'capybara'
9
+ require 'capybara/cucumber'
10
+ require 'rspec'
11
+
12
+ Capybara.app = CodeBuddy::App
13
+
14
+ class CodeBuddyWorld
15
+ include Capybara
16
+ include RSpec::Expectations
17
+ include RSpec::Matchers
18
+ end
19
+
20
+ World do
21
+ CodeBuddyWorld.new
22
+ end
@@ -0,0 +1,6 @@
1
+ Feature: Ensure CodeBuddy creates links as a stand alone Sinatra app
2
+
3
+ Scenario: Clicking on a line of a stack trace on the exception page
4
+ When I go to the new stack form page
5
+ # And show me the page
6
+ Then I should see "CodeBuddySee your Ruby stack come alive"
@@ -0,0 +1,31 @@
1
+ # Taken from the cucumber-rails project.
2
+
3
+ module NavigationHelpers
4
+ # Maps a name to a path. Used by the
5
+ #
6
+ # When /^I go to (.+)$/ do |page_name|
7
+ #
8
+ # step definition in web_steps.rb
9
+ #
10
+ def path_to(page_name)
11
+ case page_name
12
+
13
+ when /the home page/
14
+ '/'
15
+ when /the new stack form page/
16
+ '/new'
17
+
18
+ # Add more mappings here.
19
+ # Here is an example that pulls values out of the Regexp:
20
+ #
21
+ # when /^(.*)'s profile page$/i
22
+ # user_profile_path(User.find_by_login($1))
23
+
24
+ else
25
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
26
+ "Now, go and add a mapping in #{__FILE__}"
27
+ end
28
+ end
29
+ end
30
+
31
+ World(NavigationHelpers)
@@ -9,8 +9,7 @@ require 'code_buddy/stack_frame'
9
9
  require 'code_buddy/middleware'
10
10
 
11
11
  begin
12
- if Rails.env.development?
13
- CodeBuddy::App.rails = true
12
+ if Rails.env.development? || Rails.env.test?
14
13
  case Rails::VERSION::MAJOR
15
14
  when 2:
16
15
  require 'code_buddy/rails2/monkey_patch_action_controller'
@@ -21,3 +20,5 @@ begin
21
20
  rescue NameError
22
21
  nil
23
22
  end
23
+
24
+ # CodeBuddy::App.run!
@@ -5,7 +5,7 @@ module CodeBuddy
5
5
 
6
6
  class << self
7
7
  attr_reader :stack
8
- attr_accessor :rails
8
+ attr_accessor :path_prefix
9
9
 
10
10
  def exception=(exception)
11
11
  @stack = Stack.new(exception)
@@ -17,7 +17,7 @@ module CodeBuddy
17
17
  end
18
18
 
19
19
  get '/' do
20
- redirect "#{rails_prefix}/stack"
20
+ redirect "#{path_prefix}/stack"
21
21
  end
22
22
 
23
23
  get '/new' do
@@ -26,7 +26,7 @@ module CodeBuddy
26
26
 
27
27
  post '/new' do
28
28
  self.class.stack_string = params[:stack]
29
- redirect "#{rails_prefix}/stack"
29
+ redirect "#{path_prefix}/stack"
30
30
  end
31
31
 
32
32
  get '/stack' do
@@ -38,18 +38,22 @@ module CodeBuddy
38
38
  display_stack(params[:selected].to_i)
39
39
  end
40
40
 
41
+ get '/edit/:selected' do
42
+ self.class.stack.edit(params[:selected].to_i)
43
+ end
44
+
41
45
  def display_stack(selected_param)
42
46
  @stack = self.class.stack
43
47
  if @stack
44
48
  @stack.selected = selected_param
45
49
  erb :index
46
50
  else
47
- redirect "#{rails_prefix}/new"
51
+ redirect "#{path_prefix}/new"
48
52
  end
49
53
  end
50
54
 
51
- def rails_prefix
52
- self.class.rails ? '/code_buddy' : ''
55
+ def path_prefix
56
+ self.class.path_prefix
53
57
  end
54
58
 
55
59
  end
@@ -5,7 +5,7 @@ module CodeBuddy
5
5
  end
6
6
 
7
7
  def call(env)
8
- if env['PATH_INFO'] =~ /^\/code_buddy(.*)/ && Rails.env.development?
8
+ if env['PATH_INFO'] =~ /^\/code_buddy(.*)/ #&& Rails.env.development?
9
9
  env['PATH_INFO'] = $1
10
10
  App.new.call(env)
11
11
  else
@@ -1,16 +1,31 @@
1
- var Address = Backbone.Model.extend({
1
+ var CodeBuddy = {
2
+ stack : null,
3
+ stackView : null,
4
+ backbone : {}
5
+ }
6
+
7
+ CodeBuddy.backbone.Address = Backbone.Model.extend({
2
8
  selected: function() {
3
- return stack.selectedAddress() == this
4
- },
9
+ return CodeBuddy.stack.selectedAddress() == this
10
+ },
5
11
  });
6
12
 
7
- var Addresses = Backbone.Collection.extend({model:Address})
13
+ CodeBuddy.backbone.Addresses = Backbone.Collection.extend({
14
+ model:CodeBuddy.backbone.Address,
15
+
16
+ bookmarked: function() {
17
+ return this.select(function(address){
18
+ return address.get('bookmarked');
19
+ })
20
+ }
21
+ })
8
22
 
9
- var Stack = Backbone.Model.extend({
23
+ CodeBuddy.backbone.Stack = Backbone.Model.extend({
10
24
  initialize: function() {
25
+ _.bindAll(this, 'toggleBookmark', 'selectNextBookmark')
11
26
  this.bind('change:selected', this.selectionChanged);
12
27
  this.set({
13
- addresses: new Addresses(this.get('stack_frames'))
28
+ addresses: new CodeBuddy.backbone.Addresses(this.get('stack_frames'))
14
29
  })
15
30
  },
16
31
 
@@ -19,6 +34,14 @@ var Stack = Backbone.Model.extend({
19
34
  this.set({ selected: newSelected })
20
35
  }
21
36
  },
37
+
38
+ selectPrevious: function() {
39
+ this.setSelection(this.get('selected') - 1)
40
+ },
41
+
42
+ selectNext: function() {
43
+ this.setSelection(this.get('selected') + 1)
44
+ },
22
45
 
23
46
  addresses: function() {
24
47
  return this.get('addresses')
@@ -30,100 +53,138 @@ var Stack = Backbone.Model.extend({
30
53
  },
31
54
 
32
55
  selectionChanged: function(x) {
33
- this.updateSelectedAddress(x)
34
- this.view.render()
35
- },
36
-
37
- updateSelectedAddress: function(x) {
38
56
  this.addresses().at(x.previousAttributes().selected).view.render()
39
57
  this.addresses().at(x.changedAttributes().selected).view.render()
40
- }
58
+ this.view.render()
59
+ },
41
60
 
61
+ toggleBookmark: function() {
62
+ this.selectedAddress().set({bookmarked:!this.get('bookmarked')})
63
+ this.selectedAddress().view.render();
64
+ },
42
65
 
66
+ selectNextBookmark: function() {
67
+ var bookmarked = this.addresses().bookmarked();
68
+ var length = bookmarked.length;
69
+ var toSelect;
70
+ if(length > 0) {
71
+ var current = _.indexOf(bookmarked, this.selectedAddress())
72
+ if(current > -1 && current < length - 1) {
73
+ toSelect = bookmarked[current + 1]
74
+ } else {
75
+ toSelect = bookmarked[0]
76
+ }
77
+ return this.setSelection(toSelect.cid.substr(1)-1)
78
+ }
79
+ }
43
80
  });
44
81
 
45
82
  // ADDRESS VIEW - SELECTED ADDRESS IN BOLD
46
- var AddressView = Backbone.View.extend({
83
+ CodeBuddy.backbone.AddressView = Backbone.View.extend({
47
84
  tagName: "li",
48
85
 
49
86
  template: _.template("<span class='container'><%= path %>:<%= line%><span class='overlay'></span></span>"),
50
87
 
51
88
  initialize: function() {
52
- _.bindAll(this, 'render', 'close');
53
- this.model.bind('change', this.render);
54
89
  this.model.view = this;
55
90
  },
56
91
 
57
92
  events: {
58
- click: "open"
93
+ click: "open",
94
+ dblclick: "toggleBookmark"
59
95
  },
96
+
60
97
  open: function() {
61
- stack.set({selected: this.model.cid.substr(1)-1});
98
+ CodeBuddy.stack.set({selected: this.model.cid.substr(1)-1});
99
+ },
100
+
101
+ toggleBookmark: function() {
102
+ this.open();
103
+ CodeBuddy.stack.toggleBookmark();
62
104
  },
63
105
 
64
106
  render: function() {
107
+ $(this.el).removeClass('selected bookmarked')
108
+
65
109
  var html = this.template(this.model.toJSON())
66
110
 
67
111
  $(this.el).html(html);
68
112
  if (this.model.selected()) {
69
113
  $(this.el).addClass('selected')
70
- } else {
71
- $(this.el).removeClass('selected')
114
+ }
115
+ if (this.model.get('bookmarked')) {
116
+ $(this.el).addClass('bookmarked')
72
117
  }
73
118
  return this;
74
119
  }
75
120
  })
76
121
 
77
122
  // STACK VIEW - LOGIC FOR ASSIGNING EACH ADDRESS VIEW TO EACH LI TAG
78
- var StackView = Backbone.View.extend({
123
+ CodeBuddy.backbone.StackView = Backbone.View.extend({
79
124
 
80
125
  el: $("#stack"),
81
126
 
82
- events: {
83
- "keypress #stack" : "changeSelectionOnArrow"
84
- },
85
-
86
127
  initialize: function() {
87
- _.bindAll(this, 'render', 'close');
88
- this.model.bind('change', this.render);
128
+ _.bindAll(this, 'selectNext', 'selectPrevious')
89
129
  this.model.view = this;
90
-
91
130
  this.model.get('addresses').each(this.addOneAddress);
92
131
  },
93
-
94
- changeSelectionOnArrow: function(event) {
95
- var origSelection = this.model.get('selected')
96
- var newSelection = origSelection
97
- if (event.keyCode == 38) {
98
- newSelection = origSelection - 1
99
- } else if (event.keyCode == 40) {
100
- newSelection = origSelection + 1
101
- }
102
- if (newSelection != origSelection) {
103
- this.model.setSelection(newSelection)
104
-
105
- var offset = $(stack.selectedAddress().view.el).offset()
106
- var windowHeight = $(window).height()
107
- if (offset.top > windowHeight + $(window).scrollTop() - 10) {
108
- // scroll down
109
- $('html,body').animate({scrollTop: offset.top - 200}, 500);
110
- } else if (offset.top < $(window).scrollTop() + 100) {
111
- // scroll up
112
- $('html,body').animate({scrollTop: offset.top - 500}, 500);
113
- }
114
- return false
115
- } else {
116
- return true
132
+
133
+ selectPrevious: function() {
134
+ this.model.selectPrevious();
135
+ this.ensureVisibility();
136
+ return false;
137
+ },
138
+
139
+ selectNext: function() {
140
+ this.model.selectNext();
141
+ this.ensureVisibility();
142
+ return false;
143
+ },
144
+
145
+ ensureVisibility: function() {
146
+ var offset = $(CodeBuddy.stack.selectedAddress().view.el).offset()
147
+ var windowHeight = $(window).height()
148
+ if (offset.top > windowHeight + $(window).scrollTop() - 10) {
149
+ // scroll down
150
+ $('html,body').animate({scrollTop: offset.top - 200}, 500);
151
+ } else if (offset.top < $(window).scrollTop() + 100) {
152
+ // scroll up
153
+ $('html,body').animate({scrollTop: offset.top - 500}, 500);
117
154
  }
155
+ return false
118
156
  },
119
157
 
120
158
  addOneAddress: function(address, index) {
121
- var view = new AddressView({model: address});
159
+ var view = new CodeBuddy.backbone.AddressView({model: address});
122
160
  this.$("#stack").append(view.render().el);
123
161
  },
124
162
 
125
163
  render: function() {
126
164
  $('#code').html(this.model.selectedAddress().get('code'))
165
+ },
166
+
167
+ toggleCodeWindow: function() {
168
+ $('#code').toggle()
169
+ },
170
+
171
+ editCode: function() {
172
+ $.get('../edit/' + CodeBuddy.stack.get('selected'))
127
173
  }
174
+ })
128
175
 
129
- })
176
+ CodeBuddy.setKeyBindings = function(){
177
+ $(document).bind('keydown', 'up', CodeBuddy.stackView.selectPrevious)
178
+ $(document).bind('keydown', 'down', CodeBuddy.stackView.selectNext)
179
+ $(document).bind('keydown', 'a', CodeBuddy.stack.toggleBookmark)
180
+ $(document).bind('keydown', 's', CodeBuddy.stack.selectNextBookmark)
181
+ $(document).bind('keydown', 'h', CodeBuddy.stackView.toggleCodeWindow)
182
+ $(document).bind('keydown', 'e', CodeBuddy.stackView.editCode)
183
+ }
184
+
185
+ CodeBuddy.setup = function(stackJson) {
186
+ this.stack = new this.backbone.Stack(stackJson);
187
+ this.stackView = new this.backbone.StackView({model: this.stack});
188
+ this.stackView.render();
189
+ this.setKeyBindings();
190
+ }
@@ -0,0 +1,99 @@
1
+ /*
2
+ * jQuery Hotkeys Plugin
3
+ * Copyright 2010, John Resig
4
+ * Dual licensed under the MIT or GPL Version 2 licenses.
5
+ *
6
+ * Based upon the plugin by Tzury Bar Yochay:
7
+ * http://github.com/tzuryby/hotkeys
8
+ *
9
+ * Original idea by:
10
+ * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
11
+ */
12
+
13
+ (function(jQuery){
14
+
15
+ jQuery.hotkeys = {
16
+ version: "0.8",
17
+
18
+ specialKeys: {
19
+ 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20
+ 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
21
+ 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
22
+ 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
23
+ 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
24
+ 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
25
+ 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
26
+ },
27
+
28
+ shiftNums: {
29
+ "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
30
+ "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
31
+ ".": ">", "/": "?", "\\": "|"
32
+ }
33
+ };
34
+
35
+ function keyHandler( handleObj ) {
36
+ // Only care when a possible input has been specified
37
+ if ( typeof handleObj.data !== "string" ) {
38
+ return;
39
+ }
40
+
41
+ var origHandler = handleObj.handler,
42
+ keys = handleObj.data.toLowerCase().split(" ");
43
+
44
+ handleObj.handler = function( event ) {
45
+ // Don't fire in text-accepting inputs that we didn't directly bind to
46
+ if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
47
+ event.target.type === "text") ) {
48
+ return;
49
+ }
50
+
51
+ // Keypress represents characters, not special keys
52
+ var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
53
+ character = String.fromCharCode( event.which ).toLowerCase(),
54
+ key, modif = "", possible = {};
55
+
56
+ // check combinations (alt|ctrl|shift+anything)
57
+ if ( event.altKey && special !== "alt" ) {
58
+ modif += "alt+";
59
+ }
60
+
61
+ if ( event.ctrlKey && special !== "ctrl" ) {
62
+ modif += "ctrl+";
63
+ }
64
+
65
+ // TODO: Need to make sure this works consistently across platforms
66
+ if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
67
+ modif += "meta+";
68
+ }
69
+
70
+ if ( event.shiftKey && special !== "shift" ) {
71
+ modif += "shift+";
72
+ }
73
+
74
+ if ( special ) {
75
+ possible[ modif + special ] = true;
76
+
77
+ } else {
78
+ possible[ modif + character ] = true;
79
+ possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
80
+
81
+ // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
82
+ if ( modif === "shift+" ) {
83
+ possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
84
+ }
85
+ }
86
+
87
+ for ( var i = 0, l = keys.length; i < l; i++ ) {
88
+ if ( possible[ keys[i] ] ) {
89
+ return origHandler.apply( this, arguments );
90
+ }
91
+ }
92
+ };
93
+ }
94
+
95
+ jQuery.each([ "keydown", "keyup", "keypress" ], function() {
96
+ jQuery.event.special[ this ] = { add: keyHandler };
97
+ });
98
+
99
+ })( jQuery );
@@ -108,4 +108,8 @@ li {
108
108
  li:hover {
109
109
  background:#444;
110
110
  cursor:pointer;
111
+ }
112
+
113
+ .bookmarked {
114
+ background:#666;
111
115
  }
@@ -17,3 +17,5 @@ module ActionController
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ CodeBuddy::App.path_prefix = '/code_buddy'
@@ -6,6 +6,7 @@ module CodeBuddy
6
6
  app.middleware.insert_before CodeBuddy::ShowExceptions, CodeBuddy::ShowApp
7
7
  end
8
8
  end
9
+ CodeBuddy::App.path_prefix = '/code_buddy'
9
10
  end
10
11
 
11
12
  class ShowExceptions < ActionDispatch::ShowExceptions
@@ -20,3 +21,5 @@ module CodeBuddy
20
21
  end
21
22
  end
22
23
  end
24
+
25
+
@@ -5,15 +5,19 @@ module CodeBuddy
5
5
 
6
6
  def initialize(exception_or_string)
7
7
  if exception_or_string.is_a?(Exception)
8
- @selected = selected
9
- @stack_frames = exception_or_string.backtrace.collect do |string|
10
- StackFrame.new(string)
11
- end
8
+ backtrace = exception_or_string.backtrace
9
+ backtrace = backtrace.first.split("\n") if backtrace.size == 1 #haml errors come through this way
12
10
  else
13
- @stack_frames = exception_or_string.collect do |string|
14
- StackFrame.new(string)
15
- end
11
+ backtrace = exception_or_string
16
12
  end
13
+
14
+ @stack_frames = backtrace.collect do |string|
15
+ StackFrame.new(string)
16
+ end
17
+ end
18
+
19
+ def edit(index)
20
+ @stack_frames[index].open_in_editor
17
21
  end
18
22
  end
19
23
  end
@@ -39,5 +39,16 @@ module CodeBuddy
39
39
  "<span class=\"coderay\">Unable to read file:\n&nbsp;\"#{@path}\"</span>"
40
40
  end
41
41
  end
42
+
43
+ def open_in_editor
44
+ case ENV['EDITOR']
45
+ when 'mate'
46
+ `mate #{path} -l #{line}`
47
+ when 'mvim'
48
+ `mvim +#{line} #{path}`
49
+ else
50
+ puts "Sorry unable to open the file for editing. Please set your environment variable to either mate or mvim 'export EDITOR=mate' and restart the server"
51
+ end
52
+ end
42
53
  end
43
54
  end
@@ -1,3 +1,3 @@
1
1
  module CodeBuddy
2
- VERSION = "0.0.6"
2
+ VERSION = '0.0.7'
3
3
  end
@@ -3,6 +3,7 @@
3
3
  <link href="<%= @static_file_prefix %>stylesheets/code_buddy.css" media="screen" rel="stylesheet" type="text/css" />
4
4
  <link href="<%= @static_file_prefix %>stylesheets/coderay.css" media="screen" rel="stylesheet" type="text/css" />
5
5
  <script src="<%= @static_file_prefix %>javascripts/jquery.js" type="text/javascript"></script>
6
+ <script src="<%= @static_file_prefix %>javascripts/jquery.hotkeys.js" type="text/javascript"></script>
6
7
  <script src="<%= @static_file_prefix %>javascripts/underscore.js" type="text/javascript"></script>
7
8
  <script src="<%= @static_file_prefix %>javascripts/backbone.js" type="text/javascript"></script>
8
9
  </head>
@@ -14,12 +14,7 @@
14
14
  <div id='code'></div>
15
15
  <script src="<%= @static_file_prefix %>javascripts/code_buddy.js" type="text/javascript"></script>
16
16
  <script>
17
- var stack = new Stack(<%= @stack.to_json %>);
18
- var stackView = new StackView({model: stack});
19
- stackView.render();
20
- $(document).keydown(function(event) {
21
- return stack.view.changeSelectionOnArrow(event)
22
- })
17
+ CodeBuddy.setup(<%= @stack.to_json %>)
23
18
  </script>
24
19
  </body>
25
20
  </html>
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_buddy
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 17
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 6
9
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
10
11
  platform: ruby
11
12
  authors:
12
13
  - Pat Shaughnessy, Alex Rothenberg, Daniel Higginbotham
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-12-13 00:00:00 -05:00
18
+ date: 2011-01-04 00:00:00 -05:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: rack
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 3
27
30
  segments:
28
31
  - 0
29
32
  version: "0"
@@ -33,9 +36,11 @@ dependencies:
33
36
  name: sinatra
34
37
  prerelease: false
35
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
36
40
  requirements:
37
41
  - - ~>
38
42
  - !ruby/object:Gem::Version
43
+ hash: 19
39
44
  segments:
40
45
  - 1
41
46
  - 1
@@ -47,9 +52,11 @@ dependencies:
47
52
  name: json_pure
48
53
  prerelease: false
49
54
  requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
50
56
  requirements:
51
57
  - - ~>
52
58
  - !ruby/object:Gem::Version
59
+ hash: 11
53
60
  segments:
54
61
  - 1
55
62
  - 4
@@ -61,9 +68,11 @@ dependencies:
61
68
  name: coderay
62
69
  prerelease: false
63
70
  requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
64
72
  requirements:
65
73
  - - ~>
66
74
  - !ruby/object:Gem::Version
75
+ hash: 55
67
76
  segments:
68
77
  - 0
69
78
  - 9
@@ -75,9 +84,11 @@ dependencies:
75
84
  name: rake
76
85
  prerelease: false
77
86
  requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
78
88
  requirements:
79
89
  - - ~>
80
90
  - !ruby/object:Gem::Version
91
+ hash: 49
81
92
  segments:
82
93
  - 0
83
94
  - 8
@@ -89,9 +100,11 @@ dependencies:
89
100
  name: rspec
90
101
  prerelease: false
91
102
  requirement: &id006 !ruby/object:Gem::Requirement
103
+ none: false
92
104
  requirements:
93
105
  - - ~>
94
106
  - !ruby/object:Gem::Version
107
+ hash: 7
95
108
  segments:
96
109
  - 2
97
110
  - 2
@@ -103,9 +116,11 @@ dependencies:
103
116
  name: mocha
104
117
  prerelease: false
105
118
  requirement: &id007 !ruby/object:Gem::Requirement
119
+ none: false
106
120
  requirements:
107
121
  - - ~>
108
122
  - !ruby/object:Gem::Version
123
+ hash: 47
109
124
  segments:
110
125
  - 0
111
126
  - 9
@@ -113,6 +128,38 @@ dependencies:
113
128
  version: 0.9.10
114
129
  type: :development
115
130
  version_requirements: *id007
131
+ - !ruby/object:Gem::Dependency
132
+ name: cucumber
133
+ prerelease: false
134
+ requirement: &id008 !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ hash: 51
140
+ segments:
141
+ - 0
142
+ - 9
143
+ - 4
144
+ version: 0.9.4
145
+ type: :development
146
+ version_requirements: *id008
147
+ - !ruby/object:Gem::Dependency
148
+ name: aruba
149
+ prerelease: false
150
+ requirement: &id009 !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ~>
154
+ - !ruby/object:Gem::Version
155
+ hash: 19
156
+ segments:
157
+ - 0
158
+ - 2
159
+ - 2
160
+ version: 0.2.2
161
+ type: :development
162
+ version_requirements: *id009
116
163
  description: See the Ruby code running in your app.
117
164
  email:
118
165
  - pat@patshaughnessy.net, alex@alexrothenberg.com, daniel@flyingmachinestudios.com
@@ -126,18 +173,28 @@ files:
126
173
  - .gitignore
127
174
  - .rvmrc
128
175
  - Gemfile
129
- - Gemfile.lock
176
+ - History.md
130
177
  - LICENSE
131
178
  - README.rdoc
132
179
  - Rakefile
133
180
  - bin/code_buddy
134
181
  - code_buddy.gemspec
182
+ - features/rails2_app.feature
183
+ - features/rails3_app.feature
184
+ - features/sinatra.feature
185
+ - features/step_definitions/rails_setup_steps.rb
186
+ - features/support/env.rb
187
+ - features/templates/rails_exception.feature.template
188
+ - features/templates/sinatra_env.rb.template
189
+ - features/templates/sinatra_homepage.feature.template
190
+ - features/templates/sinatra_paths.rb.template
135
191
  - lib/code_buddy.rb
136
192
  - lib/code_buddy/app.rb
137
193
  - lib/code_buddy/middleware.rb
138
194
  - lib/code_buddy/public/images/buddy.jpeg
139
195
  - lib/code_buddy/public/javascripts/backbone.js
140
196
  - lib/code_buddy/public/javascripts/code_buddy.js
197
+ - lib/code_buddy/public/javascripts/jquery.hotkeys.js
141
198
  - lib/code_buddy/public/javascripts/jquery.js
142
199
  - lib/code_buddy/public/javascripts/underscore.js
143
200
  - lib/code_buddy/public/stylesheets/code_buddy.css
@@ -182,27 +239,40 @@ rdoc_options: []
182
239
  require_paths:
183
240
  - lib
184
241
  required_ruby_version: !ruby/object:Gem::Requirement
242
+ none: false
185
243
  requirements:
186
244
  - - ">="
187
245
  - !ruby/object:Gem::Version
246
+ hash: 3
188
247
  segments:
189
248
  - 0
190
249
  version: "0"
191
250
  required_rubygems_version: !ruby/object:Gem::Requirement
251
+ none: false
192
252
  requirements:
193
253
  - - ">="
194
254
  - !ruby/object:Gem::Version
255
+ hash: 3
195
256
  segments:
196
257
  - 0
197
258
  version: "0"
198
259
  requirements: []
199
260
 
200
261
  rubyforge_project: code_buddy
201
- rubygems_version: 1.3.6
262
+ rubygems_version: 1.3.7
202
263
  signing_key:
203
264
  specification_version: 3
204
265
  summary: See the Ruby code running in your app.
205
266
  test_files:
267
+ - features/rails2_app.feature
268
+ - features/rails3_app.feature
269
+ - features/sinatra.feature
270
+ - features/step_definitions/rails_setup_steps.rb
271
+ - features/support/env.rb
272
+ - features/templates/rails_exception.feature.template
273
+ - features/templates/sinatra_env.rb.template
274
+ - features/templates/sinatra_homepage.feature.template
275
+ - features/templates/sinatra_paths.rb.template
206
276
  - spec/app_spec.rb
207
277
  - spec/middleware_spec.rb
208
278
  - spec/spec_helper.rb
@@ -1,44 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- code_buddy (0.0.6)
5
- coderay (~> 0.9.6)
6
- json_pure (~> 1.4.6)
7
- rack
8
- sinatra (~> 1.1.0)
9
-
10
- GEM
11
- remote: http://rubygems.org/
12
- specs:
13
- coderay (0.9.6)
14
- diff-lcs (1.1.2)
15
- json_pure (1.4.6)
16
- mocha (0.9.10)
17
- rake
18
- rack (1.2.1)
19
- rake (0.8.7)
20
- rspec (2.2.0)
21
- rspec-core (~> 2.2)
22
- rspec-expectations (~> 2.2)
23
- rspec-mocks (~> 2.2)
24
- rspec-core (2.2.1)
25
- rspec-expectations (2.2.0)
26
- diff-lcs (~> 1.1.2)
27
- rspec-mocks (2.2.0)
28
- sinatra (1.1.0)
29
- rack (~> 1.1)
30
- tilt (~> 1.1)
31
- tilt (1.1)
32
-
33
- PLATFORMS
34
- ruby
35
-
36
- DEPENDENCIES
37
- code_buddy!
38
- coderay (~> 0.9.6)
39
- json_pure (~> 1.4.6)
40
- mocha (~> 0.9.10)
41
- rack
42
- rake (~> 0.8.7)
43
- rspec (~> 2.2.0)
44
- sinatra (~> 1.1.0)