特定の major-mode "以外" の場合に hook を設定にする emacs lisp
やり始めたら 30 分くらいハマってたのでメモ。
以下コードは、 rust-mode
"以外" の場合に after-save-hook
に executable-make-buffer-file-executable-if-script-p
を設定するものです。
(defun after-change-major-mode-hook-fn () (unless (eq major-mode 'rust-mode) (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p nil t))) (add-hook 'after-change-major-mode-hook 'after-change-major-mode-hook-fn)
解説
add-hook
は optional な第4引数にnil
以外を設定すると buffer-local な hook を設定可能after-change-major-mode-hook
は、バッファのメジャーモードが設定された後に呼び出される hook
上記の合わせ技で、特定メジャーモード以外の場合に hook を設定することを実現しています。
できなかったこと
上記にたどり着くまでに以下を試してみましたが、うまくいきませんでした。原因は分かっていません。
after-save-hook
に global (非 buffer-local) な hook を追加する。rust-mode-hook
でremove-hook
を buffer-local オプション付きで呼び出し、追加した hook を削除する。change-major-mode-hook
で buffer-local な hook を追加する。rust-mode-hook
の場合のみremove-hook
を呼び出し、追加した hook を削除する。
hook の動作原理を知らないと、このあたりはハマりどころとなって試行錯誤するハメになりそう。。。勉強せねば。。。
動機
Rust の attribute syntax が変更されたため、executable-make-buffer-file-executable-if-script-p
が、以下のような 「crate_id
が設定されているファイル」を 「shebang 付きの実行可能ファイル」と認識してしまうようになってしまいました。
#![crate_id = "foo"] #![crate_type = "bin"] fn main() {}
executable-make-buffer-file-executable-if-script-p
は、スクリプトファイルを作成する際の chmod
してパーミッション設定する手間を省いてくれる非常に便利な関数なのですが、rust のソースコードを保存する度に execute のパーミッションを設定されるのは非常に鬱陶しいかったため、rust-mode でだけ hook を削除したかった、というのが動機です。
最後に
Rust 0.10 が先日リリースされたので、みんなで使いましょう!!!
今回のリリースから、Mac/Linux 向けのバイナリや、公式の nightly-build が提供されるようになりました。もうLLVMのコンパイルを長時間待つ必要はありません!!! あなたと rustlang, 今すぐダウンロード。