4

The following show the message "something" in the echo area immediately, and this message remains there unless I do a second action (e.g. moving the cursor, executing anther command etc)

(message "something")

I would like that the message to not appear immediately, but after a delay of few second (say 2 seconds) and to automatically disappear after few second (say 3 second). Is this possible?

To be precise I would like that in the first delay of 2 seconds, I would able to see other system messages (if any).

Name
  • 7,849
  • 4
  • 41
  • 87
  • The display of a message for a finite period of time is already treated there: http://emacs.stackexchange.com/questions/18479/temporarily-show-a-message-in-the-modeline/18481#18481. If you display something temporarily you should restore the old message afterwards. Therefore, save what you get via (current-message) and view it afterwards via (message ...). – Tobias Oct 29 '16 at 18:02
  • 1
    Thanks for the link. That question was about modeline.Here is about the echo area. They are related though not identical. – Name Oct 29 '16 at 18:33
  • Oh, yes right you are. Sorry, for the confusion. When I read the other question I thought about the difference of minibuffer and echo area and got into that trap. Nevertheless, the other part of the comment about (current-message) is worth to think about. – Tobias Oct 29 '16 at 18:44

1 Answers1

3

You could try something like:

(run-with-timer 2 nil
        (lambda ()
          (message "Some message")
          (run-with-timer 3 nil
                  (lambda ()
                    (message nil)))))

run-with-timer will call a function of your choice after a delay (there's a run-with-idle-timer variant if you want to only show the message when Emacs is idle). I've used lambda here to create an anonymous function with the body of code I want to run.

The example shows a message then schedules a second timer to clear the echo-area.

This is a bit clumsy since there might be somebody else's message in the echo area by the time the second timer fires, so you may end up clearing a different message. There's probably a way to avoid that with some more work.

Edit: changed (message "") to (message nil) to clear the echo-area and return to showing any minibuffer contents (thanks Drew!)

Stuart Hickinbottom
  • 2,423
  • 16
  • 17
  • Use (message nil), to clear the message and let the contents of the minibuffer show. – Drew Oct 29 '16 at 17:18
  • The documentation of this function (25.1) suggests that these invocations are equivalent. – politza Oct 29 '16 at 18:50
  • I confirm that this solution works. Let me wait for possible alternative solution. – Name Oct 29 '16 at 19:12
  • How can we make this the default behavior for all kinds of echoed text including messages? I mean, let them disappear after a delay. – godblessfq Apr 19 '19 at 08:55
  • Seems the variable minibuffer-message-timeout should work out of the box, but it doesn't. I have come up with this: (fset 'original-message (symbol-function 'message)) (defun clear-message (&rest args) (run-with-timer 2 nil (lambda () (original-message nil))))

    you can test it with

    (run-with-timer 2 nil (lambda () (message "Some message")))

    Maybe it's better to set inhibit-message at entry and exit of the minibuffer

    – godblessfq Apr 19 '19 at 11:02