scratching-in-space
Table of Contents
Emacs scratch buffers have place oriented design.
A simple alternative: make files.
Musings about persistent scratch technology.
Introduction
If you ever typed something in a buffer called *scratch*
you will
inevitably have found yourself in this situation:
- Just typed some awesome code.
- Kill scratch buffer accidentally or unthinkingly.
- That awesome text is gone forever… and it hurts.
I did try persistent-scratch, in its simplest form, it persists your scratch buffer across sessions. You still end up having one place for your "current" scratch. It just did not click with me.
The whole idea of a scratch buffer might be obsolete (Xah Lee 2008).
What I want:
- Convenient way of writing some code interactively.
- Persist it.
scratching in space
Our disk space is vast, and emacs is great at creating files.
We can be like Sherlock Holmes and never throw our notes away.
Horde those scratches. Put them in git. Now you can grep through them, see what you were scratching years in the past.
I have a dir called ~/scratches
with all my scratches.
This is a bit similar to denote, which I use for note-taking.
here is my current hack for this:
(defvar mememacs/scratch-dir (expand-file-name "~/scratch")) (defun mememacs/latest-scratch (suffix) (unless (file-exists-p mememacs/scratch-dir) (make-directory mememacs/scratch-dir)) (when-let ((f (car (cl-remove-if-not (lambda (it) (and (string-suffix-p suffix it) (not (string-match-p "#" it)))) (process-lines "ls" "-A" "-t" mememacs/scratch-dir))))) (expand-file-name f mememacs/scratch-dir))) (defun mememacs/new-scratch-name (suffix) (unless (file-exists-p mememacs/scratch-dir) (make-directory mememacs/scratch-dir)) (expand-file-name (format "%s.%s" (make-temp-name "scratch-") suffix) mememacs/scratch-dir)) (defun mm/scratch (&optional create-new suffix) "Visit the latest scratch file with `suffix` (a file extension). With prefix arg make a new file." (interactive (list current-prefix-arg (completing-read "scratch filetype: " '("cljs" "clj")))) (let* ((latest (mememacs/latest-scratch suffix)) (buff (find-file-noselect (if (or create-new (not latest)) (mememacs/new-scratch-name suffix) latest)))) (pop-to-buffer-same-window buff) (when (eq major-mode 'emacs-lisp-mode) (elisp-enable-lexical-binding)) buff)) (defun mm/scratch-el (&optional arg) (interactive "P") (mm/scratch arg "el"))
keybinds: leader bs #'mm/scratch-el leader bS #'mm/scratch
With a nice keybind (leader b s
) I go to my current scratch file - the latest modified file in my scratch dir.
With prefix-arg, it makes a new file.
A second bind will ask me to make a clj
or cljs
file.
clojure scratch repl?
Whatever. I just do this:
echo '{}' > ~/scratch/bb.edn
Now I can start a cider repl with bb in my scratch dir.
If you want to be asked for bb
or jvm
:
echo '{}' > ~/scratch/deps.edn
Also nbb
: A nice way to scratch some cljs + javascript + node:
It currently requires some workaround that you can find here.