]> git.rkrishnan.org Git - .emacs.d.git/blob - emacs/nxhtml/related/flymake-js.el
submodulized .emacs.d setup
[.emacs.d.git] / emacs / nxhtml / related / flymake-js.el
1 ;;; flymake-js.el --- Flymake setup for javascript files
2 ;;
3 ;; Author: Lennart Borgman
4 ;; Created: Sun Dec 02 07:52:52 2007
5 ;; Version:
6 ;; Last-Updated:
7 ;; URL:
8 ;; Keywords:
9 ;; Compatibility:
10 ;;
11 ;; Features that might be required by this library:
12 ;;
13 ;;   None
14 ;;
15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16 ;;
17 ;;; Commentary:
18 ;;
19 ;; This library provides basic setup for using `flymake-mode' with
20 ;; javascript files.  To use this you must have a javascript
21 ;; installed.  There are (at least) two free javascript engines (both
22 ;; from Mozill) you can use, Rhino (implemented in Java) or
23 ;; SpiderMonkey (implemented in C). Both are supported in this
24 ;; library.
25 ;;
26 ;; I have not been able to find binaries for SpiderMonkeys to
27 ;; download. However the Rhino engine seems fast enough and is easy to
28 ;; install. You find them at
29 ;;
30 ;;    http://www.mozilla.org/rhino/
31 ;;    http://www.mozilla.org/js/spidermonkey/
32 ;;
33 ;; Put this file in your Emacs `load-path' and then in .emacs
34 ;;
35 ;;    (require 'flymake-js)
36 ;;
37 ;;
38 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39 ;;
40 ;;; Change log:
41 ;;
42 ;;
43 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
44 ;;
45 ;; This program is free software; you can redistribute it and/or
46 ;; modify it under the terms of the GNU General Public License as
47 ;; published by the Free Software Foundation; either version 2, or
48 ;; (at your option) any later version.
49 ;;
50 ;; This program is distributed in the hope that it will be useful,
51 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
52 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
53 ;; General Public License for more details.
54 ;;
55 ;; You should have received a copy of the GNU General Public License
56 ;; along with this program; see the file COPYING.  If not, write to
57 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
58 ;; Floor, Boston, MA 02110-1301, USA.
59 ;;
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61 ;;
62 ;;; Code:
63
64 ;; Flymake JS mode
65
66 (require 'flymake)
67
68 (defconst flymake-js-dir
69   (file-name-directory (or load-file-name
70                            (when (boundp 'bytecomp-filename) bytecomp-filename)
71                            buffer-file-name))
72   "Installation directory for flymake-js.")
73
74 ;;;###autoload
75 (defgroup flymake-js nil
76   "Customization group for flymake for javascript."
77   :group 'flymake)
78
79 (defcustom flymake-allowed-js-file-name-masks '(("\\.json\\'" flymake-js-init)
80                                                 ("\\.js\\'" flymake-js-init))
81   "Filename extensions that switch on js syntax checks."
82   :type '(repeat (list (regexp :tag "File name regexp")
83                        (function :tag "Init function")
84                        (choice (const :tag "No cleanup function" nil)
85                                (function :tag "Cleanup function"))))
86   :group 'flymake-js)
87
88
89 (defvar flymake-js-err-line-pattern-re
90   '(;; These pattern are probably for Rhino:
91     ("^js: \"\\(.+\\)\", line \\([0-9]+\\): \\(.+\\)$" 1 2 nil 3)
92     ("^js: uncaught JavaScript \\(.+\\)$" nil nil nil 1)
93     ;; For Rhino with jslint.js
94     ("^Lint at line \\([[:digit:]]+\\) character \\([[:digit:]]+\\): \\(.+\\)$" nil 1 2 3)
95     ;; These pattern are probably for SpiderMonkey:
96     ("^\\(.+\\)\:\\([0-9]+\\)\: \\(SyntaxError\:.+\\)\:$" 1 2 nil 3)
97     ("^\\(.+\\)\:\\([0-9]+\\)\: \\(strict warning: trailing comma.+\\)\:$" 1 2 nil 3))
98   "Regexp matching JavaScript error messages")
99
100 (defcustom flymake-js-rhino-jar "/path/to/js.jar"
101   "Path to Rihno jar file.
102 Download and install Rhino JavaScript engine from
103
104   URL `http://www.mozilla.org/rhino/'
105
106 This variable should point to the file js.jar that is in the top
107 directory of the Rhino dir tree. \(It was differently named
108 earlier and might perhaps be renamed again.)"
109   :type '(file :must-match t)
110   :group 'flymake-js)
111
112 ;;(setq flymake-log-level 3)
113 ;;(setq flymake-js-rhino-use-jslint nil)
114 (defcustom flymake-js-rhino-use-jslint nil
115   "Use jslint.js if this is non-nil.
116 jslint.js will give you warnings about style things like indentation too."
117   :type 'boolean
118   :group 'flymake-js)
119
120 (defcustom flymake-js-rhino-js (expand-file-name "rhino.js" flymake-js-dir)
121   "Path to rhino.js.
122 Only used if `flymake-js-rhino-use-jslint' is nil.
123
124 This file and env.js must be placed in the same directory. Default
125 is this directory.
126
127 Those files comes with Rhino, see `flymake-js-rhino-jar'."
128   :type '(file :must-match t)
129   :group 'flymake-js)
130
131 (defcustom flymake-js-rhino-jslint (expand-file-name "jslint.js" flymake-js-dir)
132   "Path to jslint.js.
133 Only used if `flymake-js-rhino-use-jslint' is t.
134
135 If you do not have this file you can download it from URL
136 `http://www.jslint.com/rhino/jslint.js'. I had to change quit(2)
137 to quit(0) in it \(which seems like a bug in `flymake-mode' to
138 me)."
139   :type '(file :must-match t)
140   :group 'flymake-js)
141
142 ;;(flymake-js-check-rhino-js)
143 (defun flymake-js-check-rhino-js ()
144   "Checks that the path to env.js is ok."
145   (with-current-buffer (find-file-noselect flymake-js-rhino-js)
146     (let* ((proj-folder (file-name-as-directory (file-name-directory (buffer-file-name))))
147            (proj-line (concat "var project_folder = 'file:///" proj-folder "';"))
148            (proj-line-re "^\\W*var\\W+project_folder\\W*=\\W*"))
149       (save-restriction
150         (widen)
151         (goto-char (point-max))
152         (if (re-search-backward proj-line-re nil t)
153             (let ((beg (line-beginning-position))
154                   (end (line-end-position)))
155               (unless (string= (buffer-substring-no-properties beg end)
156                                proj-line)
157                 (delete-region beg end)
158                 (insert proj-line)
159                 (basic-save-buffer)))
160           (goto-char (point-min))
161           (insert proj-line "\n")
162           (basic-save-buffer))))))
163
164 (defcustom flymake-js-engine 'rhino
165   "Javascript engine to use.
166 You may have to restart Emacs after changing this - if you can
167 not figure out what buffers and processes to kill.
168
169 I have only been able to test Rhino since I do not have
170 SpiderMonkey."
171   :type '(choice (const :tag "Rhino" rhino)
172                  (const :tag "SpiderMonkey" spidermonkey))
173   :group 'flymake-js)
174
175 (defun flymake-js-init ()
176   (message "running flymake-js-init")
177   (let* ((temp-file (flymake-init-create-temp-buffer-copy
178                      'flymake-create-temp-inplace))
179          (local-file (file-relative-name
180                       temp-file
181                       (file-name-directory buffer-file-name))))
182     (flymake-js-check-has-engine)
183     (cond
184      ((eq flymake-js-engine 'rhino)
185       (list "java" (list "-jar" flymake-js-rhino-jar
186                          (if flymake-js-rhino-use-jslint
187                              flymake-js-rhino-jslint
188                            flymake-js-rhino-js)
189                          local-file)))
190      ((eq flymake-js-engine 'spidermonkey)
191       (list "js" (list "-s" local-file)))
192      (t
193       (error "Bad value: %s" flymake-js-engine)))))
194
195 (defvar flymake-js-has-engine nil)
196
197 (defun flymake-js-check-has-engine ()
198   "Check for the needed files."
199   (if flymake-js-has-engine
200       t
201     (cond
202      ;; Rhino
203      ((eq flymake-js-engine 'rhino)
204       (unless (executable-find "java")
205         (error "Could not find java executable"))
206       (unless (file-exists-p flymake-js-rhino-jar)
207         (error "Could not find file %s\n\nPlease customize flymake-js-rhino-jar\n"
208                flymake-js-rhino-jar))
209       (if flymake-js-rhino-use-jslint
210           (unless (file-exists-p flymake-js-rhino-jslint)
211             (error "Could not find file %s" flymake-js-rhino-jslint))
212         (unless (file-exists-p flymake-js-rhino-js)
213           (error "Could not find file %s" flymake-js-rhino-js))
214         (flymake-js-check-rhino-js)))
215      ;; SpiderMonkey
216      ((eq flymake-js-engine 'spidermonkey)
217       (unless (executable-find "js")
218         (error "Could not find js program")))
219      (t
220       (error "Bad value: %s" flymake-js-engine)))
221     (setq flymake-js-has-engine t)))
222
223 ;;;###autoload
224 (defun flymake-js-load ()
225   (dolist (rec flymake-allowed-js-file-name-masks)
226     (add-to-list 'flymake-allowed-file-name-masks rec))
227   (dolist (rec flymake-js-err-line-pattern-re)
228     (add-to-list 'flymake-err-line-patterns rec)))
229
230 ;;(eval-after-load 'javascript (flymake-js-load))
231
232 (provide 'flymake-js)
233 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
234 ;;; flymake-js.el<2> ends here