forked from mirrors/org-mode
org-clock: Insert clocks after meta data
* lisp/org-clock.el (org-clock-find-position): Make sure clocks, and possibly drawer containing them, are inserted after planning info and any property drawer.
This commit is contained in:
parent
474fb12911
commit
52b63aed04
|
@ -35,7 +35,8 @@
|
|||
(declare-function calendar-absolute-from-iso "cal-iso" (&optional date))
|
||||
(declare-function notifications-notify "notifications" (&rest params))
|
||||
(declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label))
|
||||
(declare-function org-refresh-properties "org" (dprop tprop))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-table-goto-line "org-table" (n))
|
||||
(defvar org-time-stamp-formats)
|
||||
(defvar org-ts-what)
|
||||
|
@ -1421,87 +1422,98 @@ When FIND-UNCLOSED is non-nil, first check if there is an unclosed clock
|
|||
line and position cursor in that line."
|
||||
(org-back-to-heading t)
|
||||
(catch 'exit
|
||||
(let* ((org-clock-into-drawer (org-clock-into-drawer))
|
||||
(beg (save-excursion
|
||||
(beginning-of-line 2)
|
||||
(or (bolp) (newline))
|
||||
(point)))
|
||||
(end (progn (outline-next-heading) (point)))
|
||||
(re (concat "^[ \t]*" org-clock-string))
|
||||
(cnt 0)
|
||||
(drawer (if (stringp org-clock-into-drawer)
|
||||
org-clock-into-drawer "LOGBOOK"))
|
||||
first last ind-last)
|
||||
(let* ((beg (line-beginning-position 2))
|
||||
(end (save-excursion (outline-next-heading) (point)))
|
||||
(org-clock-into-drawer (org-clock-into-drawer))
|
||||
(drawer (cond
|
||||
((not org-clock-into-drawer) nil)
|
||||
((stringp org-clock-into-drawer) org-clock-into-drawer)
|
||||
(t "LOGBOOK"))))
|
||||
;; Look for a running clock if FIND-UNCLOSED in non-nil.
|
||||
(when find-unclosed
|
||||
(let ((open-clock-re
|
||||
(concat "^[ \t]*"
|
||||
org-clock-string
|
||||
" \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
|
||||
" *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
|
||||
(while (re-search-forward open-clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (and (eq (org-element-type element) 'clock)
|
||||
(eq (org-element-property :status element) 'running))
|
||||
(beginning-of-line)
|
||||
(throw 'exit t))))))
|
||||
;; Look for an existing clock drawer.
|
||||
(when drawer
|
||||
(goto-char beg)
|
||||
(let ((drawer-re (concat "^[ \t]*:" drawer ":[ \t]*$")))
|
||||
(while (re-search-forward drawer-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq (org-element-type element) 'drawer)
|
||||
(let ((cend (org-element-property :contents-end element)))
|
||||
(if (and (not org-log-states-order-reversed) cend)
|
||||
(goto-char cend)
|
||||
(forward-line))
|
||||
(throw 'exit t)))))))
|
||||
(goto-char beg)
|
||||
(when (and find-unclosed
|
||||
(re-search-forward
|
||||
(concat "^[ \t]*" org-clock-string
|
||||
" \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
|
||||
" *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")
|
||||
end t))
|
||||
(beginning-of-line 1)
|
||||
(throw 'exit t))
|
||||
(when (eobp) (newline) (setq end (max (point) end)))
|
||||
(when (re-search-forward (concat "^[ \t]*:" drawer ":") end t)
|
||||
;; we seem to have a CLOCK drawer, so go there.
|
||||
(beginning-of-line 2)
|
||||
(or org-log-states-order-reversed
|
||||
(and (re-search-forward org-property-end-re nil t)
|
||||
(goto-char (match-beginning 0))))
|
||||
(throw 'exit t))
|
||||
;; Lets count the CLOCK lines
|
||||
(goto-char beg)
|
||||
(while (re-search-forward re end t)
|
||||
(setq first (or first (match-beginning 0))
|
||||
last (match-beginning 0)
|
||||
cnt (1+ cnt)))
|
||||
(when (and (integerp org-clock-into-drawer)
|
||||
last
|
||||
(>= (1+ cnt) org-clock-into-drawer))
|
||||
;; Wrap current entries into a new drawer
|
||||
(goto-char last)
|
||||
(setq ind-last (org-get-indentation))
|
||||
(beginning-of-line 2)
|
||||
(if (and (>= (org-get-indentation) ind-last)
|
||||
(org-at-item-p))
|
||||
(when (and (>= (org-get-indentation) ind-last)
|
||||
(org-at-item-p))
|
||||
(let ((struct (org-list-struct)))
|
||||
(goto-char (org-list-get-bottom-point struct)))))
|
||||
(insert ":END:\n")
|
||||
(beginning-of-line 0)
|
||||
(org-indent-line-to ind-last)
|
||||
(goto-char first)
|
||||
(insert ":" drawer ":\n")
|
||||
(beginning-of-line 0)
|
||||
(org-indent-line)
|
||||
(org-flag-drawer t)
|
||||
(beginning-of-line 2)
|
||||
(or org-log-states-order-reversed
|
||||
(and (re-search-forward org-property-end-re nil t)
|
||||
(goto-char (match-beginning 0))))
|
||||
(throw 'exit nil))
|
||||
|
||||
(goto-char beg)
|
||||
(while (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
|
||||
(not (equal (match-string 1) org-clock-string)))
|
||||
;; Planning info, skip to after it
|
||||
(beginning-of-line 2)
|
||||
(or (bolp) (newline)))
|
||||
(when (or (eq org-clock-into-drawer t)
|
||||
(stringp org-clock-into-drawer)
|
||||
(and (integerp org-clock-into-drawer)
|
||||
(< org-clock-into-drawer 2)))
|
||||
(insert ":" drawer ":\n:END:\n")
|
||||
(beginning-of-line -1)
|
||||
(org-indent-line)
|
||||
(org-flag-drawer t)
|
||||
(beginning-of-line 2)
|
||||
(org-indent-line)
|
||||
(beginning-of-line)
|
||||
(or org-log-states-order-reversed
|
||||
(and (re-search-forward org-property-end-re nil t)
|
||||
(goto-char (match-beginning 0))))))))
|
||||
(let ((clock-re (concat "^[ \t]*" org-clock-string))
|
||||
(count 0) positions first)
|
||||
;; Count the CLOCK lines and store their positions.
|
||||
(save-excursion
|
||||
(while (re-search-forward clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq (org-element-type element) 'clock)
|
||||
(setq positions (cons (line-beginning-position) positions)
|
||||
count (1+ count))))))
|
||||
(cond
|
||||
((null positions)
|
||||
;; Skip planning line and property drawer, if any.
|
||||
(when (org-looking-at-p org-planning-line-re) (forward-line))
|
||||
(when (looking-at org-property-drawer-re)
|
||||
(goto-char (match-end 0))
|
||||
(forward-line))
|
||||
(unless (bolp) (insert "\n"))
|
||||
;; Create a new drawer if necessary.
|
||||
(when org-clock-into-drawer
|
||||
(let ((beg (point)))
|
||||
(insert ":" drawer ":\n:END:\n")
|
||||
(org-indent-region beg (point))
|
||||
(goto-char beg)
|
||||
(org-flag-drawer t)
|
||||
(forward-line))))
|
||||
;; When a clock drawer needs to be created because of the
|
||||
;; number of clock items, collect all clocks in the section
|
||||
;; and wrap them within the drawer.
|
||||
((and (wholenump org-clock-into-drawer)
|
||||
(>= (1+ count) org-clock-into-drawer))
|
||||
;; Skip planning line and property drawer, if any.
|
||||
(when (org-looking-at-p org-planning-line-re) (forward-line))
|
||||
(when (looking-at org-property-drawer-re)
|
||||
(goto-char (match-end 0))
|
||||
(forward-line))
|
||||
(let ((beg (point)))
|
||||
(insert
|
||||
(mapconcat
|
||||
(lambda (p)
|
||||
(save-excursion
|
||||
(goto-char p)
|
||||
(org-trim (delete-and-extract-region
|
||||
(save-excursion (skip-chars-backward " \r\t\n")
|
||||
(line-beginning-position 2))
|
||||
(line-beginning-position 2)))))
|
||||
positions "\n")
|
||||
"\n:END:\n")
|
||||
(let ((end (point-marker)))
|
||||
(goto-char beg)
|
||||
(save-excursion (insert ":" drawer ":\n"))
|
||||
(org-flag-drawer t)
|
||||
(org-indent-region (point) end)
|
||||
(forward-line)
|
||||
(unless org-log-states-order-reversed
|
||||
(goto-char end)
|
||||
(beginning-of-line -1))
|
||||
(set-marker end nil))))
|
||||
(org-log-states-order-reversed (goto-char (car (last positions))))
|
||||
(t (goto-char (car positions))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-out (&optional switch-to-state fail-quietly at-time)
|
||||
|
|
Loading…
Reference in New Issue