From fd37d4a10f0513053d2c3b76e918e736f0e14890 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 1 Sep 2023 00:49:42 +0000 Subject: [PATCH] Properly describe minor mode lighters while mode-line-compact * lisp/help.el (describe-minor-mode-from-indicator): New arg EVENT. If set to a mouse event and mode-line-compact, search for a suitable lighter within the entire posn object. * lisp/bindings.el (mode-line-minor-mode-help): Supply EVENT. (bug#65664) --- lisp/bindings.el | 2 +- lisp/help.el | 51 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lisp/bindings.el b/lisp/bindings.el index 68aa0a78099..207adb3a2a4 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -794,7 +794,7 @@ meaningful if it refers to a lexically bound variable." "Describe minor mode for EVENT on minor modes area of the mode line." (interactive "@e") (let ((indicator (car (nth 4 (car (cdr event)))))) - (describe-minor-mode-from-indicator indicator))) + (describe-minor-mode-from-indicator indicator event))) (defvar mode-line-defining-kbd-macro (propertize " Def" 'face 'font-lock-warning-face) "String displayed in the mode line in keyboard macro recording mode.") diff --git a/lisp/help.el b/lisp/help.el index f522cfac2a1..52c987f383d 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1230,15 +1230,60 @@ appeared on the mode-line." i)))) minor-mode-alist))) -(defun describe-minor-mode-from-indicator (indicator) +(defun describe-minor-mode-from-indicator (indicator &optional event) "Display documentation of a minor mode specified by INDICATOR. If you call this function interactively, you can give indicator which -is currently activated with completion." +is currently activated with completion. + +If non-nil, EVENT is a mouse event used to establish which minor +mode lighter was clicked." (interactive (list (completing-read "Minor mode indicator: " (describe-minor-mode-completion-table-for-indicator)))) - (let ((minor-mode (lookup-minor-mode-from-indicator indicator))) + (when (and event mode-line-compact) + (let* ((event-start (event-start event)) + (window (posn-window event-start))) + ;; If INDICATOR is a string object, WINDOW is set, and + ;; `mode-line-compact' might be enabled, find a string in + ;; `minor-mode-alist' that is present within the INDICATOR and + ;; whose extents within INDICATOR contain the position of the + ;; object within the string. + (when (windowp window) + (setq indicator (posn-object event-start)) + (catch 'found + (with-selected-window window + (let ((alist minor-mode-alist) string position) + (when (consp indicator) + (with-temp-buffer + (insert (car indicator)) + (dolist (menu alist) + ;; If this is a valid minor mode menu entry, + (when (and (consp menu) + (setq string (format-mode-line (cadr menu) + nil window)) + (> (length string) 0)) + ;; Start searching for an appearance of (cdr + ;; menu). + (goto-char (point-min)) + (while (search-forward string nil 0) + ;; If the position of the string object is + ;; contained within, set indicator to the + ;; minor mode in question. + (setq position (1+ (cdr indicator))) + (and (>= position (match-beginning 0)) + (<= position (match-end 0)) + (setq indicator (car menu)) + (throw 'found nil))))))))))))) + ;; If INDICATOR is still a cons, use its car. + (when (consp indicator) + (setq indicator (car indicator))) + (let ((minor-mode (if (symbolp indicator) + ;; indicator being set to a symbol means that + ;; the loop above has already found a + ;; matching minor mode. + indicator + (lookup-minor-mode-from-indicator indicator)))) (if minor-mode (describe-minor-mode-from-symbol minor-mode) (error "Cannot find minor mode for `%s'" indicator)))) -- 2.39.5