Compare commits

..

No commits in common. "367c8969fc8678fe24088f89409031224ec85709" and "ff0ea07f538b37eb615b77894f07eb318cac2e3f" have entirely different histories.

View File

@ -106,10 +106,8 @@ end date of the timeline."
(define-key map "k" #'timeline-tools-kill-line) (define-key map "k" #'timeline-tools-kill-line)
(define-key map (kbd "C-n") #'timeline-tools-next-line) (define-key map (kbd "C-n") #'timeline-tools-next-line)
(define-key map "n" #'timeline-tools-next-line) (define-key map "n" #'timeline-tools-next-line)
(define-key map "N" #'timeline-tools-swap-line-with-next)
(define-key map (kbd "C-p") #'timeline-tools-previous-line) (define-key map (kbd "C-p") #'timeline-tools-previous-line)
(define-key map "p" #'timeline-tools-previous-line) (define-key map "p" #'timeline-tools-previous-line)
(define-key map "P" #'timeline-tools-swap-line-with-previous)
(define-key map "o" #'delete-other-windows) (define-key map "o" #'delete-other-windows)
map)) map))
@ -470,8 +468,7 @@ archives."
(defun timeline-tools-redraw-timeline (&optional force) (defun timeline-tools-redraw-timeline (&optional force)
"Redraw timeline of current buffer. "Redraw timeline of current buffer.
If `force' is non-nil, reparse the timeline using
If FORCE is non-nil, reparse the timeline using
`timeline-tools-timeline' within the time span given by the `timeline-tools-timeline' within the time span given by the
current values of the relevant buffer local variables." current values of the relevant buffer local variables."
(interactive) (interactive)
@ -521,68 +518,38 @@ current values of the relevant buffer local variables."
(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)
'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))))
(defun timeline-tools--get-entry-from-point (&optional noerror)
"Return timeline entry of point when in timeline buffer.
Errors out if there is no entry on the current line, unless
NOERROR is non-nil; in that case, return nil when no text
property could be found (note that this can also happen if point
is outside of the current table)."
(unless (derived-mode-p 'timeline-tools-mode))
(save-mark-and-excursion
(if (not (org-at-table-p))
(if noerror nil (user-error "Not in table"))
(beginning-of-line)
(if (not (looking-at "^| "))
(if noerror nil (user-error "Not on valid row in timeline"))
(org-table-next-field)
(if-let ((entry (get-text-property (point) 'entry)))
entry
(if noerror nil (user-error "Not on valid row in timeline")))))))
(defun timeline-tools-next-line () (defun timeline-tools-next-line ()
"Move point to next line in timetable, if possible. "Move point to next line in timetable, if possible."
Otherwise don't move point and error out."
(interactive)
(unless (derived-mode-p 'timeline-tools-mode)
(user-error "Not in Timeline buffer"))
(let ((point (point))
found)
(end-of-line)
(while (and (setq found (re-search-forward "^| " nil t))
(not (timeline-tools--get-entry-from-point 'noerror))))
;; Check whether we've found something when leaving the while-loop; if not,
;; go back and error out, as promised in the docstring.
(unless found
(goto-char point)
(user-error "No next line")))
(beginning-of-line))
(defun timeline-tools-previous-line ()
"Move point to previous line in timetable, if possible.
Otherwise don't move point and error out."
(interactive) (interactive)
(unless (eq major-mode 'timeline-tools-mode) (unless (eq major-mode 'timeline-tools-mode)
(user-error "Not in Timeline buffer")) (user-error "Not in Timeline buffer"))
(beginning-of-line) (beginning-of-line)
(let ((point (point)) (let ((point (point)))
found) (when (looking-at "^| ")
(while (and (setq found (re-search-backward "^| " nil t)) (forward-line))
(not (timeline-tools--get-entry-from-point 'noerror)))) (unless (re-search-forward "^| " nil 'no-error)
;; Check whether we've found something when leaving the while-loop; if not,
;; go back and error out, as promised in the docstring.
(unless found
(goto-char point) (goto-char point)
(user-error "No previous line"))) (user-error "No next line"))
(beginning-of-line)) (beginning-of-line)))
(defun timeline-tools-previous-line ()
"Move point to previous line in timetable, if possible."
(interactive)
(unless (eq major-mode 'timeline-tools-mode)
(user-error "Not in Timeline buffer"))
(beginning-of-line)
(let ((point (point)))
(unless (re-search-backward "^| " nil 'no-error)
(goto-char point)
(user-error "No previous line"))
(beginning-of-line)))
(defun timeline-tools--get-timeline-from-buffer () (defun timeline-tools--get-timeline-from-buffer ()
"Extract current timeline from buffer and return it. "Extract current timeline from buffer and return it.
@ -615,9 +582,6 @@ Updates category properties before constructing the new timeline."
(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")
;; CAVEAT: this does not work properly when daylight time saving occured.
;; In that case, jump directly to the day you want to display. This is not
;; going to be fixed.
(setq-local timeline-tools--current-time-start (+ 86400 timeline-tools--current-time-start)) (setq-local timeline-tools--current-time-start (+ 86400 timeline-tools--current-time-start))
(setq-local timeline-tools--current-time-end (+ 86400 timeline-tools--current-time-end)) (setq-local timeline-tools--current-time-end (+ 86400 timeline-tools--current-time-end))
(timeline-tools-redraw-timeline 'force))) (timeline-tools-redraw-timeline 'force)))
@ -638,7 +602,12 @@ Updates category properties before constructing the new timeline."
(interactive) (interactive)
(unless (eq major-mode 'timeline-tools-mode) (unless (eq major-mode 'timeline-tools-mode)
(user-error "Not in Timeline buffer")) (user-error "Not in Timeline buffer"))
(let ((marker (timeline-tools-entry-marker (timeline-tools--get-entry-from-point)))) (let ((marker (save-mark-and-excursion
(beginning-of-line)
(org-table-next-field)
(get-text-property (point) 'marker))))
(unless marker
(user-error "Not on headline to jump to"))
(switch-to-buffer (marker-buffer marker)) (switch-to-buffer (marker-buffer marker))
(goto-char marker) (goto-char marker)
(org-reveal))) (org-reveal)))
@ -648,92 +617,26 @@ Updates category properties before constructing the new timeline."
(interactive) (interactive)
(unless (eq major-mode 'timeline-tools-mode) (unless (eq major-mode 'timeline-tools-mode)
(user-error "Not in Timeline buffer")) (user-error "Not in Timeline buffer"))
(save-mark-and-excursion
;; If there's an entry on the current line, delete it and redraw; the call to ;; get actual entry from headline of line
;; `erase-buffer in `timeline-tools-redraw-timeline somehow makes (beginning-of-line)
;; `save-mark-and-excursion meaningless; thus we save the number of the (unless (looking-at "^| ")
(user-error "Not in table"))
(org-table-next-field)
(let ((entry (get-text-property (point) 'entry)))
(unless entry
(user-error "Not on valid row in timeline"))
(kill-line)))
;; the call to `erase-buffer in `timeline-tools-redraw-timeline somehow
;; makes `save-mark-and-excursion meaningless; thus we save the number of the
;; current line by ourselves ;; current line by ourselves
(if (timeline-tools--get-entry-from-point) ; barfs if there's no entry
(kill-line))
(let ((linenum (line-number-at-pos (point)))) (let ((linenum (line-number-at-pos (point))))
(timeline-tools-redraw-timeline) (timeline-tools-redraw-timeline)
(goto-char (point-min)) (goto-char (point-min))
(forward-line (1- linenum)))) (forward-line (1- linenum))))
(defun timeline-tools-swap-line-with-next ()
"Swap the current line with the next line in current timeline.
Durations of the entries are kept, the start and end times are
changed accordingly."
(interactive)
(unless (derived-mode-p 'timeline-tools-mode)
(user-error "Not in Timeline buffer"))
;; The idea is to swap the two entries attached as text properties to the rows
;; and update the start end end times accordingly, and then redraw.
(let (pos-entry-1 pos-entry-2 entry-1 entry-2)
(save-mark-and-excursion
(setq entry-1 (timeline-tools--get-entry-from-point)
pos-entry-1 (point))
(timeline-tools-next-line)
(setq entry-2 (timeline-tools--get-entry-from-point)
pos-entry-2 (point)))
;; Let's create new entries and overwrite the old ones.
(let ((s1 (timeline-tools-entry-start-time entry-1))
(m1 (timeline-tools-entry-marker entry-1))
(s2 (timeline-tools-entry-start-time entry-2))
(e2 (timeline-tools-entry-end-time entry-2))
(m2 (timeline-tools-entry-marker entry-2))
entry-1-new entry-2-new)
(setq entry-1-new (timeline-tools-make-entry s1 (+ s1 (- e2 s2)) m2)
entry-2-new (timeline-tools-make-entry (+ s1 (- e2 s2)) e2 m1))
(save-mark-and-excursion
(goto-char pos-entry-1)
(put-text-property (line-beginning-position)
(line-end-position)
'entry entry-1-new)
(goto-char pos-entry-2)
(put-text-property (line-beginning-position)
(line-end-position)
'entry entry-2-new))
(timeline-tools-redraw-timeline)
;; Stay on line we were previously, by searching for an entry that has
;; the same starting time as `entry-2-new', going there.
;; XXX: problem is that entries may get transformed by functions from
;; `timeline-tools-transform-timeline', so this approach is not correct
;; in general.
(text-property-search-forward 'entry
(timeline-tools-entry-start-time entry-2-new)
#'(lambda (x y)
(equal x (timeline-tools-entry-start-time y)))))))
(defun timeline-tools-swap-line-with-previous ()
"Swap the current line with the previous line in current timeline.
See `timeline-tools-swap-line-with-next' for more details."
(interactive)
(unless (derived-mode-p 'timeline-tools-mode)
(user-error "Not in Timeline buffer"))
;; Go to the previous line and swap those.
(timeline-tools-previous-line)
(timeline-tools-swap-line-with-next)
(timeline-tools-previous-line))
;;; Manipulating Clocklines in Org Files ;;; Manipulating Clocklines
;; XXX: All this needs some autoloadable frontend ;; XXX: All this needs some autoloadable frontend