Compare commits
6 Commits
ff0ea07f53
...
367c8969fc
| Author | SHA1 | Date | |
|---|---|---|---|
| 367c8969fc | |||
| 3c7ea1b987 | |||
| e5818fdb8c | |||
| b80f05d49f | |||
| 9f0a890b1c | |||
| 8068107326 |
@ -106,8 +106,10 @@ end date of the timeline."
|
||||
(define-key map "k" #'timeline-tools-kill-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-swap-line-with-next)
|
||||
(define-key map (kbd "C-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)
|
||||
map))
|
||||
|
||||
@ -468,7 +470,8 @@ archives."
|
||||
|
||||
(defun timeline-tools-redraw-timeline (&optional force)
|
||||
"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
|
||||
current values of the relevant buffer local variables."
|
||||
(interactive)
|
||||
@ -518,38 +521,68 @@ current values of the relevant buffer local variables."
|
||||
(timeline-tools-format-entry-time line 'end)
|
||||
(timeline-tools-entry-duration line)
|
||||
(timeline-tools-entry-headline line))
|
||||
'marker (timeline-tools-entry-marker line)
|
||||
'entry line))))
|
||||
(insert "|--|\n")
|
||||
(org-table-align)
|
||||
(goto-char (point-min))
|
||||
(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 ()
|
||||
"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 (eq major-mode 'timeline-tools-mode)
|
||||
(unless (derived-mode-p 'timeline-tools-mode)
|
||||
(user-error "Not in Timeline buffer"))
|
||||
(beginning-of-line)
|
||||
(let ((point (point)))
|
||||
(when (looking-at "^| ")
|
||||
(forward-line))
|
||||
(unless (re-search-forward "^| " nil 'no-error)
|
||||
(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)))
|
||||
(user-error "No next line")))
|
||||
(beginning-of-line))
|
||||
|
||||
(defun timeline-tools-previous-line ()
|
||||
"Move point to previous line in timetable, if possible."
|
||||
"Move point to previous line in timetable, if possible.
|
||||
|
||||
Otherwise don't move point and error out."
|
||||
(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)
|
||||
(let ((point (point))
|
||||
found)
|
||||
(while (and (setq found (re-search-backward "^| " 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 previous line"))
|
||||
(beginning-of-line)))
|
||||
(user-error "No previous line")))
|
||||
(beginning-of-line))
|
||||
|
||||
(defun timeline-tools--get-timeline-from-buffer ()
|
||||
"Extract current timeline from buffer and return it.
|
||||
@ -582,6 +615,9 @@ Updates category properties before constructing the new timeline."
|
||||
(interactive)
|
||||
(if (not (eq major-mode 'timeline-tools-mode))
|
||||
(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-end (+ 86400 timeline-tools--current-time-end))
|
||||
(timeline-tools-redraw-timeline 'force)))
|
||||
@ -602,12 +638,7 @@ Updates category properties before constructing the new timeline."
|
||||
(interactive)
|
||||
(unless (eq major-mode 'timeline-tools-mode)
|
||||
(user-error "Not in Timeline buffer"))
|
||||
(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"))
|
||||
(let ((marker (timeline-tools-entry-marker (timeline-tools--get-entry-from-point))))
|
||||
(switch-to-buffer (marker-buffer marker))
|
||||
(goto-char marker)
|
||||
(org-reveal)))
|
||||
@ -617,26 +648,92 @@ Updates category properties before constructing the new timeline."
|
||||
(interactive)
|
||||
(unless (eq major-mode 'timeline-tools-mode)
|
||||
(user-error "Not in Timeline buffer"))
|
||||
(save-mark-and-excursion
|
||||
;; get actual entry from headline of line
|
||||
(beginning-of-line)
|
||||
(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
|
||||
|
||||
;; If there's an entry on the current line, delete it and redraw; 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
|
||||
|
||||
(if (timeline-tools--get-entry-from-point) ; barfs if there's no entry
|
||||
(kill-line))
|
||||
|
||||
(let ((linenum (line-number-at-pos (point))))
|
||||
(timeline-tools-redraw-timeline)
|
||||
(goto-char (point-min))
|
||||
(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
|
||||
;;; Manipulating Clocklines in Org Files
|
||||
|
||||
;; XXX: All this needs some autoloadable frontend
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user