[Date Prev] [Date Index] [Date Next]
[Thread Prev] [Thread Index] [Thread Next]

[xyzzy:04190] save-excursion 中に表示バッファを delete-buffer したときの挙動



毎度どうも、サイトウです。

ちょっとややこしい話なのですが、
2window以上にsplitされたところに "test"という名前のバッファと
そうでないバッファが開かれている状態を想定します。

そこで、以下のような関数を定義します。

foo でやりたいことは、
"test"バッファがすでにある場合はいったん delete-buffer してまた作る。
"test"バッファが表示されていた場合はウィンドウ構成も元に戻す。
--------------------------------------------
(defun get-buffer (name)
  (car (member name
       (buffer-list)
       :test #'(lambda (n b) (string= n (buffer-name b))))))

(defun foo ()
  (interactive)
  (save-excursion
    (let ((sw (selected-window))
	  (w) (b))
      (when (bufferp (get-buffer "test"))
	(setq w (get-buffer-window (get-buffer "test")))
	(delete-buffer "test"))
      (setq b (get-buffer-create "test"))
      (when w
	(set-window w)
	(set-buffer b)
	;(set-window sw)
      )
    )
  )
)

(defun bar ()
  (interactive)
  (save-excursion
    (set-buffer "*scratch*")

    (foo)
  )
)
-------------------------------------------
M-x foo を実行するとカレントバッファがどこでも
期待通りに"test"が新しいバッファに入れ替わります。

しかし、
M-x bar を実行したときの結果が
実行前のカレントバッファによって異なります。

"test"以外のバッファから実行すると
"test"だけ新しいバッファに入れ替わるが、
"test"をカレントにして実行するとカレントバッファが
"*scratch*"になってしまいます。
 
 save-excursionによって戻ろうとした"test"がdelete-bufferされて
しまったために、新しい"test"が名前が同じでも違うオブジェクト
として認識されてしまった為ではないかと思います。


長くなりましたが、やりたいことは foo をどんな状況で呼び出されても
同じ挙動をするようにしたいのです。

うまい方法をご存知の方は教えてください。

-----------------------------------
サイトウ ヒロシ
HiroshiSaito@xxxxxxx

Index Home