続続続続 dabbrev で対象バッファを絞るの巻

ドモドモ。
しつこくてごめんなさい。

※この情報は間違っています。下の方にある「追記」の方が,
正しい可能性が高いです。

前置き

あきらめきれず,引き続きソースを眺めていたら,
dabbrev-select-buffers-function
を設定すればいいぜぇ的なことが書いてあったので,
そっちを試してみることに。
で,変数 dabbrev-select-buffers-function に設定する関数は,
引数なしで,バッファのリストを返す関数でなければならん!
だそうです。


今回は emacs-lisp-mode で開いている場合は,emacs-lisp-mode で
開いている他のバッファを対象にしたいという要求なので,そうしました。
ちなみに,major-mode 変数には,現在開いているバッファのメジャーモードが
設定されています。初めて知りました。


関数は簡単です。
buffer-list で生きている?バッファを取得して,
major-mode を emacs-lisp-mode と比較して
同じだったら返すリストに追加しているだけです。
わざわざ memq 使っているのは,他にモードを追加したい場合に
対応するためです。あるかどうかしらんけど。

解決設定

;; This function should not take any argument.
(defun my-dabbrev-select-elisp-mode-buffers ()
  "Return a list of buffers opened with emacs-lisp-mode."
  (interactive)
  (let (b l (bl (buffer-list)))
    (dolist (elt bl)
      (save-excursion
        (set-buffer elt)
        (when (memq major-mode '(emacs-lisp-mode))
            (setq l (cons elt l)))))
    l))

(defun emacs-lisp-mode-hook-func ()
  (interactive)
  ...
  (set (make-local-variable 'dabbrev-select-buffers-function)
       'my-dabbrev-select-elisp-mode-buffers)
  ..)

(add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-hook-func)

まとめ

とりあえずお疲れちゃんでした。
紆余曲折しましたが,なんとか最適解にたどり着いた感があります。
.java ファイルなら,新たに関数つくって,
jde-mode なり java-mode? なりと比較すればいいしね。
もしくは,正規表現で無視するバッファを簡単に指定できる場合は,
dabbrev-ignored-buffer-regexps を使えばいいしね。
一応動作確認していますが,もすがすっど,ぬげがあるがもすれね。

余談

emacs-lisp-mode で決めうちしない方法はあるんだろうか。
開いているバッファの major-mode と比較すればいんだろうけど,
それだと複数のモードに対応できないし,
それは手入力する必要があるだろうし,難しいか。

2009/08/31 (Mon) 10:42 追記

嘘ついてました。ごめんなさい。
どうも挙動がおかしいなぁと思って見てみたら,間違ってました。
予告通り抜けがありました。


下のように書いてありました。

  "*Non-nil means dabbrev package should search *all* buffers.

Dabbrev always searches the current buffer first.  Then, if
`dabbrev-check-other-buffers' says so, it searches the buffers
designated by `dabbrev-select-buffers-function'.
(Dabbrev は常にカレントバッファ内を検索します。で,もし
`dabbrev-check-other-buffers' が t なら,dabbrev-select-buffers-function で
指定されるバッファ内を探します。)

Then, if `dabbrev-check-all-buffers' is non-nil, dabbrev searches
all the other buffers, except those named in `dabbrev-ignored-buffer-names',
or matched by `dabbrev-ignored-regexps'."
(でもって,dabbrev-check-all-buffers が non-nil なら,dabbrev は,
すべての他のバッファを探すけど,dabbrev-ignored-buffer-names で指定されるバッファ名,
もしくは,dabbrev-ignored-regexps にマッチするバッファ名のバッファは対象になりやせん。)


まとめると,目的達成のためには,
dabbrev-check-other-buffers と dabbrev-check-all-buffers を,
それぞれ バッファローカルにして,nil にする必要があるということ。


以上を踏まえると,以下の様に設定すればよしと。

(defun emacs-lisp-mode-hook-func ()
  (interactive)
  ...
  (set (make-local-variable 'dabbrev-check-other-buffers) nil)
  (set (make-local-variable 'dabbrev-check-all-buffers) nil)
  (set (make-local-variable 'dabbrev-select-buffers-function)
       'my-dabbrev-select-elisp-mode-buffers)
  ...)

(add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-hook-func)