* Intelligent stacking of messages in the echo area @ 2019-08-31 5:35 ndame 2019-08-31 9:46 ` Marcin Borkowski 2019-12-21 22:07 ` Juri Linkov 0 siblings, 2 replies; 26+ messages in thread From: ndame @ 2019-08-31 5:35 UTC (permalink / raw) To: emacs-devel@gnu.org [-- Attachment #1: Type: text/plain, Size: 1130 bytes --] If two or more packages use the echo area for informational messages then often they fight each other, overwriting each other's messages. For example, in lisp mode eldoc is automatically enabled in my emacs 26.2 If I also turn on a paren mode which shows in the message area the matching part of a paren outside of the screen then eldoc often overwrites this message with its own documentation message. Other systems solve this by stacking messages on top of each other: https://www.howtogeek.com/wp-content/uploads/2014/11/ximg_54669cfe004ae.jpg.pagespeed.gp+jp+jw+pj+js+rj+rp+rw+ri+cp+md.ic.iDwLFdLQh5.jpg Maybe the echo area could be smarter and stack messages on top of each other if they come from diferent sources and they are close to each other in time. So in case of the above example, if a message comes from eldoc and parens at the same time in quick succession then the echo area could show both of them in two lines. And if the same source is sending multiple messsages or there is enough delay between two messages from different sources (e.g. 1-2 seconds) then it would work as today using only a single line. [-- Attachment #2: Type: text/html, Size: 1266 bytes --] ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-08-31 5:35 Intelligent stacking of messages in the echo area ndame @ 2019-08-31 9:46 ` Marcin Borkowski 2019-12-21 22:07 ` Juri Linkov 1 sibling, 0 replies; 26+ messages in thread From: Marcin Borkowski @ 2019-08-31 9:46 UTC (permalink / raw) To: ndame; +Cc: emacs-devel@gnu.org Before Emacs learns to do what you want, how about a workaround? See http://mbork.pl/2017-05-01_show-some-last-messages (and the comment, which apperently I forgot to answer - sorry for that). Hth, mb On 2019-08-31, at 07:35, ndame <emacsuser@freemail.hu> wrote: > If two or more packages use the echo area for informational messages > then often they fight each other, overwriting each other's messages. > > For example, in lisp mode eldoc is automatically enabled in my emacs > 26.2 If I also turn on a paren mode which shows in the message area > the matching part of a paren outside of the screen then eldoc often > overwrites this message with its own documentation message. > > Other systems solve this by stacking messages on top of each other: > > https://www.howtogeek.com/wp-content/uploads/2014/11/ximg_54669cfe004ae.jpg.pagespeed.gp+jp+jw+pj+js+rj+rp+rw+ri+cp+md.ic.iDwLFdLQh5.jpg > > Maybe the echo area could be smarter and stack messages on top of each > other if they come from diferent sources and they are close to each > other in time. > > So in case of the above example, if a message comes from eldoc and > parens at the same time in quick succession then the echo area could > show both of them in two lines. > > And if the same source is sending multiple messsages or there is > enough delay between two messages from different sources (e.g. 1-2 > seconds) then it would work as today using only a single line. -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-08-31 5:35 Intelligent stacking of messages in the echo area ndame 2019-08-31 9:46 ` Marcin Borkowski @ 2019-12-21 22:07 ` Juri Linkov 2019-12-22 3:30 ` Eli Zaretskii ` (2 more replies) 1 sibling, 3 replies; 26+ messages in thread From: Juri Linkov @ 2019-12-21 22:07 UTC (permalink / raw) To: ndame; +Cc: emacs-devel@gnu.org [-- Attachment #1: Type: text/plain, Size: 1436 bytes --] > If two or more packages use the echo area for informational messages > then often they fight each other, overwriting each other's messages. > > For example, in lisp mode eldoc is automatically enabled in my emacs > 26.2 If I also turn on a paren mode which shows in the message area > the matching part of a paren outside of the screen then eldoc often > overwrites this message with its own documentation message. > > Maybe the echo area could be smarter and stack messages on top of each > other if they come from diferent sources and they are close to each > other in time. > > So in case of the above example, if a message comes from eldoc and > parens at the same time in quick succession then the echo area could > show both of them in two lines. > > And if the same source is sending multiple messsages or there is > enough delay between two messages from different sources (e.g. 1-2 > seconds) then it would work as today using only a single line. Please try to eval the following code in the current master. It allows messages produced in quick succession to be stacked in the echo area. So for example when both show-paren-mode and eldoc want to show their messages at the same time, the echo area shows both of them in two lines, e.g.: No matching parenthesis found defun: (NAME ARGLIST &optional DOCSTRING DECL &rest BODY) Caveat: it works best only when resize-mini-windows is at its default value 'grow-only'. [-- Attachment #2: messages-stack.el --] [-- Type: application/emacs-lisp, Size: 1069 bytes --] ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-21 22:07 ` Juri Linkov @ 2019-12-22 3:30 ` Eli Zaretskii 2019-12-23 2:59 ` Richard Stallman 2019-12-23 3:50 ` Ihor Radchenko 2 siblings, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2019-12-22 3:30 UTC (permalink / raw) To: Juri Linkov; +Cc: emacsuser, emacs-devel > From: Juri Linkov <juri@linkov.net> > Date: Sun, 22 Dec 2019 00:07:52 +0200 > Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org> > > Caveat: it works best only when resize-mini-windows is at its default value > 'grow-only'. So perhaps the doc string should mention this caveat. I believe most people don't change the default, so it isn't a significant disadvantage that other values interfere with this feature. Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-21 22:07 ` Juri Linkov 2019-12-22 3:30 ` Eli Zaretskii @ 2019-12-23 2:59 ` Richard Stallman 2019-12-23 22:46 ` Juri Linkov 2019-12-23 3:50 ` Ihor Radchenko 2 siblings, 1 reply; 26+ messages in thread From: Richard Stallman @ 2019-12-23 2:59 UTC (permalink / raw) To: Juri Linkov; +Cc: emacsuser, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > (defcustom messages-stack-timeout 2 > "Number of seconds between messages before clearing the stack." "Stack" implies LIFO behavior. Is that what this does? If not, let's replace "stack" with some other word. -- Dr Richard Stallman Founder, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 2:59 ` Richard Stallman @ 2019-12-23 22:46 ` Juri Linkov 0 siblings, 0 replies; 26+ messages in thread From: Juri Linkov @ 2019-12-23 22:46 UTC (permalink / raw) To: Richard Stallman; +Cc: emacsuser, emacs-devel > > (defcustom messages-stack-timeout 2 > > "Number of seconds between messages before clearing the stack." > > "Stack" implies LIFO behavior. Is that what this does? > If not, let's replace "stack" with some other word. It's used for "message stacking", but the data structure is not a stack. It's rather more like a queue, but then "message queue" is a completely different concept. Until someone proposes a better name, let's stick to the name "multi-message-timeout". ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-21 22:07 ` Juri Linkov 2019-12-22 3:30 ` Eli Zaretskii 2019-12-23 2:59 ` Richard Stallman @ 2019-12-23 3:50 ` Ihor Radchenko 2019-12-23 13:38 ` Eli Zaretskii 2019-12-23 22:47 ` Juri Linkov 2 siblings, 2 replies; 26+ messages in thread From: Ihor Radchenko @ 2019-12-23 3:50 UTC (permalink / raw) To: Juri Linkov, ndame; +Cc: emacs-devel@gnu.org Hi, FYI: A slightly improved version of the code, which prevents stacking potentially "spammy" messages (like from eldoc or org-display-outline-path). The messages are detected by looking at messages-log-max variable, which is typically set to nil by such functions. (defun set-stacked-message (message) (let ((last-message (car messages-stack))) (unless (and last-message (equal message (aref last-message 1))) (when (and last-message (aref last-message 2)) ;; the last message had `message-log-max' equal to nil. Potential clutter. (setq messages-stack (cdr messages-stack))) (when (and last-message (> (float-time) (+ (aref last-message 0) messages-stack-timeout))) (setq messages-stack nil)) (push (vector (float-time) message (not message-log-max)) messages-stack) ;; (push (vector (float-time) message) messages-stack) (when (> (length messages-stack) messages-stack-max) (setf (nthcdr messages-stack-max messages-stack) nil))) (mapconcat (lambda (m) (aref m 1)) (reverse messages-stack) messages-stack-separator))) Also, it would be great to avoid stacking the echo-keystrokes, but I have no clue how to detect them. Best, Ihor Juri Linkov <juri@linkov.net> writes: >> If two or more packages use the echo area for informational messages >> then often they fight each other, overwriting each other's messages. >> >> For example, in lisp mode eldoc is automatically enabled in my emacs >> 26.2 If I also turn on a paren mode which shows in the message area >> the matching part of a paren outside of the screen then eldoc often >> overwrites this message with its own documentation message. >> >> Maybe the echo area could be smarter and stack messages on top of each >> other if they come from diferent sources and they are close to each >> other in time. >> >> So in case of the above example, if a message comes from eldoc and >> parens at the same time in quick succession then the echo area could >> show both of them in two lines. >> >> And if the same source is sending multiple messsages or there is >> enough delay between two messages from different sources (e.g. 1-2 >> seconds) then it would work as today using only a single line. > > Please try to eval the following code in the current master. > > It allows messages produced in quick succession to be stacked > in the echo area. > > So for example when both show-paren-mode and eldoc want to show their > messages at the same time, the echo area shows both of them in two lines, > e.g.: > > No matching parenthesis found > defun: (NAME ARGLIST &optional DOCSTRING DECL &rest BODY) > > Caveat: it works best only when resize-mini-windows is at its default value > 'grow-only'. > > > (defcustom messages-stack-timeout 2 > "Number of seconds between messages before clearing the stack." > :type 'number > :group 'minibuffer > :version "27.1") > > (defcustom messages-stack-max 8 > "Max size of the message stack." > :type 'number > :group 'minibuffer > :version "27.1") > > (defvar messages-stack-separator "\n") > > (defvar messages-stack nil) > > (defun set-stacked-message (message) > (let ((last-message (car messages-stack))) > (unless (and last-message (equal message (aref last-message 1))) > (when (and last-message (> (float-time) (+ (aref last-message 0) > messages-stack-timeout))) > (setq messages-stack nil)) > (push (vector (float-time) message) messages-stack) > (when (> (length messages-stack) messages-stack-max) > (setf (nthcdr messages-stack-max messages-stack) nil))) > (mapconcat (lambda (m) (aref m 1)) > (reverse messages-stack) > messages-stack-separator))) > > (setq set-message-function 'set-stacked-message) -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 3:50 ` Ihor Radchenko @ 2019-12-23 13:38 ` Eli Zaretskii 2019-12-24 9:24 ` Ihor Radchenko 2019-12-23 22:47 ` Juri Linkov 1 sibling, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2019-12-23 13:38 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacsuser, emacs-devel, juri > From: Ihor Radchenko <yantar92@gmail.com> > Date: Mon, 23 Dec 2019 11:50:48 +0800 > Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org> > > A slightly improved version of the code, which prevents stacking > potentially "spammy" messages (like from eldoc or > org-display-outline-path). The messages are detected by looking at > messages-log-max variable, which is typically set to nil by such > functions. I'd rather think a better way would be to have a variable which allows to filter messages by regular expressions: any message that matches a regexp in a list will not be stacked. > Also, it would be great to avoid stacking the echo-keystrokes, but I > have no clue how to detect them. See above. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 13:38 ` Eli Zaretskii @ 2019-12-24 9:24 ` Ihor Radchenko 2019-12-24 15:36 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2019-12-24 9:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacsuser, emacs-devel, juri > I'd rather think a better way would be to have a variable which allows > to filter messages by regular expressions: any message that matches a > regexp in a list will not be stacked. It is a good idea. However, generating a universal regexp for, say, eldoc may be challenging. >> Also, it would be great to avoid stacking the echo-keystrokes, but I >> have no clue how to detect them. > > See above. I cannot find what you refer to. Best, Ihor Eli Zaretskii <eliz@gnu.org> writes: >> From: Ihor Radchenko <yantar92@gmail.com> >> Date: Mon, 23 Dec 2019 11:50:48 +0800 >> Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org> >> >> A slightly improved version of the code, which prevents stacking >> potentially "spammy" messages (like from eldoc or >> org-display-outline-path). The messages are detected by looking at >> messages-log-max variable, which is typically set to nil by such >> functions. > > I'd rather think a better way would be to have a variable which allows > to filter messages by regular expressions: any message that matches a > regexp in a list will not be stacked. > >> Also, it would be great to avoid stacking the echo-keystrokes, but I >> have no clue how to detect them. > > See above. -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-24 9:24 ` Ihor Radchenko @ 2019-12-24 15:36 ` Eli Zaretskii 2019-12-25 4:21 ` Ihor Radchenko 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2019-12-24 15:36 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacsuser, emacs-devel, juri > From: Ihor Radchenko <yantar92@gmail.com> > Cc: juri@linkov.net, emacsuser@freemail.hu, emacs-devel@gnu.org > Date: Tue, 24 Dec 2019 17:24:29 +0800 > > > I'd rather think a better way would be to have a variable which allows > > to filter messages by regular expressions: any message that matches a > > regexp in a list will not be stacked. > > It is a good idea. However, generating a universal regexp for, say, eldoc > may be challenging. Then maybe we should allow a function as well. > >> Also, it would be great to avoid stacking the echo-keystrokes, but I > >> have no clue how to detect them. > > > > See above. > > I cannot find what you refer to. The idea about filtering driven by regular expressions. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-24 15:36 ` Eli Zaretskii @ 2019-12-25 4:21 ` Ihor Radchenko 0 siblings, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2019-12-25 4:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacsuser, emacs-devel, juri [-- Attachment #1: Type: text/plain, Size: 366 bytes --] > Then maybe we should allow a function as well. Good idea. Instead of piling up heuristics into set-multi-message, it may be better to run an abnormal hook. See the attached. > The idea about filtering driven by regular expressions. Do you know a good regexp to match a keystroke sequence? It seems easier for me to compare with this-command-keys. Best, Ihor [-- Attachment #2: multi-message.el --] [-- Type: application/emacs-lisp, Size: 2290 bytes --] [-- Attachment #3: Type: text/plain, Size: 785 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: Ihor Radchenko <yantar92@gmail.com> >> Cc: juri@linkov.net, emacsuser@freemail.hu, emacs-devel@gnu.org >> Date: Tue, 24 Dec 2019 17:24:29 +0800 >> >> > I'd rather think a better way would be to have a variable which allows >> > to filter messages by regular expressions: any message that matches a >> > regexp in a list will not be stacked. >> >> It is a good idea. However, generating a universal regexp for, say, eldoc >> may be challenging. > > Then maybe we should allow a function as well. > >> >> Also, it would be great to avoid stacking the echo-keystrokes, but I >> >> have no clue how to detect them. >> > >> > See above. >> >> I cannot find what you refer to. > > The idea about filtering driven by regular expressions. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 3:50 ` Ihor Radchenko 2019-12-23 13:38 ` Eli Zaretskii @ 2019-12-23 22:47 ` Juri Linkov 2019-12-24 9:40 ` Ihor Radchenko 2020-01-24 10:14 ` Eric S Fraga 1 sibling, 2 replies; 26+ messages in thread From: Juri Linkov @ 2019-12-23 22:47 UTC (permalink / raw) To: Ihor Radchenko; +Cc: ndame, emacs-devel@gnu.org [-- Attachment #1: Type: text/plain, Size: 437 bytes --] > A slightly improved version of the code, which prevents stacking > potentially "spammy" messages (like from eldoc or > org-display-outline-path). The messages are detected by looking at > messages-log-max variable, which is typically set to nil by such > functions. Good heuristics. Another heuristics that could be added is to filter out transient messages ending with ellipsis - added here to a new variable like Eli asked to do: [-- Attachment #2: multi-message.el --] [-- Type: application/emacs-lisp, Size: 1718 bytes --] ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 22:47 ` Juri Linkov @ 2019-12-24 9:40 ` Ihor Radchenko 2019-12-24 15:43 ` Eli Zaretskii 2019-12-25 0:15 ` Juri Linkov 2020-01-24 10:14 ` Eric S Fraga 1 sibling, 2 replies; 26+ messages in thread From: Ihor Radchenko @ 2019-12-24 9:40 UTC (permalink / raw) To: Juri Linkov; +Cc: ndame, emacs-devel@gnu.org I was testing the code for a while. There seem to be one irritating (for me) problem with the way set-message-function is implemented. When I run a command changing current buffer and emitting multiple messages, emacs frame is redrawn every time a new message comes out. Specifically, I was running org-capture, which changes windows configuration, switches to different buffer, and emits multiple messages while running. Normally, it runs very fast (the capture template I used does not require any user input), but with multi-message, I can see the frame being redrawn on every new message popping up. Since window configuration is different, full redraw is forced and the whole org-capture runs a lot slower. Best, Ihor Juri Linkov <juri@linkov.net> writes: >> A slightly improved version of the code, which prevents stacking >> potentially "spammy" messages (like from eldoc or >> org-display-outline-path). The messages are detected by looking at >> messages-log-max variable, which is typically set to nil by such >> functions. > > Good heuristics. Another heuristics that could be added is > to filter out transient messages ending with ellipsis - > added here to a new variable like Eli asked to do: > > > (defcustom multi-message-timeout 2 > "Number of seconds between messages before clearing the accumulated list." > :type 'number > :group 'minibuffer > :version "28.1") > > (defcustom multi-message-max 8 > "Max size of the list of accumulated messages." > :type 'number > :group 'minibuffer > :version "28.1") > > (defcustom multi-message-transient "\\.\\.\\.\\'" > "Regexp to filter out transient messages that should not be stacked." > :type 'regexp > :group 'minibuffer > :version "28.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) > (string-match-p multi-message-transient (aref last-message 1))) > (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))) > > (setq set-message-function 'set-multi-message) -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-24 9:40 ` Ihor Radchenko @ 2019-12-24 15:43 ` Eli Zaretskii 2019-12-24 17:32 ` Ihor Radchenko 2019-12-25 0:15 ` Juri Linkov 1 sibling, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2019-12-24 15:43 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacsuser, emacs-devel, juri > From: Ihor Radchenko <yantar92@gmail.com> > Date: Tue, 24 Dec 2019 17:40:18 +0800 > Cc: ndame <emacsuser@freemail.hu>, "emacs-devel@gnu.org" <emacs-devel@gnu.org> > > When I run a command changing current buffer and emitting multiple > messages, emacs frame is redrawn every time a new message comes out. > Specifically, I was running org-capture, which changes windows > configuration, switches to different buffer, and emits multiple messages > while running. Normally, it runs very fast (the capture template I used > does not require any user input), but with multi-message, I can see the > frame being redrawn on every new message popping up. Since window > configuration is different, full redraw is forced and the whole > org-capture runs a lot slower. Are you sure this is not due to the code that you wrote (and didn't show)? IOW, if you change the window configuration, and then display something, shouldn't you expect a thorough redisplay? ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-24 15:43 ` Eli Zaretskii @ 2019-12-24 17:32 ` Ihor Radchenko 0 siblings, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2019-12-24 17:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacsuser, emacs-devel, juri > Are you sure this is not due to the code that you wrote (and didn't > show)? IOW, if you change the window configuration, and then display > something, shouldn't you expect a thorough redisplay? Let me show some benchmarks with emacs -Q: <the code from multi-message.el> ;C-x C-e (setq nomulti nil) ; C-x C-e (setq multi nil) ; C-x C-e (let ((start (float-time))) (setq set-message-function 'set-multi-message) (dotimes (i 8) (message "foo %s" i) (split-window-below) (split-window-below) (message "foo2") (delete-other-windows)) (setq multi-message-list nil) (push (- (float-time) start) multi) (car multi)) ; C-x C-e several times. ;; I can clearly see flickering (redrawing) of ;; emacs frame every time the mini-buffer is resized (let ((start (float-time))) (setq set-message-function nil) (dotimes (i 8) (message "foo %s" i) (split-window-below) (split-window-below) (message "foo2") (delete-other-windows)) (setq multi-message-list nil) (push (- (float-time) start) nomulti) (car nomulti)) ; C-x C-e several times ;; No redrawing is happening (message "Without multi-message: %s sec\nWith multi-message: %s sec" (/ (seq-reduce #'+ nomulti 0) (seq-length nomulti)) (/ (seq-reduce #'+ multi 0) (seq-length nomulti))) Without multi-message: 0.009443044662475586 sec With multi-message: 0.03390545646349589 sec The difference is more that 3 times. With an actual heavy-duty emacs config the difference is a lot more noticeable. Best regards, Ihor Eli Zaretskii <eliz@gnu.org> writes: >> From: Ihor Radchenko <yantar92@gmail.com> >> Date: Tue, 24 Dec 2019 17:40:18 +0800 >> Cc: ndame <emacsuser@freemail.hu>, "emacs-devel@gnu.org" <emacs-devel@gnu.org> >> >> When I run a command changing current buffer and emitting multiple >> messages, emacs frame is redrawn every time a new message comes out. >> Specifically, I was running org-capture, which changes windows >> configuration, switches to different buffer, and emits multiple messages >> while running. Normally, it runs very fast (the capture template I used >> does not require any user input), but with multi-message, I can see the >> frame being redrawn on every new message popping up. Since window >> configuration is different, full redraw is forced and the whole >> org-capture runs a lot slower. > > Are you sure this is not due to the code that you wrote (and didn't > show)? IOW, if you change the window configuration, and then display > something, shouldn't you expect a thorough redisplay? -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-24 9:40 ` Ihor Radchenko 2019-12-24 15:43 ` Eli Zaretskii @ 2019-12-25 0:15 ` Juri Linkov 2019-12-25 5:35 ` Ihor Radchenko 1 sibling, 1 reply; 26+ messages in thread From: Juri Linkov @ 2019-12-25 0:15 UTC (permalink / raw) To: Ihor Radchenko; +Cc: ndame, emacs-devel@gnu.org > I was testing the code for a while. > There seem to be one irritating (for me) problem with the way > set-message-function is implemented. > When I run a command changing current buffer and emitting multiple > messages, emacs frame is redrawn every time a new message comes out. > Specifically, I was running org-capture, which changes windows > configuration, switches to different buffer, and emits multiple messages > while running. Normally, it runs very fast (the capture template I used > does not require any user input), but with multi-message, I can see the > frame being redrawn on every new message popping up. Since window > configuration is different, full redraw is forced and the whole > org-capture runs a lot slower. Maybe this is because multi-line messages resize the echo-area window every time a new message line is added (when resize-mini-windows is non-nil), so height changes of the echo-area window invoke window-configuration-change-hook. It seems the same problem existed for a long time, but had no noticeable effect because multi-line messages were rare. Now for the multi-message feature where multi-line messages are not an exception but a rule, one way to mitigate it is to use a message separator other than a newline, e.g. (setq multi-message-separator (propertize ";" 'face 'minibuffer-prompt)) In a wide frame, one echo-area line can accommodate several short messages without resizing the echo-area window. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-25 0:15 ` Juri Linkov @ 2019-12-25 5:35 ` Ihor Radchenko 2020-01-29 22:54 ` Juri Linkov 0 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2019-12-25 5:35 UTC (permalink / raw) To: Juri Linkov; +Cc: ndame, emacs-devel@gnu.org > Maybe this is because multi-line messages resize the echo-area window > every time a new message line is added (when resize-mini-windows is non-nil), > so height changes of the echo-area window invoke window-configuration-change-hook. I suspect that it is exactly the case. However, window-configuration-change-hook is not fired so frequently in other functions like split-window. Most likely, it is because window-configuration-change-hook is only called during redisplay. From its docstring: "Functions called during redisplay when window configuration has changed." I guess that resizing echo-area forcefully calls redisplay and hence window-configuration-change-hook, thus slowing down command execution. Best, Ihor > Now for the multi-message feature where multi-line messages are > not an exception but a rule, one way to mitigate it is to use > a message separator other than a newline, e.g. > > (setq multi-message-separator (propertize ";" 'face 'minibuffer-prompt)) > > In a wide frame, one echo-area line can accommodate several short messages > without resizing the echo-area window. This is a workaround, not a solution. Also, I am using a laptop with small screen and this workaround does not really work for me (at least for org-capture, which emits fairly long messages). Juri Linkov <juri@linkov.net> writes: >> I was testing the code for a while. >> There seem to be one irritating (for me) problem with the way >> set-message-function is implemented. >> When I run a command changing current buffer and emitting multiple >> messages, emacs frame is redrawn every time a new message comes out. >> Specifically, I was running org-capture, which changes windows >> configuration, switches to different buffer, and emits multiple messages >> while running. Normally, it runs very fast (the capture template I used >> does not require any user input), but with multi-message, I can see the >> frame being redrawn on every new message popping up. Since window >> configuration is different, full redraw is forced and the whole >> org-capture runs a lot slower. > > Maybe this is because multi-line messages resize the echo-area window > every time a new message line is added (when resize-mini-windows is non-nil), > so height changes of the echo-area window invoke window-configuration-change-hook. > > It seems the same problem existed for a long time, but had no noticeable effect > because multi-line messages were rare. > > Now for the multi-message feature where multi-line messages are > not an exception but a rule, one way to mitigate it is to use > a message separator other than a newline, e.g. > > (setq multi-message-separator (propertize ";" 'face 'minibuffer-prompt)) > > In a wide frame, one echo-area line can accommodate several short messages > without resizing the echo-area window. -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-25 5:35 ` Ihor Radchenko @ 2020-01-29 22:54 ` Juri Linkov 0 siblings, 0 replies; 26+ messages in thread From: Juri Linkov @ 2020-01-29 22:54 UTC (permalink / raw) To: Ihor Radchenko; +Cc: ndame, emacs-devel@gnu.org >> Maybe this is because multi-line messages resize the echo-area window >> every time a new message line is added (when resize-mini-windows is non-nil), >> so height changes of the echo-area window invoke window-configuration-change-hook. > > I suspect that it is exactly the case. > However, window-configuration-change-hook is not fired so frequently in > other functions like split-window. > Most likely, it is because window-configuration-change-hook is only > called during redisplay. From its docstring: > "Functions called during redisplay when window configuration has > changed." > > I guess that resizing echo-area forcefully calls redisplay and hence > window-configuration-change-hook, thus slowing down command execution. To avoid continual resizing of echo-area when new messages arrive, maybe 'resize-mini-windows' should allow setting it to a fixed number of lines, so e.g. (setq resize-mini-windows 10) would mean that the height of the echo-area will be kept always at 10 lines, even when it displays less lines. If this is impossible to do then a possible workaround is to emulate this in set-multi-message by inserting empty lines to fill the height to a fixed amount of lines. This is a possible change over the previous patch: @@ -452,7 +474,11 @@ set-multi-message (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) + (mapconcat (lambda (m) (if (stringp m) m (aref m 1))) + (append (reverse multi-message-list) + ;; Fill remaining space by empty lines to keep fixed height + ;; of the echo-area to avoid continual resizing of echo-area + ;; when new messages arrive. + (make-list (- multi-message-max (length multi-message-list)) "")) multi-message-separator))) Then another problem is that clear-message doesn't keep fixed height of echo-area. Maybe an additional workaround would be to issue an empty message that will be filled by empty lines in set-multi-message for clear-message as well: (defun clear-multi-message--wrapper (orig-fun) (funcall orig-fun) (setq multi-message-list nil) (message "\n")) (setq clear-message-function 'clear-minibuffer-message) (add-function :around clear-message-function #'clear-multi-message--wrapper) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2019-12-23 22:47 ` Juri Linkov 2019-12-24 9:40 ` Ihor Radchenko @ 2020-01-24 10:14 ` Eric S Fraga 2020-01-28 22:34 ` Juri Linkov 1 sibling, 1 reply; 26+ messages in thread From: Eric S Fraga @ 2020-01-24 10:14 UTC (permalink / raw) To: emacs-devel On Tuesday, 24 Dec 2019 at 00:47, Juri Linkov wrote: > Good heuristics. Another heuristics that could be added is > to filter out transient messages ending with ellipsis - > added here to a new variable like Eli asked to do: Just to say thank you. I've been using this bit of code for the past two or three weeks and it works very well. I added to your regex for my particular situation: #+begin_src elisp (defcustom multi-message-transient "\\(\\.\\.\\.\\'\\|^,\\|^C-\\|^pop3 retrieved\\)" "Regexp to filter out transient messages that should not be stacked." :type 'regexp :group 'minibuffer :version "28.1") #+end_src The "," is because I use evil mode and comma is my leader character. -- Eric S Fraga via Emacs 28.0.50 & org 9.3.1 on Debian 9.9 -- : Professor Eric S Fraga; use plain text: http://useplaintext.email : https://www.ucl.ac.uk/chemical-engineering/people/prof-eric-fraga : PGP/GnuPG key: 8F5C 279D 3907 E14A 5C29 570D C891 93D8 FFFC F67D ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2020-01-24 10:14 ` Eric S Fraga @ 2020-01-28 22:34 ` Juri Linkov 2020-01-29 22:41 ` Juri Linkov 0 siblings, 1 reply; 26+ messages in thread From: Juri Linkov @ 2020-01-28 22:34 UTC (permalink / raw) To: Eric S Fraga; +Cc: emacs-devel >> Good heuristics. Another heuristics that could be added is >> to filter out transient messages ending with ellipsis - >> added here to a new variable like Eli asked to do: > > Just to say thank you. I've been using this bit of code for the past > two or three weeks and it works very well. > > I added to your regex for my particular situation: > > #+begin_src elisp > (defcustom multi-message-transient "\\(\\.\\.\\.\\'\\|^,\\|^C-\\|^pop3 retrieved\\)" > "Regexp to filter out transient messages that should not be stacked." > :type 'regexp > :group 'minibuffer > :version "28.1") > #+end_src Thanks. This means that this option multi-message-transient is useful after all. BTW, I customized it to "^Mark\\|\\.\\.\\.\\'" to skip mark-related messages like "Mark set" and "Mark deactivated". Now what remains to do is to combine multi-message feature with minibuffer-message, so when the minibuffer is not active then multi-line messages are displayed in the echo-area, otherwise multi-line messages are displayed at the end of the minibuffer: (defun set-multi-message--wrapper (orig-fun message) (let* ((multi-message (set-multi-message message))) (or (funcall orig-fun multi-message) multi-message))) (setq set-message-function 'set-minibuffer-message) (add-function :around set-message-function #'set-multi-message--wrapper) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2020-01-28 22:34 ` Juri Linkov @ 2020-01-29 22:41 ` Juri Linkov 2020-01-29 23:53 ` Stefan Monnier 0 siblings, 1 reply; 26+ messages in thread From: Juri Linkov @ 2020-01-29 22:41 UTC (permalink / raw) To: Eric S Fraga; +Cc: emacs-devel > Now what remains to do is to combine multi-message feature with minibuffer-message, > so when the minibuffer is not active then multi-line messages are displayed > in the echo-area, otherwise multi-line messages are displayed at the end > of the minibuffer: > > (defun set-multi-message--wrapper (orig-fun message) > (let* ((multi-message (set-multi-message message))) > (or (funcall orig-fun multi-message) > multi-message))) > > (setq set-message-function 'set-minibuffer-message) > (add-function :around set-message-function #'set-multi-message--wrapper) Turning this into defcustom is a challenge. I tried to introduce a fictitious 'set-minibuffer-multi-message', but I see no way to use 'add-function' on a symbol in :set of defcustom. It seems something like (local 'SYMBOL) but for global scope is missing, e.g. like an non-existent '(global sym)' demonstrated below, but I'm not sure. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index e3dc6f03c4..18067bfd07 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -646,6 +646,19 @@ minibuffer-prompt-properties--setter :format "%v") (other :tag "Unlimited" t)) "24.3") + (set-message-function + minibuffer (choice + (const :tag "Handle minibuffer" set-minibuffer-message) + (const :tag "Accumulate messages" set-multi-message) + (const :tag "Accumulate messages and handle minibuffer" set-minibuffer-multi-message) + (function :tag "Other function")) + "28.1" + :set (lambda (sym val) + (cond + ((eq val 'set-minibuffer-multi-message) + (set-default sym 'set-minibuffer-message) + (add-function :around (global sym) #'set-multi-message--wrapper)) + (t (set-default sym val))))) (unibyte-display-via-language-environment mule boolean) (blink-cursor-alist cursor alist "22.1") (overline-margin display integer "22.1") ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2020-01-29 22:41 ` Juri Linkov @ 2020-01-29 23:53 ` Stefan Monnier 2020-01-30 22:35 ` Juri Linkov 0 siblings, 1 reply; 26+ messages in thread From: Stefan Monnier @ 2020-01-29 23:53 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel, Eric S Fraga > Turning this into defcustom is a challenge. I tried to introduce > a fictitious 'set-minibuffer-multi-message', but I see no way to use > 'add-function' on a symbol in :set of defcustom. It seems something > like (local 'SYMBOL) but for global scope is missing, e.g. like > an non-existent '(global sym)' demonstrated below, but I'm not sure. `(default-value sym)` should do the trick. Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2020-01-29 23:53 ` Stefan Monnier @ 2020-01-30 22:35 ` Juri Linkov 2020-01-30 23:07 ` Stefan Monnier 0 siblings, 1 reply; 26+ messages in thread From: Juri Linkov @ 2020-01-30 22:35 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel, Eric S Fraga >> Turning this into defcustom is a challenge. I tried to introduce >> a fictitious 'set-minibuffer-multi-message', but I see no way to use >> 'add-function' on a symbol in :set of defcustom. It seems something >> like (local 'SYMBOL) but for global scope is missing, e.g. like >> an non-existent '(global sym)' demonstrated below, but I'm not sure. > > `(default-value sym)` should do the trick. Maybe I'm doing something wrong, but with the following patch it fails: Debugger entered--Lisp error: (void-variable v) (default-value v) (lambda nil (default-value v))() advice--add-function(:around ((lambda nil (default-value v)) lambda (gv--val) (set-default v gv--val)) set-multi-message--wrapper nil) (add-function :around (default-value sym) #'set-multi-message--wrapper) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index e3dc6f03c4..ecfb2a63c1 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -646,6 +646,20 @@ minibuffer-prompt-properties--setter :format "%v") (other :tag "Unlimited" t)) "24.3") + (set-message-function + minibuffer (choice + (const :tag "No special handling" nil) + (const :tag "Handle minibuffer" set-minibuffer-message) + (const :tag "Accumulate messages" set-multi-message) + (const :tag "Accumulate messages and handle minibuffer" set-minibuffer-multi-message) + (function :tag "Other function")) + "28.1" + :set (lambda (sym val) + (cond + ((eq val 'set-minibuffer-multi-message) + (set-default sym 'set-minibuffer-message) + (add-function :around (default-value sym) #'set-multi-message--wrapper)) + (t (set-default sym val))))) (unibyte-display-via-language-environment mule boolean) (blink-cursor-alist cursor alist "22.1") (overline-margin display integer "22.1") ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2020-01-30 22:35 ` Juri Linkov @ 2020-01-30 23:07 ` Stefan Monnier 0 siblings, 0 replies; 26+ messages in thread From: Stefan Monnier @ 2020-01-30 23:07 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel, Eric S Fraga > Debugger entered--Lisp error: (void-variable v) > (default-value v) > (lambda nil (default-value v))() > advice--add-function(:around ((lambda nil (default-value v)) lambda (gv--val) (set-default v gv--val)) set-multi-message--wrapper nil) > (add-function :around (default-value sym) #'set-multi-message--wrapper) My crystal ball says you need to activate lexical-binding for this anonymous function as well. IOW, you need to turn the outer ' into a ` and then use ,(lambda ...) Or move this function to a top-level definition and then refer to it by name. Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area
@ 2022-04-09 4:46 emacsq
2022-04-09 18:53 ` Juri Linkov
0 siblings, 1 reply; 26+ messages in thread
From: emacsq @ 2022-04-09 4:46 UTC (permalink / raw)
To: emacs-devel@gnu.org
Have this fetaure gone nowhere? Showing multiple messages at
once in the echo area if one comes quickly after the other from
a different package, so they don't just hide/overwrite each other.
I remembered a discussion about it from 2019 and checked, but
apparently emacs 28 does not have this.
> (defcustom multi-message-timeout 2
> "Number of seconds between messages before clearing the accumulated list."
> :type 'number
> :group 'minibuffer
> :version "28.1")
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Intelligent stacking of messages in the echo area 2022-04-09 4:46 emacsq @ 2022-04-09 18:53 ` Juri Linkov 0 siblings, 0 replies; 26+ messages in thread From: Juri Linkov @ 2022-04-09 18:53 UTC (permalink / raw) To: emacsq; +Cc: emacs-devel@gnu.org >> (defcustom multi-message-timeout 2 >> "Number of seconds between messages before clearing the accumulated list." >> :type 'number >> :group 'minibuffer >> :version "28.1") > Have this fetaure gone nowhere? Showing multiple messages at > once in the echo area if one comes quickly after the other from > a different package, so they don't just hide/overwrite each other. > > I remembered a discussion about it from 2019 and checked, but > apparently emacs 28 does not have this. We still have unsolved bug#40774. Maybe it could be fixed now. Or maybe better to create a new report. ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2022-04-09 18:53 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-08-31 5:35 Intelligent stacking of messages in the echo area ndame 2019-08-31 9:46 ` Marcin Borkowski 2019-12-21 22:07 ` Juri Linkov 2019-12-22 3:30 ` Eli Zaretskii 2019-12-23 2:59 ` Richard Stallman 2019-12-23 22:46 ` Juri Linkov 2019-12-23 3:50 ` Ihor Radchenko 2019-12-23 13:38 ` Eli Zaretskii 2019-12-24 9:24 ` Ihor Radchenko 2019-12-24 15:36 ` Eli Zaretskii 2019-12-25 4:21 ` Ihor Radchenko 2019-12-23 22:47 ` Juri Linkov 2019-12-24 9:40 ` Ihor Radchenko 2019-12-24 15:43 ` Eli Zaretskii 2019-12-24 17:32 ` Ihor Radchenko 2019-12-25 0:15 ` Juri Linkov 2019-12-25 5:35 ` Ihor Radchenko 2020-01-29 22:54 ` Juri Linkov 2020-01-24 10:14 ` Eric S Fraga 2020-01-28 22:34 ` Juri Linkov 2020-01-29 22:41 ` Juri Linkov 2020-01-29 23:53 ` Stefan Monnier 2020-01-30 22:35 ` Juri Linkov 2020-01-30 23:07 ` Stefan Monnier -- strict thread matches above, loose matches on Subject: below -- 2022-04-09 4:46 emacsq 2022-04-09 18:53 ` Juri Linkov
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).