find-function/find-variableがdebianで動かない問題
DebianなEmacsユーザのFAQとなっている問題。
Debian GNU/Linuxのemacsenは*.elと*.elcを別々の場所に置いているため、find-functionなどが*.elを見つけられない問題がある。たとえばskk.elcは/usr/share/emacs22/site-lisp/ddskk/skk.elcにある一方で、skk.elは /usr/share/emacs/site-lisp/ddskk/skk.el にある。パッケージによってはこの問題に対処してのことか*.elへsymlinkを張ってくれているが、張ってくれないパッケージもある。以前は
(when (boundp 'debian-emacs-flavor) (setq find-function-source-path (mapcar (lambda (path) (cond ((string-match (concat "/" (symbol-name debian-emacs-flavor) "/site-lisp/") path) (replace-match "/emacs/site-lisp/" nil t path)) ((string-match (format "/%d.%d/site-lisp/" emacs-major-version emacs-minor-version) path) (replace-match "/site-lisp/" nil t path)) (t path))) load-path)))
こんなのを張っておけば大丈夫だったのだが、emacs22でこの問題が再発したようだ。ソースを追ってみると find-function-search-for-symbol にたどりついた。
find-function-search-for-symbol is a compiled Lisp function in `/m/usr/share/emacs/22.1/lisp/emacs-lisp/find-func.elc'. (find-function-search-for-symbol SYMBOL TYPE LIBRARY) Search for SYMBOL's definition of type TYPE in LIBRARY. Visit the library in a buffer, and return a cons cell (BUFFER . POSITION), or just (BUFFER . nil) if the definition can't be found in the file. If TYPE is nil, look for a function definition. Otherwise, TYPE specifies the kind of definition, and it is interpreted via `find-function-regexp-alist'. The search is done in the source for library LIBRARY.
こいつがLIBRARY中のSYMBOLを探す関数。だが、引数LIBRARYが正しくないので見つからないと言われてしまうのだ。*.elc→*.elの変換は find-function-search-for-symbol がやってくれるのでディレクトリ名だけを修正する。
(when (boundp 'debian-emacs-flavor) (defadvice find-function-search-for-symbol (around debian activate) "" (if (string-match (symbol-name debian-emacs-flavor) library) (setq library (replace-match "emacs" nil nil library))) ad-do-it))
Debian Emacs Policyだと複数のemacsenバージョンを共存させるため*.elと*.elcを別々に置くことになってるんだが、それはあくまでDebian側の勝手なんで、この問題はDebianパッケージで修正するべき事柄だと思う。それともDebian Emacs Policyで「*.elへのsymlinkを張る」と決めておいて徹底させるか。こんな問題、出てから何年もたつんだから…たのみますよ、メンテナさん。
追記:ddskkをアップグレードしたらsymlinkを張ってくれたのでskkについてはこの問題はなくなった。一方mmm-modeはsymlinkを張ってくれないのでこの問題が発生する。メンテナによっては気付かないこともあるので、やっぱりfind-function側で対応する方がいいかもしれない。