30

I use quite a few minor modes and usually I know which minor mode is enabled in every major mode. If I really want to see the full list, I can run C-h v minor-mode-list.

At the same time, my mode line get really clogged, so when I vertically split frame, sometimes I cannot read end of the mode line.

Actual question: how to disable showing of minor modes list in mode line? For example, now it may look like this:

-:--- main.c        All (7,12)     (C/l FlyC SScr Abbrev Fill) [main] 16:19 0.45

I want it to look more concise:

-:--- main.c        All (7,12)     (C/l) [main] 16:19
2

9 Answers 9

21

Diminish mode (available in Melpa) will do this.

(diminish 'projectile-mode)
2
  • 4
    If you just want to shorten the name of the minor mode instead of hiding it entirely you can use (diminish 'projectile-mode "p")
    – erikstokes
    Nov 28, 2014 at 17:39
  • 8
    Note also that the actual usage of diminish is (eval-after-load "filladapt" '(diminish 'filladapt-mode)) (using the example from the Emacs Wiki) and not just (diminish 'filladapt-mode) as suggested by the answer. You can only use the short version if the mode is guaranteed to already be loaded.
    – phils
    Nov 28, 2014 at 21:17
19

As mbork commented, you can use delight.el to selectively modify or disable minor (and indeed major) mode text in the mode line.

One of the advantages is that it takes care of the eval-after-load (which you need to write manually with diminish.el in most use-cases), which makes the configuration cleaner. You still need the same information -- the name of the mode, and the library which implements it (which Emacs will tell you if you ask it about the mode) -- but you can wrap it all up into a single form:

 (require 'delight)
 (delight '((some-mode nil "some-library")
            (some-other-mode nil "some-other-library")))

(Or follow the link above for some real usage examples.)

I would recommend taking this approach, because even if you don't want most minor mode lighter text, there's a good chance that you'll find some of them useful (and you can still modify those ones to be shorter).

If you truly want to eliminate all minor mode lighter text (and again, I don't recommend it), you could modify the mode-line-modes variable. The mode line variables changed a while back, so you may want to use M-x find-variable RET mode-line-modes RET and then manually adapt your default definition, editing out the section concerning minor-modes-alist.

Of course then you'd need to maintain it, which isn't so flash, so you might prefer replacing the minor-mode-alist symbol within the existing value. The following is somewhat implementation-specific, but certainly nicer than setting mode-line-modes in its entirety, and you can toggle it on and off.

(define-minor-mode minor-mode-blackout-mode
  "Hides minor modes from the mode line."
  t)

(catch 'done
  (mapc (lambda (x)
          (when (and (consp x)
                     (equal (cadr x) '("" minor-mode-alist)))
            (let ((original (copy-sequence x)))
              (setcar x 'minor-mode-blackout-mode)
              (setcdr x (list "" original)))
            (throw 'done t)))
        mode-line-modes))

(global-set-key (kbd "C-c m") 'minor-mode-blackout-mode)
8
  • Well, it's sad that there is no 'delight' package. Nov 27, 2014 at 11:53
  • 2
    What with Emacs being old and package.el being new, there's a heap of useful libraries which don't have packages. If you're going to limit yourself that way, I'd suggest looking at el-get which will act as a manager (updating included) for a large variety of other library source types.
    – phils
    Nov 27, 2014 at 13:23
  • 1
    @Drew, I know about load-path and require. I used to 'install' all Emacs packages this way when I started to use it a year ago. Nov 27, 2014 at 17:53
  • 4
    I've just added delight to MELPA.
    – sanityinc
    Nov 28, 2014 at 14:37
  • 2
    n.b. delight is in GNU ELPA these days, and not in MELPA (mentioned in case anyone gets confused by the previous comments).
    – phils
    Dec 12, 2016 at 0:12
9

Here is what worked for me:

(defvar hidden-minor-modes ; example, write your own list of hidden
  '(abbrev-mode            ; minor modes
    auto-fill-function
    flycheck-mode
    flyspell-mode
    inf-haskell-mode
    haskell-indent-mode
    haskell-doc-mode
    smooth-scroll-mode))

(defun purge-minor-modes ()
  (interactive)
  (dolist (x hidden-minor-modes nil)
    (let ((trg (cdr (assoc x minor-mode-alist))))
      (when trg
        (setcar trg "")))))

(add-hook 'after-change-major-mode-hook 'purge-minor-modes)

Thanks to Drew's comment, I've improved realization of this solution. Now it uses benefits of association lists and should be a bit more efficient ;-)

4
  • FWIW, it won't catch previously-unloaded minor modes which are enabled manually, nor modes which dynamically update their lighter text (not that the other libraries do the latter, either). But otherwise it seems a reasonably practical approach.
    – phils
    Nov 27, 2014 at 12:53
  • 1
    The point of minor-mode-alist being an alist is that entries can be added and removed at the head to shadow and unshadow entries further down the list that have the same key. If you want to do the kind of thing you are doing, just change the first entry (found using assoc, changed using setcar etc.) for each key, so that you do not lose this useful, intended feature.
    – Drew
    Nov 27, 2014 at 17:23
  • @Drew, You are right, see my improved my solution. Nov 27, 2014 at 18:41
  • Yup; that's what I meant.
    – Drew
    Nov 27, 2014 at 21:10
9

Use Rich-minority with config:

(require 'rich-minority)
(rich-minority-mode 1)
(setf rm-blacklist "")

I also have the thought like you, but I shorten the mode-line more paranoid:

  • Remove all unwanted spaces
  • Remove all spaces and "min-width" of the buffer position info field.
;; Remove all unwanted spaces
(setq-default mode-line-format
          '("%e" mode-line-front-space mode-line-mule-info mode-line-client mode-line-modified mode-line-remote mode-line-buffer-identification mode-line-position
        (vc-mode vc-mode) " "
        mode-line-modes mode-line-misc-info mode-line-end-spaces))
;; Remove all spaces and "min-width" of position info on mode-line
(setq mode-line-position
      `((1 ,(propertize
         " %p"
         'local-map mode-line-column-line-number-mode-map
         'mouse-face 'mode-line-highlight
         ;; XXX needs better description
         'help-echo "Size indication mode\n\
mouse-1: Display Line and Column Mode Menu"))
    (size-indication-mode
     (2 ,(propertize
          "/%I"
          'local-map mode-line-column-line-number-mode-map
          'mouse-face 'mode-line-highlight
          ;; XXX needs better description
          'help-echo "Size indication mode\n\
mouse-1: Display Line and Column Mode Menu")))
    (line-number-mode
     ((column-number-mode
       (1 ,(propertize
        "(%l,%c)"
        'local-map mode-line-column-line-number-mode-map
        'mouse-face 'mode-line-highlight
        'help-echo "Line number and Column number\n\
mouse-1: Display Line and Column Mode Menu"))
       (1 ,(propertize
        "L%l"
        'local-map mode-line-column-line-number-mode-map
        'mouse-face 'mode-line-highlight
        'help-echo "Line Number\n\
mouse-1: Display Line and Column Mode Menu"))))
     ((column-number-mode
       (1 ,(propertize
        "C%c"
        'local-map mode-line-column-line-number-mode-map
        'mouse-face 'mode-line-highlight
        'help-echo "Column number\n\
mouse-1: Display Line and Column Mode Menu"))))))
      )

Now, I can always see Twittering-mode notification and Org-mode's timer :D

4

It's worth noting that use-package supports diminish and delight. If you use it to manage your packages you can hide the minor modes in the mode line adding the :diminish or :delight keywords.

(use-package abbrev
  :diminish abbrev-mode
  :config
  (if (file-exists-p abbrev-file-name)
     (quietly-read-abbrev-file)))
3

I'll throw my solution to this into the ring as well:

(defun modeline-set-lighter (minor-mode lighter)
  (when (assq minor-mode minor-mode-alist)
    (setcar (cdr (assq minor-mode minor-mode-alist)) lighter)))

(defun modeline-remove-lighter (minor-mode)
  (modeline-set-lighter minor-mode ""))

modeline-set-lighter allows you to set the lighter of a minor mode to any string you like. modeline-remove-lighter allows you to remove the lighter of a minor mode completely.

Then, at the end of my init-file I just call these functions for the minor modes whose lighters I want to modify:

(modeline-remove-lighter 'auto-complete-mode)
(modeline-remove-lighter 'git-gutter+-mode)
(modeline-remove-lighter 'guide-key-mode)
(modeline-remove-lighter 'whitespace-mode)
(modeline-set-lighter 'abbrev-mode " Abbr")
(modeline-set-lighter 'auto-fill-function (string 32 #x23ce))
3

You can also bluntly remove all minor modes, in the following way:

(setq mode-line-modes
      (mapcar (lambda (elem)
                (pcase elem
                  (`(:propertize (,_ minor-mode-alist . ,_) . ,_)
                   "")
                  (t elem)))
              mode-line-modes))

This will also work for minor modes defined in the future, since it just completely removes the use of minor-mode-alist from the mode-line-format.

7
  • After removing can I add a single mode such as flycheck-mode?
    – alper
    Jul 22, 2020 at 1:08
  • Everything's possible, but it's more work.
    – Stefan
    Jul 22, 2020 at 13:36
  • Ah I realize that :-( I was able to remove bunch of modes but there were ones I cound't find their names to remove
    – alper
    Jul 22, 2020 at 20:20
  • If you want to remove some and keep others, I think you're better off with something like delight. If that doesn't support your needs, maybe a patch or feature request is in order.
    – Stefan
    Jul 22, 2020 at 21:43
  • I just wanted to keep flycheck and remove all the others, but for some I didn't know their aliases. Using delight I accomplisth to remove some but some remain. Is it possible to list the used mode's alias?
    – alper
    Jul 23, 2020 at 10:13
2

I don't see the point of installing fancy named extensions for something as simple as:

(setcar (alist-get minor-mode minor-mode-alist) "")

For example:

(dolist (mode '(projectile-mode
                whitespace-mode
                hs-minor-mode
                outline-minor-mode
                auto-fill-function))
  (setcar (alist-get mode minor-mode-alist) ""))

You can do any sort of stuff this way. Replacing text is obvious from the above. Also, for example, to put flymake mode at the start of the list:

(let ((mode (assq #'flymake-mode minor-mode-alist)))
  (setq minor-mode-alist (cons mode (remq mode minor-mode-alist))))
2

If you don't want to do diminish/delight on every package. You could try minions it will hide all minor mode and can be toggled using mouse. Or you can use awesome-tray which you can use to refine what to show in modeline.

1
  • This answer did it! Minions mode cleans up your mode line like a Kärcher:)
    – ja0nz
    Jan 10, 2021 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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