13

When I close a frame, I'd like for its buffer to be killed.

If the buffer is displayed in other frames, the buffer should not be killed.

Do nothing if more than one buffer is displayed in a frame.

What's a good way to set this up?

1
  • All the answers do not work individually for me. However if I keep all three of them, it actually works. Jan 2, 2017 at 19:38

3 Answers 3

12

If I've understood the question, here's a function that does what you want:

(defun maybe-delete-frame-buffer (frame)
  "When a dedicated FRAME is deleted, also kill its buffer.
A dedicated frame contains a single window whose buffer is not
displayed anywhere else."
  (let ((windows (window-list frame)))
    (when (eq 1 (length windows))
      (let ((buffer (window-buffer (car windows))))
        (when (eq 1 (length (get-buffer-window-list buffer nil t)))
          (kill-buffer buffer))))))

You can add it as a hook that gets called whenever a frame is closed using:

(add-to-list 'delete-frame-functions #'maybe-delete-frame-buffer)
0
6

Below is a function (tested, but not extensively) that meets your first requirement: it kills the current buffer when you close a frame UNLESS the buffer is also visible in another frame.

(defun kill-buffer-when-frame-delete-dwim (frame)
  "Kill current buffer unless it's visible in another frame
besides current FRAME."
  (unless (delq nil (mapcar #'(lambda (x)
                                (memq (current-buffer)
                                      (mapcar #'window-buffer x)))
                            (mapcar #'window-list
                                    (delq frame (frame-list)))))
    (kill-buffer (current-buffer))))

(add-hook 'delete-frame-functions 'kill-buffer-when-frame-delete-dwim)

I'm unclear on the second requirement:

  • By more than one buffer displayed in the frame, do you mean the frame has a) two or more windows, and b) the windows have different buffers displayed in them?
  • By do nothing, do you mean a) delete the frame but do not kill the current buffer, or b) really do nothing at all: do not delete the frame or kill the current buffer?
2
  • Hi Dan. The idea is that if more than one buffer is shown in a frame, via multiple windows in that frame, then no buffer will be killed, but the frame will still be deleted.
    – dharmatech
    Oct 31, 2014 at 21:49
  • But I could see other behaviours being useful. I.e. kill all buffers shown, as long as they aren't shown in other frames.
    – dharmatech
    Oct 31, 2014 at 21:50
1

Here's a simple approach:

(defun close-frame-buffer (frame)
  (kill-buffer
    (window-buffer
      (frame-root-window frame))))

(add-hook 'delete-frame-functions 'close-frame-buffer)

It will kill a buffer even if it's open in another frame however.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.