I want to delight narrow-to-region. When I call org-toggle-narrow-to-subtree it calls org-narrow-to-subtree which calls narrow-to-region. When this is called the modeline shows "Narrow". Is there a way to delight that? I would like to replace that with a unicode character, which I did with minor modes. Help tells me that narrow-to-region is a c function an not lisp. Does this mean no delighting possible?


No, delight can't affect the appearance of "Narrow" in the mode line, because it is not a mode name/lighter (despite appearing in the same section of the mode line).

Only major mode names and minor mode lighter text can be Delighted.

The mode line syntax %n is what produces the word "Narrow" (when appropriate), and that appears in the mode-line-modes variable -- which is one of the components of the overall C-hv mode-line-format (see which) -- following the list of minor modes. The string " Narrow" is hard-coded in the C code for formatting the mode line.

Your options are probably:

  • Remove the %n entirely (and optionally add a custom replacement).
  • Do some post-processing of the formatted mode line to search and replace the text " Narrow"

For the latter, I have a feeling that one of the alternatives to delight works by performing the user's desired search/replacements on the formatted mode line whenever it is rendered, but I can't recall the name of that library.

For the former, you could use something like the following, to replace the "%n" in mode-line-modes with the following mode line construct:

(:eval (when (buffer-narrowed-p) " <N>"))

That's necessarily less efficient than the C code, but I can't imagine it being noticeable.

;; Replace "Narrow" with "<N>" in mode line, when narrowed.
(defvar my-mode-line-narrowed " <N>"
  "Appears in the mode line when the buffer is narrowed.")
(catch 'done
  (let ((x mode-line-modes))
    (while x
      (when (and (stringp (car x)) (string= (car x) "%n"))
        (setcar x '(:eval (when (buffer-narrowed-p) my-mode-line-narrowed)))
        (throw 'done t))
      (setq x (cdr x)))))

You can then M-: (setq my-mode-line-narrowed "foo") RET to play with different indicators.


Similar to @phils's answer, but skipping the explaining, which he's done well.

(defun remove-Narrow-lighter ()
  "Remove `Narrow' lighter from mode line."
  (let ((%n-cons  (regexp-car-member "%n\\(.*\\)\\'" mode-line-modes)))
    (when %n-cons (setcar %n-cons ""))))

(defun regexp-car-member (regexp xs)
  "Like `member', but tests by matching REGEXP against cars."
  (and (consp xs)  (if (and (stringp (car xs))  (string-match-p regexp (car xs)))
                     (regexp-car-member regexp (cdr xs)))))

I do something similar to this in zones.el, but to change the narrowing lighter to reflect the current narrowing (zone), not to remove it altogether.

(FWIW, I don't recommend removing this lighter altogether, as it's usually important to know when the buffer is narrowed.)

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.