Add "Cool new scratch buffers" archive post
This commit is contained in:
parent
40c78e93c9
commit
325a37a08c
1 changed files with 75 additions and 0 deletions
75
posts/Cool_new_scratch_buffers.mdwn
Normal file
75
posts/Cool_new_scratch_buffers.mdwn
Normal file
|
@ -0,0 +1,75 @@
|
|||
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`:
|
||||
|
||||
[[!format el """
|
||||
(defun raise-scratch ()
|
||||
"Show the *scratch* buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer "*scratch*"))
|
||||
"""]]
|
||||
|
||||
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.
|
||||
|
||||
[[!format el """
|
||||
(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*"))
|
||||
(buffer (get-buffer bname))
|
||||
(mode-sym (intern (concat mode "-mode"))))
|
||||
|
||||
(unless buffer
|
||||
(setq buffer (generate-new-buffer bname))
|
||||
(with-current-buffer buffer
|
||||
(when (fboundp mode-sym)
|
||||
(funcall mode-sym))))
|
||||
|
||||
(switch-to-buffer buffer)))
|
||||
"""]]
|
||||
|
||||
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.
|
||||
|
||||
**Update:** fixed my flawed code.
|
||||
|
||||
[[!meta date="2012-08-02 00:27:00"]]
|
||||
[[!tag emacs elisp coding]]
|
Loading…
Reference in a new issue