2

Suppose I have a buffer and I make several indirect buffer clones of it. Is it possible to kill all these buffers except for the currently visited one?

I have found buffer-base-buffer in the manual, which allows to find the parent base buffer, but is there a way of listing all the buffers, that are indirect and have this base-buffer? (without going through all buffers and comparing their buffer-base-buffer).

More precisely, the operation I want to have is "Leave only (1) this buffer from all the indirect ones sharing the same base and (2) the base buffer itself. Then make the base look just like the current indirect buffer (narrowing, point, ...?), so that the indirect buffer can be killed as well and all I am left with is the base buffer."

serycjon
  • 381
  • 2
  • 8
  • Other than collecting your own buffer list, e.g. by hooking into `clone-indirect-buffer-hook`, I don't think you can avoid going through `(buffer-list)` and determining which buffers share a `(buffer-base-buffer)`. – Basil Mar 02 '18 at 14:38
  • Ok, thanks. By the way, as the last step in killing all the indirect buffers, I would like to make the `base-buffer`, that is left to look like the indirect buffer, from which I am killing. Do I need 'to copy' the narrowing and point position only, or is there more to do? (the operation I want to have is "leave only this buffer from all the indirect ones sharing the same base and the base buffer itself") – serycjon Mar 02 '18 at 15:03
  • Wrt your comment question: if you kill the base buffer then that automatically kills all indirect buffers based on it. So just kill the indirect buffers other than the one you are currently in. That will leave that indirect buffer and its base buffer. – Drew Mar 02 '18 at 22:26
  • OK, the last question is then how to transfer the current state (narrowing, point, ?) from the current (last) indirect buffer to the base buffer so that I can close even the last indirect one. But I think I can figure this out by myself or it might be a material for whole new question. Thanks guys! – serycjon Mar 03 '18 at 23:02

1 Answers1

2

"Leave only (1) this buffer from all the indirect ones sharing the same base and (2) the base buffer itself."

(defun my-kill-other-indirect-bufs ()
  "Kill all indirect buffers other than the current buffer."
  (interactive)
  (dolist (buf  (buffer-list))
    (when (and (buffer-base-buffer buf)  (not (eq (current-buffer) buf)))
      (kill-buffer buf))))

If you use Icicles then the commands that provide completion for buffer names let you use C-x i - and C-x i + to remove and keep only, respectively, indirect buffers.

This is one of a set of on-the-fly filtering keys for buffer-name candidates. You can add to or remove from this set by customizing option icicle-buffer-candidate-key-bindings.

For example, you could add a key that filters to show only indirect buffers other than the current one, and then you could use multi-command icicle-kill-buffer (bound to C-x k in Icicle mode, by default) to kill all such buffers.

You would just add an entry such as this to icicle-buffer-candidate-key-bindings:

Key: C-x I
Command: my-remove-buffer-cands-for-other-indirect
Condition: t

Where command my-remove-buffer-cands-for-other-indirect would be, e.g.:

(defun my-remove-buffer-cands-for-other-indirect ()
  "Remove buffer-name candidates for indirect buffers except current."
  (interactive)
  (setq icicle-must-pass-after-match-predicate
        (lambda (buf) (or (eq (current-buffer) (get-buffer buf))
                          (not (buffer-base-buffer (get-buffer buf))))))
  (icicle-complete-again-update))

That filters buffer-name completion candidates to allow only the current buffer and non-indirect buffers.

Drew
  • 75,699
  • 9
  • 109
  • 225