sleep in emacs lisp

2020-08-09 08:46发布

问题:

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

回答1:

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)))


回答2:

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.



回答3:

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)
  )


标签: emacs lisp sleep