(make-local-variable '*pre/post-command-hook*)
「このモードでは `*pre/post-command-hook*` で何かしたい」という時。
とりあえずそれを実現する方法。
A: `*pre/post-command-hook*` を buffer-local に
そのモードのフック(かなにか)で `*pre/post-command-hook*` を buffer-local にしておいて `add-hook` する。
問題点は後で。
(add-hook '*hoge-mode-hook* (defun enable-local-post-command-hook () (make-local-variable '*post-command-hook*) (add-hook '*post-command-hook* (defun my-local-hook-fn () (do-something ...)))))
B: major-mode を見て何かする関数
`*pre/post-command-hook*` は buffer-global なままにしておいて、「このモード」だったら「何か」する関数を突っ込む。
(add-hook '*post-command-hook* (defun my-local-hook-fn () (when (eq buffer-mode 'hoge-mode) (do-something ...))))
何が問題なのか
B のやり方だと、それ以外のモードでもその関数を無駄に呼び出すことになる。のでできれば避けたい気分。
しかし A をやってしまうと、その `*pre/post-command-hook*` がその buffer では独自の hook になるので、global な `*pre/post-command-hook*` が実行されなくなってしまう。
例えば global に `*post-command-hook*` で `paren-highlight` していても、ある buffer で `make-local-variable` するとその buffer では paren が効かない、というようなことになる。paren が効かない位ならまだいいが、`*pre-command-hook*` で何かして `*post-command-hook*` で後処理をするみたいなことをしてると、後処理だけが実行されなくて「どーなってんだこりゃ??」となる。
どうしよう?
A は危険なので B でやる、というのが安全&現実的。
思いつき。
全ての buffer に local な pre/post-command-hook を用意しておいて、global な *pre/post-command-hook* から kick する。
(provide "local-pre/post-command-hook") (in-package "editor") (export '(local-pre-command-hook local-post-command-hook)) (defvar-local local-pre-command-hook nil) (defvar-local local-post-command-hook nil) (add-hook '*pre-command-hook* (defun run-local-pre-command-hooks () ;; (when (local-variable-p ...) とかした方がいい? (run-hooks 'local-pre-command-hook))) (add-hook '*post-command-hook* (defun run-local-post-command-hooks () (run-hooks 'local-post-command-hook)))
特定の buffer/major-mode でのみ実行したい関数は local の方に `add-hook` すれば、その buffer でのみ実行されて他の buffer では実行されない。もっとも run-local-pre/post-command-hook はどの buffer でもってことになっちゃうが、B のやり方で複数やるよりはマシ。
ただ、これを使う方が(公開とか考えるなら)こんなめんどいコトをする羽目になる。
(defun do-something () "hoge-mode でのみ実行したい処理。" ...) (add-hook '*hoge-mode-hook* (defun register-do-something-to-local-post-command-hook () #+local-pre/post-command-hook (add-hook 'local-post-command-hook 'do-something) #-local-pre/post-command-hook (add-hook '*post-command-hook* (defun run-do-something-on-post-command () (when (eq buffer-mode 'hoge-mode) (do-something))))))
余談
`*pre/post-command-hook*` はキー押すたびに実行されるので、あんまり時間かかる処理はしたくない、のは確か。なんだけど、人間がキー押すのって速い人でも 10キー/sec くらいで、つまり 100msec くらいは時間ある。がっつりループとかしなければ大抵は 10msec ありゃ十分。なのであんまり気にしないという富豪的思考。