功能是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 的。
Bitnut
3
可以用 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))))
1 个赞
cireu
6
为什么会爆栈,又不是直接递归,只是包在lambda里让run-with-timer调用而已。函数执行完run-with-timer就不会继续增长栈了
1 个赞
借鉴 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)
lignit
9
我想到使用 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))
1 个赞
我想达到的功能是到了20分钟,提示休息一下,休息好了,如果继续按一下 y 再次倒计时。 run-with-timer 的 REPEAT 在运行一次后虽然运行回调函数,但运行回调函数时不会中断,会马上 repeat