Indirect buffers allow you to edit the same buffer in another buffer. The most interesting thing, however, is that the indirect buffer can have a different major mode.
This is great: If you want to write some elisp in a mail, start writing the mail, create an indirect buffer, put it in emacs-lisp-mode, write your lisp function, switch back to the original mail, and send it.
Emacs 21 provides functions to do this easily:
Here’s the code to put in your ~/.emacs in order to get something like
(defun indirect-buffer () "Edit stuff in this buffer in an indirect buffer. The indirect buffer can have another major mode." (interactive) (let ((buffer-name (generate-new-buffer-name "*indirect*"))) (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name))))
‘M-x indirect-buffer’ to create an indirect buffer of the current buffer.
And this is what I use now regularly for reading book material containing sourcecode examples.
(defvar indirect-mode-name nil "Mode to set for indirect buffers.") (make-variable-buffer-local 'indirect-mode-name)
(defun indirect-region (start end) "Edit the current region in another buffer. If the buffer-local variable `indirect-mode-name' is not set, prompt for mode name to choose for the indirect buffer interactively. Otherwise, use the value of said variable as argument to a funcall." (interactive "r") (let ((buffer-name (generate-new-buffer-name "*indirect*")) (mode (if (not indirect-mode-name) (setq indirect-mode-name (intern (completing-read "Mode: " (mapcar (lambda (e) (list (symbol-name e))) (apropos-internal "-mode$" 'commandp)) nil t))) indirect-mode-name))) (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name)) (funcall mode) (narrow-to-region start end) (goto-char (point-min)) (shrink-window-if-larger-than-buffer)))
It seems one can also set the mode from a fake
auto-mode-alist in the usual way). At least with Emacs v20. So a fake-file-name of say “x.el” will result in emacs-lisp-mode.
(with-current-buffer the-indirect-buffer (set 'buffer-file-name fake-file-name) (set-auto-mode) ; in files.el ; (set 'buffer-file-name nil) doesn't appear necessary. )