2012-08-07 23:07:20 +02:00
|
|
|
#+TITLE: Cool new scratch buffers
|
|
|
|
|
|
|
|
I had a thought today: It would be nice if I could have more than one
|
|
|
|
scratch buffer, and even nicer if they could easily have different
|
|
|
|
major modes.
|
|
|
|
|
|
|
|
So, I had this function in my emacs init file, =raise-scratch=:
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(defun raise-scratch ()
|
|
|
|
"Show the *scratch* buffer."
|
|
|
|
(interactive)
|
|
|
|
(switch-to-buffer "*scratch*"))
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
Its nice, it allowed me to do exactly what I wanted to do, easily open
|
|
|
|
my scratch buffer. I bound this to ~XF86HomePage~, which makes sense to
|
|
|
|
me, since emacs always starts in the ~*scratch*~ buffer.
|
|
|
|
|
|
|
|
Today, though, it didn't seem to be quite enough. As I said, it would
|
|
|
|
be nice to have the ability to have multiple scratch buffers with
|
|
|
|
different major modes. This is handy for messing around with some
|
|
|
|
~sawfish-mode~ code, or ~python-mode~, for example.
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(defun raise-scratch (&optional mode)
|
|
|
|
"Show the *scratch* buffer. If called with a universal
|
|
|
|
argument, ask the user which mode to use. If MODE is not nil,
|
|
|
|
open a new buffer with the name *MODE-scratch* and load MODE as
|
|
|
|
its major mode."
|
|
|
|
(interactive (list (if current-prefix-arg
|
|
|
|
(read-string "Mode: ")
|
|
|
|
nil)))
|
|
|
|
(let* ((bname (if mode
|
|
|
|
(concat "*" mode "-scratch*")
|
|
|
|
"*scratch*"))
|
2012-08-07 23:10:45 +02:00
|
|
|
(buffer (get-buffer bname))
|
|
|
|
(mode-sym (intern (concat mode "-mode"))))
|
2012-08-07 23:07:20 +02:00
|
|
|
|
|
|
|
(unless buffer
|
|
|
|
(setq buffer (generate-new-buffer bname))
|
|
|
|
(with-current-buffer buffer
|
2012-08-07 23:10:45 +02:00
|
|
|
(when (fboundp mode-sym)
|
|
|
|
(funcall mode-sym)
|
|
|
|
(goto-char (point-max))
|
|
|
|
(newline))))
|
2012-08-07 23:07:20 +02:00
|
|
|
|
|
|
|
(switch-to-buffer buffer)))
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
This is quite a bit bigger. It now takes an optional =mode= argument,
|
|
|
|
when it is called interactively it will check if the universal prefix
|
|
|
|
argument (~C-u~) was used and if so, asks for the value of =mode=.
|
|
|
|
|
|
|
|
If mode has been specified it will create a new buffer with the name
|
|
|
|
~*MODE-scratch*~. It will then insert a file local property line
|
|
|
|
specifying the major mode to use and then switches to it.
|
|
|
|
|
|
|
|
It's the first time I'm using a list with the ~interactive~ command, it
|
|
|
|
always seemed very alien to me, but it seems quite clear how it works
|
|
|
|
now.
|
|
|
|
|
|
|
|
It was a challenge to figure out how I wanted to do this. My first
|
|
|
|
idea was to ask for a file extension and match that to
|
|
|
|
~auto-mode-alist~, but that has regexps for keys, so not easily matched.
|
|
|
|
Then there is the problem of figuring out how to load the right major
|
|
|
|
mode in another way, since adding such a file local property line
|
|
|
|
happens /after/ the buffer has been loaded, and thus has no effect on
|
|
|
|
which major mode is chosen.
|
|
|
|
|
|
|
|
Of course, this approach doesn't ensure the right major mode gets
|
|
|
|
chosen, but that's really up to whomever uses it.
|
|
|
|
|
|
|
|
It makes me very happy to use such an extensible editor.
|
2012-08-07 23:10:45 +02:00
|
|
|
|
|
|
|
*Update:* fixed my flawed code.
|