Spec-Zone.ru › Elisp

Таймеры бездействия

Вот как настроить таймер, который запускается, когда Emacs бездействует в течение определенного промежутка времени. Помимо настройки, таймеры бездействия работают так же, как и обычные таймеры.

Команда: run-with-idle-timer secs repeat function &rest args

Настроить таймер, который запустится в следующий раз, когда Emacs будет бездействовать в течение secs секунд. Значение secs может быть числом или значением типа, возвращаемым current-idle-time.

Если repeat равно nil, таймер запустится только один раз, в первый раз, когда Emacs достаточно долго будет бездействовать. Чаще repeat имеет ненулевое значение nil, что означает запуск таймера каждый раз, когда Emacs бездействует в течение secs секунд.

Функция run-with-idle-timer возвращает значение таймера, которое можно использовать при вызове cancel-timer (см. Таймеры).

Emacs становится бездействующим, когда начинает ожидать ввода пользователя (если не ожидает ввода с таймаутом, см. Чтение одного события), и остается бездействующим до тех пор, пока пользователь не предоставит какой-либо ввод. Если таймер установлен на пять секунд бездействия, он запустится примерно через пять секунд после того, как Emacs впервые станет бездействующим. Даже если repeat имеет ненулевое значение nil, этот таймер не запустится снова, пока Emacs остается бездействующим, потому что продолжительность бездействия будет продолжать увеличиваться и не уменьшится до пяти секунд снова.

Emacs может выполнять различные действия во время бездействия: сбор мусора, автосохранение или обработку данных из подпроцесса. Но эти промежутки во время бездействия не влияют на таймеры бездействия, потому что они не сбрасывают часы бездействия до нуля. Таймер бездействия, установленный на 600 секунд, запустится, когда пройдет десять минут с момента завершения последней команды пользователя, даже если вывод подпроцесса принимался тысячи раз в течение этих десяти минут, и даже если были сборы мусора и автосохранения.

Когда пользователь предоставляет ввод, Emacs становится активным во время выполнения ввода. Затем он снова становится бездействующим, и все установленные таймеры бездействия, которые повторяются, будут запускаться снова по одному.

Не пишите функцию таймера бездействия, содержащую цикл, который выполняет определенное количество обработки каждый раз и завершается, когда (input-pending-p) имеет ненулевое значение nil. Такой подход кажется очень естественным, но имеет две проблемы:

  • Он блокирует весь вывод процесса (поскольку Emacs принимает вывод процесса только во время ожидания).
  • Он блокирует любые таймеры бездействия, которые должны быть запущены в это время.

Аналогично, не пишите функцию таймера бездействия, которая устанавливает другой таймер бездействия (включая тот же таймер) с аргументом secs, меньшим или равным текущему времени бездействия. Такой таймер запустится практически мгновенно и будет продолжать запускаться снова и снова, вместо того, чтобы ждать следующего момента, когда Emacs станет бездействующим. Правильный подход заключается в повторной установке с соответствующим приращением текущего значения времени бездействия, как описано ниже.

Функция: current-idle-time

Если Emacs бездействует, эта функция возвращает длительность бездействия Emacs, используя тот же формат, что и current-time (см. Время суток).

Когда Emacs не бездействует, current-idle-time возвращает nil. Это удобный способ проверить, бездействует ли Emacs.

Основное применение current-idle-time — когда функция таймера бездействия хочет «передохнуть» некоторое время. Она может настроить другой таймер бездействия, чтобы вызвать ту же функцию снова через несколько секунд дополнительного бездействия. Вот пример:

(defvar my-resume-timer nil
  "Timer for `my-timer-function' to reschedule itself, or nil.")

(defun my-timer-function ()
  ;; If the user types a command while my-resume-timer
  ;; is active, the next time this function is called from
  ;; its main idle timer, deactivate my-resume-timer.
  (when my-resume-timer
    (cancel-timer my-resume-timer))
  ...do the work for a while...
  (when taking-a-break
    (setq my-resume-timer
          (run-with-idle-timer
            ;; Compute an idle time break-length
            ;; more than the current value.
            (time-add (current-idle-time) break-length)
            nil
            'my-timer-function))))

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API