summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c
index 0f792b487ed..94ad0607732 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "buffer.h"
#include "pdumper.h"
+#include "atimer.h"
/* CACHEABLE is ordinarily nothing, except it is 'volatile' if
necessary to cajole GCC into not warning incorrectly that a
@@ -1078,6 +1079,47 @@ usage: (while TEST BODY...) */)
return Qnil;
}
+static void
+with_delayed_message_display (struct atimer *timer)
+{
+ message3 (build_string (timer->client_data));
+}
+
+static void
+with_delayed_message_cancel (void *timer)
+{
+ xfree (((struct atimer *) timer)->client_data);
+ cancel_atimer (timer);
+}
+
+DEFUN ("funcall-with-delayed-message",
+ Ffuncall_with_delayed_message, Sfuncall_with_delayed_message,
+ 3, 3, 0,
+ doc: /* Like `funcall', but display MESSAGE if FUNCTION takes longer than TIMEOUT.
+TIMEOUT is a number of seconds, and can be an integer or a floating
+point number.
+
+If FUNCTION takes less time to execute than TIMEOUT seconds, MESSAGE
+is not displayed. */)
+ (Lisp_Object timeout, Lisp_Object message, Lisp_Object function)
+{
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ CHECK_NUMBER (timeout);
+ CHECK_STRING (message);
+
+ /* Set up the atimer. */
+ struct timespec interval = dtotimespec (XFLOATINT (timeout));
+ struct atimer *timer = start_atimer (ATIMER_RELATIVE, interval,
+ with_delayed_message_display,
+ xstrdup (SSDATA (message)));
+ record_unwind_protect_ptr (with_delayed_message_cancel, timer);
+
+ Lisp_Object result = CALLN (Ffuncall, function);
+
+ return unbind_to (count, result);
+}
+
DEFUN ("macroexpand", Fmacroexpand, Smacroexpand, 1, 2, 0,
doc: /* Return result of expanding macros at top level of FORM.
If FORM is not a macro call, it is returned unchanged.
@@ -4511,6 +4553,7 @@ alist of active lexical bindings. */);
defsubr (&Slet);
defsubr (&SletX);
defsubr (&Swhile);
+ defsubr (&Sfuncall_with_delayed_message);
defsubr (&Smacroexpand);
defsubr (&Scatch);
defsubr (&Sthrow);