Update @ 2013 March: cleaned up deprecated recommendations
js2-refactor.el). If you are going to use js2-mode, either install the mooz fork or install the GNU ELPA version available via M-x list-packages:
How to install the mooz fork of js2-mode
The original old js2-mode had a problem of enforcing an unpopular indentation style, did not play well with idle-highlight-mode, and was not a derived mode of prog-mode. The mooz fork fixed them and then those changes were incorporated back to the original js2-mode. I don’t know which of the two the GNU ELPA one is based on but it also has those changes.
My setup recommendation for js2-mode
0. Enabling js2-mode or js2-minor-mode
If you want all js files to be open in js2-mode instead of the Emacs built-in js-mode (formerly known as espresso-mode), add this line:
(add-to-list 'auto-mode-alist (cons (rx ".js" eos) 'js2-mode))
(add-hook 'js-mode-hook 'js2-minor-mode)
Latest release note from original js2-mode (as of 2013 March) says
This is the first major new release for js2-mode in three years. It incorporates several sets of changes:
* changes and fixes from Mooz’s github fork
* changes suggested by Stefan Monnier and the emacs maintainers
changes I made to allow js2 to be used as a minor mode
Work is continuing on js2-mode by various contributors, but there is currently not a “canonical” version that I’m aware of — that is, the GitHub forks are not(?) directly contributing back to the ELPA version, nor vice-versa. So I will periodically (perhaps every 6 months) hand-merge them and upload the results here after it’s been tested by enough dogfooders.
This latest version is also the head SVN revision if you want to grab the source that way. The internal elisp version number, `js2-mode-version’, is 20120726.
prog-mode-hook in js2-mode. (deprecated recommendation that now only applies to old js2-mode)
For some reason, old js2-mode is not a derived mode of prog-mode when it should be. prog-mode is available from Emacs 24 on. Here’s an excerpt from Emacs 24 NEWS:
`prog-mode’ is a new major mode from which programming modes
should be derived.
`prog-mode-hook’ can be used to enable features for programming
modes, e.g. (add-hook ‘prog-mode-hook ‘flyspell-prog-mode) to enable
on-the-fly spell checking for comments and strings.
To ensure that
prog-mode-hook runs in js2-mode, add:
;; add buffer-local indicator for whether prog-mode-hook has run. (defun my-set-pmh-ran () (set (make-local-variable 'my-pmh-ran) t)) (add-hook 'prog-mode-hook 'my-set-pmh-ran) (add-hook 'js2-mode-hook 'my-run-pmh-if-not-ran) (defun my-run-pmh-if-not-ran () (unless (bound-and-true-p my-pmh-ran) (run-hooks 'prog-mode-hook)))
The reason I’ve added the check to see whether
prog-mode-hook is run is that you don’t want to end up running
prog-mode-hook twice when you upgrade to the latest version of js2-mode.
3. Make js2-mode use spaces instead of tabs if that’s what you prefer. (deprecated recommendation that now only applies to old js2-mode)
(add-hook 'js2-mode-hook 'my-disable-indent-tabs-mode) (defun my-disable-indent-tabs-mode () (set-variable 'indent-tabs-mode nil))
(Update: It seems TAB now inserts spaces even when indent-tabs-mode is on.)
(eval-after-load "js2-mode" '(progn (setq js2-missing-semi-one-line-override t) (setq-default js2-basic-offset 2) ; 2 spaces for indentation (if you prefer 2 spaces instead of default 4 spaces for tab) ;; add from jslint global variable declarations to js2-mode globals list ;; modified from one in http://www.emacswiki.org/emacs/Js2Mode (defun my-add-jslint-declarations () (when (> (buffer-size) 0) (let ((btext (replace-regexp-in-string (rx ":" (* " ") "true") " " (replace-regexp-in-string (rx (+ (char "\n\t\r "))) " " ;; only scans first 1000 characters (save-restriction (widen) (buffer-substring-no-properties (point-min) (min (1+ 1000) (point-max)))) t t)))) (mapc (apply-partially 'add-to-list 'js2-additional-externs) (split-string (if (string-match (rx "/*" (* " ") "global" (* " ") (group (*? nonl)) (* " ") "*/") btext) (match-string-no-properties 1 btext) "") (rx (* " ") "," (* " ")) t)) ))) (add-hook 'js2-post-parse-callbacks 'my-add-jslint-declarations)))
js2-parse-global-vars-decls makes js2-mode recognize JsLint global variables directives such as:
/*global console, jQuery, $, _, Backbone */
M-x customize-group RET js2-mode