Endless Parentheses

Concise ramblings on Emacs productivity.

Emacs narrow-or-widen-dwim

Narrowing is one of those features you won’t even hear about in a more mundane editor, but Emacs has an entire keymap for it. While I wouldn’t want to be without this feature, I’m all for simplification.

Michael Fogleman (the same justicier who took matters to his own hands on Hungry Delete Mode) mentioned the following gem on the The Toggle-Map and Wizardry post. I took the liberty of adding a bit of functionality. To use it, you’ll also need the endless/inside-org-code-block-p function.

(defun narrow-or-widen-dwim (p)
  "Widen if buffer is narrowed, narrow-dwim otherwise.
Dwim means: region, org-src-block, org-subtree, or
defun, whichever applies first. Narrowing to
org-src-block actually calls `org-edit-src-code'.

With prefix P, don't widen, just narrow even if buffer
is already narrowed."
  (interactive "P")
  (declare (interactive-only))
  (cond ((and (buffer-narrowed-p) (not p)) (widen))
        ((region-active-p)
         (narrow-to-region (region-beginning)
                           (region-end)))
        ((derived-mode-p 'org-mode)
         ;; `org-edit-src-code' is not a real narrowing
         ;; command. Remove this first conditional if
         ;; you don't want it.
         (cond ((ignore-errors (org-edit-src-code) t)
                (delete-other-windows))
               ((ignore-errors (org-narrow-to-block) t))
               (t (org-narrow-to-subtree))))
        ((derived-mode-p 'latex-mode)
         (LaTeX-narrow-to-environment))
        (t (narrow-to-defun))))

(define-key endless/toggle-map "n"
  #'narrow-or-widen-dwim)
;; This line actually replaces Emacs' entire narrowing
;; keymap, that's how much I like this command. Only
;; copy it if that's what you want.
(define-key ctl-x-map "n" #'narrow-or-widen-dwim)
(add-hook 'LaTeX-mode-hook
          (lambda ()
            (define-key LaTeX-mode-map "\C-xn"
              nil)))

If you’re the kind of person who knows how to use narrow-to-page, this command might not be for you. Meanwhile, for us mortals, it more than fits the bill.

Update 05 Sep 2014

Sacha Chua’s comment below gave me a glimpse of inspiration.

I’ve never liked org’s default keybind for editing a source code block, C-c ', and have been looking for a better one. But if you meditate on it for a minute, the effect of C-c ' is a narrow command with some bells attached. So it fits perfectly into narrow-or-widen-dwim (updated above).

Now that I’m no longer using C-c ' to edit code blocks, I also need a better key to finish editing code blocks, and C-x C-s makes perfect sense.

(eval-after-load 'org-src
  '(define-key org-src-mode-map
     "\C-x\C-s" #'org-edit-src-exit))

Update 23 Sep 2014

I’ve updated it to no longer use the org-in-src-block-p function and just try calling org-edit-src-code instead. org-in-src-block-p has proven quite unreliable.

Update 05 Dec 2015

Now it should also work with any type of org-block supported by org-narrow-to-block.

Update 07 Dec 2015

Use LaTeX-mode-hook instead of eval-after-load, as suggested by Omar in the comments.

Tags: narrow, intuitive, keybind, init.el, emacs

Say thanks on Gratipay
comments powered by Disqus