[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 9d5fc2c7eb: * lisp/minibuffer.el (set-message-functions): New use
From: |
Juri Linkov |
Subject: |
master 9d5fc2c7eb: * lisp/minibuffer.el (set-message-functions): New user option. |
Date: |
Sun, 13 Nov 2022 13:58:33 -0500 (EST) |
branch: master
commit 9d5fc2c7eb3cfc2ae36cdc750a4605b4b08771b8
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>
* 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.
---
etc/NEWS | 9 ++++++
lisp/minibuffer.el | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/etc/NEWS b/etc/NEWS
index 0b8f4539f9..7cd192b9d3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 4898dfdb98..6bb0fa3ae9 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 9d5fc2c7eb: * lisp/minibuffer.el (set-message-functions): New user option.,
Juri Linkov <=