At times while working on a code, it's useful to quickly open a *scratch* buffer to paste a snippet from that code file.

If I am working on a Perl script, I would like to quickly open a *scratch* buffer with in cperl-mode. It would also be nice to quickly jump back to the code buffer I was originally working in.

1 Answer 1


It will be convenient to bind the below function to a key binding of your choice. If you are currently working on a FILE buffer, calling the below function will toggle between FILE's major-mode specific *scratch* buffer called *scratch-MAJOR-MODE* and the FILE buffer.

Given the example in question, if I am working on a Perl script called myperl.pl, calling this function will toggle between myperl.pl and *scratch-cperl-mode*.

(defun modi/switch-to-scratch-and-back (&optional arg)
  "Toggle between *scratch-MODE* buffer and the current buffer.
If a scratch buffer does not exist, create it with the major mode set to that
of the buffer from where this function is called.

        COMMAND -> Open/switch to a scratch buffer in the current buffer's major mode
    C-0 COMMAND -> Open/switch to a scratch buffer in `fundamental-mode'
    C-u COMMAND -> Open/switch to a scratch buffer in `org-mode'
C-u C-u COMMAND -> Open/switch to a scratch buffer in `emacs-elisp-mode'

Even if the current major mode is a read-only mode (derived from `special-mode'
or `dired-mode'), we would want to be able to write in the scratch buffer. So
the scratch major mode is set to `org-mode' for such cases.

Return the scratch buffer opened."
  (interactive "p")
  (if (and (or (null arg)               ; no prefix
               (= arg 1))
           (string-match-p "\\*scratch" (buffer-name)))
      (switch-to-buffer (other-buffer))
    (let* ((mode-str (cl-case arg
                       (0  "fundamental-mode") ; C-0
                       (4  "org-mode") ; C-u
                       (16 "emacs-lisp-mode") ; C-u C-u
                       ;; If the major mode turns out to be a `special-mode'
                       ;; derived mode, a read-only mode like `help-mode', open
                       ;; an `org-mode' scratch buffer instead.
                       (t (if (or (derived-mode-p 'special-mode) ; no prefix
                                  (derived-mode-p 'dired-mode))
                            (format "%s" major-mode)))))
           (buf (get-buffer-create (concat "*scratch-" mode-str "*"))))
      (switch-to-buffer buf)
      (funcall (intern mode-str))   ; http://stackoverflow.com/a/7539787/1219634
  • How could I exclude dired mode, term mode and other non editable mode for this function?
    – godblessfq
    Aug 31, 2016 at 7:31
  • @godblessfq I had fixed this just recently in my config. For now you can get that version from there. I'll update this answer when I get to a computer. Aug 31, 2016 at 23:24
  • @godblessfq I have updated the answer. Try it out and see if it works for you. Sep 1, 2016 at 15:26
  • works like a charm!
    – godblessfq
    Sep 3, 2016 at 3:59

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.