I tend to use often non-file buffers kinda like post-it-notes and it is way too easy to kill them inadvertently, as there is no confirmation to kill. Even if you enforce the habit of writing only in file buffers (subject to confirmation), you might still inadvertently write in a non-file buffer.
Therefore, I created a kill-hook to ask kill confirmation, but only for buffers that I created (setting global
buffer-offer-save would make Emacs unusable). To identify user buffers, I exploit the fact that the name of buffers created automatically starts with a star.
Now, given its prominence, I would like to use the
*scratch* buffer as a note taking buffer too.
In this case, to fit the Emacs naming convention, I need to rename it
scratch (or anyway something without the star).
I see two possibilities:
I prevent its creation: in the kill hook I check if I am going to kill the last buffer and create my
scratch, to prevent the creation of Emacs'
I look for a create create-scratch-buffer hook and rename the scratch here.
As for point 1,
(length (list-buffers)) includes also so called non-interesting (hidden) buffers and I would happily avoid to parse names with regexp on every hook call (to detect interesting buffers).
As for point 2, how can I detect the scratch buffer creation? Perhaps with a mode hook, e.g. something like:
(add-hook 'after-change-major-mode-hook 'rename-scratch)
My actual kill hook follows.
(add-to-list 'kill-buffer-query-functions 'ask-before-killing-user-buffer) (defun ask-before-killing-user-buffer () "If the current buffer is a user buffer, ask for saving before killing. Here a user buffer is one not: associated to a file, belonging to a process or auto-created by Emacs. The latter are considered such when starting with the usual `*'. The proposed filename will not be accepted if any buffer is already visiting the file" (interactive) (let* (save-name visited-by exit-while-p (ask "Save file as: ") (buffer (current-buffer)) (buffer-name (buffer-name)) (user-buff-p (if (or (string-match "^ \\|\\*" buffer-name) (get-buffer-process buffer) (buffer-file-name)) nil t))) ;; Ask to save modified buffer (if (and user-buff-p (buffer-modified-p)) (if (y-or-n-p (format "`%s' was modified; save it? " buffer-name)) (progn ;; accept only non visited file names (setq default-directory DEFAULT-SAVE-DIR) (while (not exit-while-p) (setq save-name (file-truename (read-file-name ask nil nil nil buffer-name))) (setq visited-by (find-buffer-visiting save-name)) (if visited-by (setq ask (format "`%s' is being visited by buffer `%s'.\nPlease choose another name: " save-name (buffer-name visited-by))) (setq exit-while-p t))) (write-file save-name t)))) t))
Try to answer to your comments, clarifiying what I am willing to achieve.
I have a shortcut creating buffers named
scratch2, etc to readily copy snippets from web pages or from ebooks, to type a nearby task, the draft of an email, etc. Normally these are ephemeral buffers never translating into files, they live until the text snippets are copied in actual documents (but occasionally the buffer is edited and saved). Important original material gets immediately the status of file-buffer (with the related backup facilities); it is anyway unpleasant to accidentally kill my scratches, despite I can recover them going on the source web page, ebook etc. Just like it is not crucial to lose your remember-the-milk notes, but ...
Currently using a mode hook seems to me a solution without to much overhead:
(defun rename-scratch-buffer () (if (and (get-buffer "*scratch*") (not (get-buffer "scratch"))) (with-current-buffer "*scratch*" (rename-buffer "scratch")))) (add-hook 'after-change-major-mode-hook 'rename-scratch-buffer)