all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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-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  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-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 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-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: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  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-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-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-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
  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
  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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.