I have a working snippet that advices both kill-buffer and kill-this-buffer to not kill the scratch buffer:
(defun ninrod/scratch-bodyguard (buffer-assassin &rest arguments)
(let ((buffer-to-kill (buffer-name (current-buffer))))
(if (equal buffer-to-kill "*scratch*")
(message "DENIED! don't kill my precious *scratch*!!")
(apply buffer-assassin arguments))))
(defun ninrod/scratch-protection (buffer-assassin &rest arguments)
(let ((buffer-to-kill (car arguments)))
(if (equal buffer-to-kill "*scratch*")
(message "DENIED! don't kill my precious *scratch*!!")
(apply buffer-assassin arguments))))
(advice-add #'kill-this-buffer :around #'ninrod/scratch-bodyguard)
(advice-add #'kill-buffer :around #'ninrod/scratch-protection)
The problem is that these lines:
(message "DENIED! don't kill my precious *scratch*!!")
(apply buffer-assassin arguments))))
Are repeated in both functions, so I thought that I could apply the DRY principle and refactor the snippet to this:
(defun ninrod--protection (buffer-assassin buffer-to-kill &rest arguments)
(if (equal buffer-to-kill "*scratch*")
(message "DENIED! don't kill my precious *scratch*!!")
(apply buffer-assassin arguments)))
(defun ninrod/scratch-bodyguard (buffer-assassin &rest arguments)
(let ((buffer-to-kill (buffer-name (current-buffer))))
(ninrod--protection 'buffer-assassin buffer-to-kill arguments)))
(defun ninrod/scratch-protection (buffer-assassin &rest arguments)
(let ((buffer-to-kill (car arguments)))
(ninrod--protection 'buffer-assassin buffer-to-kill arguments)))
(advice-add #'kill-this-buffer :around #'ninrod/scratch-bodyguard)
(advice-add #'kill-buffer :around #'ninrod/scratch-protection)
This causes all hell to break loose. Now I can't even close emacs, because apparently emacs tries to kill all buffers and as I've just tampered with the kill buffer functions, well, it's bad. Very bad.
I know I mean well, but I'm must be doing something very stupid. For starters, I don't know if I can really pass around functions as parameters? So it could be that?
How would you refactor that snippet to apply the dry principle?
edit:
this works:
(defun ninrod--protection (buffer-assassin buffer-to-kill &rest arguments)
(if (equal buffer-to-kill "*scratch*")
(message "DENIED! don't kill my precious *scratch*!!")
(apply buffer-assassin arguments)))
(defun ninrod/scratch-bodyguard (buffer-assassin &rest arguments)
(let ((buffer-to-kill (buffer-name (current-buffer))))
(ninrod--protection 'buffer-assassin buffer-to-kill arguments)))
(advice-add #'kill-this-buffer :around #'ninrod/scratch-bodyguard)
so the problem lies exactly here:
(defun ninrod/scratch-protection (buffer-assassin &rest arguments)
(let ((buffer-to-kill (car arguments)))
(ninrod--protection 'buffer-assassin buffer-to-kill arguments)))
edit2: quoting or unquoting the function buffer-assassin
does not make a difference
Symbol's function definition is void: buffer-assassin
error, unquoted it'sWrong type arguments: stringp, (#<buffer whatever>)
. The second error is due to the&rest
that @YoungFrog mentioned. As he/she said, there are different types of hell.Cx-b
*scratch*
RET
to recreate the*scratch*
buffer.