Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sleep in emacs lisp

Tags:

sleep

emacs

lisp

script A

    (insert (current-time-string))
    (sleep-for 5)
    (insert (current-time-string))

M-x eval-buffer, two time strings are inserted with 5 secs apart

script B

some comint code (that add hook, and start process)

    (sleep-for 60) ;delay a bit for process to finish
    (insert "ZZZ")

M-x eval-buffer, "ZZZ" is inserted right away, without any time delay

what might have happened? btw, it's Emacs 23.2 on Win XP

like image 282
Bill Rong Avatar asked Jul 05 '11 05:07

Bill Rong


3 Answers

If all you want to do is to wait for a process to finish, you should probably not use sleep-for at all. Instead call the process synchronously, not asynchronously:

http://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html#Synchronous-Processes

This way, Emacs will block until the process has finished.

If you must (or really want to) use an asynchronous process, for instance because it takes very long and you don't want Emacs to freeze during that time (you speak of 60 seconds, which is quite long), then the right way to wait for the process to finish is by using a sentinel. A sentinel is a callback that gets called whenever the status of a process changes, e.g., when it terminates.

(defun my-start-process ()
  "Returns a process object of an asynchronous process."
  ...)

(defun my-on-status-change (process status)
  "Callback that receives notice for every change of the `status' of `process'."
  (cond ((string= status "finished\n") (insert "ZZZ"))
        (t (do-something-else))))

;; run process with callback
(let ((process (my-start-process)))
  (when process
    (set-process-sentinel process 'my-on-status-change)))
like image 140
Thomas Avatar answered Sep 23 '22 03:09

Thomas


It probably interrupted the sleep to deal with the subprocess IO. You should really use something like run-with-idle-timer for such "delay a bit for process" things, since Emacs is single-threaded.

like image 25
Eli Barzilay Avatar answered Sep 22 '22 03:09

Eli Barzilay


From the official documentation it might be implemented not only by 'sleep-for but by the 'sit-for also:

(defun smart-translate ()
  "Shows translation of a word at the current point
at the full frame for several seconds and 
returns to the initial buffer"
  (interactive)
  (google-translate-at-point)
  (switch-to-buffer "*Google Translate*")
  (delete-other-windows)
  (sit-for 5)
  (previous-buffer)
  )
like image 36
Alioth Avatar answered Sep 21 '22 03:09

Alioth