2022-02-10 11:33:08 +00:00
|
|
|
#+TITLE: chronometrist-third
|
|
|
|
#+SUBTITLE: Third Time System extension for Chronometrist
|
|
|
|
#+PROPERTY: header-args :tangle yes :load yes :comments link
|
|
|
|
|
|
|
|
* Program source
|
2022-02-10 16:25:28 +00:00
|
|
|
** Library headers and commentary
|
2022-02-10 16:35:31 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp :comments no
|
2022-02-10 16:25:28 +00:00
|
|
|
;;; chronometrist-third.el --- Third Time support for Chronometrist -*- lexical-binding: t; -*-
|
|
|
|
|
|
|
|
;; Author: contrapunctus <xmpp:contrapunctus@jabjab.de>
|
|
|
|
;; Maintainer: contrapunctus <xmpp:contrapunctus@jabjab.de>
|
|
|
|
;; Keywords: calendar
|
|
|
|
;; Homepage: https://tildegit.org/contrapunctus/chronometrist
|
|
|
|
;; Package-Requires: ((emacs "25.1") (alert "1.2") (chronometrist "0.6.0"))
|
|
|
|
;; Version: 0.0.1
|
|
|
|
|
|
|
|
;; This is free and unencumbered software released into the public domain.
|
|
|
|
;;
|
|
|
|
;; Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
|
|
;; distribute this software, either in source code form or as a compiled
|
|
|
|
;; binary, for any purpose, commercial or non-commercial, and by any
|
|
|
|
;; means.
|
|
|
|
;;
|
|
|
|
;; For more information, please refer to <https://unlicense.org>
|
|
|
|
|
|
|
|
;;; Commentary:
|
2022-02-10 16:35:31 +00:00
|
|
|
;; Add support for the Third Time system to Chronometrist. In Third
|
2022-02-10 16:25:28 +00:00
|
|
|
;; Time, you work for any length of time you like, and "earn" a third
|
2022-02-10 16:35:31 +00:00
|
|
|
;; of the work time as break time. For a more detailed explanation,
|
2022-02-10 16:25:28 +00:00
|
|
|
;; see
|
|
|
|
;; https://www.lesswrong.com/posts/RWu8eZqbwgB9zaerh/third-time-a-better-way-to-work
|
|
|
|
|
|
|
|
;; For information on usage and customization, see https://tildegit.org/contrapunctus/chronometrist-goal/src/branch/production/README.md
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** Dependencies
|
2022-02-10 16:35:31 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp :comments no
|
2022-02-10 16:25:28 +00:00
|
|
|
;;; Code:
|
|
|
|
(require 'chronometrist)
|
|
|
|
(require 'alert)
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** group :custom:group:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
(defgroup chronometrist-third nil
|
|
|
|
"Third Time support for Chronometrist."
|
|
|
|
:group 'chronometrist)
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** divisor :custom:variable:
|
2022-02-10 11:33:08 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
(defcustom chronometrist-third-divisor 3
|
2022-02-10 16:35:31 +00:00
|
|
|
"Number to determine accumulation of break time relative to work time."
|
|
|
|
:type 'number)
|
2022-02-10 11:33:08 +00:00
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-10 16:25:28 +00:00
|
|
|
** duration-format :custom:variable:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-24 10:17:06 +00:00
|
|
|
(defcustom chronometrist-third-duration-format "%H, %M and %S%z"
|
2022-02-10 16:35:31 +00:00
|
|
|
"Format string for durations, passed to `format-seconds'."
|
|
|
|
:type 'string)
|
2022-02-10 16:25:28 +00:00
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** break-time :variable:
|
2022-02-10 11:33:08 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
(defvar chronometrist-third-break-time 0
|
|
|
|
"Accumulated break time in seconds.")
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** alert-functions :custom:variable:
|
2022-02-10 13:47:04 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:25:28 +00:00
|
|
|
(defcustom chronometrist-third-alert-functions '(chronometrist-third-half-alert chronometrist-third-quarter-alert chronometrist-third-break-over-alert)
|
2022-02-10 13:47:04 +00:00
|
|
|
"List of timed alerts for the Third Time system.
|
|
|
|
|
2022-02-10 16:25:28 +00:00
|
|
|
Typically, each function in this list should call
|
|
|
|
`chronometrist-third-run-at-time' to run another function, which
|
2022-02-11 06:26:33 +00:00
|
|
|
in turn should call `alert' to notify the user.
|
|
|
|
|
|
|
|
All functions in this list are started when the user clocks out,
|
|
|
|
and stopped when they clock in."
|
2022-02-10 13:47:04 +00:00
|
|
|
:group 'chronometrist-third
|
|
|
|
:type 'hook)
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** timer-list :variable:
|
2022-02-10 13:47:04 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:25:28 +00:00
|
|
|
(defvar chronometrist-third-timer-list nil)
|
2022-02-11 06:26:33 +00:00
|
|
|
#+END_SRC
|
2022-02-10 16:25:28 +00:00
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** run-at-time :procedure:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:25:28 +00:00
|
|
|
(defun chronometrist-third-run-at-time (time repeat function &rest args)
|
2022-02-11 06:26:33 +00:00
|
|
|
"Like `run-at-time', but store timer objects in `chronometrist-third-timer-list'."
|
2022-02-10 16:25:28 +00:00
|
|
|
(cl-pushnew (apply #'run-at-time time repeat function args) chronometrist-third-timer-list))
|
2022-02-11 06:26:33 +00:00
|
|
|
#+END_SRC
|
2022-02-10 16:25:28 +00:00
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** half-alert :procedure:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 13:47:04 +00:00
|
|
|
(defun chronometrist-third-half-alert ()
|
2022-02-11 06:26:33 +00:00
|
|
|
"Display an alert when half the break time is consumed."
|
|
|
|
(let ((half-time (/ chronometrist-third-break-time 2.0)))
|
|
|
|
(and (not (zerop chronometrist-third-break-time))
|
|
|
|
(chronometrist-third-run-at-time
|
|
|
|
half-time nil
|
2022-02-12 18:20:34 +00:00
|
|
|
(lambda (half-time)
|
2022-02-11 06:26:33 +00:00
|
|
|
(alert
|
|
|
|
(format "%s left on your break."
|
2022-02-12 18:20:34 +00:00
|
|
|
(format-seconds chronometrist-third-duration-format half-time))))
|
|
|
|
half-time))))
|
2022-02-11 06:26:33 +00:00
|
|
|
#+END_SRC
|
2022-02-10 16:25:28 +00:00
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** quarter-alert :procedure:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:25:28 +00:00
|
|
|
(defun chronometrist-third-quarter-alert ()
|
|
|
|
"Display an alert when 3/4ths of the break time is consumed."
|
2022-02-11 06:26:33 +00:00
|
|
|
(let ((three-fourths (* chronometrist-third-break-time 7.5)))
|
|
|
|
(and (not (zerop chronometrist-third-break-time))
|
|
|
|
(chronometrist-third-run-at-time
|
|
|
|
three-fourths nil
|
2022-02-12 18:20:34 +00:00
|
|
|
(lambda (three-fourths)
|
2022-02-11 06:26:33 +00:00
|
|
|
(alert
|
|
|
|
(format "%s left on your break."
|
2022-02-11 07:05:56 +00:00
|
|
|
(format-seconds chronometrist-third-duration-format
|
2022-02-12 18:20:34 +00:00
|
|
|
(- chronometrist-third-break-time three-fourths)))))
|
|
|
|
three-fourths))))
|
2022-02-11 06:26:33 +00:00
|
|
|
#+END_SRC
|
2022-02-10 16:25:28 +00:00
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** break-over-alert :procedure:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:25:28 +00:00
|
|
|
(defun chronometrist-third-break-over-alert ()
|
|
|
|
"Display an alert when break time is over."
|
2022-02-10 13:47:04 +00:00
|
|
|
(and (not (zerop chronometrist-third-break-time))
|
2022-02-10 16:25:28 +00:00
|
|
|
(chronometrist-third-run-at-time
|
|
|
|
chronometrist-third-break-time nil
|
|
|
|
(lambda () (alert (format "Break time is over!"))))))
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** start-alert-timers :procedure:
|
2022-02-10 16:25:28 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
(defun chronometrist-third-start-alert-timers ()
|
2022-02-11 06:26:33 +00:00
|
|
|
"Run functions in `chronometrist-third-alert-functions'."
|
2022-02-10 16:25:28 +00:00
|
|
|
(mapc #'funcall chronometrist-third-alert-functions))
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** stop-alert-timers :procedure:
|
2022-02-10 16:25:28 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
|
|
(defun chronometrist-third-stop-alert-timers ()
|
2022-02-11 06:26:33 +00:00
|
|
|
"Stop timers in `chronometrist-third-timer-list'."
|
2022-02-10 16:25:28 +00:00
|
|
|
(mapc (lambda (timer) (cancel-timer timer)) chronometrist-third-timer-list))
|
2022-02-10 13:47:04 +00:00
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** clock-in :hook:procedure:
|
2022-02-10 11:33:08 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:35:31 +00:00
|
|
|
(defun chronometrist-third-clock-in (&optional _arg)
|
2022-02-11 06:26:33 +00:00
|
|
|
"Stop alert timers and update break time."
|
2022-02-10 16:25:28 +00:00
|
|
|
(chronometrist-third-stop-alert-timers)
|
2022-02-10 13:17:35 +00:00
|
|
|
(unless (zerop chronometrist-third-break-time)
|
2022-02-23 09:22:53 +00:00
|
|
|
(-let* (((&plist :stop stop) (cl-second (chronometrist-to-list (chronometrist-active-backend))))
|
|
|
|
(used-break (ts-diff (ts-now) (chronometrist-iso-to-ts stop)))
|
|
|
|
(used-break-string (format-seconds chronometrist-third-duration-format used-break))
|
|
|
|
(new-break (- chronometrist-third-break-time used-break))
|
|
|
|
(old-break chronometrist-third-break-time))
|
|
|
|
(setq chronometrist-third-break-time (if (> new-break 0) new-break 0))
|
2022-02-12 18:32:49 +00:00
|
|
|
(alert
|
|
|
|
(if (zerop chronometrist-third-break-time)
|
|
|
|
(format "You have used up all %s of your break time (%s break)"
|
2022-02-23 09:22:53 +00:00
|
|
|
(format-seconds chronometrist-third-duration-format old-break)
|
|
|
|
used-break-string)
|
2022-02-12 18:32:49 +00:00
|
|
|
(format "You have used %s of your break time (%s left)"
|
2022-02-23 09:22:53 +00:00
|
|
|
used-break-string
|
2022-02-12 18:32:49 +00:00
|
|
|
(format-seconds chronometrist-third-duration-format chronometrist-third-break-time)))))))
|
2022-02-10 11:33:08 +00:00
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** clock-out :hook:procedure:
|
2022-02-10 11:33:08 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-10 16:35:31 +00:00
|
|
|
(defun chronometrist-third-clock-out (&optional _arg)
|
2022-02-11 06:26:33 +00:00
|
|
|
"Update break time based on the latest work interval.
|
|
|
|
Run `chronometrist-third-alert-functions' to alert user when
|
|
|
|
break time is up."
|
2022-02-10 16:25:28 +00:00
|
|
|
(let* ((latest-work-duration (chronometrist-interval (chronometrist-latest-record (chronometrist-active-backend))))
|
|
|
|
(break-time-increment (/ latest-work-duration chronometrist-third-divisor)))
|
|
|
|
(cl-incf chronometrist-third-break-time break-time-increment)
|
2022-02-12 18:32:49 +00:00
|
|
|
(alert (format "You have gained %s of break time (%s total)"
|
2022-02-12 16:11:15 +00:00
|
|
|
(format-seconds chronometrist-third-duration-format break-time-increment)
|
|
|
|
(format-seconds chronometrist-third-duration-format chronometrist-third-break-time)))
|
2022-02-10 13:47:04 +00:00
|
|
|
;; start alert timer(s)
|
2022-02-10 16:25:28 +00:00
|
|
|
(chronometrist-third-start-alert-timers)))
|
2022-02-10 11:33:08 +00:00
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-11 06:26:33 +00:00
|
|
|
** third-minor-mode :minor:mode:
|
2022-02-10 13:47:04 +00:00
|
|
|
#+BEGIN_SRC emacs-lisp
|
2022-02-11 16:31:24 +00:00
|
|
|
;;;###autoload
|
2022-02-10 13:47:04 +00:00
|
|
|
(define-minor-mode chronometrist-third-minor-mode
|
|
|
|
nil nil nil nil
|
|
|
|
(cond (chronometrist-third-minor-mode
|
|
|
|
(add-hook 'chronometrist-after-in-functions #'chronometrist-third-clock-in)
|
|
|
|
(add-hook 'chronometrist-after-out-functions #'chronometrist-third-clock-out))
|
|
|
|
(t (remove-hook 'chronometrist-after-in-functions #'chronometrist-third-clock-in)
|
|
|
|
(remove-hook 'chronometrist-after-out-functions #'chronometrist-third-clock-out))))
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-10 16:35:31 +00:00
|
|
|
** Provide
|
|
|
|
#+BEGIN_SRC emacs-lisp :comments no
|
|
|
|
(provide 'chronometrist-third)
|
|
|
|
|
|
|
|
;;; chronometrist-third.el ends here
|
|
|
|
#+END_SRC
|
|
|
|
|
2022-02-14 19:56:15 +00:00
|
|
|
* Local variables :noexport:
|
2022-02-10 11:33:08 +00:00
|
|
|
# Local Variables:
|
|
|
|
# my-org-src-default-lang: "emacs-lisp"
|
2022-02-10 13:23:06 +00:00
|
|
|
# eval: (when (package-installed-p 'literate-elisp) (require 'literate-elisp) (literate-elisp-load (buffer-file-name)))
|
2022-02-10 11:33:08 +00:00
|
|
|
# End:
|