Package: emacs;
Reported by: Pengji Zhang <me <at> pengjiz.com>
Date: Sat, 29 Mar 2025 11:09:02 UTC
Severity: normal
Tags: patch
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: help-debbugs <at> gnu.org (GNU bug Tracking System) To: Pengji Zhang <me <at> pengjiz.com> Subject: bug#77361: closed (Re: bug#77361: [PATCH] New user option to hide minor mode lighters) Date: Sun, 13 Apr 2025 08:48:02 +0000
[Message part 1 (text/plain, inline)]
Your bug report #77361: [PATCH] New user option to hide minor mode lighters which was filed against the emacs package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 77361 <at> debbugs.gnu.org. -- 77361: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77361 GNU Bug Tracking System Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Eli Zaretskii <eliz <at> gnu.org> To: Pengji Zhang <me <at> pengjiz.com> Cc: 77361-done <at> debbugs.gnu.org Subject: Re: bug#77361: [PATCH] New user option to hide minor mode lighters Date: Sun, 13 Apr 2025 11:46:33 +0300> From: Pengji Zhang <me <at> pengjiz.com> > Cc: 77361 <at> debbugs.gnu.org > Date: Sun, 06 Apr 2025 16:05:00 +0800 > > Eli Zaretskii <eliz <at> gnu.org> writes: > > > Please in future submissions of the patch mention the bug number in > > the log message. > > Thanks for the review! Bug number added in the updated patch. > > >> --- a/doc/lispref/modes.texi > >> +++ b/doc/lispref/modes.texi > >> @@ -2163,6 +2163,18 @@ Mode Line Basics > >> variable can be buffer-local to only compress mode-lines in certain > >> buffers. > >> > >> +@vindex mode-line-collapse-minor-modes > >> + To further ``compress'' the mode line, you may customize the > >> +@code{mode-line-collapse-minor-modes} option to a non-@code{nil} value, > >> +and Emacs will hide some minor mode indicators on the mode line by > >> +collapsing them into a single clickable button. The option can also be > >> +a list of symbols to select minor modes indicators to hide or show. If > >> +the list starts with the symbol @code{not}, it specifies minor modes to > >> +show, otherwise it means minor modes to hide. For example, setting it > >> +to @code{(not flymake-mode)} makes only the indicator for Flymake mode > >> +shown, and setting it to @code{(eldoc-mode)} hides only the indicator > >> +for ElDoc mode. > > > > I think this text and the preceding paragraph should be moved to the > > Emacs user manual, into the "Optional Mode Line" node. These are > > user-facing features, so their place is not in the ELisp Reference > > manual. > > > > For the user manual, the above description of the possible values of > > mode-line-collapse-minor-modes is too detailed. I suggest to have > > there only the first sentence, and then refer to the doc string for > > the various alternative forms of the value. > > I have moved the paragraph for 'mode-line-compact' to the "Optional Mode > Line" node, and added the first sentence for > 'mode-line-collapse-minor-modes' to that paragraph. > > >> ++++ > >> +*** New user option 'mode-line-collapse-minor-modes'. > >> +If non-nil, minor mode lighters on the mode line are collapsed into a > >> +single button. It could also be a list to specify minor mode lighters > > ^^^^^^^^^^^^^^^^^^^^^^^ > > "The value could also be a list..." > > Fixed. > > >> +(defcustom mode-line-collapse-minor-modes nil > >> + "Minor modes for which mode line lighters are hidden. > >> +Hidden lighters are collapsed into one. > >> + > >> +The value could be a list (MODES ...) which means to collapse lighters > >> +only for MODES, or a list (not MODES ...) which means to collapse all > >> +lighters for minor modes not in MODES. Other non-nil values make all > >> +lighters hidden." > >> + :type '(choice (const :tag "No modes" nil) > >> + (repeat :tag "Modes" symbol) > >> + (cons :tag "All modes except" > >> + (const not) (repeat symbol)) > >> + (const :tag "All modes" t)) > >> + :group 'mode-line) > > > > The :version tag is missing. > > Added. Thanks, now installed on the master branch, and closing the bug.
[Message part 3 (message/rfc822, inline)]
From: Pengji Zhang <me <at> pengjiz.com> To: bug-gnu-emacs <at> gnu.org Subject: [PATCH] New user option to hide minor mode lighters Date: Sat, 29 Mar 2025 19:07:40 +0800[Message part 4 (text/plain, inline)]Hello, The attached patch adds a new user option to hide some minor mode lighters on the mode line (by collapsing them into a menu), which is to shorten the mode line and prioritize important information when many minor modes are on. There exist a few packages that solve the problem. To name a few: - diminish[1] and delight[2]. Both offer a way to change the minor mode lighters by modifying 'minor-mode-alist'. To hide a minor mode lighter, one may change it to nil. - minions[3], which partially inspired this patch. It replaces minor mode lighters by a menu to toggle all minor modes. This patch is different from those solutions in two aspects: - Unlike diminish or delight, one can still see the lighters by clicking the button, instead of hiding them permanently. Besides, this patch is compatible with those two packages. - Unlike minions, this patch focuses on *lighters* for *enabled* minor modes. The menu contains only lighters, making it a more space efficient replacement for lighters on mode line, instead of a way to manage minor modes like minions. So I hope this patch is still useful given the existing similar solutions. Please let me know what you think. Thanks! Pengji [1] https://github.com/myrjola/diminish.el [2] https://elpa.gnu.org/packages/delight.html [3] https://github.com/tarsius/minions[0001-New-user-option-to-hide-minor-mode-lighters.patch (text/x-patch, inline)]From c1e27606247761c31cec3d363714875c74b30277 Mon Sep 17 00:00:00 2001 From: Pengji Zhang <me <at> pengjiz.com> Date: Sat, 29 Mar 2025 19:04:58 +0800 Subject: [PATCH] New user option to hide minor mode lighters * lisp/bindings.el (mode-line-collapse-minor-modes): New user option. (mode-line-minor-modes): New variable to hold mode line constructs for minor modes. (mode-line-modes): Use the new variable 'mode-line-minor-modes', and adjust the order of elements so the indicator for hidden minor modes is shown towards the end. (mode-line--make-lighter-menu): New helper function to generate the menu for hidden minor modes. (mode-line--minor-modes): New helper function to computer mode line constructs for minor mode lighters. * doc/lispref/modes.texi (Mode Line Basics): Document the new user option. * etc/NEWS (Note): Annouce the new user option. --- doc/lispref/modes.texi | 12 ++++ etc/NEWS | 9 +++ lisp/bindings.el | 122 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 136 insertions(+), 7 deletions(-) diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 788d98fdf20..23c363be12c 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -2163,6 +2163,18 @@ Mode Line Basics variable can be buffer-local to only compress mode-lines in certain buffers. +@vindex mode-line-collapse-minor-modes + To further ``compress'' the mode line, you may customize the +@code{mode-line-collapse-minor-modes} option to a non-@code{nil} value, +and Emacs will hide some minor mode indicators on the mode line by +collapsing them into a single clickable button. The option can also be +a list of symbols to select minor modes indicators to hide or show. If +the list starts with the symbol @code{not}, it specifies minor modes to +show, otherwise it means minor modes to hide. For example, setting it +to @code{(not flymake-mode)} makes only the indicator for Flymake mode +shown, and setting it to @code{(eldoc-mode)} hides only the indicator +for ElDoc mode. + @node Mode Line Data @subsection The Data Structure of the Mode Line @cindex mode line construct diff --git a/etc/NEWS b/etc/NEWS index 1bd2fd6d486..8b7dfa0ee04 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -316,6 +316,15 @@ This will inhibit implied resizing while a new frame is made and can be useful on tiling window managers where the initial frame size should be specified by external means. +** Mode Line + ++++ +*** New user option 'mode-line-collapse-minor-modes'. +If non-nil, minor mode lighters on the mode line are collapsed into a +single button. It could also be a list to specify minor mode lighters +to hide or show. The default value is nil, which retains the previous +behavior of showing all minor mode lighters. + ** Tab Bars and Tab Lines --- diff --git a/lisp/bindings.el b/lisp/bindings.el index 9707ce4b474..a32e3d58dc7 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -429,6 +429,120 @@ bindings--sort-menu-keymap (bindings--menu-item-string (cdr-safe b)))))) (nconc (make-sparse-keymap prompt) bindings))) +(defcustom mode-line-collapse-minor-modes nil + "Minor modes for which mode line lighters are hidden. +Hidden lighters are collapsed into one. + +The value could be a list (MODES ...) which means to collapse lighters +only for MODES, or a list (not MODES ...) which means to collapse all +lighters for minor modes not in MODES. Other non-nil values make all +lighters hidden." + :type '(choice (const :tag "No modes" nil) + (repeat :tag "Modes" symbol) + (cons :tag "All modes except" + (const not) (repeat symbol)) + (const :tag "All modes" t)) + :group 'mode-line) + +(defvar mode-line-minor-modes '(:eval (mode-line--minor-modes)) + "Mode line construct for minor mode lighters.") +;;;###autoload +(put 'mode-line-minor-modes 'risky-local-variable t) + +(defun mode-line--make-lighter-menu (alist) + "Return a menu keymap for minor mode lighters in ALIST. +ALIST should be in the same format as `minor-mode-alist'. + +Return nil if no lighters in ALIST should be visible, for example, there +are no active minor modes or non-empty lighters." + (let ((menu (make-sparse-keymap "Minor Modes")) + (empty t)) + (dolist (item alist) + (when-let* ((variable (car item)) + ((and (boundp variable) + (symbol-value variable))) + (lighter (format-mode-line `("" ,@(cdr-safe item)))) + ((not (string= lighter ""))) + (toggle (or (get variable :minor-mode-function) variable)) + ;; Follow the format in `mouse-minor-mode-menu' + (name (format "%s - %s" lighter + (capitalize + (string-replace + "-" " " (symbol-name toggle)))))) + (when (eq ? (aref name 0)) + (setq name (substring name 1))) + (let* ((map (cdr-safe (assq variable minor-mode-map-alist))) + (mm-menu (and (keymapp map) + (keymap-lookup map "<menu-bar>")))) + (setq mm-menu + (cond (mm-menu (mouse-menu-non-singleton mm-menu)) + ((fboundp toggle) + (define-keymap :name name + "<help>" (list 'menu-item + "Help for minor mode" + (lambda () (interactive) + (describe-function toggle))) + "<turn-off>" (list 'menu-item + "Turn off minor mode" + toggle))) + ;; No menu and not a minor mode function, so just + ;; display the label without a sub-menu. + (t nil))) + (keymap-set menu (format "<%s>" toggle) + (list 'menu-item name mm-menu)) + (setq empty nil)))) + (and (not empty) menu))) + +(defun mode-line--minor-modes () + "Compute mode line constructs for minor mode lighters." + (let (visible hidden) + (cond + ((not mode-line-collapse-minor-modes) + (setq visible minor-mode-alist + hidden nil)) + ((eq 'not (car-safe mode-line-collapse-minor-modes)) + (let ((modes (cdr mode-line-collapse-minor-modes))) + (dolist (item minor-mode-alist) + (if (memq (car item) modes) + (push item visible) + (push item hidden))) + (setq visible (nreverse visible) + hidden (nreverse hidden)))) + ((listp mode-line-collapse-minor-modes) + (let ((modes mode-line-collapse-minor-modes)) + (dolist (item minor-mode-alist) + (if (memq (car item) modes) + (push item hidden) + (push item visible))) + (setq visible (nreverse visible) + hidden (nreverse hidden)))) + (t (setq visible nil + hidden minor-mode-alist))) + (list "" + `(:propertize ("" ,visible) + mouse-face mode-line-highlight + help-echo "Minor mode\n\ +mouse-1: Display minor mode menu\n\ +mouse-2: Show help for minor mode\n\ +mouse-3: Toggle minor modes" + local-map ,mode-line-minor-mode-keymap) + (when-let* ((menu (mode-line--make-lighter-menu hidden)) + (menu-binding (list 'menu-item "Display" menu + :filter #'bindings--sort-menu-keymap)) + (toggle-binding (list 'menu-item "Toggle" mode-line-mode-menu + :fitler #'bindings--sort-menu-keymap)) + (keymap (define-keymap + "<mode-line> <down-mouse-1>" menu-binding + "<mode-line> <mouse-2>" #'describe-mode + "<mode-line> <down-mouse-3>" toggle-binding))) + `(:propertize ,(if (char-displayable-p ?…) " …" " ...") + mouse-face mode-line-highlight + help-echo "Hidden minor modes\n\ +mouse-1: Display hidden minor modes\n\ +mouse-2: Show help for enabled minor modes\n\ +mouse-3: Toggle minor modes" + local-map ,keymap))))) + (defvar mode-line-major-mode-keymap (let ((map (make-sparse-keymap))) (define-key map [mode-line down-mouse-1] @@ -466,17 +580,11 @@ mode-line-modes mouse-face mode-line-highlight local-map ,mode-line-major-mode-keymap) '("" mode-line-process) - `(:propertize ("" minor-mode-alist) - mouse-face mode-line-highlight - help-echo "Minor mode\n\ -mouse-1: Display minor mode menu\n\ -mouse-2: Show help for minor mode\n\ -mouse-3: Toggle minor modes" - local-map ,mode-line-minor-mode-keymap) (propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer" 'mouse-face 'mode-line-highlight 'local-map (make-mode-line-mouse-map 'mouse-2 #'mode-line-widen)) + '("" mode-line-minor-modes) ")" (propertize "%]" 'help-echo recursive-edit-help-echo) " ")) -- 2.49.0
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.