Спать в Emacs Lisp
сценарий А
(insert (current-time-string))
(sleep-for 5)
(insert (current-time-string))
M-x eval-buffer
, две строки времени вставляются с интервалом в 5 секунд
сценарий Б
некоторый код коминта (который добавляет ловушку и запускает процесс)
(sleep-for 60) ;delay a bit for process to finish
(insert "ZZZ")
M-x eval-buffer
, "ZZZ" вставляется сразу, без задержки
что могло случиться? Кстати, это Emacs 23.2 на Win XP
2 ответа
Если все, что вы хотите сделать, это дождаться завершения процесса, вам, вероятно, не следует использовать sleep-for
совсем. Вместо этого вызовите процесс синхронно, а не асинхронно:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html
Таким образом, Emacs будет блокироваться до завершения процесса.
Если вы должны (или действительно хотите) использовать асинхронный процесс, например, потому что он занимает очень много времени и вы не хотите, чтобы Emacs зависал в течение этого времени (вы говорите о 60 секундах, что довольно долго), тогда правильный путь ждать завершения процесса с помощью дозорного. Часовой является обратным вызовом, который вызывается всякий раз, когда изменяется состояние процесса, например, когда он завершается.
(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)))
Это, вероятно, прервало сон, чтобы иметь дело с IO подпроцесса. Вы должны действительно использовать что-то вроде run-with-idle-timer
для таких вещей "немного задержка для процесса", так как Emacs является однопоточным.
Из официальной документации это может быть реализовано не только в режиме ожидания, но и в режиме ожидания:
(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)
)