Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If I ever close the *scratch* buffer it is always an accident.

I have persistent-scratch so it's as easy as a persistent-scratch-reload but it'd be nice if the scratch couldn't be killed. How can I do that?

share|improve this question
1  
Do you actually make use of the features provided by the mode of *scratch*? If not - if you use it essentially for Emacs-Lisp code and you could just as easily use Emacs-Lisp mode, then consider not using *scratch* for your Lisp fiddling. Just use C-x f with a file buffer that you can save or toss at will. – Drew Jan 5 at 0:06
    
In a similar way you can always restore scratch by just switching to *scratch*—Emacs will create it if it doesn't exist—and entering Lisp Interaction Mode. – lunaryorn Jan 5 at 5:37
    
@Drew yeah, I keep coming back to this idea over the years, e.g. a ~/.emacs.d/scratch.el. But It just doesn't feel right, I don't know why. – fommil Jan 12 at 23:04
    
Or just tossa.el, tossb,..., anywhere. It's trivial to do %m ^toss to mark all such files in a Dired buffer, then D to delete them all. – Drew Jan 13 at 1:18
    
I'm giving the scratch.el approach another try. Maybe if I can clean up flycheck it'll be nice emacs.stackexchange.com/questions/19506 – fommil Jan 13 at 12:07
up vote 13 down vote accepted

You can (ab-)use kill-buffer-query-functions for this purpose:

(add-hook 'kill-buffer-query-functions #'my/dont-kill-scratch)
(defun my/dont-kill-scratch ()
  (if (not (equal (buffer-name) "*scratch*"))
      t
    (message "Not allowed to kill %s, burying instead" (buffer-name))
    (bury-buffer)
    nil))

In my old Emacs configuration I used this to protect a bunch of important buffer like *Messages*.

Note that my function uses bury-buffer to achieve the effect of killing a buffer—doing the buffer away—without actually killing the buffer. Emacs will switch to a different buffer just as if you had killed scratch, but keep scratch alive and just put it at the end of the buffer list.

Or, simply

(add-hook 'kill-buffer-query-functions
          (lambda() (not (equal (buffer-name) "*scratch*"))))
share|improve this answer
    
Please forgive me any mistakes in the code—I copy-pasted this answer together on mobile. – lunaryorn Jan 4 at 17:50
    
cool! BTW, why do you use the #? I don't think that's needed anymore – fommil Jan 4 at 17:52
3  
@fommil It makes the byte compiler warn if the symbol is not defined as a function. It does not make any difference semantically here (but can when using lambdas) but you should use it nonetheless to support the byte compiler. – lunaryorn Jan 4 at 17:56
2  
@fommil Also, I think it's good style to use the function quote when referring to functions, if only to support readers of your code. Here it's clear that we refer to a function, but in other places it may not. In these situations the function quote can provide an important clue. – lunaryorn Jan 4 at 17:58
1  
And besides: (eq 'foo #'foo) holds. Both forms literally evaluate to the same object, namely the symbol foo. – lunaryorn Jan 4 at 21:12

A new feature has been introduced for persistent scratch called "remember"

From https://www.masteringemacs.org/article/whats-new-in-emacs-24-4

The new command ``remember-notes`` creates a buffer which is saved

on ``kill-emacs``.

You may think of it as a \*scratch\* buffer whose content is preserved.

In fact, it was designed as a replacement for \*scratch\* buffer and can

be used that way by setting ``initial-buffer-choice`` to

``remember-notes`` and ``remember-notes-buffer-name`` to “\*scratch\*”.

Without the second change, \*scratch\* buffer will still be there for

notes that do not need to be preserved.
share|improve this answer
    
Neat! Also note that it has an associated variable remember-notes-bury-on-kill (which is t by default). It does what the name suggests – which seems quite relevant for the original question. – Harald Hanche-Olsen Jan 28 at 8:59
    
Wow, thanks, that's a nice feature, for sure! – lunaryorn Jan 28 at 9:25
    
this doesn't work for me, the buffer is always called notes (which opens on startup) and it doesn't hijack *scratch* (I tried with and without escapes to the asterix) – fommil Jan 28 at 10:02
    
@fommil Just curious. Why do you want the scratch to be persistent. Why not use notes for persistent and scratch for non persistent usage? – Talespin_Kit Jan 29 at 15:50

ok, this whole discussion has prompted me to return to an approach I've tried to setup but @Drew has rekindled an interest in.

Create a file like this in ~/.emacs.d/scratch.el

;;; scratch.el --- Emacs Lisp Scratch -*- lexical-binding: t -*-


;; Local Variables:
;; flycheck-disabled-checkers: (emacs-lisp-checkdoc)
;; byte-compile-warnings: (not free-vars unresolved)
;; End:
;;; scratch.el ends here

thanks to http://emacs.stackexchange.com/a/19507/5142 for the Local Variables.

And then add the following to ~/.emacs.d/init.el as per @lunaryorn's answer:

;; *scratch* is immortal
(add-hook 'kill-buffer-query-functions
          (lambda () (not (member (buffer-name) '("*scratch*" "scratch.el")))))

(find-file (expand-file-name "scratch.el" user-emacs-directory))
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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