spectator-emacs 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spectator-emacs (0.1.0)
4
+ spectator-emacs (0.2.0)
5
5
  docopt
6
6
  open4
7
7
  rb-inotify (~> 0.8.8)
data/README.md CHANGED
@@ -54,6 +54,7 @@ You can customize various aspects of how spectator-emacs works:
54
54
  `enotify-failure-face`for failures, `enotify-warning-face` for
55
55
  success with pending examples)
56
56
  * The Enotify slot id to register for notifications
57
+ * The major mode used for the rspec output buffer
57
58
 
58
59
  An example `.spectator-emacs' file:
59
60
 
@@ -67,7 +68,9 @@ require 'spectator/emacs'
67
68
  :success => "success",
68
69
  :pending => "pending"
69
70
  },
70
- :slot_id => "project foobar"
71
+ # Use org-mode to display the report buffer
72
+ :report_buffer_mode => "org",
73
+ :slot_id => "project foobar",
71
74
  :notification_face => {
72
75
  :pending => :font_lock_warning_face,
73
76
  # see the docs for detail on Symbol#keyword
@@ -138,9 +141,8 @@ Put this in your .emacs:
138
141
 
139
142
  ```lisp
140
143
  (require 'enotify)
144
+ (require 'enotify-tdd)
141
145
  (enotify-minor-mode t)
142
- (add-to-list 'load-path "path/to/enotify-spectator-emacs")
143
- (require 'enotify-spectator-emacs)
144
146
  ```
145
147
 
146
148
  ## Copyright
data/Rakefile CHANGED
@@ -44,7 +44,7 @@ task :default => :spec
44
44
 
45
45
  desc "Run spectator-emacs"
46
46
  task :'spectator-emacs' do
47
- load "bin/spectator-emacs"
47
+ system "ruby", "-Ilib", "bin/spectator-emacs"
48
48
  end
49
49
 
50
50
  ## YARD stuff
@@ -0,0 +1,300 @@
1
+ ;;; enotify-spectator.el --- Enotify plugin for spectator-emacs (ruby TDD)
2
+
3
+ ;; Copyright (C) 2012 Alessandro Piras
4
+
5
+ ;; Author: Alessandro Piras <laynor@gmail.com>
6
+ ;; Keywords: convenience
7
+ ;; URL: http://www.github.com/laynor/spectator-emacs
8
+
9
+ ;; This file is part of spectator-emacs.
10
+
11
+ ;; This program is free software; you can redistribute it and/or modify
12
+ ;; it under the terms of the GNU General Public License as published by
13
+ ;; the Free Software Foundation, either version 3 of the License, or
14
+ ;; (at your option) any later version.
15
+
16
+ ;; This program is distributed in the hope that it will be useful,
17
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ ;; GNU General Public License for more details.
20
+
21
+ ;; You should have received a copy of the GNU General Public License
22
+ ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ ;;; Commentary:
25
+
26
+ ;; This enotify plugin is meant to be used together with the
27
+ ;; spectator-emacs ruby gem.
28
+ ;;
29
+ ;; Installation: add this file to your load path and require it:
30
+ ;; (add-to-list 'load-path "path/to/enotify-spectator/")
31
+ ;; (require 'enotify-spectator)
32
+ ;;
33
+ ;; This plugin can take advantage of alert.el. If you want to enable
34
+ ;; alert.el alerts, customize `enotify-spectator-use-alert' and ensure
35
+ ;; alert.el is loaded before this file.
36
+
37
+ ;;; Code:
38
+
39
+ (require 'enotify)
40
+
41
+ (defgroup enotify-spectator nil
42
+ "Enotify plugin for spectator-emacs"
43
+ :group 'enotify)
44
+
45
+ (defcustom enotify-spectator-use-alert nil
46
+ "whether enotify-spectator should use alert.el"
47
+ :group 'enotify-spectator
48
+ :type 'boolean)
49
+
50
+ (defcustom enotify-spectator-alert-severity 'trivial
51
+ "severity for alert.el alerts"
52
+ :group 'enotify-spectator
53
+ :type '(choice (const :tag "Urgent" urgent)
54
+ (const :tag "High" high)
55
+ (const :tag "Moderate" moderate)
56
+ (const :tag "Normal" normal)
57
+ (const :tag "Low" low)
58
+ (const :tag "Trivial" trivial)))
59
+
60
+ (defcustom enotify-spectator-alert-use-separate-log-buffers nil
61
+ "whether enotify-spectator should use different alert log
62
+ buffers for each project."
63
+ :group 'enotify-spectator
64
+ :type 'boolean)
65
+
66
+
67
+ (defcustom enotify-spectator-change-face-timeout nil
68
+ "amount of seconds after which the notification face should be changed."
69
+ :group 'enotify-spectator
70
+ :type '(choice (const nil) integer))
71
+
72
+ (defcustom enotify-spectator-timeout-face :standard
73
+ "face to apply to the notification text on timeout"
74
+ :group 'enotify-spectator
75
+ :type '(choice (const :tag "Standard enotify face" :standard )
76
+ (const :tag "Standard enotify success face" :success)
77
+ (const :tag "Standard enotify warning face" :warning)
78
+ (const :tag "Standard enotify failure face" :failure)
79
+ face))
80
+
81
+ (defcustom enotify-rspec-handler 'enotify-rspec-handler
82
+ "Message handler for enotify spectator-emacs notifications.
83
+ This function should take 2 arguments, (id data), where id is the
84
+ enotify slot id, and data contains the rspec output.
85
+ The default handler just writes the results in a buffer in org-mode.")
86
+
87
+ (defvar enotify-rspec-result-message-handler 'enotify-rspec-result-message-handler
88
+ "Don't touch me - used by spectator-emacs.")
89
+
90
+ (defvar enotify-rspec-mouse-1-handler 'enotify-rspec-mouse-1-handler
91
+ "Mouse-1 handler function. It takes an event parameter. See enotify README for details.")
92
+
93
+ (defcustom spectator-get-project-root-dir-function 'rinari-root
94
+ "Function used to get ruby project root."
95
+ :group 'enotify-spectator)
96
+
97
+ (defcustom spectator-test-server-cmd "spork"
98
+ "Test server command - change this to bundle exec spork if you are using bundle.
99
+ Change to nil if you don't want to use any test server."
100
+ :group 'enotify-spectator)
101
+
102
+ (defcustom spectator-watchr-cmd "spectator-emacs"
103
+ "Command to run watchr - change this to bundle exec watchr if you are using bundle."
104
+ :group 'enotify-spectator)
105
+
106
+
107
+
108
+ ;;;; Alert.el stuff
109
+
110
+ (when (featurep 'alert)
111
+ (defun enotify-spectator-alert-id (info)
112
+ (car (plist-get info :data)))
113
+ (defun enotify-spectator-alert-face (info)
114
+ (enotify-face (cdr (plist-get info :data))))
115
+
116
+ (defun enotify-spectator-chomp (str)
117
+ "Chomp leading and tailing whitespace from STR."
118
+ (while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'"
119
+ str)
120
+ (setq str (replace-match "" t t str)))
121
+ str)
122
+
123
+ (defun* enotify-spectator-colorized-summary (info &optional (with-timestamp t))
124
+ (let* ((s+t (plist-get info :message))
125
+ (summary (if with-timestamp s+t (car (last (split-string s+t ":"))))))
126
+ (enotify-spectator-chomp
127
+ (propertize summary 'face (enotify-spectator-alert-face info)))))
128
+
129
+ (defun enotify-spectator-alert-log (info)
130
+ (let ((bname (format "*Alerts - Spectator-emacs [%s]*" (enotify-spectator-alert-id info))))
131
+ (with-current-buffer
132
+ (get-buffer-create bname)
133
+ (goto-char (point-max))
134
+ (insert (format-time-string "%H:%M %p - ")
135
+ (enotify-spectator-colorized-summary info nil)
136
+ ?\n))))
137
+
138
+ (defun alert-spectator-notify (info)
139
+ "alert.el notifier function for enotify-spectator."
140
+ (when enotify-spectator-alert-use-separate-log-buffers
141
+ (enotify-spectator-alert-log info))
142
+ (message "%s: %s"
143
+ (alert-colorize-message (format "Enotify - spectator-emacs [%s]:"
144
+ (enotify-spectator-alert-id info))
145
+ (plist-get info :severity))
146
+ (enotify-spectator-colorized-summary info)))
147
+
148
+ ;;; enotify-spectator alert style
149
+ (alert-define-style 'enotify-spectator
150
+ :title "Display message in minibuffer for enotify-spectator alerts"
151
+ :notifier #'alert-spectator-notify
152
+ :remover #'alert-message-remove)
153
+
154
+ (defun enotify-spectator-summary (id)
155
+ "Extract summary from enotify notifiations sent by spectator-emacs."
156
+ (let* ((notification (enotify-mode-line-notification id))
157
+ (help-text (plist-get notification :help))
158
+ (face (enotify-face (plist-get notification :face)))
159
+ (summary-text (nth 1 (split-string help-text "\n"))))
160
+ summary-text))
161
+
162
+
163
+ (defun enotify-spectator-face (id)
164
+ "Extracts the face used for the enotify notification sent by spectator-emacs"
165
+ (enotify-face (plist-get (enotify-mode-line-notification id) :face)))
166
+
167
+ ;;; Use enotify-spectator style for all the alerts whose category is enotify-spectator
168
+ (alert-add-rule :predicate (lambda (info)
169
+ (eq (plist-get info :category)
170
+ 'enotify-spectator))
171
+ :style 'enotify-spectator))
172
+
173
+
174
+ ;;;; Enotify stuff
175
+
176
+ (defun enotify-rspec-result-buffer-name (id)
177
+ (format "*RSpec Results: %s*" id))
178
+
179
+ (defun enotify-rspec-handler (id data)
180
+ (let ((buf (get-buffer-create (enotify-rspec-result-buffer-name id))))
181
+ (save-current-buffer
182
+ (set-buffer buf)
183
+ (erase-buffer)
184
+ (insert data)
185
+ (flet ((message (&rest args) (apply 'format args)))
186
+ (org-mode)))))
187
+
188
+ (defun enotify-rspec-result-message-handler (id data)
189
+ (when enotify-spectator-change-face-timeout
190
+ (run-with-timer enotify-spectator-change-face-timeout nil
191
+ 'enotify-change-notification-face
192
+ id enotify-spectator-timeout-face))
193
+ (when (and enotify-spectator-use-alert (featurep 'alert))
194
+ (let ((alert-log-messages (if enotify-spectator-alert-use-separate-log-buffers
195
+ nil
196
+ alert-log-messages)))
197
+ (alert (enotify-spectator-summary id)
198
+ :title id
199
+ :data (cons id (enotify-spectator-face id))
200
+ :category 'enotify-spectator
201
+ :severity enotify-spectator-alert-severity)))
202
+ (funcall enotify-rspec-handler id data))
203
+
204
+ (defun enotify-rspec-mouse-1-handler (event)
205
+ (interactive "e")
206
+ (switch-to-buffer-other-window
207
+ (enotify-rspec-result-buffer-name
208
+ (enotify-event->slot-id event))))
209
+
210
+
211
+ ;;;; Rinari / spectator-emacs stuff
212
+ (defvar spectator-script " # -*-ruby-*-
213
+ require 'rspec-rails-watchr-emacs'
214
+ @specs_watchr ||= Rspec::Rails::Watchr.new(self,
215
+ ## uncomment the line below if you are using RspecOrgFormatter
216
+ # :error_count_line => -6,
217
+ ## uncomment to customize the notification messages that appear on the notification area
218
+ # :notification_message => {:failure => 'F', :success => 'S', :pending => 'P'},
219
+ ## uncomment to customize the message faces (underscores are changed to dashes)
220
+ # :notification_face => {
221
+ # :failure => :my_failure_face, #will be `my-failure-face' on emacs
222
+ # :success => :my_success_face,
223
+ # :pending => :my_pending_face},
224
+ ## uncomment for custom matcher!
225
+ # :custom_matcher => lambda { |path, specs| puts 'Please fill me!' }
226
+ ## uncomment for custom summary extraction
227
+ # :custom_extract_summary_proc => lambda { |results| puts 'Please Fill me!' }
228
+ ## uncomment for custom enotify slot id (defaults to the base directory name of
229
+ ## your application rendered in CamelCase
230
+ # :slot_id => 'My slot id'
231
+ )
232
+ ")
233
+
234
+
235
+ (defun spectator-generate-script ()
236
+ "Creates a spectator-emacs script in the project root directory"
237
+ (let ((dir (funcall spectator-get-project-root-dir-function)))
238
+ (when dir
239
+ (with-temp-file (concat dir "/.spectator")
240
+ (insert spectator-script)))))
241
+
242
+ (defun spectator-script ()
243
+ (interactive)
244
+ (find-file (concat (funcall spectator-get-project-root-dir-function) "/.spectator")))
245
+
246
+ (defun spectator-run-in-shell (cmd &optional dir bufname)
247
+ (let* ((default-directory (or dir default-directory))
248
+ (shproc (shell bufname)))
249
+ (comint-send-string shproc (concat cmd "\n"))))
250
+
251
+ (defun spectator-app-name ()
252
+ (let ((root-dir (funcall spectator-get-project-root-dir-function)))
253
+ (when root-dir
254
+ (apply 'concat
255
+ (mapcar 'capitalize
256
+ (split-string (file-name-nondirectory
257
+ (directory-file-name
258
+ root-dir))
259
+ "[^a-zA-Z0-9]"))))))
260
+
261
+ (defun spectator ()
262
+ (interactive)
263
+ (let ((project-root (funcall spectator-get-project-root-dir-function))
264
+ (app-name (spectator-app-name)))
265
+ (spectator-run-in-shell spectator-test-server-cmd
266
+ project-root
267
+ (concat "*Spork - " app-name "*"))
268
+ (spectator-run-in-shell (concat spectator-watchr-cmd " .spectator")
269
+ project-root
270
+ (concat "*Spectator - " app-name "*"))))
271
+
272
+ ;;; Some utilities
273
+
274
+ (defun spectator-find-spectator-1 (pattern)
275
+ (let ((bnames (mapcar 'buffer-name (buffer-list)))
276
+ (app-name (spectator-app-name)))
277
+ (when app-name
278
+ (find-if (lambda (el) (string-match (format "%s.*%s" pattern app-name) el))
279
+ bnames))))
280
+ (defun spectator-maybe-switch-to-buffer (buf &optional msg)
281
+ (if buf
282
+ (switch-to-buffer buf)
283
+ (message "Could not open buffer. %s" (or msg "Did you run spectator? Try M-x spectator RET."))))
284
+
285
+ (defun spectator-find-spectator ()
286
+ (interactive)
287
+ (spectator-maybe-switch-to-buffer (spectator-find-spectator-1 "*Spectator")))
288
+
289
+ (defun spectator-find-spectator-results ()
290
+ (interactive)
291
+ (spectator-maybe-switch-to-buffer (spectator-find-spectator-1 "*RSpec Results")
292
+ "Either spectator is not running or no tests have been executed yet."))
293
+
294
+ (defun spectator-find-spectator-spork ()
295
+ (interactive)
296
+ (spectator-maybe-switch-to-buffer (spectator-find-spectator-1 "*Spork")))
297
+
298
+ (provide 'enotify-spectator)
299
+
300
+ ;;; enotify-spectator.el ends here
@@ -1,6 +1,6 @@
1
1
  module Spectator
2
2
  module Emacs
3
3
  # spectator-emacs version
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
6
6
  end
@@ -3,6 +3,12 @@ require 'spectator'
3
3
  require 'socket'
4
4
  require 'open4'
5
5
 
6
+ class NilClass
7
+ def to_lisp
8
+ 'nil'
9
+ end
10
+ end
11
+
6
12
  class Object
7
13
  # Returns a string representing the object as a lisp sexp.
8
14
  def to_lisp
@@ -294,7 +300,7 @@ module Spectator
294
300
 
295
301
  # Registers the slot named `@enotify_slot_id` with Enotify.
296
302
  def enotify_register
297
- enotify_send :register => @enotify_slot_id, :handler_fn => :enotify_rspec_result_message_handler
303
+ enotify_send :register => @enotify_slot_id, :handler_fn => "tdd"
298
304
  end
299
305
 
300
306
  # Sends a notification to the enotify host with the RSpec results.
@@ -312,9 +318,9 @@ module Spectator
312
318
  :text => @notification_messages[status],
313
319
  :face => @notification_face[status],
314
320
  :help => format_tooltip(stats),
315
- :mouse_1 => :enotify_rspec_mouse_1_handler
321
+ :mouse_1 => "tdd"
316
322
  },
317
- :data => stdout
323
+ :data => { :mode => @report_buffer_mode, :report_text => stdout }
318
324
  }
319
325
 
320
326
  enotify_send message
@@ -394,6 +400,12 @@ module Spectator
394
400
  # the faces to apply to the notification *icon* in the Emacs modeline.
395
401
  # Values must be {Symbol}s, like for example `:font_lock_constant_face`
396
402
  # in order to use Emacs' `font-lock-warning-face`.
403
+ # ##### :report_buffer_mode ({String})
404
+ # The major mode to use for the report buffer on emacs.
405
+ # It must be specified in the same way as an emacs magic comment, i.e.
406
+ # without the trailing "-mode".
407
+ # For example, if you are using RspecOrgFormatter, and you want to use
408
+ # org-mode to display the report, specify `"org"`.
397
409
  # Defaults to
398
410
  #
399
411
  # ```
@@ -428,6 +440,7 @@ module Spectator
428
440
  puts "======= OPTIONS ======="
429
441
  options.each {|k, v| puts "#{k} => #{v}"}
430
442
  @enotify_host = options[:enotify_host]
443
+ @report_buffer_mode = options[:report_buffer_mode]
431
444
  @enotify_port = options[:enotify_port]
432
445
  @notification_messages = options[:notification_messages]
433
446
  @notification_face = options[:notification_face]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectator-emacs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-03 00:00:00.000000000 Z
12
+ date: 2013-02-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rdoc
@@ -195,6 +195,7 @@ files:
195
195
  - README.md
196
196
  - Rakefile
197
197
  - bin/spectator-emacs
198
+ - emacs/enotify-spectator.el
198
199
  - lib/spectator/emacs.rb
199
200
  - lib/spectator/emacs/version.rb
200
201
  - spec/emacs_spec.rb
@@ -216,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
217
  version: '0'
217
218
  segments:
218
219
  - 0
219
- hash: -2575753694497142155
220
+ hash: -703244129636977448
220
221
  required_rubygems_version: !ruby/object:Gem::Requirement
221
222
  none: false
222
223
  requirements:
@@ -225,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
226
  version: '0'
226
227
  segments:
227
228
  - 0
228
- hash: -2575753694497142155
229
+ hash: -703244129636977448
229
230
  requirements: []
230
231
  rubyforge_project:
231
232
  rubygems_version: 1.8.24