No longer store timeline of current buffer in separate variable

This does not play nicely with undo, because undo won't track changes to local
variables.  Thus, if we every want to have a working undo in timeline buffers,
the timeline needs to be saved as something textual.  Luckily, we already store
each entry of the timeline as a text property in the timeline table, and from
now on we will extract the timeline from there whenever we need it.

Undo is still not working fully yet, there are some oddities that need to be
addressed first.
This commit is contained in:
Daniel - 2020-01-26 20:42:08 +01:00
parent 85cfd25097
commit 619e5bdcae
No known key found for this signature in database
GPG Key ID: 1C7071A75BB72D64
1 changed files with 60 additions and 48 deletions

View File

@ -91,9 +91,6 @@ end date of the timeline."
(defvar timeline-tools--current-files nil (defvar timeline-tools--current-files nil
"Files from which the current timeline has been extracted.") "Files from which the current timeline has been extracted.")
(defvar timeline-tools--current-timeline nil
"Currently displayed timeline in abstract form.")
(defvar timeline-tools-mode-map (defvar timeline-tools-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [remap self-insert-command] 'undefined) (define-key map [remap self-insert-command] 'undefined)
@ -434,10 +431,10 @@ interactively, START and END are queried with `org-read-date."
(setq-local timeline-tools--current-time-start (org-time-string-to-seconds tstart)) (setq-local timeline-tools--current-time-start (org-time-string-to-seconds tstart))
(setq-local timeline-tools--current-time-end (org-time-string-to-seconds tend)) (setq-local timeline-tools--current-time-end (org-time-string-to-seconds tend))
(setq-local timeline-tools--current-files files) (setq-local timeline-tools--current-files files)
(setq-local timeline-tools--current-timeline nil)
(setq-local timeline-tools-time-format timeline-tools-time-format) (setq-local timeline-tools-time-format timeline-tools-time-format)
(setq-local timeline-tools-headline-time-format timeline-tools-headline-time-format) (setq-local timeline-tools-headline-time-format timeline-tools-headline-time-format)
(hl-line-mode) (hl-line-mode)
(buffer-enable-undo)
(timeline-tools-redraw-timeline 'force)) (timeline-tools-redraw-timeline 'force))
(pop-to-buffer target-buffer) (pop-to-buffer target-buffer)
t)) t))
@ -466,45 +463,64 @@ current values of the relevant buffer local variables."
(interactive) (interactive)
(if (not (eq major-mode 'timeline-tools-mode)) (if (not (eq major-mode 'timeline-tools-mode))
(user-error "Not in Timeline buffer") (user-error "Not in Timeline buffer")
(when force (let ((timeline (if force
(setq-local timeline-tools--current-timeline (timeline-tools-transform-timeline
(timeline-tools-transform-timeline (timeline-tools-timeline
(timeline-tools-timeline timeline-tools--current-time-start
timeline-tools--current-time-start timeline-tools--current-time-end
timeline-tools--current-time-end timeline-tools--current-files))
timeline-tools--current-files)))) (timeline-tools--get-timeline-from-buffer))))
(erase-buffer) (erase-buffer)
(insert (format "* Timeline from [%s] to [%s]\n\n" (insert (format "* Timeline from [%s] to [%s]\n\n"
(format-time-string timeline-tools-headline-time-format (format-time-string timeline-tools-headline-time-format
timeline-tools--current-time-start) timeline-tools--current-time-start)
(format-time-string timeline-tools-headline-time-format (format-time-string timeline-tools-headline-time-format
timeline-tools--current-time-end))) timeline-tools--current-time-end)))
(insert "|--|\n") (insert "|--|\n")
(insert "| Category | Start | End | Duration | Task |\n") (insert "| Category | Start | End | Duration | Task |\n")
(let ((last-category nil) (let ((last-category nil)
(current-category nil)) (current-category nil))
(dolist (line timeline-tools--current-timeline) (dolist (line timeline)
(setq current-category (funcall timeline-tools-category-function (setq current-category (funcall timeline-tools-category-function
line line
timeline-tools--current-time-start timeline-tools--current-time-start
timeline-tools--current-time-end)) timeline-tools--current-time-end))
(when (not (equal last-category current-category)) (when (not (equal last-category current-category))
(insert "|--|\n") (insert "|--|\n")
(setq last-category current-category)) (setq last-category current-category))
(insert (insert
(propertize (format "| %s | %s | %s | %s min | %s | \n" (propertize (format "| %s | %s | %s | %s min | %s | \n"
current-category current-category
(timeline-tools-format-entry-time line 'start) (timeline-tools-format-entry-time line 'start)
(timeline-tools-format-entry-time line 'end) (timeline-tools-format-entry-time line 'end)
(timeline-tools-entry-duration line) (timeline-tools-entry-duration line)
(timeline-tools-entry-headline line)) (timeline-tools-entry-headline line))
'marker (timeline-tools-entry-marker line) 'marker (timeline-tools-entry-marker line)
'entry line)))) 'entry line))))
(insert "|--|\n") (insert "|--|\n")
(org-table-align) (org-table-align)
(goto-char (point-min)) (goto-char (point-min))
(timeline-tools-next-line) (timeline-tools-next-line))))
(buffer-enable-undo)))
(defun timeline-tools--get-timeline-from-buffer ()
"Extract current timeline from buffer and return it.
This function expects the individual lines of a timeline to be
text properties under the keyword `entry' in the current buffer,
as it is done by `timeline-tools-redraw-timeline'."
(if (not (eq major-mode 'timeline-tools-mode))
(user-error "Not in Timeline buffer")
(let (timeline)
(save-mark-and-excursion
(goto-char (point-min))
(while (zerop (forward-line))
;; scan line for a text property named `entry'
(while (and (not (eolp))
(not (get-text-property (point) 'entry)))
(forward-char))
;; if not at the end, we have found something … add it
(unless (eolp)
(push (get-text-property (point) 'entry) timeline)))
(nreverse timeline)))))
(defun timeline-tools-reparse-timeline () (defun timeline-tools-reparse-timeline ()
"Parse timeline from files again and redraw current display. "Parse timeline from files again and redraw current display.
@ -564,11 +580,7 @@ Updates category properties before constructing the new timeline."
(let ((entry (get-text-property (point) 'entry))) (let ((entry (get-text-property (point) 'entry)))
(unless entry (unless entry
(user-error "Not on valid row in timeline")) (user-error "Not on valid row in timeline"))
(unless (< 1 (length timeline-tools--current-timeline)) (kill-line)))
(user-error "Cannot delete last line"))
(setq-local timeline-tools--current-timeline
(timeline-tools-transform-timeline
(delq entry timeline-tools--current-timeline)))))
;; the call to `erase-buffer in `timeline-tools-redraw-timeline somehow ;; the call to `erase-buffer in `timeline-tools-redraw-timeline somehow
;; makes `save-mark-and-excursion meaningless; thus we save the number of the ;; makes `save-mark-and-excursion meaningless; thus we save the number of the
;; current line by ourselves ;; current line by ourselves