Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run jslint as a javascript compile tool in emacs for Windows?

I'm using GNU Emacs on Win32.

I want to be able to run jslint as a compilation on .js files, and then step through the errors that jslint reports.

I have jslint, the WScript version.

like image 973
Cheeso Avatar asked Mar 17 '10 20:03

Cheeso


People also ask

What is JSHint library?

JSHint is a program that flags suspicious usage in programs written in JavaScript. The core project consists of a library itself as well as a CLI program distributed as a Node module.


2 Answers

EDIT - There's now a simplified module that does this for you.

http://marmalade-repo.org/packages/fly-jshint-wsh

This .el package:

  • downloads jshint or jslint for you (configurable)
  • applies the necessary WSH-friendly modifications I describe below
  • saves the modified result to a temporary file
  • invokes that script via flymake in js-mode buffers

Easy peasy. Still Windows only though.

I kept all the old parts of this answer for reasons of historical interest, but you don't need to read any further.


Note - Below I describe how to modify jslint.js for use within emacs.
If you don't want to do it yourself, the already-modified code required is available.
That link has an additional piece, flymake-for-jslint-for-wsh.el, that allows you to use jslint with flymake, on Windows.


To use jslint within emacs,

Download jslint.js, the WScript version.

Edit the jslint.js file. Scroll to the bottom and find this:

 (function(){if(!JSLINT(WScript.StdIn.ReadAll(),.....

Replace that (and everything that follows) with this:

(function(){
    var filename = "stdin";
    var content= "";
    if (WScript.Arguments.length > 0){
        filename = WScript.Arguments(0);
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        //var file = fso.GetFile(filename);
        var fs = fso.OpenTextFile(filename, 1);
        content = fs.ReadAll();
        fs.Close();
        fso = null;
        fs = null;
    } else {
        content = WScript.StdIn.ReadAll();
    }
    if(!JSLINT(content,{passfail:false})){
        WScript.StdErr.WriteLine("JSLINT");
        for (var i=0; i<JSLINT.errors.length; i++) {
            // sample error msg:
            //  sprintf.js(53,42) JSLINT: Use the array literal notation [].
            var e=JSLINT.errors[i];
            if (e !== null){
                var line = (typeof e.line == "undefined")?'0':e.line;
                WScript.StdErr.WriteLine(filename + '(' +line+','+e.character+') JSLINT: '+e.reason);
                WScript.StdErr.WriteLine('    ' + (e.evidence||'').replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"));
            }
        }}}());

This change does two things:

  1. allows you to specify the file to run lint on, on the command line, rather than as stdin. Stdin still works if no file is specified at all.
  2. emits the error messages in a format that is more similar to most C/C++ compilers.

The first change allows you to invoke jslint.js from within emacs with M-x compile. The second allows you to interpet error messages with M-x next-error.

Save that file to jslint-for-wsh.js

Then, in your init.el, or emacs.el, add to your compilation-error-regexp-alist, this regexp:

 ;; JSLINT
 ("^[ \t]*\\([A-Za-z.0-9_: \\-]+\\)(\\([0-9]+\\)[,]\\( *[0-9]+\\))\\( Microsoft JScript runtime error\\| JSLINT\\): \\(.+\\)$" 1 2 3)

In your javascript mode hook, set the compile command:

  (setq compile-command
       (let ((file (file-name-nondirectory buffer-file-name)))
         (concat "%windir%\\system32\\cscript.exe \\LOCATION\\OF\\jslint-for-wsh.js "  file)))

That's it.


When you then open a .js file, and run M-x compile, you will run jslint.js on the existing buffer. You'll get a list of errors, and M-x next-error works as you expect.

alt text

Yipee!!

You can also run jslint as the flymake syntax checker tool, on Linux or Windows. See http://www.emacswiki.org/emacs/FlymakeJavaScript for details.

alt text

like image 171
Cheeso Avatar answered Oct 08 '22 01:10

Cheeso


JSLint does not support WSH anymore. I just added instructions to EmacsWiki for setting up JSLint with Node.js on Windows.

Update

Possibly a better alternative to flymake is Flycheck, for which I also provided instructions on EmacsWiki concerning how to set it up with JSLint.

Steps

  1. Install Node.js.

  2. Install the jslint package for Node.js:

    C:\>npm -g install jslint
    

    On Windows there is an issue with calling jslint from EMACS 23. Thus, create a wrapper ~/.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 from Emacs’ built in shell EShell:

    $ ~/.emacs.d/jslint.bat
    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-command: ~/.emacs.d/jslint.bat

  7. Optionally customize other flymake-jslint options.

  8. Restart Emacs to make sure that everything loads fine.

  9. Test by opening a flawed JavaScript file.

    Screenshot of flymake-jslint running in Emacs 23 on Windows XP/SP3

Troubleshooting

  • Customize flymake-log-level and inspect the *Messages* buffer.

  • Check flymake-jslint-args.

  • Make sure that the command configured in flymake-jslint-command runs in EShell.

like image 42
feklee Avatar answered Oct 08 '22 00:10

feklee