小黒さんのSchemeにおける glint + Emacs + flymake を試してみた

id:koguro:20080309:1205012807 で公開されている小黒さんの glint を試してみました。
昨日の Gauche.night で発表されていたのものですがこれを待っていました!。
こんな便利なものを作ってくれ小黒さんに感謝。

何ができるか?

glint は Gauche 用に書いたソースコードの syntax チェックをしてくれます。
これと Emacs の flymake (Emacs22 からは標準で付属)を組み合わせるとソースの編集中に syntax エラーが分かります。

インストール

Gauche 0.8.13 をあらかじめインストールしておいてください。他のバージョンでは動作しない可能性があるので注意してください。

wget http://homepage.mac.com/naoki.koguro/prog/codecheck/codecheck-0.1.tgz
tar zvxf codecheck-0.1.tgz
cd codecheck-0.1
ls
./configure
make
sudo make install

glint 単体の動作チェックをしましょう。

glint example/hidden_dangers.scm
example/hidden_dangers.scm:1: error: syntax-error: malformed let: (let (a 3) a)

うまく動いています。(僕のところでは /usr/local/bin/glint の #!/bin/sh を #!/bin/bash に書き換える必要がありました。)

Emacs の flymake との連携

Emacs 22以外の環境ではFlymakeをインストールしてください。

.emacs に以下の記述を追記します。

(require 'flymake)

(defvar flymake-glint-err-line-patterns '(("^\\(.+\\):\\([0-9]+\\): \\(.+\\)$" 1 2 nil 3)))
(defconst flymake-allowed-gauche-file-name-masks '(("\\.scm$" flymake-gauche-init)))

(defun flymake-gauche-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 "glint" (list local-file))))

(defun flymake-gauche-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-gauche-file-name-masks))
  (setq flymake-err-line-patterns flymake-glint-err-line-patterns)
  (flymake-mode t))

; http://www.credmp.org/index.php/2007/07/20/on-the-fly-syntax-checking-java-in-emacs/
(defun credmp/flymake-display-err-minibuf () 
  "Displays the error/warning for the current line in the minibuffer"
  (interactive)
  (let* ((line-no             (flymake-current-line-no))
         (line-err-info-list  (nth 0 (flymake-find-err-info flymake-err-info line-no)))
         (count               (length line-err-info-list))
         )
    (while (> count 0)
      (when line-err-info-list
        (let* ((file       (flymake-ler-file (nth (1- count) line-err-info-list)))
               (full-file  (flymake-ler-full-file (nth (1- count) line-err-info-list)))
               (text (flymake-ler-text (nth (1- count) line-err-info-list)))
               (line       (flymake-ler-line (nth (1- count) line-err-info-list))))
          (message "[%s] %s" line text)
          )
        )
      (setq count (1- count)))))

(add-hook 'scheme-mode-hook '(lambda ()
                               (flymake-gauche-load)
                               (define-key scheme-mode-map "\C-cd" 'credmp/flymake-display-err-minibuf)))

Emacs を再起動するか eval-region で該当する部分を eval してください。

動作確認

hoge.scm というファイルを作ってわざと間違ってみましょう。
let のカッコが少ない間違いをしてみる。C-x C-s で保存すると。

エラー行がピンクになりました。
C-c d をするとエラーメッセージを見ることができます。(これは別の flymake から持ってきました。)

素晴らしい。