Both @andreas-röhler and @drew had reasonable answers. However, I wasn't happy with either of them on their own.
The problems I had were:
- Both leave stuff on the undo stack, which interferes with editing and can neadlessly mark a buffer as dirty.
- @drew's requires rebinding, which I'd like to avoid.
So, what I did is make my own based mostly on @drew's code. It defines a minor mode narrow-reindent-mode
which advises narrow-to-*
and widen
to use indent-rigidly
to perform alignment.
The full code is ~70 lines so I won't post it here, but it is in this gist.
The heart of it is narrow-reindent--after-narrow
:
(defun narrow-reindent--after-narrow (&rest _r)
"Indent narrowed buffer. This function is used as advice for
`narrow-to-defun' and friends."
(when narrow-reindent-mode
(let ((beg (point-min))
(end (point-max)))
(setq narrow-reindent--point-min beg)
(setq narrow-reindent--point-max end)
(setq narrow-reindent--indent-amount (indent-rigidly--current-indentation beg end))
(without-undo
(indent-rigidly beg end (- narrow-reindent--indent-amount))))))
It works with both narrow-to-defun
and narrow-to-region
(have not tested narrow-to-page
).
EDIT: This has been turned into a full-fledged package and is available on MELPA and MELPA Stable as narrow-reindent
. The current repository is here.