8

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?

  • 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 '16 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 '16 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 '16 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 '16 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 '16 at 12:07
14

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*"))))
  • Please forgive me any mistakes in the code—I copy-pasted this answer together on mobile. – lunaryorn Jan 4 '16 at 17:50
  • cool! BTW, why do you use the #? I don't think that's needed anymore – fommil Jan 4 '16 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 '16 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 '16 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 '16 at 21:12
4

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.
  • 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 '16 at 8:59
  • Wow, thanks, that's a nice feature, for sure! – lunaryorn Jan 28 '16 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 '16 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 '16 at 15:50
1

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 https://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))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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