summaryrefslogtreecommitdiff
path: root/lisp/minibuffer.el
diff options
context:
space:
mode:
authorJuri Linkov <juri@linkov.net>2022-11-13 20:57:50 +0200
committerJuri Linkov <juri@linkov.net>2022-11-13 20:57:50 +0200
commit9d5fc2c7eb3cfc2ae36cdc750a4605b4b08771b8 (patch)
tree24eceb982f1ceeea63e483fed3ee7f18c61e4bd4 /lisp/minibuffer.el
parenta5bf6fb526692e21b270145070a9e5f321f9eca7 (diff)
downloademacs-9d5fc2c7eb3cfc2ae36cdc750a4605b4b08771b8.tar.gz
* 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.
Diffstat (limited to 'lisp/minibuffer.el')
-rw-r--r--lisp/minibuffer.el83
1 files changed, 82 insertions, 1 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 4898dfdb983..6bb0fa3ae98 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.