aboutsummaryrefslogtreecommitdiff
path: root/org-tempus.el
blob: 992460afe30368b0d17c2532df4a57d08c003451 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
;;; org-tempus.el --- Org functions to track work hours  -*- lexical-binding: t; -*-

;; Copyright (C) 2025  Raul Benencia

;; Author: Raul Benencia <id@rbenencia.name>
;; Maintainer: Raul Benencia <id@rbenencia.name>
;; URL: https://github.com/rul/org-tempus
;; Version: 0.0.1
;; Package-Requires: ((emacs "27.1"))
;; Keywords: convenience, time, clock

;; This file is NOT part of GNU Emacs.

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or (at
;; your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:
;;
;; TODO

;;; Code:
(require 'org-clock)

(defgroup org-tempus ()
  "Display mode line indicator with information about clocked time."
  :group 'org)

(defcustom org-tempus-add-to-global-mode-string t
  "When non-nil, append the Org Tempus construct to the mode line."
  :type 'boolean
  :package-version '(org-tempus . "0.0.1")
  :group 'org-tempus)

(defcustom org-tempus-update-interval 60
  "Seconds between automatic mode line refreshes."
  :type 'integer
  :group 'org-tempus)

(defvar org-tempus-mode-line-string ""
  "Org Tempus mode line indicator.")

(defvar org-tempus--timer nil
  "Timer used to refresh the Org Tempus mode line.")

(defun org-tempus--current-task-name ()
  "Return unpropertized name of current task."
  (substring-no-properties org-clock-current-task))

(defun org-tempus--sum-today ()
  "Return unpropertized time clocked in today."
  (substring-no-properties (org-clock-sum-today))
  )

(defun org-tempus--current-task-time ()
  "Return clocked time for current task."
  (number-to-string (org-clock-get-clocked-time)))

(defun org-tempus--update-mode-line ()
  "Update the Org Tempus mode line indicator."
  (setq org-tempus-mode-line-string
        (propertize
         (if (org-clock-is-active)
             (concat "🧉 " (org-tempus--current-task-name) " " (org-tempus--current-task-time) " " (org-clock-sum-today))
           (concat "☠️ " " "))
         'mouse-face 'mode-line-highlight))
  (force-mode-line-update))

;;;###autoload
(define-minor-mode org-tempus-mode
  "Minor mode to enhance time tracking in ‘org-mode’."
  :lighter " Tempus fugit"
  :global t
  (if org-tempus-mode
      (progn
        (when (timerp org-tempus--timer)
          (cancel-timer org-tempus--timer))
        (setq org-tempus--timer
              (run-at-time org-tempus-update-interval
                           org-tempus-update-interval
                           #'org-tempus--update-mode-line))
        (add-hook 'org-clock-in-hook #'org-tempus--update-mode-line)
        (add-hook 'org-clock-out-hook #'org-tempus--update-mode-line)
        (when org-tempus-add-to-global-mode-string
          (or global-mode-string (setq global-mode-string '("")))
          (or (memq 'org-tempus-mode-line-string global-mode-string)
              (setq global-mode-string
                    (append global-mode-string '(org-tempus-mode-line-string)))))
        (org-tempus--update-mode-line))

    (when org-tempus-add-to-global-mode-string
      (or global-mode-string (setq global-mode-string '("")))
      (setq global-mode-string
            (remove 'org-tempus-mode-line-string global-mode-string))
      (force-mode-line-update))
    (when (timerp org-tempus--timer)
      (cancel-timer org-tempus--timer))
    (setq org-tempus--timer nil)
    (remove-hook 'org-clock-in-hook #'org-tempus--update-mode-line)
    (remove-hook 'org-clock-out-hook #'org-tempus--update-mode-line)))

(provide 'org-tempus)
;;; org-tempus.el ends here
nihil fit ex nihilo