-

moinmoin-mode を使うと Wrong type argument エラー、を直す

最近、Emacs使用中、diffを見たときとか、予想しないタイミングで↓のエラーが出て、そこで止まってしまうために先に進めなくなるので困っていた。発生条件もよくわからず。

Wrong type argument: symbolp, (lambda nil (goto-char 1))

emacs-versionは "22.0.92.1" (Carbon Emacs Package 2007年1月版)、Meadow 3.00-dev でも発生していて emacs-version は "22.0.90.1")

トレースを見ると font-lock-compile-keywords でコケている。

ググったりしても出てこず立ち往生だったのだが、使っているelを強引に全部grepしたら分かるんじゃ?と思ってやってみたら原因を突き止められて、直せた。

原因は、TracWiki編集のときに使っているmoinmoin-modeで、関数の中でfont-lock-mode用の変数をグローバルにセットしていた。(たぶん行儀が悪い。バッファローカルにするべき。)で、その値が関数名のシンボルである必要があるのに匿名関数(エラーメッセージに出ているlambda)になっているので、moinmoin-modeじゃないときでもたまたまfont-lock-modeにその値が渡るときにWrong type argumentとなる。

font-lockはEmacs上でほとんどのところで使用するために、いつもエラーが出ていたというわけでした。言われてみれば、moinmoin-modeに入ったあとでこのエラーが発生していた(1回も入っていなければこのエラーにはならん)、というのは確かにそうだったかも。最近Wikiにドキュメントアップしまくりだったから気がついたんだろう。

elispでプログラム書くほど分かってないけど、font-lockに関する変数の流儀みたいなのはあるだろうと思ったので、他のモードのやり方を参考に直してみた。

パッチ

--- moinmoin-mode.el.orig
+++ moinmoin-mode.el
@@ -203,14 +203,8 @@
       (unless (get-text-property (match-beginning 0) 'moinmoin-verbatim)
         (throw 'match t)))))
 
-(defun moinmoin-setup-font-lock ()
-  (setq font-lock-beginning-of-syntax-function '(lambda () (goto-char 1)))
-  (setq font-lock-multiline t)
-  (make-local-variable 'font-lock-extra-managed-props)
-  (add-to-list 'font-lock-extra-managed-props 'moinmoin-verbatim) ; Not Comment Start
-  (add-to-list 'font-lock-extra-managed-props 'display)
-  (font-lock-add-keywords nil `(
-    ("\\(?:^\\|[^|]\\)\\(\\(?:||\\)+\\)\\(<.*?>\\)?"
+(defvar moinmoin-mode-font-lock-keywords
+  `(("\\(?:^\\|[^|]\\)\\(\\(?:||\\)+\\)\\(<.*?>\\)?"
      (1 'moinmoin-table-separator)
      (2 'moinmoin-table-pi t t))
     ("'''\\(.*?\\)'''" (1 'moinmoin-bold prepend))
@@ -322,8 +316,15 @@
      (2 (list 'face 'moinmoin-pi          'moinmoin-verbatim t) t t)
      (3 (list 'face 'moinmoin-code        'moinmoin-verbatim t) t)
      (4 (list 'face 'moinmoin-code-braces 'moinmoin-verbatim t) t))
-    ) 'set))
+    ))
 
+(defun moinmoin-setup-font-lock ()
+  (set (make-local-variable 'font-lock-defaults)
+       '(moinmoin-mode-font-lock-keywords t nil nil nil (font-lock-multiline . t)))
+  (make-local-variable 'font-lock-extra-managed-props)
+  (add-to-list 'font-lock-extra-managed-props 'moinmoin-verbatim) ; Not Comment Start
+  (add-to-list 'font-lock-extra-managed-props 'display))
+
 ^L
 ;;; Automagic typing helpers
 (defun moinmoin-insert-quote ()

いつからこうだったかなぁ。本家に言ってみるか。
→ 追記(2007-03-09): 言ってみた。英語で書くの苦労・・・