From c78f760c56e4f75cebc9bf9b427096866aba514e Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Tue, 7 Aug 2012 23:07:20 +0200 Subject: Add "Cool new scratch buffers" post --- blog/blog-2012-08-02-0027.org | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 blog/blog-2012-08-02-0027.org (limited to 'blog') diff --git a/blog/blog-2012-08-02-0027.org b/blog/blog-2012-08-02-0027.org new file mode 100644 index 0000000..1a91be7 --- /dev/null +++ b/blog/blog-2012-08-02-0027.org @@ -0,0 +1,73 @@ +#+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*")) + (buffer (get-buffer bname))) + + (unless buffer + (setq buffer (generate-new-buffer bname)) + (with-current-buffer buffer + (add-file-local-variable-prop-line 'mode (make-symbol mode)) + (set-auto-mode t) + (goto-char (point-max)) + (newline))) + + (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. -- cgit v1.2.3-54-g00ecf