diff options
Diffstat (limited to 'lisp/minibuffer.el')
-rw-r--r-- | lisp/minibuffer.el | 83 |
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. |