javascript-modeでのflymakeに、今までSpiderMonkeyを使っていたけど、試しにnode-jslintを使ってみることにした。
GitHub - reid/node-jslint: The JavaScript Code Quality Tool — for Node.js.
node-jslintはnpmでinstallすると"jslint"コマンドを提供してくれるコマンドラインツール。lintnodeという、nodeでwebサーバを立ち上げてそこでjslintを実行する、というものもあるようだったが、そこまでするのはなぁ…ということで見送り。
まずはコマンドラインで使ってみる。
$ npm install jslint -g $ cat hoge.js a; var b; alert("hoge") var c = { foo: "hoge", bar: "fuga", }; $ jslint hoge.js hoge.js /*jslint node: true, es5: true */ 1 1,1: Expected an assignment or function call and instead saw an expression. a; 2 3,14: Expected ';' and instead saw 'var'. alert("hoge") $ jslint --no-es5 hoge.js hoge.js /*jslint es5: false, node: true */ 1 1,1: Expected an assignment or function call and instead saw an expression. a; 2 3,14: Expected ';' and instead saw 'var'. alert("hoge") 3 6,16: Unexpected ','. bar: "fuga",
デフォルトでes5オプションが有効になっていて、これだとObjectの最後のカンマの検出などがされない。"--no-es5"オプションを渡すと検出してくれる。
エラー出力の形式がjslint packageのreporterによって決められているので、これに従って"flymake-err-line-patterns"を調整。
EmacsWiki: Flymake Java Scriptを参考に。
(require 'flymake) (add-to-list 'flymake-allowed-file-name-masks '("\\.js\\'" flymake-js-init)) (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 "jslint" (list "--no-es5" local-file)))) (defun flymake-js-load () (interactive) (setq flymake-err-line-patterns (cons '("^ *[[:digit:]] \\([[:digit:]]+\\),\\([[:digit:]]+\\)\: \\(.+\\)$" nil 1 2 3) flymake-err-line-patterns)) (flymake-mode t)) (add-hook 'js-mode-hook (lambda () (flymake-js-load)))
下記設定をしておくことにより"M-e"でエラー行に飛んでminibufferにエラー内容が表示される。
(require 'flymake) (global-set-key "\M-e" 'flymake-goto-next-error) (global-set-key "\M-E" 'flymake-goto-prev-error) ;; gotoした際にエラーメッセージをminibufferに表示する (defun display-error-message () (message (get-char-property (point) 'help-echo))) (defadvice flymake-goto-prev-error (after flymake-goto-prev-error-display-message) (display-error-message)) (defadvice flymake-goto-next-error (after flymake-goto-next-error-display-message) (display-error-message)) (ad-activate 'flymake-goto-prev-error 'flymake-goto-prev-error-display-message) (ad-activate 'flymake-goto-next-error 'flymake-goto-next-error-display-message)
Cocoa Emacs特有? かどうかよく分からないけど、flymakeがsubprocessとしてjslintを実行する際にPATHとかexec-pathが通ってないとうまくいかないので下記設定を追加してある。
;; exec-pathにshellから得られる$PATHを追加 (loop for x in (reverse (split-string (substring (shell-command-to-string "echo $PATH") 0 -1) ":")) do (add-to-list 'exec-path x)) ;; process-environmentも変更 (setenv "PATH" (substring (shell-command-to-string "echo $PATH") 0 -1))