DelightedModes

Delight enables you to easily customise how major and minor modes appear in the ModeLine.

It is similar in purpose to DiminishedModes but it accounts for major modes as well as minor modes, and also incorporates the necessary ‘eval-after-load’ call for minor modes, which makes the configuration simpler.

Another alternative to delight is dim.

Download and Install

Install the delight package from the default GNU ELPA repository:

 M-x package-install RET delight RET

The latest version of delight.el is also available from its Savannah repository (n.b. the code is no longer maintained here at the EmacsWiki).

Example usage

Modifying a single mode at a time:

 (require 'delight)
 (delight 'abbrev-mode " Abv" 'abbrev)
 (delight 'rainbow-mode)

Modifying multiple modes:

 (require 'delight)
 (delight '((abbrev-mode " Abv" abbrev)
            (smart-tab-mode " \\t" smart-tab)
            (eldoc-mode nil "eldoc")
            (rainbow-mode)
            (overwrite-mode " Ov" t)
            (emacs-lisp-mode "Elisp" :major)))

The first argument is the mode symbol.

The second argument is the replacement name to use in the mode line (or nil to hide it).

The third argument is either the keyword :major for major modes or, for minor modes, the library which defines the mode. This is passed to ‘eval-after-load’ and so should be either the name (as a string) of the library file which defines the mode, or the feature (symbol) provided by that library. If this argument is nil, the mode symbol will be passed as the feature. If this argument is either t or 'emacs then it is assumed that the mode is already loaded (you can use this with standard minor modes that are pre-loaded by default when Emacs starts).

In the above example, rainbow-mode is the symbol for both the minor mode and the feature which provides it, and its lighter text will be hidden from the mode line.

To determine which library defines a mode, use e.g.: C-h f eldoc-mode RET. The name of the library is displayed in the first paragraph, with an “.el” suffix (in this example it displays “eldoc.el”, and therefore we could use the value “eldoc” for the library).

If you simply cannot figure out which library to specify, an alternative approach is to evaluate (delight 'something-mode nil t) once you know for sure that the mode has already been loaded, perhaps by using the mode hook for that mode.

Some corner cases

If all else fails, it’s worth looking at C-h v minor-mode-alist (after enabling the minor mode in question). There are rare cases where the entry in minor-mode-alist has a different symbol to the minor mode with which it is associated, and in these situations you will need to specify the name in the alist, rather than the name of the mode itself.

Some known examples are:

minor modehow to delight
auto-fill-mode(delight 'auto-fill-function " AF" t)
server-mode(delight 'server-buffer-clients " SV" 'server)

Note also that it can be easier to configure some package modelines directly. For example, the Projectile readme shows how to customize it:

  (setq projectile-mode-line '(:eval (format " Proj[%s]" (projectile-project-name))))

Important notes

Although strings are common, any mode-line construct is permitted as the value (for both minor and major modes); so before you override a value you should check the existing one, as you may want to replicate any structural elements in your replacement if it turns out not to be a simple string.

Conversely, you may incorporate additional mode-line constructs in your replacement values, if you so wish. e.g.:

 (delight 'emacs-lisp-mode
          '("Elisp" (lexical-binding ":Lex" ":Dyn"))
          :major)

See ‘mode-line-format’ for information about mode-line constructs, and M-: (info "(elisp) Mode Line Format") for further details.

Settings for minor modes are held in a global variable and tend to take immediate effect upon calling ‘delight’. Major mode names are held in buffer-local variables, however, so changes to these will not take effect in a given buffer unless the major mode is called again, or the buffer is reverted. Calling M-x normal-mode is sufficient in most cases.

Also bear in mind that some modes may dynamically update these values themselves (for instance dired-mode updates mode-name if you change the sorting criteria) in which cases this library may prove inadequate.

Integration with powerline, and other libraries

With the exception of Emacs’ default mode line rendering, anything rendering a mode line construct will call format-mode-line. By default, delight.el wants to display delighted major mode names only in the mode line and not elsewhere, and so delighted major mode names are inhibited during calls to format-mode-line.

Libraries like PowerLine call format-mode-line, but for the purpose of replacing the standard mode line rendering, in which case we do want to see the delighted major mode names.

As of version 1.04, delight.el will respect the value of inhibit-mode-name-delight if it has been bound by something else, and so it is possible for other libraries/advice to let-bind this variable to nil around calls to format-mode-line in order that the delighted value will be used for major modes.

DelightedPowerLine is a small library implementing this behaviour for PowerLine specifically.

Configuration with use-package

The popular use-package macro supports delight.el so you can also delight modes as part of your package configurations. The following is quoted from the use-package README file:

delight is invoked with the :delight keyword, which is passed a minor mode symbol, a replacement string or quoted mode-line data (in which case the minor mode symbol is guessed to be the package name with “-mode” appended at the end), both of these, or several lists of both. If no arguments are provided, the default mode name is hidden completely.

 ;; Don't show anything for rainbow-mode.
 (use-package rainbow-mode
  :delight)
 
 ;; Don't show anything for auto-revert-mode, which doesn't match
 ;; its package name.
 (use-package autorevert
  :delight auto-revert-mode)
 
 ;; Remove the mode name for projectile-mode, but show the project name.
 (use-package projectile
  :delight '(:eval (concat " " (projectile-project-name))))
 
 ;; Completely hide visual-line-mode and change auto-fill-mode to " AF".
 (use-package emacs
  :delight
  (auto-fill-function " AF")
  (visual-line-mode))