|
|
;;; rich-minority.el --- Clean-up and Beautify the list of minor-modes.
|
|
|
|
|
|
;; Copyright (C) 2014 <bruce.connor.am@gmail.com>
|
|
|
|
|
|
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
|
|
|
;; URL: http://github.com/Bruce-Connor/rich-minority
|
|
|
;; Package-Requires: ((cl-lib "0.5"))
|
|
|
;; Version: 20140821.2020
|
|
|
;; X-Original-Version: 0.1.1
|
|
|
;; Keywords: mode-line faces
|
|
|
;; Prefix: rm
|
|
|
;; Separator: -
|
|
|
|
|
|
;;; Commentary:
|
|
|
;;
|
|
|
;; rich-minority-mode
|
|
|
;; ══════════════════
|
|
|
;;
|
|
|
;; Emacs package for hiding and/or highlighting the list of minor-modes
|
|
|
;; in the mode-line.
|
|
|
;;
|
|
|
;; Usage
|
|
|
;; ─────
|
|
|
;;
|
|
|
;; To activate the enrichment of your minor-modes list, call `M-x
|
|
|
;; rich-minority-mode', or add this to your init file:
|
|
|
;;
|
|
|
;; ╭────
|
|
|
;; │ (rich-minority-mode 1)
|
|
|
;; ╰────
|
|
|
;;
|
|
|
;; By default, this has a couple of small effects (provided as examples)
|
|
|
;; it is up to you to customize it to your liking with the following
|
|
|
;; three variables:
|
|
|
;;
|
|
|
;; rm-excluded-modes: List of minor mode names that will be hidden from the
|
|
|
;; minor-modes list. Use this to hide *only* a few modes
|
|
|
;; that are always active and don't really contribute
|
|
|
;; information.
|
|
|
;; rm-included-modes: List of minor mode names that are allowed on the
|
|
|
;; minor-modes list. Use this to hide *all but* a few
|
|
|
;; modes.
|
|
|
;; rm-text-properties: List text properties to apply to each minor-mode
|
|
|
;; lighter. For instance, by default we highlight
|
|
|
;; `Ovwrt' with a red face, so you always know if
|
|
|
;; you're in `overwrite-mode'.
|
|
|
;;
|
|
|
;;
|
|
|
;; Installation
|
|
|
;; ────────────
|
|
|
;;
|
|
|
;; This package is available fom Melpa, you may install it by calling
|
|
|
;; `M-x package-install'.
|
|
|
;;
|
|
|
;; Alternatively, you can download it manually, place it in your
|
|
|
;; `load-path' and require it with
|
|
|
;;
|
|
|
;; ╭────
|
|
|
;; │ (require 'rich-minority)
|
|
|
;; ╰────
|
|
|
|
|
|
(require 'cl-lib)
|
|
|
|
|
|
(defun rm-bug-report ()
|
|
|
"Opens github issues page in a web browser. Please send any bugs you find.
|
|
|
Please include your Emacs and rich-minority versions."
|
|
|
(interactive)
|
|
|
(message "Your rm-version is: %s, and your emacs version is: %s.\nPlease include this in your report!"
|
|
|
rich-minority-version emacs-version)
|
|
|
(browse-url "https://github.com/Bruce-Connor/rich-minority/issues/new"))
|
|
|
(defun rm-customize ()
|
|
|
"Open the customization menu in the `rich-minority' group."
|
|
|
(interactive)
|
|
|
(customize-group 'rich-minority t))
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
;; Customization variables.
|
|
|
(defcustom rm-blacklist '(" hl-p")
|
|
|
"List of minor modes you want to hide from the mode-line.
|
|
|
|
|
|
Has three possible values:
|
|
|
|
|
|
- nil: All minor modes are shown in the mode-line (but see also
|
|
|
`rm-included-modes').
|
|
|
|
|
|
- List of strings: Represents a list of minor mode names that
|
|
|
will be hidden from the minor-modes list.
|
|
|
|
|
|
- A string: If this variable is set to a single string, this
|
|
|
string must be a regexp. This regexp will be compared to each
|
|
|
minor-mode lighter, and those which match are hidden from the
|
|
|
minor-mode list.
|
|
|
|
|
|
If you'd like to use a list of regexps, simply use something like the following:
|
|
|
(setq rm-excluded-modes (mapconcat 'identity list-of-regexps \"\\\\|\"))
|
|
|
|
|
|
Don't forget to start each string with a blank space, as most
|
|
|
minor-mode lighters start with a space."
|
|
|
:type '(choice (repeat string)
|
|
|
(regexp :tag "Regular expression."))
|
|
|
:group 'rich-minority
|
|
|
:package-version '(rich-minority . "0.1.1"))
|
|
|
(define-obsolete-variable-alias 'rm-excluded-modes 'rm-blacklist "0.1.1")
|
|
|
(define-obsolete-variable-alias 'rm-hidden-modes 'rm-excluded-modes "0.1.1")
|
|
|
|
|
|
(defcustom rm-whitelist nil
|
|
|
"List of minor modes you want to include in the mode-line.
|
|
|
|
|
|
- nil: All minor modes are shown in the mode-line (but see also
|
|
|
`rm-excluded-modes').
|
|
|
|
|
|
- List of strings: Represents a list of minor mode names that are
|
|
|
allowed on the minor-modes list. Any minor-mode whose lighter
|
|
|
is not in this list will NOT be displayed.
|
|
|
|
|
|
- A string: If this variable is set to a single string, this
|
|
|
string must be a regexp. This regexp will be compared to each
|
|
|
minor-mode lighter, and only those which match are displayed on
|
|
|
the minor-mode list.
|
|
|
|
|
|
If you'd like to use a list of regexps, simply use something like the following:
|
|
|
(setq rm-included-modes (mapconcat 'identity list-of-regexps \"\\\\|\"))
|
|
|
|
|
|
Don't forget to start each string with a blank space, as most
|
|
|
minor-mode lighters start with a space."
|
|
|
:type '(choice (repeat string)
|
|
|
(regexp :tag "Regular expression."))
|
|
|
:group 'rich-minority
|
|
|
:package-version '(rich-minority . "0.1.1"))
|
|
|
(define-obsolete-variable-alias 'rm-included-modes 'rm-whitelist "0.1.1")
|
|
|
|
|
|
(defcustom rm-text-properties
|
|
|
'(("\\` Ovwrt\\'" 'face 'font-lock-warning-face))
|
|
|
"Alist of text properties to be applied to minor-mode lighters.
|
|
|
The car of each element must be a regexp, and the cdr must be a
|
|
|
list of text properties.
|
|
|
|
|
|
(REGEXP PROPERTY-NAME PROPERTY-VALUE ...)
|
|
|
|
|
|
If the regexp matches a minor mode lighter, the text properties
|
|
|
are applied to it. They are tested in order, and search stops at
|
|
|
the first match.
|
|
|
|
|
|
These properties take priority over those defined in
|
|
|
`rm-base-text-properties'."
|
|
|
:type '(repeat (cons regexp (repeat sexp)))
|
|
|
:group 'rich-minority
|
|
|
:package-version '(rich-minority . "0.1"))
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
;; Functions and Defvars
|
|
|
(defconst rm--help-echo-bottom
|
|
|
"Mouse-1: Mode Menu.\nMouse-2: Mode Help.\nMouse-3: Toggle Minor Modes.")
|
|
|
|
|
|
;;;###autoload
|
|
|
(defun rm--mode-list-as-string-list ()
|
|
|
"Return `minor-mode-list' as a simple list of strings."
|
|
|
(let ((full-list (remove "" (mapcar #'format-mode-line minor-mode-alist))))
|
|
|
(setq rm--help-echo
|
|
|
(format "Full list:\n %s\n\n%s"
|
|
|
(mapconcat 'identity full-list "\n ")
|
|
|
rm--help-echo-bottom))
|
|
|
(mapcar #'rm--propertize
|
|
|
(rm--remove-hidden-modes
|
|
|
full-list))))
|
|
|
|
|
|
(defvar-local rm--help-echo nil
|
|
|
"Used to set the help-echo string dynamically.")
|
|
|
|
|
|
(defcustom rm-base-text-properties
|
|
|
'('help-echo 'rm--help-echo
|
|
|
'mouse-face 'mode-line-highlight
|
|
|
'local-map 'mode-line-minor-mode-keymap)
|
|
|
"List of text propeties to apply to every minor mode."
|
|
|
:type '(repeat sexp)
|
|
|
:group 'rich-minority
|
|
|
:package-version '(rich-minority . "0.1"))
|
|
|
|
|
|
(defun rm--propertize (mode)
|
|
|
"Propertize the string MODE according to `rm-text-properties'."
|
|
|
(if (null (stringp mode))
|
|
|
`(:propertize ,mode ,@rm-base-text-properties)
|
|
|
(let ((al rm-text-properties)
|
|
|
done prop)
|
|
|
(while (and (null done) al)
|
|
|
(setq done (pop al))
|
|
|
(if (string-match (car done) mode)
|
|
|
(setq prop (cdr done))
|
|
|
(setq done nil)))
|
|
|
(eval `(propertize ,mode ,@prop ,@rm-base-text-properties)))))
|
|
|
|
|
|
(defun rm--remove-hidden-modes (li)
|
|
|
"Remove from LI elements that match `rm-excluded-modes' or don't match `rm-included-modes'."
|
|
|
(let ((pred (if (listp rm-excluded-modes) #'member #'rm--string-match))
|
|
|
(out li))
|
|
|
(when rm-excluded-modes
|
|
|
(setq out
|
|
|
(remove nil
|
|
|
(mapcar
|
|
|
(lambda (x) (unless (and (stringp x)
|
|
|
(funcall pred x rm-excluded-modes))
|
|
|
x))
|
|
|
out))))
|
|
|
(when rm-included-modes
|
|
|
(setq pred (if (listp rm-included-modes) #'member #'rm--string-match))
|
|
|
(setq out
|
|
|
(remove nil
|
|
|
(mapcar
|
|
|
(lambda (x) (unless (and (stringp x)
|
|
|
(null (funcall pred x rm-included-modes)))
|
|
|
x))
|
|
|
out))))
|
|
|
out))
|
|
|
|
|
|
(defun rm--string-match (string regexp)
|
|
|
"Like `string-match', but arg STRING comes before REGEXP."
|
|
|
(string-match regexp string))
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
;; minor-mode
|
|
|
(defvar rm--mode-line-construct
|
|
|
'(:eval (rm--mode-list-as-string-list))
|
|
|
"Construct used to replace `minor-mode-alist'.")
|
|
|
|
|
|
(defvar rm--warning-absent-element
|
|
|
"Couldn't find %S inside `mode-line-modes'. If you didn't change it yourself, please file a bug report with M-x rm-bug-report"
|
|
|
"Warning message used when something wasn't found.")
|
|
|
|
|
|
(defvar rm--backup-construct nil
|
|
|
"Construct containing `minor-mode-alist' which we removed from the mode-line.")
|
|
|
|
|
|
;;;###autoload
|
|
|
(define-minor-mode rich-minority-mode nil nil " $"
|
|
|
:global t
|
|
|
(if rich-minority-mode
|
|
|
(let ((place (or (member 'minor-mode-alist mode-line-modes)
|
|
|
(cl-member-if
|
|
|
(lambda (x) (and (listp x)
|
|
|
(equal (car x) :propertize)
|
|
|
(equal (cadr x) '("" minor-mode-alist))))
|
|
|
mode-line-modes))))
|
|
|
(if place
|
|
|
(progn
|
|
|
(setq rm--backup-construct (car place))
|
|
|
(setcar place rm--mode-line-construct))
|
|
|
(setq rich-minority-mode nil)
|
|
|
(if (member 'sml/pos-id-separator mode-line-format)
|
|
|
(message "You don't need to activate rich-minority-mode if you're using smart-mode-line")
|
|
|
(warn rm--warning-absent-element 'minor-mode-alist))))
|
|
|
(let ((place (member rm--mode-line-construct mode-line-modes)))
|
|
|
(if place
|
|
|
(setcar place rm--backup-construct)
|
|
|
(warn rm--warning-absent-element rm--mode-line-construct)))))
|
|
|
|
|
|
(provide 'rich-minority)
|
|
|
|
|
|
;;; rich-minority.el ends here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|