* lisp/minibuffer.el (set-message-functions): New user option.

(set-message-function): Change the default from
'set-minibuffer-message' to 'set-message-functions'.
'set-minibuffer-message' is set as the default value
of the user option 'set-message-functions'.
(set-message-functions): New function.
(inhibit-message-regexps): New customizable variable (bug#52314).
(inhibit-message): New function.
(multi-message-timeout, multi-message-max): New defcustoms.
(multi-message-separator, multi-message-list): New variables.
(set-multi-message): New function.
This commit is contained in:
Juri Linkov 2022-11-13 20:57:50 +02:00
parent a5bf6fb526
commit 9d5fc2c7eb
2 changed files with 91 additions and 1 deletions

View file

@ -712,6 +712,15 @@ part of the buffer.
+++
** 'count-words' will now report sentence count when used interactively.
** New user option 'set-message-functions'.
It allows selecting more functions for 'set-message-function'
in addition to the default function that handles messages
in the active minibuffer. The most useful are 'inhibit-message'
that allows specifying a list of messages to inhibit via
'inhibit-message-regexps', and 'set-multi-message' that
accumulates recent messages and displays them stacked
in the echo area.
---
** New user option 'find-library-include-other-files'.
If set to nil, commands like 'find-library' will only include library

View file

@ -850,7 +850,88 @@ via `set-message-function'."
;; was handled specially by this function.
t))))
(setq set-message-function 'set-minibuffer-message)
(setq set-message-function 'set-message-functions)
(defcustom set-message-functions '(set-minibuffer-message)
"List of functions to handle display of echo-area messages.
Each function is called with one argument that is the text of a message.
If a function returns nil, a previous message string is given to the
next function in the list, and if the last function returns nil, the
last message string is displayed in the echo area.
If a function returns a string, the returned string is given to the
next function in the list, and if the last function returns a string,
it's displayed in the echo area.
If a function returns any other non-nil value, no more functions are
called from the list, and no message will be displayed in the echo area."
:type '(choice (const :tag "No special message handling" nil)
(repeat
(choice (function-item :tag "Inhibit some messages"
inhibit-message)
(function-item :tag "Accumulate messages"
set-multi-message)
(function-item :tag "Handle minibuffer"
set-minibuffer-message)
(function :tag "Custom function"))))
:version "29.1")
(defun set-message-functions (message)
(run-hook-wrapped 'set-message-functions
(lambda (fun)
(when (stringp message)
(let ((ret (funcall fun message)))
(when ret (setq message ret))))
nil))
message)
(defcustom inhibit-message-regexps nil
"List of regexps that inhibit messages by the function `inhibit-message'."
:type '(repeat regexp)
:version "29.1")
(defun inhibit-message (message)
"Don't display MESSAGE when it matches the regexp `inhibit-message-regexps'.
This function is intended to be added to `set-message-functions'."
(or (and (consp inhibit-message-regexps)
(string-match-p (mapconcat #'identity inhibit-message-regexps "\\|")
message))
message))
(defcustom multi-message-timeout 2
"Number of seconds between messages before clearing the accumulated list."
:type 'number
:version "29.1")
(defcustom multi-message-max 8
"Max size of the list of accumulated messages."
:type 'number
:version "29.1")
(defvar multi-message-separator "\n")
(defvar multi-message-list nil)
(defun set-multi-message (message)
"Return recent messages as one string to display in the echo area.
Note that this feature works best only when `resize-mini-windows'
is at its default value `grow-only'."
(let ((last-message (car multi-message-list)))
(unless (and last-message (equal message (aref last-message 1)))
(when last-message
(cond
((> (float-time) (+ (aref last-message 0) multi-message-timeout))
(setq multi-message-list nil))
((or
;; `message-log-max' was nil, potential clutter.
(aref last-message 2)
;; Remove old message that is substring of the new message
(string-prefix-p (aref last-message 1) message))
(setq multi-message-list (cdr multi-message-list)))))
(push (vector (float-time) message (not message-log-max)) multi-message-list)
(when (> (length multi-message-list) multi-message-max)
(setf (nthcdr multi-message-max multi-message-list) nil)))
(mapconcat (lambda (m) (aref m 1))
(reverse multi-message-list)
multi-message-separator)))
(defun clear-minibuffer-message ()
"Clear minibuffer message.