« ^ »

list-buffersで表示されないバッファの条件を調べた

所要時間: 約 2分

https://sximada.qrunch.io/entries/igZwGMywTUSL9IJdの転載。

Emacsで M-x list-buffers を実行するとバッファ一覧が表示されるが、一部表示されていないバッファもある。 例えば url-retrieve が作成した接続を管理するためのバッファなどがそれにあたる。

以前からあまり気にしてはいなかったけれど、ちょっと気になったからどうなったら表示されなくなるのか調べてみた。

list-buffers--refresh 全体

list-buffers は内部で list-buffers--refresh を呼び出している。コードは次のようになっている。

buff-menu.el.gz

(defun list-buffers--refresh (&optional buffer-list old-buffer)
  ;; Set up `tabulated-list-format'.
  (let ((name-width Buffer-menu-name-width)
	(size-width Buffer-menu-size-width))
    ;; Handle obsolete variable:
    (if Buffer-menu-buffer+size-width
	(setq name-width (- Buffer-menu-buffer+size-width size-width)))
    (setq tabulated-list-format
	  (vector '("C" 1 t :pad-right 0)
		  '("R" 1 t :pad-right 0)
		  '("M" 1 t)
		  `("Buffer" ,name-width t)
		  `("Size" ,size-width tabulated-list-entry-size->
                           :right-align t)
		  `("Mode" ,Buffer-menu-mode-width t)
		  '("File" 1 t))))
  (setq tabulated-list-use-header-line Buffer-menu-use-header-line)
  ;; Collect info for each buffer we're interested in.
  (let ((buffer-menu-buffer (current-buffer))
	(show-non-file (not Buffer-menu-files-only))
	entries)
    (dolist (buffer (or buffer-list
			(buffer-list (if Buffer-menu-use-frame-buffer-list
					 (selected-frame)))))
      (with-current-buffer buffer
	(let* ((name (buffer-name))
	       (file buffer-file-name))
	  (when (and (buffer-live-p buffer)
		     (or buffer-list
			 (and (or (not (string= (substring name 0 1) " "))
                                  file)
			      (not (eq buffer buffer-menu-buffer))
			      (or file show-non-file))))
	    (push (list buffer
			(vector (if (eq buffer old-buffer) "." " ")
				(if buffer-read-only "%" " ")
				(if (buffer-modified-p) "*" " ")
				(Buffer-menu--pretty-name name)
				(number-to-string (buffer-size))
				(concat (format-mode-line mode-name nil nil buffer)
					(if mode-line-process
					    (format-mode-line mode-line-process
							      nil nil buffer)))
				(Buffer-menu--pretty-file-name file)))
		  entries)))))
    (setq tabulated-list-entries (nreverse entries)))
  (tabulated-list-init-header))

バッファ一覧の取得

バッファの取得は selected-framebuffer-list を使っている。

    (dolist (buffer (or buffer-list
			(buffer-list (if Buffer-menu-use-frame-buffer-list
					 (selected-frame)))))

(selected-frame) は現在のフレームを返す。

(selected-frame)
#<frame README.org<emacs-display-buffer> 0x101825830>

buffer-list は第一引数でframeを受けとり、バッファのリストを返す。 バッファはたくさんあるので以下は個数だけ数えてみた。

(length (buffer-list (selected-frame)))
132

それで取得したバッファをdolistで一つずつ処理している。

バッファのリストを以下で対象とするかどうかを判定している。

	  (when (and (buffer-live-p buffer)
		     (or buffer-list
			 (and (or (not (string= (substring name 0 1) " "))
                                  file)
			      (not (eq buffer buffer-menu-buffer))
			      (or file show-non-file))))

この中でバッファ名の最初が半角空白なファイルに関連づいていないバッファを除外している。 この条件があるから M-x list-buffers に表示されない。

ちなみに M-x list-buffers に来ないバッファの内容を確認したい場合は M-x display-buffer すると 全バッファの一覧が表示されるのでそこから選べば良い。