关于jslint就不多做介绍了,从事javascript工作的,即使没有使用它,应该也听过它的大名吧。虽然我个人不能完全赞同jslint的约束规则(比如,不能使用++),但是大部分的规则还是很科学的。建议使用jslint之前,先好好看看jslint的作者Douglas Crockford的Javascript The Good Parts一书,书中解释了为什么规则是那样定义的。
在emacs下使用jslint的方法有很多种,大多数方法都可以在这篇emacs wiki 中找到。在这里我会介绍其中一种我认为比较不错的方法。
我使用的环境是Debian + emacs23^for-windows 。
安装nodejs
过程略,到官网 下载最新版本安装即可。
安装node-jslint
使用npm^npm 安装node-jslint。
等待安装完成后,在命令行中输入jslint /path/to/jsfile
,就能看到jslint的检查报告了。我们注意到,jslint的错误报告对每个错误打印了两行的信息^jslint-error-msg ,而flymake却只能抓取一行的信息。为了让二者兼容,我们需要建立一个wrapper,把jslint的输出格式转换成flymake能够抓取的。建立一个名为jslint-wapper的文件,填入以下内容,保存。
#!/bin/bash
jslint $@ | sed 'N;s/\n//'
该文件的作用是对jslint产生的错误报告做一层过滤,把换行符去掉。运行jslint-wapper /path/to/jsfile
的时候,错误信息就会在一行内显示出来。
flymake-jslint.el
建立文件flymake-jslint.el,填入以下内容:
( defcustom jslint-command "jslint"
"where jslint locates"
:type 'string
:group 'jslint )
( defvar jslint-flags nil )
( defvar jslint-command-options nil )
( defvar jslint-predefs nil )
( when ( load "flymake" t )
( 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 jslint-command ( list ( jslint-compose-options )
local-file ))))
( defun jslint-compose-options ()
( defun compose-predefs ()
( if jslint-predefs
( mapconcat
( lambda ( x )
( concat "--predef " x ))
jslint-predefs " " )
"" ))
( defun compose-flags ()
( if jslint-flags
( mapconcat
( lambda ( x )
( if ( consp x )
( if ( cdr x )
( concat "--" ( car x ))
( concat "--" ( car x ) " false" ))
( concat "--" x )))
jslint-flags " " )
"" ))
( defun compose-command-options ()
( if jslint-command-options
( mapconcat
( lambda ( x )
( if ( consp x )
( concat "--" ( car x ) " "
( number-to-string ( cdr x )))))
jslint-command-options " " )
"" ))
( concat " " ( compose-flags ) " "
( compose-predefs ) " "
( compose-command-options ) " " ))
( setq flymake-err-line-patterns
( cons ' ( "^[[:space:]]+#[[:digit:]]+ \\(.+\\) // Line \\([[:digit:]]+\\), Pos \\([[:digit:]]+\\)$" nil 2 3 1 )
flymake-err-line-patterns ))
( add-to-list 'flymake-allowed-file-name-masks
' ( "\\.js\\'" flymake-jslint-init )))
( provide 'flymake-jslint )
上面的代码,一部分来自emacs-wiki,我又在上面加入了自定义jslint规则的功能,后面会有介绍。
配置.emacs
配置如下:
;; add flymake-jslint.el to load path
( add-to-list 'load-path "/path/to/flymake-jslint" )
( require 'flymake-jslint )
;; jslint-wrapper
( setq jslint-command "/path/to/jslint-wrapper" )
( add-hook 'js-mode-hook
( lambda () ( flymake-mode t )))
完成后重启emacs,就能看到效果啦!下面是我的屏幕截图:
自定义规则
上面提到了自定义jslint规则的功能,使用方法如下:
;; global variables
( setq jslint-predefs ' ( "$" "backbone" ))
;; flags
( setq jslint-flags ' ( "plusplus" "browser" ))
;; options
( setq jslint-command-options
' (( "indent" . 4 )
( "maxerr" . 100 )
( "maxlen" . 80 )))
jslint-predefs
定义了全局变量,jslint-flags定义了一些规则的开关,而jslint-command-options则定义了缩进 ,最大显示错误数 和行最大长度 三个参数。详细的规则可以参见官网的说明 。