[Org] Extend functionality to insert past interruptions
For this a new function ‘timeline-tools-clockline-no-org-agenda-conflicts’ as been added that reads in a clock line (start and end times), updates all org agenda files to fix conflicting clock lines, and returns the string of the new clock line. This works for all complete clock lines (i.e., those with end times), but not for open clock lines (i.e., those missing an end timestamp).
This commit is contained in:
parent
26dad5a0d5
commit
016fbf3c10
6
init.el
6
init.el
|
@ -608,7 +608,6 @@
|
|||
hydra-org-agenda-view/body
|
||||
org-babel-execute:hy
|
||||
db/org-timestamp-difference
|
||||
db/read-clockline
|
||||
db/org-capture-code-snippet
|
||||
hydra-org-clock/body
|
||||
db/make-org-capture-frame))
|
||||
|
@ -1020,7 +1019,7 @@
|
|||
(file db/org-default-refile-file)
|
||||
,(concat "* DONE %^{What}\n"
|
||||
":LOGBOOK:\n"
|
||||
"%(db/read-clockline)\n" ; evaluated before above prompt?
|
||||
"%(timeline-tools-clockline-no-org-agenda-conflicts)\n" ; evaluated before above prompt?
|
||||
":END:\n"
|
||||
"%?"))
|
||||
("j" "journal entry"
|
||||
|
@ -2579,7 +2578,8 @@
|
|||
:load-path "site-lisp"
|
||||
:commands (timeline-tools-format-timeline
|
||||
timeline-tools-format-timeline-of-day
|
||||
timeline-tools-copy-clocklines))
|
||||
timeline-tools-copy-clocklines
|
||||
timeline-tools-clockline-no-org-agenda-conflicts))
|
||||
|
||||
(use-package typing
|
||||
:commands (typing-of-emacs)
|
||||
|
|
|
@ -194,19 +194,6 @@ _y_: ?y? year _q_: quit _L__l__c_: ?l?
|
|||
(m (floor (/ (- s (* 3600 h)) 60))))
|
||||
(format (if neg "-%d:%02d" "%2d:%02d") h m)))
|
||||
|
||||
(defun db/read-clockline ()
|
||||
"Read starting and ending time from user and return org mode
|
||||
clock line."
|
||||
(let* ((now (format-time-string "%H:%M"))
|
||||
(starting (format "[%s]" (org-read-date t nil nil "Started: "
|
||||
(current-time)
|
||||
now)))
|
||||
(ending (format "[%s]" (org-read-date t nil nil "Ended: "
|
||||
(current-time)
|
||||
now)))
|
||||
(difference (db/org-timestamp-difference starting ending)))
|
||||
(format "CLOCK: %s--%s => %s" starting ending difference)))
|
||||
|
||||
;; Capture Code Snippets
|
||||
;; from http://ul.io/nb/2018/04/30/better-code-snippets-with-org-capture/
|
||||
(defun db/org-capture-code-snippet (filename)
|
||||
|
|
|
@ -595,56 +595,89 @@ Interactively query for the exact value of \"short\"."
|
|||
|
||||
;; XXX: All this needs some autoloadable frontend
|
||||
|
||||
(defun timeline-tools-add-clockline-to-marker (target-marker start end)
|
||||
"Add clock line to task under TARGET-MARKER from START to END.
|
||||
(defun timeline-tools-clockline-no-conflict (start end &rest buffers)
|
||||
"Return clock line string from START to END.
|
||||
|
||||
START and END must be suitable arguments for `float-time’.
|
||||
Update conflicting clock lines in BUFFERS before returning the
|
||||
clock line."
|
||||
(let ((new-start (float-time start))
|
||||
(new-end (float-time end)))
|
||||
(dolist (buffer buffers)
|
||||
(with-current-buffer buffer
|
||||
(timeline-tools-map-clocklines
|
||||
(lambda (timestamp-1 timestamp-2)
|
||||
(let ((current-start (org-time-string-to-seconds timestamp-1))
|
||||
(current-end (org-time-string-to-seconds timestamp-2))
|
||||
(kill-whole-line nil) ; don’t delete newlines if not asked to
|
||||
)
|
||||
(cond
|
||||
;; if the current clock line is completely contained within the
|
||||
;; given period, delete it
|
||||
((and (<= new-start current-start current-end new-end))
|
||||
(kill-whole-line))
|
||||
;; if the current clock line completely contains the given one,
|
||||
;; split it
|
||||
((and (<= current-start new-start new-end current-end))
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline current-start new-start)
|
||||
(open-line 1)
|
||||
(timeline-tools-insert-clockline new-end current-end))
|
||||
;; New interval overlaps beginning of current line
|
||||
((<= new-start current-start new-end current-end)
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline new-end current-end))
|
||||
;; New interval overlaps at end of current line
|
||||
((<= current-start new-start current-end new-end)
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline current-start new-start)))))
|
||||
|
||||
;; Keep headline as they are, i.e., do nothing
|
||||
#'ignore)))
|
||||
|
||||
;; Return valid clockline
|
||||
(with-temp-buffer
|
||||
(timeline-tools-insert-clockline new-start new-end)
|
||||
(buffer-string))))
|
||||
|
||||
(defun timeline-tools-add-clockline-to-marker
|
||||
(target-marker start end &rest buffers)
|
||||
"Add clock line from START to END to task under TARGET-MARKER.
|
||||
|
||||
START and END must be given as time objects as returned by
|
||||
`encode-time’, or as an integer or float denoting seconds since
|
||||
1970-01-01. TARGET-MARKER must be positioned on the task where
|
||||
the clock line is to be added to."
|
||||
the clock line is to be added to. BUFFERS must be a list of
|
||||
buffers where to look for conflicting clock lines. Those
|
||||
conflicting clock lines are updated accordingly. If BUFFERS is
|
||||
not given, update clock lines in the buffer of TARGET-MARKER."
|
||||
(when (not (markerp target-marker))
|
||||
(user-error "Marker not valid"))
|
||||
(let ((new-start (float-time start))
|
||||
(new-end (float-time end)))
|
||||
(with-current-buffer (marker-buffer target-marker)
|
||||
(timeline-tools-map-clocklines
|
||||
(lambda (timestamp-1 timestamp-2)
|
||||
(let ((current-start (org-time-string-to-seconds timestamp-1))
|
||||
(current-end (org-time-string-to-seconds timestamp-2))
|
||||
(kill-whole-line nil) ; don’t delete newlines if not asked to
|
||||
)
|
||||
(cond
|
||||
;; if the current clock line is completely contained within the
|
||||
;; given period, delete it
|
||||
((and (<= new-start current-start current-end new-end))
|
||||
(kill-whole-line))
|
||||
;; if the current clock line completely contains the given one,
|
||||
;; split it
|
||||
((and (<= current-start new-start new-end current-end))
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline current-start new-start)
|
||||
(open-line 1)
|
||||
(timeline-tools-insert-clockline new-end current-end))
|
||||
;; New interval overlaps beginning of current line
|
||||
((<= new-start current-start new-end current-end)
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline new-end current-end))
|
||||
;; New interval overlaps at end of current line
|
||||
((<= current-start new-start current-end new-end)
|
||||
(beginning-of-line)
|
||||
(kill-line)
|
||||
(timeline-tools-insert-clockline current-start new-start)))))
|
||||
|
||||
;; Keep headline as they are, i.e., do nothing
|
||||
#'ignore))
|
||||
|
||||
;; Finally add the new clock line
|
||||
(let ((new-start (float-time start))
|
||||
(new-end (float-time end))
|
||||
(org-buffers (if buffers buffers (list (marker-buffer target-marker)))))
|
||||
(org-with-point-at target-marker
|
||||
(org-clock-find-position nil)
|
||||
(open-line 1)
|
||||
(timeline-tools-insert-clockline new-start new-end))))
|
||||
(insert (apply #'timeline-tools-clockline-no-conflicts
|
||||
new-start new-end org-buffers)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun timeline-tools-clockline-no-org-agenda-conflicts ()
|
||||
"Read clock line from user and return it.
|
||||
|
||||
Update all files in `org-agenda-files’ to update conflicting clock lines."
|
||||
(let* ((now (format-time-string "%H:%M"))
|
||||
(start (org-read-date t nil nil "Started: " (current-time) now))
|
||||
(end (org-read-date t nil nil "Ended: " (current-time) now)))
|
||||
(apply #'timeline-tools-clockline-no-conflict
|
||||
(org-time-string-to-seconds start)
|
||||
(org-time-string-to-seconds end)
|
||||
(mapcar #'find-file-noselect
|
||||
(cl-remove-if-not #'file-exists-p org-agenda-files)))))
|
||||
|
||||
(defun timeline-tools-copy-clocklines (source-id target-id)
|
||||
"Copy clock lines from SOURCE-ID to TARGET-ID.
|
||||
|
|
Loading…
Reference in New Issue
Block a user