>> 古い記事: anbt-sql-formatter メモ
<< 新しい記事: 対訳: オープンソース・ソフトウェア教育 / teachingopensource.org

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Elisp メモ: メジャーモードを切り替えるタイミングで処理を実行させる

注)以下の方法がベストか?という点についてはよく分かりません。 添削歓迎です。


M-x apropos RET hook RET して "major-mode" で検索すると after-change-major-mode-hook と change-major-mode-hook という項目が出てくるので調べてみた。

大ざっぱに言えばモード移行時に「現在のモードの最後」に実行するか 「次のモードの最初」に実行するかの違いらしく、 次のように my-mode を作り my-mode から別のモードへ切り替えると どのモードの時に呼ばれているか確認できる。


(defun my-mode ()
  (interactive)
  (setq major-mode 'my-mode)
  (setq mode-name "MY mode")

  (add-hook 'change-major-mode-hook
            (lambda ()
              (message (format "change-major-mode-hook: %s" major-mode))
              (sit-for 2)))

  (add-hook 'after-change-major-mode-hook
            (lambda ()
              (message (format "after-change-major-mode-hook: %s" major-mode))
              (sit-for 2))))

ただし、これだけだと大域的なフック変数に登録されてしまうらしく、 すべてのモード切り替え時に実行されてしまって都合が悪い。 M-x でミニバッファを開くだけでも change-major-mode-hook に登録した関数が実行されてしまう。

そうではなく、「my-mode から」別のモードへ切り替える時「だけ」実行させたい。 調べてみると、フック変数をバッファローカルにすると良いらしい。

GNU Emacs Lispリファレンスマニュアル: Creating Buffer-Local の change-major-mode-hook の説明から引用:

この変数をバッファローカルにしておくとその役目を終えると変数は消えてしまい、 それ以降のメジャーモードに干渉しない。

フック変数をローカルにするためには make-local-hook を使う……のかと思ったが、 それではダメで、 add-hook の第4引数を nil 以外にすると期待通りに動いた。


my-mode の時だけあるアドバイスが有効になる (my-mode に切り替えたときにアドバイスが有効になり、 他のモードに切り替えたときに無効になる) ようにするサンプル:


(defun my-mode ()
  (interactive)
  (setq major-mode 'my-mode)
  (setq mode-name "MY mode")
  
  (defadvice next-line
    (after advc-foo activate)
    (message (format "%c" (char-after))))
  (ad-activate 'next-line) ;; my-mode 実行時にアドバイスを有効に
  
  ;;(make-local-hook 'change-major-mode-hook)
  (add-hook 'change-major-mode-hook
            (lambda ()
                ;; my-mode から別のモードへの切り替え時にアドバイスを無効に
                (ad-deactivate 'next-line))
            nil
            t))

環境

GNU Emacs 23.0.91.1

>> 古い記事: anbt-sql-formatter メモ
<< 新しい記事: 対訳: オープンソース・ソフトウェア教育 / teachingopensource.org
** ホームに戻る

コメント

コメントの投稿

管理者にだけ表示を許可する

|
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。