Narrow-to-region-indirect for Emacs
I'm once again an Emacs convert (spoken multiple times since this was first posted). I used Emacs a fair bit back in 2011 as my main editor (when vimpulse
was becoming a viable alternative to native Vim and I forced Emacs upon myself for as long as I could), I even wrote a few posts about extending it. But eventually it was starting to feel sluggish with everything I was throwing at it and I had to give it up (looking back, it was probably a bad minor-mode or two).
However in the time I was away from Emacs the eco-system has really modernized. There are various starter kits for getting up and running quickly with sane defaults in CURRENTYEAR, we have package.el
since Emacs 24, along with MELPA as a maintained repository of elisp packages, and even a set of decent color themes! And of course I can't leave out evil (the extensible vi layer) which I can't do without.
There were a mountain of features I missed from Emacs while in Vim-land (although there are plenty of ports both ways), but I want to share the killer feature for me since picking it up again: narrowing, and indirect buffers.
images/2013-04-18/emacs.png
Narrowing
Emacs has a concept of narrowing buffers, which restricts your view of a buffer to an area that you specify, which is great for focusing on a particular method or for running commands that operate on the entire buffer. You can also change your major mode while in a narrow buffer, which is great for editing code in the middle of an email (for example).
Recently I was working with a lot of client-side JavaScript and would often prototype in a single HTML file, with CSS at the top, followed by the content, and ending with the JavaScript at the bottom. This works well enough when things are small but doesn't scale well, leading to a lot of jumping back and forth throughout the file. However using the concept of narrowing it is possible to treat the single HTML file as though it were actually three! (splitting into multiple files would be too easy)
I begin by opening the HTML file, and split Emacs into three windows. Then in each window I select the appropriate code and run the narrow-to-region
command, but oh no! This actually narrows all three of the editor windows at once, when I only wanted to narrow oneā¦
Indirect Buffers
This is where indirect buffers come in. From the docs:
"An indirect buffer shares the text of some other buffer, which is called the base buffer of the indirect buffer. In some ways it is a buffer analogue of a symbolic link between files."
By turning each window view into an indirect buffer, we will be able to narrow them separately, all we need to do is run clone-indirect-buffer
on each window to create an indirect buffer from the underlying buffer. Then we can use the narrow-to-region
command again, only this time each window will remain separated as intended. Once the panes are narrowed they can each have their own major-mode set too. When done you can simply kill the buffer like you would with a regular file.
A Handy Shortcut
Of course this wouldn't be much of an Emacs post without some lisp, so here is a shortcut command that combines the cloning and narrowing:
(defun narrow-to-region-indirect (start end)
"Restrict editing in this buffer to the current region, indirectly."
(interactive "r")
(deactivate-mark)
(let ((buf (clone-indirect-buffer nil nil)))
(with-current-buffer buf
(narrow-to-region start end))
(switch-to-buffer buf)))