[Timeline] More refactoring

This commit is contained in:
Daniel - 2018-01-21 18:47:11 +01:00
parent cbaf589c53
commit 78480d5fae
Signed by: dbo
GPG Key ID: 4F63DB96D45AA9C6
1 changed files with 44 additions and 56 deletions

View File

@ -27,7 +27,7 @@
;; Utilities ;; Utilities
(defun timeline-tools-map-clock-lines-and-entries (clockline-fn headline-fn) (defun timeline-tools-map-clocklines (clockline-fn headline-fn)
"Iterate point over all clocklines and headlines of the current buffer. "Iterate point over all clocklines and headlines of the current buffer.
For each clockline, call CLOCKLINE-FN with the starting and For each clockline, call CLOCKLINE-FN with the starting and
@ -53,11 +53,39 @@ region will be traversed."
(save-mark-and-excursion (save-mark-and-excursion
(funcall headline-fn))))))))) (funcall headline-fn)))))))))
(defun timeline-tools-get-headline (marker)
"Get headline of task at MARKER."
(assert (markerp marker))
(save-match-data
(let* ((heading (save-mark-and-excursion
(with-current-buffer (marker-buffer marker)
(goto-char (marker-position marker))
(thing-at-point 'line t)))))
(string-match (format "^\\(\\*+\\)\\(?: +%s\\)?\\(?: %s\\)? +\\(.*?\\)[ \t]*\\(?::\\(?:[A-Za-z_]+:\\)+\\)?$"
(regexp-opt org-todo-keywords-1)
org-priority-regexp)
heading)
(match-string 4 heading))))
(defun timeline-tools-insert-clockline (time-1 time-2)
"Insert new clock line from TIME-1 to TIME-2.
Insertion will be done at the beginning of the current line.
TIME-1 and TIME-2 must be given in a format understandable by
`format-time-string, which see. Saves mark and point."
(let ((timestamp-format (concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]")))
(save-mark-and-excursion
(beginning-of-line)
(indent-according-to-mode)
(insert "CLOCK: ")
(insert (format-time-string timestamp-format time-1))
(insert "--")
(insert (format-time-string timestamp-format time-2))
(org-clock-update-time-maybe))))
;; Reporting ;; Reporting
;; All of what follows should be available in org-mode somewhere, but doing it
;; myself was more fun :)
;; XXX: Find actual org-mode functions that do the stuff we are doing here ;; XXX: Find actual org-mode functions that do the stuff we are doing here
(defun timeline-tools-clocklines-in-range (tstart tend) (defun timeline-tools-clocklines-in-range (tstart tend)
@ -84,7 +112,7 @@ always true that TSTART ≤ END ≤ TEND or TSTART ≤ START ≤ TEND."
((consp tend) (float-time tend)) ((consp tend) (float-time tend))
(t tend))) (t tend)))
task-clock-times times) task-clock-times times)
(timeline-tools-map-clock-lines-and-entries (timeline-tools-map-clocklines
;; when on clock line, collect times ;; when on clock line, collect times
#'(lambda (start end) #'(lambda (start end)
(let* ((ts (float-time (let* ((ts (float-time
@ -111,7 +139,7 @@ always true that TSTART ≤ END ≤ TEND or TSTART ≤ START ≤ TEND."
(setq times nil)))) (setq times nil))))
task-clock-times))) task-clock-times)))
(defun timeline-tools-timeline-in-range (tstart tend &optional files) (defun timeline-tools-timeline (tstart tend &optional files)
"Return list of clocked times between TSTART and TEND from FILES. "Return list of clocked times between TSTART and TEND from FILES.
Each element in this list is of the form Each element in this list is of the form
@ -182,20 +210,7 @@ Resulting gaps are distributed evenly among adjacent slots."
(setf (first entry-2) middle))))) (setf (first entry-2) middle)))))
new-timeline)) new-timeline))
(defun timeline-tools-get-headline (marker) ;;;###autoload
"Get headline of task at MARKER."
(assert (markerp marker))
(save-match-data
(let* ((heading (save-mark-and-excursion
(with-current-buffer (marker-buffer marker)
(goto-char (marker-position marker))
(thing-at-point 'line t)))))
(string-match (format "^\\(\\*+\\)\\(?: +%s\\)?\\(?: %s\\)? +\\(.*?\\)[ \t]*\\(?::\\(?:[A-Za-z_]+:\\)+\\)?$"
(regexp-opt org-todo-keywords-1)
org-priority-regexp)
heading)
(match-string 4 heading))))
(defun timeline-tools-format-timeline (tstart tend &optional files) (defun timeline-tools-format-timeline (tstart tend &optional files)
"Display timeline of tasks between TSTART and TEND from FILES. "Display timeline of tasks between TSTART and TEND from FILES.
@ -205,7 +220,7 @@ When called interactively, START and END are queried with
`org-read-date." `org-read-date."
(interactive (list (org-read-date nil nil nil "Start time: ") (interactive (list (org-read-date nil nil nil "Start time: ")
(org-read-date nil nil nil "End time: "))) (org-read-date nil nil nil "End time: ")))
(let ((timeline (->> (timeline-tools-timeline-in-range tstart tend files) (let ((timeline (->> (timeline-tools-timeline tstart tend files)
(timeline-tools-skip-short-entries (timeline-tools-skip-short-entries
timeline-tools-short-task-threshold) timeline-tools-short-task-threshold)
timeline-tools-cluster-same-category))) timeline-tools-cluster-same-category)))
@ -235,7 +250,8 @@ When called interactively, START and END are queried with
(display-buffer target-buffer) (display-buffer target-buffer)
t))) t)))
(defun timeline-tools-timeline-of-day (date &optional files) ;;;###autoload
(defun timeline-tools-format-timeline-of-day (date &optional files)
"Format timeline of given DATE. "Format timeline of given DATE.
DATE should be a string of the form %Y-%m-%d. When called DATE should be a string of the form %Y-%m-%d. When called
@ -251,38 +267,6 @@ ending at 23:61. When not given, FILES defaults to
;;; Manipulating Clock Lines ;;; Manipulating Clock Lines
(defun timeline-tools-insert-clockline (time-1 time-2)
"Insert new clock line from TIME-1 to TIME-2.
Insertion will be done at the beginning of the current line.
TIME-1 and TIME-2 must be given in a format understandable by
`format-time-string, which see. Saves mark and point."
(let ((timestamp-format (concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]")))
(save-mark-and-excursion
(beginning-of-line)
(indent-according-to-mode)
(insert "CLOCK: ")
(insert (format-time-string timestamp-format time-1))
(insert "--")
(insert (format-time-string timestamp-format time-2))
(org-clock-update-time-maybe))))
(defun timeline-tools-insert-clockline-to-current-task (starting-time ending-time)
;; XXX: this function has a similar name to the next one, but does something
;; different
"Add clock line from STARTING-TIME to ENDING-TIME to task under point."
(interactive
(list (org-read-date 4 'totime nil
"Start:" (current-time) nil t)
(org-read-date 4 'totime nil
"End:" (current-time) nil t)))
(if (not (eq major-mode 'org-mode))
(user-error "Must be in org mode")
(save-mark-and-excursion
(org-clock-find-position nil)
(open-line 1)
(timeline-tools-insert-clockline starting-time ending-time))))
(defun timeline-tools-add-clockline-to-marker (target-marker start end) (defun timeline-tools-add-clockline-to-marker (target-marker start end)
"Add clock line to task under TARGET-MARKER from START to END. "Add clock line to task under TARGET-MARKER from START to END.
@ -295,7 +279,7 @@ the clock line is to be added to."
(let ((new-start (float-time start)) (let ((new-start (float-time start))
(new-end (float-time end))) (new-end (float-time end)))
(with-current-buffer (marker-buffer target-marker) (with-current-buffer (marker-buffer target-marker)
(timeline-tools-map-clock-lines-and-entries (timeline-tools-map-clocklines
(lambda (timestamp-1 timestamp-2) (lambda (timestamp-1 timestamp-2)
(let ((current-start (float-time (let ((current-start (float-time
(apply #'encode-time (apply #'encode-time
@ -334,7 +318,9 @@ the clock line is to be added to."
;; Finally add the new clock line ;; Finally add the new clock line
(org-with-point-at target-marker (org-with-point-at target-marker
(timeline-tools-insert-clockline-to-current-task new-start new-end)))) (org-clock-find-position nil)
(open-line 1)
(timeline-tools-insert-clockline new-start new-end))))
(defun timeline-tools-clocklines-of-task (marker) (defun timeline-tools-clocklines-of-task (marker)
"Return list of all clock lines of task under MARKER. "Return list of all clock lines of task under MARKER.
@ -351,7 +337,7 @@ reversed of what it is in the subtree of MARKER."
(save-mark-and-excursion (save-mark-and-excursion
(org-with-point-at marker (org-with-point-at marker
(org-narrow-to-subtree) (org-narrow-to-subtree)
(timeline-tools-map-clock-lines-and-entries (timeline-tools-map-clocklines
(lambda (start end) (lambda (start end)
(push (cons (org-time-string-to-seconds start) (push (cons (org-time-string-to-seconds start)
(org-time-string-to-seconds end)) (org-time-string-to-seconds end))
@ -380,5 +366,7 @@ of TARGET-ID accordingly."
(timeline-tools-add-clockline-to-marker target-marker (timeline-tools-add-clockline-to-marker target-marker
(car clock-line) (cdr clock-line))))) (car clock-line) (cdr clock-line)))))
;; XXX: This needs some autoloadable frontend
(provide 'timeline-tools) (provide 'timeline-tools)
;;; timeline-tools.el ends here ;;; timeline-tools.el ends here