[gnu.emacs] kill-buffer.el package

deven@rpi.edu (Deven T. Corzine) (11/27/89)

On 15 Nov 89 06:19:15 GMT, mrd@sun.soe.clarkson.edu (Michael DeCorte) said:

Michael> Is there some way to get emacs to say 'hey you sure you want
Michael> to do this?' when I try to kill a buffer with a process
Michael> accociated with it (eg. *shell*).

As it happens, I have written a kill-buffer package to deal with this
exact problem.  It replaces the original kill-buffer (saving the subr
definition, of course) and if there is a process running in a buffer
which is being killed, it asks the user if to kill the process, and
also if to save the file, (y-or-n-p's) and if buffer is still unsaved
or has running processes, yes-or-no-p on whether to really kill it.

I have been using it without problems since making a few bug fixes and
enhancements...  been intending to post it, just prompted to by seeing
your message...

Enjoy.  (watch for .sig)

Deven

;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; kill-buffer.el --- enhancements to kill-buffer function
;; Author          : Deven Corzine
;; Created On      : Fri Oct 20 09:01:39 1989
;; Last Modified By: Deven Corzine
;; Last Modified On: Sun Nov 26 15:44:32 1989
;; Update Count    : 13
;; Status          : Complete, no known bugs.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; History 		
;; 26-Nov-1989		Deven Corzine	
;;    Last Modified: Thu Nov  2 11:57:50 1989 #11 (Deven Corzine)
;;    Modified to erase buffer before killing.  (so killing *scratch*
;;      when only buffer will (effectively) kill it.)

;; 2-Nov-1989		Deven Corzine	
;;    Last Modified: Mon Oct 30 10:34:54 1989 #10 (Deven Corzine)
;;    Modified to work properly for already-killed buffers.
;;    Modified to catch errors and call original-kill-buffer instead
;;      of breaking.

;; 30-Oct-1989		Deven Corzine	
;;    Last Modified: Mon Oct 30 09:57:42 1989 #6 (Deven Corzine)
;;    Modified to print a message when buffer is killed interactively.
;;    Fixed typo in format string when buffer needs to be saved but is
;;      not bound to a file.

;; 20-Oct-1989		Deven Corzine	
;;    Last Modified: Fri Oct 20 10:40:17 1989 #3 (Deven Corzine)
;;    Changed wording on buffer kill confirmation for when a process
;;      remains running to make it clear the question refers to killing
;;      the buffer, not the process.

;; 20-Oct-1989		Deven Corzine	
;;    Last Modified: Fri Oct 20 10:17:40 1989 #2 (Deven Corzine)
;;    Changed wording on process kill query to be less ambiguous.

;; 20-Oct-1989		Deven Corzine	
;;    Last Modified: Fri Oct 20 09:19:48 1989 #1 (Deven Corzine)
;;    Modified to honor buffer-offer-save and check for abbrevs to save.

;; 20-Oct-1989		Deven Corzine	
;;     #0
;;    Wrote new kill-buffer function to check for processes, and to ask
;;      whether to save buffer (if bound to a file and modified) and to
;;      ask whether to kill each process running in the buffer.
;;    Companion function kill-current-buffer for a convenient keybinding.

;; save original kill-buffer primitive
(or (fboundp 'original-kill-buffer)
    (fset 'original-kill-buffer
          (symbol-function 'kill-buffer)))

(defun kill-buffer (&optional buffer)
  "One arg, a string or a buffer.  Get rid of the specified buffer.

Modified to check for processes, and offer option of killing running
processes or saving buffer if changed.  If BUFFER is t, then use the
current-buffer.  If nil, (as in interactively) prompt for buffer."
  (interactive)
  (condition-case nil
      (let* ((buf (or (and buffer (not (eq buffer t))
                           (get-buffer buffer))
                      (and (eq buffer t) (current-buffer))
                      (get-buffer (read-buffer "Kill buffer: "
                                               (current-buffer) t))))
             (buf (and (buffer-name buf) (set-buffer buf)))
             (proc (get-buffer-process buf))
             (unsaved (and (buffer-modified-p buf)
                           (or (buffer-file-name buf)
                               (and buffer-offer-save
                                    (> (buffer-size) 0))))))
        (if buf
            (progn
              (while (and proc
                          (y-or-n-p (format
                                     "Kill process %s running in buffer %s? "
                                     (process-name proc) (buffer-name buf))))
                (condition-case nil
                    (kill-process proc)
                  (error nil))
                (delete-process proc)
                (setq proc (get-buffer-process buf)))
              (if (and unsaved (y-or-n-p (if (buffer-file-name buf)
                                             (format "Save file %s? " unsaved)
                                           (format "Save buffer %s? "
                                                   (buffer-name buf)))))
                  (progn
                    (condition-case nil
                        (save-buffer buf)
                      (error nil))
                    (setq unsaved nil)))
              (if (and save-abbrevs abbrevs-changed
                       (y-or-n-p (format "Save abbrevs in %s? "
                                         abbrev-file-name)))
                  (write-abbrev-file nil))
              (if (or (not (or proc unsaved))
                      (yes-or-no-p
                       (format "%s%s%s%s; kill anyway? "
                               (if proc "Process(es) " "Buffer ")
                               (if proc "" (buffer-name buf))
                               (if proc
                                   (if unsaved
                                       "running in modified buffed "
                                     "running in buffer ")
                                 " modified")
                               (if proc (buffer-name buf) ""))))
                  (progn
                    (erase-buffer)
                    (set-buffer-modified-p nil)
                    (if (or (interactive-p)
                            (eq buffer t))
                        (message "Buffer %s killed." (buffer-name buf)))
                    (original-kill-buffer buf))))))
    (error (original-kill-buffer buffer))))

(defun kill-current-buffer ()
  "Kills the current buffer."
  (interactive)
  (kill-buffer t))
-- 
Deven T. Corzine        Internet:  deven@rpi.edu, shadow@pawl.rpi.edu
Snail:  2151 12th St. Apt. 4, Troy, NY 12180   Phone:  (518) 274-0327
Bitnet:  deven@rpitsmts, userfxb6@rpitsmts     UUCP:  uunet!rpi!deven
Simple things should be simple and complex things should be possible.