editorkicker 0.1.0
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/CHANGES.txt +6 -0
- data/MIT-LICENSE +20 -0
- data/README.txt +133 -0
- data/editorkicker.gemspec +46 -0
- data/lib/editor_kicker.rb +104 -0
- data/plugin/rails/editorkicker/CHANGES.txt +6 -0
- data/plugin/rails/editorkicker/MIT-LICENSE +20 -0
- data/plugin/rails/editorkicker/README.txt +67 -0
- data/plugin/rails/editorkicker/init.rb +64 -0
- data/plugin/rails/editorkicker/lib/editor_kicker.rb +104 -0
- data/setup.rb +1585 -0
- metadata +66 -0
data/CHANGES.txt
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2008 kuwata-lab.com all rights reserved.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.txt
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
= README.txt for EditorKicker
|
2
|
+
|
3
|
+
Release: 0.1.0
|
4
|
+
|
5
|
+
http://editorkicker.rubyforge.org/
|
6
|
+
http://rubyforge.org/projects/editorkicker/
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
== About
|
11
|
+
|
12
|
+
EditorKicker is a pretty utility to invoke your favorite editor
|
13
|
+
and open errored file when CGI script or Rails program cause error.
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
== Install
|
18
|
+
|
19
|
+
(for Ruby on Rails)
|
20
|
+
|
21
|
+
$ ruby script/plugin install http://github.com/kwatch/editorkicker.git/ruby/plugin/rails/editorkicker
|
22
|
+
|
23
|
+
(for CGI/mod_ruby)
|
24
|
+
|
25
|
+
You must install CGI-Exception library, too.
|
26
|
+
|
27
|
+
## install EditorKicker
|
28
|
+
$ sudo gem install editorkicker
|
29
|
+
## or
|
30
|
+
$ cd /tmp
|
31
|
+
$ wget http://rubyforge.org/projects/editorkicker/.../editorkicker-XXX.tar.gz
|
32
|
+
$ tar xzf editorkicker-XXX.tar.gz
|
33
|
+
$ cd editorkicker-XXX/
|
34
|
+
$ sudo ruby install.rb
|
35
|
+
|
36
|
+
## install cgi-exception
|
37
|
+
$ sudo gem install cgi-exception
|
38
|
+
## or
|
39
|
+
$ cd /tmp
|
40
|
+
$ wget http://rubyforge.org/projects/cgi-exception
|
41
|
+
$ tar xzf cgi-exception-XXX.tar.gz
|
42
|
+
$ cd cgi-exception-XXX/
|
43
|
+
$ sudo ruby install.rb
|
44
|
+
|
45
|
+
It is not recommended to install by RubyGems, because 'require rubygems'
|
46
|
+
is an heavy-weight operation for CGI.
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
== Setup
|
51
|
+
|
52
|
+
ATTENTION! Don't forget to call 'M-x server-start' if you're Emacs user.
|
53
|
+
|
54
|
+
(for Ruby on Rails)
|
55
|
+
|
56
|
+
$ export EDITOR_KICKER="mate -n %s '%s'" (for TextMate)
|
57
|
+
$ export EDITOR_KICKER="emacsclient -n +%s '%s'" (for Emacs)
|
58
|
+
$ ruby script/server # development mode
|
59
|
+
|
60
|
+
Setting of $EDITOR_KICKER is optional. If $EDITOR_KICKER is not set,
|
61
|
+
EditorKicker will detect TextMate or Emacs automatically.
|
62
|
+
|
63
|
+
(for CGI/mod_ruby)
|
64
|
+
|
65
|
+
#!/usr/bin/env ruby
|
66
|
+
require 'cgi'
|
67
|
+
require 'cgi_exception'
|
68
|
+
|
69
|
+
### load and set up editor-kicker only when running in local machine
|
70
|
+
if ENV['SERVER_NAME'] == 'localhost'
|
71
|
+
require 'editor_kicker'
|
72
|
+
## for TextMate
|
73
|
+
mate = '/Applications/TextMate.app/Contents/Resources/mate'
|
74
|
+
ENV['EDITOR_KICKER'] = "#{mate} -l %s '%s'"
|
75
|
+
## for Emacs
|
76
|
+
emacsclient = '/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
|
77
|
+
ENV['EDITOR_KICKER'] = "#{emacsclient} -n -s /tmp/emacs501/server +%s '%s'"
|
78
|
+
end
|
79
|
+
|
80
|
+
cgi = CGI.new
|
81
|
+
print cgi.header
|
82
|
+
print "<h1>Hello</h1>"
|
83
|
+
...
|
84
|
+
|
85
|
+
If you're Emacs user, you have to change owner of socket file
|
86
|
+
(ex. '/tmp/emacsXXX/server') to Apache's process user.
|
87
|
+
|
88
|
+
### assume that CGI script is executed by 'daemon' user.
|
89
|
+
### ('/tmp/emacs501/server' will be created by M-x server-strart)
|
90
|
+
$ sudo chown -R daemon /tmp/emacs501/server
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
== Trouble shooting
|
95
|
+
|
96
|
+
|
97
|
+
=== (Emacs) can't find socket
|
98
|
+
|
99
|
+
Error:
|
100
|
+
|
101
|
+
emacsclient: can't find socket; have you started the server?
|
102
|
+
To start the server in Emacs, type "M-x server-start".
|
103
|
+
|
104
|
+
Solution:
|
105
|
+
|
106
|
+
Type 'M-x server start' in your Emacs.
|
107
|
+
|
108
|
+
In addition if you are CGI user, set $EDITOR_KICKER environment variable
|
109
|
+
to "emacsclient -n -s /tmp/emacs501/server +%s '%s'" in your CGI script
|
110
|
+
to specify socket file by '-s' option.
|
111
|
+
(Notice that '-s' option of emacsclient is available from Emacs 22.)
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
== Todo
|
116
|
+
|
117
|
+
* Merb support
|
118
|
+
* Mack support
|
119
|
+
* Ramaze support
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
== Author
|
124
|
+
|
125
|
+
makoto kuwata <kwa(at)kuwata-lab.com>
|
126
|
+
|
127
|
+
Copyright 2008 kuwata-lab.com all rights reserved.
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
== License
|
132
|
+
|
133
|
+
MIT License
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Release: 0.1.0 $
|
5
|
+
### Copyright 2008 kuwata-lab.com all rights reserved.
|
6
|
+
###
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
|
10
|
+
spec = Gem::Specification.new do |s|
|
11
|
+
## package information
|
12
|
+
s.name = "editorkicker"
|
13
|
+
s.author = "makoto kuwata"
|
14
|
+
s.email = "kwa(at)kuwata-lab.com"
|
15
|
+
s.rubyforge_project = 'editorkicker'
|
16
|
+
s.version = "0.1.0"
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.homepage = "http://editorkicker.rubyforge.org/"
|
19
|
+
s.summary = "a pretty tool to invoke your favorite editor when error raised"
|
20
|
+
s.description = <<-'END'
|
21
|
+
EditorKicker is a pretty tool to invoke your favorite editor and open
|
22
|
+
errored file automatically when error raised in your script.
|
23
|
+
END
|
24
|
+
|
25
|
+
## files
|
26
|
+
files = []
|
27
|
+
files += Dir.glob('lib/*')
|
28
|
+
files += %W[README.txt CHANGES.txt MIT-LICENSE setup.rb #{s.name}.gemspec]
|
29
|
+
files += Dir.glob('plugin/**/*')
|
30
|
+
#files += Dir.glob('doc-api/**/*')
|
31
|
+
s.files = files
|
32
|
+
end
|
33
|
+
|
34
|
+
# Quick fix for Ruby 1.8.3 / YAML bug (thanks to Ross Bamford)
|
35
|
+
if (RUBY_VERSION == '1.8.3')
|
36
|
+
def spec.to_yaml
|
37
|
+
out = super
|
38
|
+
out = '--- ' + out unless out =~ /^---/
|
39
|
+
out
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if $0 == __FILE__
|
44
|
+
Gem::manage_gems
|
45
|
+
Gem::Builder.new(spec).build
|
46
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
##
|
2
|
+
## $Rev$
|
3
|
+
## $Release: 0.1.0 $
|
4
|
+
## Copyright 2008 kuwata-lab.com all rights reserved.
|
5
|
+
##
|
6
|
+
|
7
|
+
##
|
8
|
+
## Invoke your favorite editor and Open errored file by it.
|
9
|
+
##
|
10
|
+
## Don't forget to do `M-x server-start' if you use Emacs.
|
11
|
+
##
|
12
|
+
module EditorKicker
|
13
|
+
|
14
|
+
def self.handle_exception(ex)
|
15
|
+
self.handler.handle(ex)
|
16
|
+
end
|
17
|
+
|
18
|
+
class <<self
|
19
|
+
alias handle handle_exception
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.handler
|
23
|
+
@@handler
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.handler=(handler)
|
27
|
+
@@handler = handler
|
28
|
+
end
|
29
|
+
|
30
|
+
class ExceptionHandler
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@kicker = self # you can set Proc object to @kicker
|
34
|
+
@writable_check = false
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :command, :kicker, :writable_check
|
38
|
+
|
39
|
+
## detect error location from error and open related file
|
40
|
+
def handle(ex)
|
41
|
+
filepath, linenum = detect_location(ex)
|
42
|
+
kick(filepath, linenum) if filepath && linenum
|
43
|
+
end
|
44
|
+
|
45
|
+
## get filename and linenum from error
|
46
|
+
def detect_location(ex, backtrace=nil)
|
47
|
+
filepath = linenum = nil
|
48
|
+
backtrace ||= ex.backtrace
|
49
|
+
if backtrace && !backtrace.empty?
|
50
|
+
tuple = nil
|
51
|
+
if backtrace.find {|str| tuple = get_location(str) }
|
52
|
+
filepath, linenum = tuple
|
53
|
+
end
|
54
|
+
#elsif ex.is_a?(SyntaxEx)
|
55
|
+
# if ex.to_s =~ /^(.+):(\d+): syntax error,/
|
56
|
+
# filepath, linenum = $1, $2.to_i
|
57
|
+
# end
|
58
|
+
elsif ex.to_s =~ /\A(.+):(\d+): / # for SyntaxError
|
59
|
+
filepath, linenum = $1, $2.to_i
|
60
|
+
end
|
61
|
+
return filepath, linenum
|
62
|
+
end
|
63
|
+
|
64
|
+
## get filepath and linenum from string
|
65
|
+
def get_location(str)
|
66
|
+
return nil if str !~ /^(.+):(\d+)(:in `.+'|$)/
|
67
|
+
return nil if @writable_check && !File.writable?($1)
|
68
|
+
return [$1, $2.to_i]
|
69
|
+
end
|
70
|
+
|
71
|
+
## detect command to invoke editor
|
72
|
+
def detect_command
|
73
|
+
command = ENV['EDITOR_KICKER']
|
74
|
+
return command if command
|
75
|
+
bin = '/Applications/TextMate.app/Contents/Resources/mate'
|
76
|
+
return "#{bin} -l %s '%s'" if test(?f, bin)
|
77
|
+
return "emacsclient -n +%s '%s'"
|
78
|
+
end
|
79
|
+
|
80
|
+
## open file with editor
|
81
|
+
def kick(filepath, linenum)
|
82
|
+
if File.exists?(filepath)
|
83
|
+
@kicker.call(filepath, linenum)
|
84
|
+
else
|
85
|
+
log("#{filepath}: not found.")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
## default activity of kick()
|
90
|
+
def call(filepath, linenum) # should separate to a class?
|
91
|
+
command = (@command || detect_command()) % [linenum, filepath] # or [filepath, linenum]
|
92
|
+
log(command)
|
93
|
+
`#{command.untaint}`
|
94
|
+
end
|
95
|
+
|
96
|
+
def log(message)
|
97
|
+
$stderr.puts "** [EditorKicker] #{message}"
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
self.handler = ExceptionHandler.new
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2008 kuwata-lab.com all rights reserved.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,67 @@
|
|
1
|
+
=====================================
|
2
|
+
EditorKicker plugin for Ruby on Rails
|
3
|
+
=====================================
|
4
|
+
|
5
|
+
Release: 0.1.0
|
6
|
+
|
7
|
+
|
8
|
+
About
|
9
|
+
-----
|
10
|
+
|
11
|
+
EditorKicker is a pretty tool to invoke your favorite editor and
|
12
|
+
open errored file automatically when an exception raised on your script.
|
13
|
+
This is a plug-in of EditorKicker for Ruby on Rails.
|
14
|
+
|
15
|
+
Notice that this plug-in works only under development mode.
|
16
|
+
So it is no problem to commit this plug-in files into your app repository.
|
17
|
+
|
18
|
+
|
19
|
+
Target
|
20
|
+
------
|
21
|
+
|
22
|
+
* Rails version
|
23
|
+
- 2.1.X
|
24
|
+
- 2.0.X
|
25
|
+
- 1.2.X (I hope)
|
26
|
+
|
27
|
+
* Supported text editor by default
|
28
|
+
- TextMate
|
29
|
+
- Emacs
|
30
|
+
|
31
|
+
|
32
|
+
Install
|
33
|
+
-------
|
34
|
+
|
35
|
+
$ ruby script/plugin install http://github.com/kwatch/editorkicker.git/ruby/plugin/rails/editorkicker
|
36
|
+
|
37
|
+
|
38
|
+
Usage
|
39
|
+
-----
|
40
|
+
|
41
|
+
1. Intall EditorKicker plugin into your Rails application.
|
42
|
+
2. (optional) Set environtment variable $EDITOR_KICKER with command string to
|
43
|
+
invoke text editor (default "mate -l %s '%s'" or "emacsclient -n +%s '%s').
|
44
|
+
3. Restart Rails server in development mode.
|
45
|
+
4. Do 'M-x server-start' if you want to use Emacs. (*** IMPORTANT! ***)
|
46
|
+
|
47
|
+
|
48
|
+
Setup
|
49
|
+
-----
|
50
|
+
|
51
|
+
Environment variable $EDITOR_KICKER represents command string to invoke your
|
52
|
+
favorite editor with filename and linenum.
|
53
|
+
Default is "mate -l %s '%s'" or "emacsclient -n +%s '%s'".
|
54
|
+
|
55
|
+
|
56
|
+
Author
|
57
|
+
------
|
58
|
+
|
59
|
+
makoto kuwata <kwa(at)kuwata-lab.com>
|
60
|
+
|
61
|
+
Copyright 2008 kuwata-lab.com all rights reserved.
|
62
|
+
|
63
|
+
|
64
|
+
License
|
65
|
+
-------
|
66
|
+
|
67
|
+
MIT License
|
@@ -0,0 +1,64 @@
|
|
1
|
+
##
|
2
|
+
## $Rev$
|
3
|
+
## $Release: 0.1.0 $
|
4
|
+
## Copyright 2008 kuwata-lab.com all rights reserved.
|
5
|
+
##
|
6
|
+
|
7
|
+
##
|
8
|
+
## Notice that this plugin is loaded only when in development mode.
|
9
|
+
## So you can commit this plugin into your Rails app repository.
|
10
|
+
##
|
11
|
+
|
12
|
+
if defined?(RAILS_ENV) && RAILS_ENV == 'development'
|
13
|
+
|
14
|
+
require 'editor_kicker'
|
15
|
+
|
16
|
+
module ::EditorKicker
|
17
|
+
|
18
|
+
class RailsExceptionHandler < ExceptionHandler
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
super
|
22
|
+
self.writable_check = true
|
23
|
+
end
|
24
|
+
|
25
|
+
## detect filepath and linenum
|
26
|
+
def detect_location(ex, backtrace=nil)
|
27
|
+
if ex.is_a?(ActionView::TemplateError)
|
28
|
+
# assert ex.respond_to?(:file_name)
|
29
|
+
# assert ex.respond_to?(:line_number)
|
30
|
+
filepath, linenum = ex.file_name, ex.line_number
|
31
|
+
if filepath && linenum
|
32
|
+
filepath = "app/views/#{filepath}" unless filepath[0] == ?/ || filepath =~ /\Aapp\/views\//
|
33
|
+
return filepath, linenum
|
34
|
+
end
|
35
|
+
end
|
36
|
+
# assert ex.respond_to?(:application_backtrace)
|
37
|
+
return super(ex, ex.application_backtrace)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
self.handler = RailsExceptionHandler.new
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
module ::ActionController #:nodoc:
|
48
|
+
module Rescue #:nodoc:
|
49
|
+
protected
|
50
|
+
|
51
|
+
alias _rescue_action_locally_orig rescue_action_locally #:nodoc:
|
52
|
+
|
53
|
+
def rescue_action_locally(ex) # :nodoc:
|
54
|
+
ret = _rescue_action_locally_orig(ex) # call original
|
55
|
+
::EditorKicker.handle_exception(ex)
|
56
|
+
ret
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
::ActionController::Base.new.logger.info("** [EditorKicker] loaded.")
|
63
|
+
|
64
|
+
end
|