tags:

views:

128

answers:

2

Is there any way to write something like this without taking over emacs?

(defun dumb-wait (seconds)
    (let ((done (+ (second (current-time)) seconds)))
        (while (< (second (current-time)) done)
            (message "waiting"))))

(dump-wait 5) will block emacs from 5 seconds. Is there anyway to write this so it doesn't block? I just want to be in a loop and check some condition from time to time, and still be able to use emacs.

Thanks!

+5  A: 

(run-at-time time repeat function &rest args) should do it. nil as time means now.

(setq my-timer 
      (run-at-time nil 5 (lambda () (message "waiting")))) ; returns timer object
;; or
(setq my-timer
      (run-at-time nil 5 'message "waiting"))

(cancel-timer my-timer) ; use timer object from above

Edit:

The parameter repeat expects a number as seconds, however there's a function timer-duration, which you can use instead of the number. It returns the number of seconds as provided with a string parameter. This is somewhat easier to read for big intervals.

(timer-duration "3 hours 2 seconds 1 millisec") ; => 10802.001

Possible word you can use are defined in the variable timer-duration-words.

andre-r
+2  A: 

On a related note, there's no general way to write Emacs Lisp code that doesn't block because the language doesn't have features like coroutines, continuations and threading (yet). Instead, you've got to look for asynchronous inbuilts that do something closest to what you want. Example: url-retrieve and async-shell-command. Some applications like SLIME have managed to work around this issue and have implemented a sort of threading on their own, while others like gnus are waiting for Emacs Lisp to improve.

Ramkumar Ramachandra