DivmodNevow/Athena/Emacs/Files: javascript-mode.el

File javascript-mode.el, 9.6 kB (added by exarkun, 2 years ago)

Emacs javascript-mode library

Line 
1 ;;; javascript-mode.el --- major mode for editing JavaScript code
2
3 ;; Copyright (C) 1997-2001 Steven Champeon
4 ;;               2002      Ville Skytt?
5
6 ;; Author:     1997 Steven Champeon <schampeo@hesketh.com>
7 ;; Maintainer: Ville Skytt? <scop@xemacs.org>
8 ;; Keywords:   languages javascript
9
10 ;; This file is part of XEmacs.
11
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING.  If not, write to
24 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
26
27 ;; Synched up with: not in GNU Emacs.
28
29 ;;; Commentary:
30
31 ;; javascript-mode was originally derived from java-cust.el
32 ;; (by Jonathan Payne) by Steven Champeon. It has been modified
33 ;; a lot afterwards by Ville Skytt?.
34
35 ;; Contributors:
36 ;;   Sreng Truong      (bug fix for 21.1)
37 ;;   Sebastian Delmont (fix for prototype function indentation problems)
38 ;;   Stefan Schlee     (GNU Emacs compatibility fixes)
39
40 ;; TODO:
41 ;; - Multiple font-lock/highlight levels.
42 ;; - Investigate if Semantic Bovinator should be used.
43 ;; - Check syntax-table stuff.
44
45 ;;; Code:
46
47 (require 'cc-mode)
48 (require 'comint)
49
50 (eval-when-compile
51   (require 'regexp-opt)
52   (require 'font-lock)
53   (require 'speedbar)
54   )
55
56 ;; ------------------------------------------------------------------------ ;;
57
58 (defconst javascript-mode-version "1.7" "Version of `javascript-mode'.")
59
60 ;; ------------------------------------------------------------------------ ;;
61
62 (defgroup javascript nil
63   "Major mode for editing JavaScript code."
64   :tag "JavaScript"
65   :group 'languages
66   :prefix "javascript-")
67
68 (defcustom javascript-mode-hook nil
69   "Hook for customizing `javascript-mode'."
70   :group 'javascript
71   :type 'hook)
72
73 (defgroup javascript-shell nil
74   "JavaScript shell options."
75   :group 'javascript
76   :prefix "javascript-shell-")
77
78 (defcustom javascript-shell-command "jsshell"
79   "*Command for starting `javascript-shell'.
80 Set arguments for this command in `javascript-shell-command-args'."
81   :type 'string
82   :group 'javascript-shell)
83
84 (defcustom javascript-shell-command-args '()
85   "*Command line arguments for `javascript-shell-command'."
86   :type '(repeat (string :tag "Argument"))
87   :group 'javascript-shell)
88
89 (defcustom javascript-shell-prompt-pattern "^js> *"
90   "*JavaScript shell prompt pattern."
91   :type 'regexp
92   :group 'javascript-shell)
93
94 (defcustom javascript-shell-mode-hook nil
95   "Hook for customizing `javascript-shell-mode'."
96   :type 'hook
97   :group 'javascript-shell)
98
99 ;; ------------------------------------------------------------------------ ;;
100
101 (defvar javascript-mode-abbrev-table nil
102   "Abbrev table in use in `javascript-mode' buffers.")
103 (define-abbrev-table 'javascript-mode-abbrev-table ())
104
105 ;; ------------------------------------------------------------------------ ;;
106
107 (defvar javascript-mode-map nil
108   "Keymap used in `javascript-mode' buffers.")
109 (if javascript-mode-map
110     ()
111   (setq javascript-mode-map (copy-keymap c++-mode-map))
112   (define-key javascript-mode-map [(meta backspace)] 'backward-kill-word)
113   (define-key javascript-mode-map [(meta backward)]  'backward-kill-word)
114   (define-key javascript-mode-map [(meta delete)]    'backward-kill-word)
115   (define-key javascript-mode-map [(meta control h)] 'backward-kill-word)
116   )
117
118 ;; ------------------------------------------------------------------------ ;;
119
120 ;; Reserved words in JavaScript.
121 (defconst javascript-reserved-words
122   (eval-when-compile
123     (regexp-opt
124      '(
125        "abstract"
126        "boolean"
127        "break"
128        "byte"
129        "case"
130        "catch"
131        "char"
132        "class"
133        "const"
134        "continue"
135        "debugger"
136        "default"
137        "delete"
138        "do"
139        "double"
140        "else"
141        "enum"
142        "export"
143        "extends"
144        "false"
145        "final"
146        "finally"
147        "float"
148        "for"
149        "function"
150        "goto"
151        "if"
152        "implements"
153        "import"
154        "in"
155        "instanceof"
156        "int"
157        "interface"
158        "long"
159        "native"
160        "new"
161        "null"
162        "package"
163        "private"
164        "protected"
165        "public"
166        "return"
167        "short"
168        "static"
169        "super"
170        "switch"
171        "synchronized"
172        "this"
173        "throw"
174        "throws"
175        "transient"
176        "true"
177        "try"
178        "typeof"
179        "var"
180        "void"
181        "volatile"
182        "while"
183        "with"
184        ) t))
185   "Expression for matching reserved words in `javascript-mode' buffers.
186
187 From Core JavaScript Reference 1.5, Appendix A (Reserved Words):
188 <http://developer.netscape.com/docs/manuals/js/core/jsref15/keywords.html>")
189
190
191 ;; JavaScript identifiers
192 ;; This one is intentionally not too strict...
193 (defconst javascript-identifier
194   "[a-zA-Z_\\$][a-zA-Z0-9_\\$]*"
195   "Expression for matching identifiers in `javascript-mode' buffers.
196
197 From Core JavaScript Guide 1.5, Chapter 2 (Values, Variables and Literals):
198 <http://developer.netscape.com/docs/manuals/js/core/jsguide15/ident.html>")
199
200 ;; ------------------------------------------------------------------------ ;;
201
202 ;; Font lock keywords
203 (defconst javascript-font-lock-keywords
204   (list
205
206    ;; Reserved words.
207    (cons (concat
208           "\\(^\\|[ \t;{(]\\)\\("
209           javascript-reserved-words
210           "\\)[ \t\n(){};,]")
211          '(2 'font-lock-keyword-face))
212
213    ;; Function declarations.
214    (cons (concat
215           "\\(^\\|[ \t;{]\\)function[ \t]+\\("
216           javascript-identifier
217           "\\)")
218          '(2 'font-lock-function-name-face))
219    ;; This would catch both declarations and calls.
220    ;(cons (concat
221    ;       "\\(^\\|[ \t.;{(]\\)\\("
222    ;       javascript-identifier
223    ;       "\\)[ \t]*(")
224    ;      '(2 'font-lock-function-name-face))
225
226    ;; Variables and constants.
227    (cons (concat
228           "\\(^\\|[ \t;{(]\\)\\(const\\|var\\)[ \t]+\\("
229           javascript-identifier
230           "\\)")
231          '(3 'font-lock-variable-name-face))
232    ;; This would catch more of them and properties as well.
233    ;(cons (concat
234    ;       "\\(^\\|[ \t(\\[\\.{;]\\)\\("
235    ;       javascript-identifier
236    ;       "\\)[ \t]*[^(]")
237    ;      '(2 'font-lock-variable-name-face))
238
239    )
240   "Highlighting rules for `javascript-mode' buffers.")
241
242 ;; ------------------------------------------------------------------------ ;;
243
244 ;;;###autoload
245 (defun javascript-mode ()
246   "Major mode for editing JavaScript code.
247
248 See the documentation for `c++-mode': JavaScript mode is an extension of it.
249 Use the hook `javascript-mode-hook' to execute custom code when entering
250 JavaScript mode.
251
252 \\{javascript-mode-map}"
253   (interactive)
254
255   (let ((current-c++-mode-hook (and (boundp 'c++-mode-hook) c++-mode-hook)))
256
257     ;; Temporarily disable the c++-mode hook; don't wanna run
258     ;; it when loading up c++-mode.
259     (setq c++-mode-hook nil)
260     (c++-mode)
261
262     ;; Do our stuff.
263     (setq major-mode 'javascript-mode mode-name "JavaScript")
264     (use-local-map javascript-mode-map)
265     (setq local-abbrev-table javascript-mode-abbrev-table)
266     (c-set-offset 'inher-cont '+)
267
268     ;; Change menu name.  Kudos to Geert Ribbers.
269     (easy-menu-remove '("C++"))
270     (easy-menu-add (c-mode-menu "JavaScript") javascript-mode-map)
271
272     ;; GNU Emacs reportedly needs this for font locking to work properly.
273     (unless (featurep 'xemacs)
274       (set (make-local-variable 'font-lock-defaults)
275            '(javascript-font-lock-keywords nil nil)))
276
277     ;; cc-mode does not handle JavaScript prototype function declarations well.
278     ;; Thanks to Sebastian Delmont.
279     (set (make-local-variable 'c-lambda-key) "function")
280     (c-set-offset 'inlambda 0)
281
282     ;; Restore the original c++-mode-hook.
283     (setq c++-mode-hook current-c++-mode-hook)
284
285     (run-hooks 'javascript-mode-hook)))
286
287 ;; ------------------------------------------------------------------------ ;;
288
289 ;;;###autoload
290 (defun javascript-shell ()
291   "Run a JavaScript shell as an inferior process.
292
293 Use the `javascript-shell-command' variable to set the command and
294 `javascript-shell-command-args' for its arguments to specify the
295 command line that invokes your preferred JavaScript shell.
296
297 Free JavaScript shell implementations are available for example from
298 <http://www.mozilla.org/js/>.
299
300 Usage examples:        command    arguments
301  Mozilla SpiderMonkey  jsshell
302  Mozilla Rhino         java       -jar /path/to/js.jar"
303
304   (interactive)
305
306   (unless (comint-check-proc "*JavaScript*")
307     (set-buffer
308      (apply 'make-comint "JavaScript"
309             javascript-shell-command nil javascript-shell-command-args))
310     (javascript-shell-mode)
311     )
312
313   (pop-to-buffer "*JavaScript*")
314   )
315
316
317 (defun javascript-shell-mode ()
318   "Major mode for interacting with a JavaScript shell."
319   (comint-mode)
320   (setq comint-prompt-regexp javascript-shell-prompt-pattern)
321   (setq mode-name 'javascript-shell-mode)
322   (setq mode-name "JavaScript Shell")
323   (setq mode-line-process '(":%s"))
324   (run-hooks 'javascript-shell-mode-hook)
325   )
326
327 ;; ------------------------------------------------------------------------ ;;
328
329 ;;;###autoload
330 (add-to-list 'auto-mode-alist '("\\.js$" . javascript-mode))
331
332 ;; Speedbar handling
333 (if (fboundp 'speedbar-add-supported-extension)
334     (speedbar-add-supported-extension ".js"))
335
336 ;; ------------------------------------------------------------------------ ;;
337
338 (provide 'javascript-mode)
339
340 ;;; javascript-mode.el ends here
jethro@divmod.org