Skip to content

Commit

Permalink
pomm: add org-clock integration
Browse files Browse the repository at this point in the history
  • Loading branch information
SqrtMinusOne committed Jul 9, 2024
1 parent 14c7b42 commit 2acf510
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ To customize timestamp, set the =pomm-csv-history-file-timestamp-format= variabl
#+end_src

The format is the same as in =format-time-string=.
** Usage with =org-clock=
The package can be used with [[https://orgmode.org/manual/Clocking-commands.html][org-clock]] in the following way. Set up these two hooks:

#+begin_src emacs-lisp
(add-hook 'pomm-on-status-changed-hook #'pomm--sync-org-clock)
(add-hook 'pomm-third-time-on-status-changed-hook
#'pomm-third-time--sync-org-clock
#+end_src

Then, start the timer (either =pomm= or =pomm-third-time=) and =org-clock-in=, in whichever order. The package will call =org-clock-out= when a break starts and =org-clock-in-last= when it ends.

Setting =pomm-org-clock-in-immediately= to =nil= "defers" calling =org-clock-in-last= until after any command from the user (via =post-command-hook=). I've added this because I occasionally return to my PC a few minutes after the break ends, so I don't want these minutes to show up in =org-clock=.

* Alternatives
There is a number of packages with a similar purpose, here is a rough comparison of features:
Expand Down
17 changes: 17 additions & 0 deletions pomm-third-time.el
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,23 @@ Take a look at the `pomm-third-time' function for more details."
(setf (alist-get 'context pomm-third-time--state)
(prin1-to-string (read-minibuffer "Context: " (current-word)))))

(defun pomm-third-time--sync-org-clock ()
"Sync org-clock with the pomodoro timer."
(let* ((status (alist-get 'status pomm-third-time--state))
(kind (alist-get 'kind (alist-get 'current pomm-third-time--state)))
(active-p (and (eq kind 'work)
(eq status 'running)))
(resume-next-time-p (not (eq status 'stopped))))
(cond
((and active-p (not org-clock-current-task)
pomm--sync-org-clock-was-stopped)
(if pomm-org-clock-in-immediately
(org-clock-in-last)
(pomm--org-clock-in-last-after-action)))
((and (not active-p) org-clock-current-task)
(org-clock-out)
(setq pomm--sync-org-clock-was-stopped resume-next-time-p)))))

;;;###autoload
(defun pomm-third-time-start-with-context ()
"Prompt for context call call `pomm-third-time-start'."
Expand Down
38 changes: 38 additions & 0 deletions pomm.el
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ Each element of the list is a cons cell, where:
:group 'pomm
:type 'hook)

(defcustom pomm-org-clock-in-immediately t
"Run `org-clock-in-last' immediately after the break ends.
If nil, the clock in happens after the first command."
:group 'pomm
:type 'boolean)

(defvar pomm--state nil
"The current state of the Pomodoro timer.
Expand Down Expand Up @@ -536,6 +543,37 @@ minor mode."
(remove-hook 'pomm-on-status-changed-hook #'pomm-update-mode-line-string)
(remove-hook 'pomm-on-status-changed-hook #'force-mode-line-update))))

(defvar pomm--sync-org-clock-was-stopped nil
"If t, `pomm--sync-org-clock' had stopped `org-clock.")

(defun pomm--org-clock-in-last-after-action ()
"Run `org-clock-in-last' after some action by the user.
This exists because I sometimes return to PC after a the break ends."
(add-hook 'post-command-hook #'pomm--org-clock-in-last-and-remove-from-hook))

(defun pomm--org-clock-in-last-and-remove-from-hook ()
"Run `org-clock-in-last' and remove self from the `post-command-hook'."
(org-clock-in-last)
(remove-hook 'post-command-hook #'pomm--org-clock-in-last-and-remove-from-hook))

(defun pomm--sync-org-clock ()
"Sync org-clock with the pomodoro timer."
(let* ((status (alist-get 'status pomm--state))
(kind (alist-get 'kind (alist-get 'current pomm--state)))
(active-p (and (eq kind 'work)
(eq status 'running)))
(resume-next-time-p (not (eq status 'stopped))))
(cond
((and active-p (not org-clock-current-task)
pomm--sync-org-clock-was-stopped)
(if pomm-org-clock-in-immediately
(org-clock-in-last)
(pomm--org-clock-in-last-after-action)))
((and (not active-p) org-clock-current-task)
(org-clock-out)
(setq pomm--sync-org-clock-was-stopped resume-next-time-p)))))

;;;###autoload
(defun pomm-start ()
"Start or continue the pomodoro timer.
Expand Down

0 comments on commit 2acf510

Please sign in to comment.