There are multiple options for checking Javascript syntax that can be used within flymake. The javascript engines SpiderMonkey and Rhino can both check Javascript syntax. Alternatively, you can use Douglas Crockford’s rather handy JSLint, which is much less forgiving of bad syntax, and can enforce a sensible coding style. Another option is JSHint, which is a fork of JSLint, modified to be not as strict and more configurable in its requirements than the original. The following describe some of these options.
See: Flycheck (a modern alternative to flymake)
As of September 2013, the jslint package available via npm (see below) is based on a seven months old JSLint, which is outdated. This may have changed by now. Be sure to double check.
1. Install Node.js.
2. From the command line of your OS, install JSLint with npm, the package manager for Node.js:
$ npm -g install jslint
~/.emacs.d/jslint.bat
(“jslint” needs to be part of the file name!):@ECHO OFF node "%APPDATA%"\npm\node_modules\jslint\bin\jslint.js >"%TEMP%"\jslint.out 2>&1 %* TYPE "%TEMP%"\jslint.out
3. Test JSLint (on Windows use ~/.emacs.d/jslint.bat
):
$ jslint No files specified. [...]
4. Install flymake-jslint and its dependency flymake-easy.
5. Add to ~/.emacs
:
(require 'flymake-jslint) (add-hook 'js-mode-hook 'flymake-jslint-load)
6. Customize flymake-jslint options. On Windows set flymake-jslint-command
to: ~/.emacs.d/jslint.bat
7. Restart Emacs to make sure that everything loads fine.
8. Test by opening a flawed JavaScript file.
flymake-log-level
and inspect the *Messages*
buffer.flymake-jslint-command
runs in EShell.flymake-jslint-args
.I had trouble getting jshint-mode working properly, so I created a simple way to use JSHint from the command-line: flymake-node-jshint.
– Henrik Jegbjerg Hansen <[email protected]>
I tried Variant 2 first, and I spent several hours trying to make it work (debugging the flymake-jshint.el, jshint-mode.js and jshint.js). I tried Variant 1 and it worked at once!
– Alejandro Russo <[email protected]>
You can do
$ npm -g install jshint
and then install flymake-jshint using marmalade (http://marmalade-repo.org/). You may need to do the following in /usr/local/bin:
ln -s /usr/local/Cellar/node/0.6.6/lib/node_modules/csslint/cli.js
and then put (add-to-list ‘exec-path “/usr/local/bin”) somwhere in your .emacs.
-Dave Dreisigmeyer
First, you will need to install Rhino, and download jslint.js for Rhino [1]. I’ve got it located in ~/soft/jslint, and you will want to update the code below to match where you’ve put it.
Next you will want to create a file called flymake-jslint.el on your LoadPath like the following
(require 'flymake) (defun flymake-jslint-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "rhino" (list (expand-file-name "~/soft/jslint/jslint.js") local-file)))) (setq flymake-allowed-file-name-masks (cons '(".+\\.js$" flymake-jslint-init flymake-simple-cleanup flymake-get-real-file-name) flymake-allowed-file-name-masks)) (setq flymake-err-line-patterns (cons '("^Lint at line \\([[:digit:]]+\\) character \\([[:digit:]]+\\): \\(.+\\)$" nil 1 2 3) flymake-err-line-patterns)) (provide 'flymake-jslint)
and import it from your DotEmacs like so:
(require 'flymake-jslint) (add-hook 'js-mode-hook (lambda () (flymake-mode t)))
You can control options of JSLint by using special comments in your source code which are described in the documentation [2]. For example, the following is the same as using the recommended options on jslint.com, and also the assume a browser option. It also defines the name MochiKit, which is imported elsewhere.
/*jslint browser: true, undef: true, eqeqeq: true, nomen: true, white: true */ /*global MochiKit */
Seems like you really want (flymake-mode 1)
in that hook, not (flymake-mode t)
. According to the documentation, to turn on the minor mode explicitly requires that the arg be positive, not non-nil. --DinoChiesa
If you run the above in a persistent server on v8 instead of invoking rhino every time, it goes about twice as fast. Server code with instructions is available at http://github.com/keturn/lintnode
JavaScript syntax checking using spidermonkey. This also detects object trailing comma like:
var obj = {
a: 1,
b: 2,
}; // this line is highlighted.
You’ll need Karl’s JavaScriptMode, spidermonkey 1.5 or greater and emacs 22.
(defconst flymake-allowed-js-file-name-masks '(("\\.json$" flymake-js-init) ("\\.js$" flymake-js-init))) (defcustom flymake-js-detect-trailing-comma t nil :type 'boolean) (defvar flymake-js-err-line-patterns '(("^\\(.+\\)\:\\([0-9]+\\)\: \\(SyntaxError\:.+\\)\:$" 1 2 nil 3))) (when flymake-js-detect-trailing-comma (setq flymake-js-err-line-patterns (append flymake-js-err-line-patterns '(("^\\(.+\\)\:\\([0-9]+\\)\: \\(strict warning: trailing comma.+\\)\:$" 1 2 nil 3))))) (defun flymake-js-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "js" (list "-s" local-file)))) (defun flymake-js-load () (interactive) (defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted) (setq flymake-check-was-interrupted t)) (ad-activate 'flymake-post-syntax-check) (setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks flymake-allowed-js-file-name-masks)) (setq flymake-err-line-patterns flymake-js-err-line-patterns) (flymake-mode t)) (add-hook 'javascript-mode-hook '(lambda () (flymake-js-load)))
There’s another implementation of Flymake JavaScript mode that sits on top of the Rhino engine.
I have some problems with this one. I assume it is a problem with the path to rhino.js and env.js, but I am not sure. I have placed those file in the folder c:/emacs/rhino-related/ which I mention in rhino.js (see below, is this correct?):
// Where you store your files var project_folder = 'c:/emacs/rhino-related/'; // Browser environment wrapper over Rhino load(project_folder + 'env.js'); // For DOM constructing window.location = project_folder + 'blank.html'; var my_script = arguments[0]; // If DOM ready window.onload = function(){ // Avoid recursive inclusion if ("rhino_flymake.js" != my_script) { load(my_script); } }
I get strange errors, like:
parsed 'Exception in thread "Thread-0" org.mozilla.javascript.WrappedException:
Wrapped java.net.MalformedURLException: unknown protocol: c',
no line-err-info
It looks like Rhino can not take care of the c: in the path. Anyone who understands what is happening? – LennartBorgman
I do not have a Windows box to verify the fix below, but according to some forum posts, you should declare the path in scheme file:///C:/path/to/file
.
var project_folder = 'file:///c:/emacs/rhino-related/';
– Nyuhuhuu
Thanks Nyuhuhuu, that made it work on Windows.
Before I fixed the issue you speak of, I had to fix an apparent problem with ‘compilation-error-regexp-alist-alist’ in ‘flymake.el’. For details on that, please see this post on gnu.emacs.help.
After that was fixed, I was able to get the Java Rhino process running on target with this (using the Windows build of Emacs, on Windows XP):
var project_folder = 'c:\\Progra~1\\emacs\site\\rhino-web-browser-js-environment\\';
Then in my ‘flymake-js-init’ function definition, I have this:
(list "java" (list "-jar" "c:/Progra~1/rhino1_6R7/js.jar" "c:/Progra~1/emacs/site/rhino-web-browser-js-environment/rhino_flymake.js" local-file))))
That said, after said success I ran into other problems, apparently unrelated to any of my previous fixes and configurations, down the road. Please see the last half of the third comment on this post on gnu.emacs.help.
It would be very cool if this could be made to work. If we can figure it out, we could make a nice how-to on this that I bet a lot of people would benefit from.
-- ChristopherMBalz
I get a lot of errors on the first line, like
- Context.Java(1757) - MemberBox.java(187) etc.
That is this?
There’s no need to install Rhino on Windows; Windows has a built-in Javascript engine in WSH. Therefore you can run a JS program on any Windows, via WSH. Which means you can run JSHINT. Please note that this solution does not work for JSLint: Since February 2013, JSLint requires ECMAScript Fifth Edition, and does not run with WSH anymore.
There are two modules; both allow you to use JSHINT as the flymake tool for .js buffers on windows.
The first, flymake-for-jslint-for-wsh.el, requires you to download JSHINT, modify it slightly, save it, and set a variable in your .emacs pointing to the modified script.
A newer version downloads and modifies JSHINT at runtime. This version is also available on the Marmalade Repo as fly-jshint-wsh.
A sample of using jslint-for-wsh.js as a “compile” command in emacs: