dabbrev で対象バッファを絞るの巻 最終話

ドモドモ。
はい,しつこいですね。
でも最終話。であることを祈って。。。

まとめ

先にまとめておきます。
dabbrev で対象バッファを絞るための設定には,主に,
dabbrev-check-other-buffers, dabbrev-check-all-buffers,dabbrev-select-buffers-function,
この3つの変数が関係してきます。

dabbrev-check-other-buffers

カレントバッファ以外の,他のバッファを対象にするかどうかを制御。
t の時は,dabbrev-select-buffers-function でかき集めたバッファを対象にします。
これ重要。

dabbrev-check-all-buffers

基本全てのバッファを対象にします。
でも,dabbrev-ignored-buffer-names ,dabbrev-ignored-regexps が設定されていれば,
それぞれで指定しているバッファは除外されます。

dabbrev-select-buffers-function

対象としたいバッファをかき集める関数を指定しまうー。
引数なしで,バッファのリストを返す必要があります。
例えばこう。

(defun my-dabbrev-select-jde-mode-buffers ()
  "Return a list of buffers opened with jde-mode or java-mode."
  (let (l (bl (buffer-list)))
    (dolist (elt bl)
      (save-excursion
        (set-buffer elt)
        (when (memq major-mode '(java-mode jde-mode))
          (setq l (cons elt l)))))
    l))

どうすればいいのか?

  • dabbrev-check-other-buffers はデフォルトでは t になっているので,そのまま。
  • dabbrev-check-all-buffers をバッファローカルにして nil にする。
  • dabbrev-select-buffers-function に対象としたいバッファをかき集める関数を設定する。

以上を踏まえると次のような設定を,フックに追加? すればいいことになりやす。

(set (make-local-variable 'dabbrev-check-all-buffers) nil)
(set (make-local-variable 'dabbrev-select-buffers-function)
     'my-dabbrev-select-jde-mode-buffers)

ちなみにワタシは以下のように,.emacs に書きました。

(defun jde-mode-hook-func ()
  ...
  (set (make-local-variable 'dabbrev-check-all-buffers) nil)
  (set (make-local-variable 'dabbrev-select-buffers-function)
       'my-dabbrev-select-jde-mode-buffers)
  ...)

(add-hook 'jde-mode-hook 'jde-mode-hook-func)
(add-hook 'jde-entering-java-buffer-hook 'jde-mode-hook-func)


さてこれで,ac-dabbrev.el を使用しても,あのわずらわしい,
Scanning メッセージのドバッと感から解放されるわけです!
はぁ,よかった。やっとこさ快適環境のできあがりですね。
Visual Studio なり eclipse を使えよ! という突っ込みは勘弁してくだちい(笑)


てか,Info の焼き直しみたいになったなぁ感があるのがちょっと・・・。

最終話に至る過程

前回のエントリでも嘘をついていたことが判明。
がそれを修正しても,jde-mode の時はすべてのバッファを見に行ってしまう現象に
出くわして,しばらくほっといて,再度,粘ってみました。
往々にしてこういうときは,原因は自分にあるんですよね・・・。


でも,whitypig さんそこまで人間出来てません。
とりあえず,emacs-lisp-mode では起きない。
jde-mode,java-mode では起きることは分かった。
同じ設定しているはずなのに。。。


だもんで,dabbrev.el 内の,dabbrev-expand に edebug-defun して,
ひたすら追ってみました。
すると,dabbrev-select-buffers-function を funcall した前後で,
dabbrev-check-all-buffers の値が,nil から t になることを突き止める。


で,dabbrev-check-all-buffers には,自分が書いた関数である,
my-dabbrev-select-jde-mode-buffers が設定されている。やな予感・・・。
いやそんなはずはない! ちゃんと確認したもん!
と自分を正当化する whitypig さん。
このときはまだじぶんの哀れさには気づいていませんでした。


こんだー,こいつを追ってみると,buffer-list で取得した各バッファ
に,set-buffer して major-mode を調べているだけ。
で,関数の最後にポイントをおいて here!(h ね) としてみると,
確かに dabbrev-check-all-buffers の値が t になっている・・・。
いやな汗がダラダラダラダラダラダラダラダラ・・・。
ん? あれ? ぎょっ! ぬぁあああああああ!!
set-buffer で,注目しているバッファを切り替えているのに,
save-excursion してねぇ!!
汗汗。my-dabbrev-select-elisp-mode-buffers 関数を見てみると,
ちゃんと save-excursion している!!
whitypig さんはころんだ!
whitypig さんはまだ起き上がれない!
whitypig さんはまだ起き上がれない!
whitypig さんはまだ起き上がれない!
whitypig さんはまだ起き上がれない!
whitypig さんはまだ起き上がれない!
whitypig さんはまだ起き上がれない!
whitypig さんは起き上がろうとしない!
whitypig さんは起き上がろうとしない!
whitypig さんは起き上がろうとしない!
パルプンテ唱えて砕け散りたい感じー? みたいな(ハート)
あれパルプンテってドラクエ9 にあるの? (ハナシソラスナ)
そういえばパルプンテってさー(マテマテ)


てか,save-excursion は バッファローカルな変数とかも保存して復元するんだね。
おっちゃん,ポジションとマークとバッファだけだとおもてたよ。


で,save-excursion して無事,期待通りに動くことを確認しましたとさ。
(ほんとか? またどっかに抜けがあるんじゃね?
ま,そんときはそんときということで)


おつかれっした!