最近腰疼,写个实用的久坐提示

功能是20分钟倒计时,弹出确认框提醒,“站起来活动活动”,点击确认递归调用,点击取消结束。

(defun my-rest ()
   (interactive)
   (progn
     (setq org-timer-start-time 
       (time-add (current-time) 1200))
     (org-timer-set-mode-line 'on)
     (run-with-timer
        1200 nil
        (lambda ()
          (progn
            (org-timer-stop)
            (if (y-or-n-p "站起来活动活动")
              (my-rest)))))))

一直递归会爆栈吧, Elisp 应该没有 TCO 的。

可以用 run-with-timer 这个函数设置时间。我自己用这个函数来定时检查是否天黑,然后切换主题。

(run-with-timer SECS REPEAT FUNCTION &rest ARGS)

1 个赞

不用递归,改用 hook

(setq my-rest-hook nil)
(defun my-rest ()
  (interactive)
  (progn
    (setq org-timer-start-time
          (time-add (current-time) 1200))
    (org-timer-set-mode-line 'on)
    (run-with-timer
     1200 nil
     (lambda ()
       (run-hooks 'my-rest-hook)))))
(add-hook 'my-rest-hook (lambda ()
                          (if (y-or-n-p "take a rest and type y or stop")
                              (my-rest)
                            (org-timer-stop))))

这不是一样爆栈吗。。。。。。。。

为什么会爆栈,又不是直接递归,只是包在lambda里让run-with-timer调用而已。函数执行完run-with-timer就不会继续增长栈了

借鉴 org-pomodoro 运行一个每一秒执行一次的 timer 来检测是否到了时间

(org-timer-start)
(setq org-timer-start-time (time-add (current-time) 1200))
(org-timer-set-mode-line 'on)
(defun my-rest ()
  (if (equal (org-timer-hms-to-secs (org-timer-value-string)) 0)
      (progn (org-timer-set-mode-line 'off)
                  (if (y-or-n-p "take a rest ... & press y go on")
                      (progn
                          (setq org-timer-start-time (time-add (current-time) 1200))
                          (org-timer-set-mode-line 'on))))))
(setq my-rest-timer
   (run-with-timer t 1 'my-rest))
;;(cancel-timer my-rest-timer)

坚持做小燕飞一个月,必有奇效。

我想到使用 run-with-timer 返回的 timer。在被定时的函数中询问问题,如果休息,就把 timer 取消。否则就按照 run-with-timer 的 REPEAT 参数来重复。

(defun my-rest-question ()
  (let (answer)
    (setq answer (y-or-n-p "Have a rest now: "))
    (when answer
      (cancel-timer my-rest-timer))))

(setq my-rest-timer
      (run-with-timer 20 20 'my-rest-question))

我想达到的功能是到了20分钟,提示休息一下,休息好了,如果继续按一下 y 再次倒计时。 run-with-timer 的 REPEAT 在运行一次后虽然运行回调函数,但运行回调函数时不会中断,会马上 repeat

其实… 久坐提示我觉得应该买个智能手表