Subject: [PATCH] Option to choose the major model new scratch buffers

From: Augusto Stoffel <[email-masked]>
Date: Sat, 27 Aug 2022 15:01:28 +0200

Tags: patch

I just noticed the new `scratch-buffer' command and I think it would be
nice to provide an option to create scratch buffers with different major
modes.  WDYT?

What is the best way to get a list of all available major modes?  I can
think of two methods, none of which is perfect.  One is commented out in
the patch; I like the uncommented one (using the auto-mode-alist) a bit
better.

>From c710c8d65d62292e22282da90fa471c16b1d3cb6 Mon Sep 17 00:00:00 2001
From: Augusto Stoffel <[email-masked]>
Date: Sat, 27 Aug 2022 09:50:17 +0200
Subject: [PATCH] Provide option to choose a major mode in 'scratch-buffer'

* lisp/simple.e (get-scratch-buffer-create, scratch-buffer): New
optional MODE argument.
---
 lisp/simple.el | 61 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 17 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index 460aff8bd8..bc9c71dee9 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -10650,24 +10650,51 @@ capitalize-dwim
 
 (fn CL-X)")
 
-(defun get-scratch-buffer-create ()
-  "Return the *scratch* buffer, creating a new one if needed."
-  (or (get-buffer "*scratch*")
-      (let ((scratch (get-buffer-create "*scratch*")))
-        ;; Don't touch the buffer contents or mode unless we know that
-        ;; we just created it.
-        (with-current-buffer scratch
-          (when initial-scratch-message
-            (insert (substitute-command-keys initial-scratch-message))
-            (set-buffer-modified-p nil))
-          (funcall initial-major-mode))
-        scratch)))
-
-(defun scratch-buffer ()
+(defun get-scratch-buffer-create (&optional mode)
+  "Return a scratch buffer for MODE, creating a new one if needed.
+If MODE is nil, use `initial-major-mode' and insert
+`initial-scratch-message'."
+  (let ((name (if mode
+                  (format "*scratch-%s*"
+                          (string-trim-right (symbol-name mode) "-mode"))
+                "*scratch*")))
+    (or (get-buffer name)
+        (let ((scratch (get-buffer-create name)))
+          ;; Don't touch the buffer contents or mode unless we know that
+          ;; we just created it.
+          (with-current-buffer scratch
+            (when (and (not mode) initial-scratch-message)
+              (insert (substitute-command-keys initial-scratch-message))
+              (set-buffer-modified-p nil))
+            (funcall (or mode initial-major-mode)))
+          scratch))))
+
+(defun scratch-buffer (&optional mode)
   "Switch to the *scratch* buffer.
-If the buffer doesn't exist, create it first."
-  (interactive)
-  (pop-to-buffer-same-window (get-scratch-buffer-create)))
+If the buffer doesn't exist, create it first.
+With a prefix argument, select a major mode for the scratch buffer."
+  (interactive
+   (list (when current-prefix-arg
+           (intern
+            (completing-read "Scratch buffer mode: "
+                             (delete-dups
+                              (delq nil
+                                    (mapcar (pcase-lambda (`(_ . ,it))
+                                              (and (symbolp it)
+                                                   (commandp it)
+                                                   it))
+                                            auto-mode-alist))))))))
+            ;; (completing-read "Scratch buffer mode: "
+            ;;                  obarray
+            ;;                  (lambda (sym)
+            ;;                    (and (commandp sym)
+            ;;                         (if (autoloadp (symbol-function sym))
+            ;;                             (string-suffix-p "-mode"
+            ;;                                              (symbol-name sym))
+            ;;                           (memq 'derived-mode-parent
+            ;;                                 (symbol-plist sym)))))
+            ;;                  t)))))
+  (pop-to-buffer-same-window (get-scratch-buffer-create mode)))
 
 (defun kill-buffer--possibly-save (buffer)
   (let ((response
-- 
2.37.2