Skip to content
2009/01/12 / highmt

Meadowでhtmllint

Meadowでhtmllintを使う設定。
探せばありそうなものだけれども、あまりメンテナンスされていなさそうなモードを入れなといけないのが気分的になんとなく。

(eval-after-load "compile"
  '(define-compilation-mode htmllint-mode "htmllint"
     (set (make-local-variable 'compilation-error-regexp-alist)
          '(htmllint-1 htmllint-0))
     (set (make-local-variable 'compilation-error-regexp-alist-alist)
          '((htmllint-1 "^\\(.+\\)(\\([0-9]+\\))" 1 2)
            (htmllint-0 "^\\(.+\\)(\\(\\))" 1 nil)))))
(defvar html-htmllint-command "perl htmllint * | nkf -s")
(defun html-do-htmllint ()
  (interactive)
  (let ((targetfile (buffer-file-name))
        (my-replace-string #'(lambda (target regexp newtext)
                               (if (string-match regexp target)
                                   (replace-match newtext t t target)))))
    (if targetfile
        (let ((command (funcall my-replace-string html-htmllint-command "\\*" (shell-quote-argument targetfile))))
          (compilation-start command 'htmllint-mode)))))
(eval-after-load "sgml-mode"
  '(define-key html-mode-map "\C-c@c" 'html-do-htmllint))

結果としてえらい苦労してしまったのだけれども、ポイントは

  • compileじゃなくてcompilation-startを使う。
    開いているバッファに対する保存操作をスキップするため。
  • htmllintの出力行ではタグジャンプできないので新しくdefine-compilation-modeする。
    はじめはcompilation-error-regexp-alistにhtmllint用の設定を追加しただけだったのだが、
    そうでない設定のほうでもひっかかってしまって、結果として正しくタグジャンプできなかった。
    ということでcompilation-error-regexp-alistをまるまる差し替えることに。
    しかし、グローバルに変えるよりmake-local-variableしたほうがよいだろうということでいろいろやってみたのだけれど、
    どうもcompilation-startはバッファを1回削除するらしく、set-bufferしてmake-local-variableしても、
    compilation-startしたときにはグローバルな値になってしまう。
    じゃあgrepはどうやっているんだ、とソースを見るとdefine-compilation-modeしていたのでその方法で。
  • 行番号のない出力行は行番号のある出力行と別に扱う。
    htmllintでは、"xxx.html(14)”みたいに括弧内に行番号を出力するのだけれども、
    たまに”xxx.html()”のように括弧しかない出力行がある。
    これを行番号ありのものと同列に扱うと、行番号が0として扱われる。
    そうすると、タグジャンプすると行番号から1行多い位置に飛ぶ。
    ソースがよくわからなくてどういうことか悩んだのだけれども、どうもそういうことらしいので、
    行番号がない出力に対しては明示的に行番号なしとして扱う必要があるみたい。

うーん。自分はedebugなしでは絶対無理。
関数がCで実装されてたら今のところ手が出せないかも。

——–
2009/01/24 

正規表現は

"^\\(.+\\)(\\([0-9]+\\)):"
"^\\(.+\\)(\\(\\)):"

のように":"を最後につけていたほうがよいみたい。
本文中に括弧で囲まれた数字とか出てくると誤認識する。

あと、nkfでなくてcoding-system-for-readを使ったほうがよいのかも。

広告
%d人のブロガーが「いいね」をつけました。