New feature: allow some commands to loop over siblings.

This commit introduce `org-loop-over-siblings-within-active-region-p'
as a new defcustom that you can turn on (`non-nil') to allow commands
to loop over siblings in the active region.

The list of commands is this:

- org-archive-subtree
- org-archive-to-archive-sibling
- org-toggle-archive-tag
- org-deadline
- org-schedule

When `org-loop-over-siblings-within-active-region-p' is `non-nil' and
you run one of the command above on a region containing several headlines,
then Org will apply the command to each headline.

This can be particularily useful for archiving several headlines, or to
add a deadline or schedule several entries.

* org.el (org-loop-over-siblings-within-active-region-p): New
defcustom so that `org-loop-over-siblings-in-active-region'
can be turned on and off.
(org-deadline, org-schedule): Use the new macro.

* org-macs.el (org-loop-over-siblings-in-active-region): New
macro to let some commands act upon several siblings in the
active region.

* org-archive.el (org-archive-subtree)
(org-archive-to-archive-sibling, org-toggle-archive-tag): Use
`org-loop-over-siblings-in-active-region'.
This commit is contained in:
Bastien Guerry 2011-07-18 10:09:53 +02:00
parent 52fd747983
commit 366254217a
3 changed files with 311 additions and 277 deletions

View File

@ -190,157 +190,157 @@ If the cursor is not at a headline when this command is called, try all level
1 trees. If the cursor is on a headline, only try the direct children of 1 trees. If the cursor is on a headline, only try the direct children of
this heading." this heading."
(interactive "P") (interactive "P")
(if find-done (org-loop-over-siblings-in-active-region
(org-archive-all-done) (if find-done
;; Save all relevant TODO keyword-relatex variables (org-archive-all-done)
;; Save all relevant TODO keyword-relatex variables
(let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
(tr-org-todo-keywords-1 org-todo-keywords-1) (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
(tr-org-todo-kwd-alist org-todo-kwd-alist) (tr-org-todo-keywords-1 org-todo-keywords-1)
(tr-org-done-keywords org-done-keywords) (tr-org-todo-kwd-alist org-todo-kwd-alist)
(tr-org-todo-regexp org-todo-regexp) (tr-org-done-keywords org-done-keywords)
(tr-org-todo-line-regexp org-todo-line-regexp) (tr-org-todo-regexp org-todo-regexp)
(tr-org-odd-levels-only org-odd-levels-only) (tr-org-todo-line-regexp org-todo-line-regexp)
(this-buffer (current-buffer)) (tr-org-odd-levels-only org-odd-levels-only)
;; start of variables that will be used for saving context (this-buffer (current-buffer))
;; The compiler complains about them - keep them anyway! ;; start of variables that will be used for saving context
(file (abbreviate-file-name (buffer-file-name))) ;; The compiler complains about them - keep them anyway!
(olpath (mapconcat 'identity (org-get-outline-path) "/")) (file (abbreviate-file-name (buffer-file-name)))
(time (format-time-string (olpath (mapconcat 'identity (org-get-outline-path) "/"))
(substring (cdr org-time-stamp-formats) 1 -1) (time (format-time-string
(current-time))) (substring (cdr org-time-stamp-formats) 1 -1)
category todo priority ltags itags atags (current-time)))
;; end of variables that will be used for saving context category todo priority ltags itags atags
location afile heading buffer level newfile-p infile-p visiting) ;; end of variables that will be used for saving context
location afile heading buffer level newfile-p infile-p visiting)
;; Find the local archive location
(setq location (org-get-local-archive-location) ;; Find the local archive location
afile (org-extract-archive-file location) (setq location (org-get-local-archive-location)
heading (org-extract-archive-heading location) afile (org-extract-archive-file location)
infile-p (equal file (abbreviate-file-name afile))) heading (org-extract-archive-heading location)
(unless afile infile-p (equal file (abbreviate-file-name afile)))
(error "Invalid `org-archive-location'")) (unless afile
(error "Invalid `org-archive-location'"))
(if (> (length afile) 0)
(setq newfile-p (not (file-exists-p afile)) (if (> (length afile) 0)
visiting (find-buffer-visiting afile) (setq newfile-p (not (file-exists-p afile))
buffer (or visiting (find-file-noselect afile))) visiting (find-buffer-visiting afile)
(setq buffer (current-buffer))) buffer (or visiting (find-file-noselect afile)))
(unless buffer (setq buffer (current-buffer)))
(error "Cannot access file \"%s\"" afile)) (unless buffer
(if (and (> (length heading) 0) (error "Cannot access file \"%s\"" afile))
(string-match "^\\*+" heading)) (if (and (> (length heading) 0)
(setq level (match-end 0)) (string-match "^\\*+" heading))
(setq heading nil level 0)) (setq level (match-end 0))
(save-excursion (setq heading nil level 0))
(org-back-to-heading t) (save-excursion
;; Get context information that will be lost by moving the tree (org-back-to-heading t)
(setq category (org-get-category nil 'force-refresh) ;; Get context information that will be lost by moving the tree
todo (and (looking-at org-todo-line-regexp) (setq category (org-get-category nil 'force-refresh)
(match-string 2)) todo (and (looking-at org-todo-line-regexp)
priority (org-get-priority (match-string 2))
(if (match-end 3) (match-string 3) "")) priority (org-get-priority
ltags (org-get-tags) (if (match-end 3) (match-string 3) ""))
itags (org-delete-all ltags (org-get-tags-at)) ltags (org-get-tags)
atags (org-get-tags-at)) itags (org-delete-all ltags (org-get-tags-at))
(setq ltags (mapconcat 'identity ltags " ") atags (org-get-tags-at))
itags (mapconcat 'identity itags " ")) (setq ltags (mapconcat 'identity ltags " ")
;; We first only copy, in case something goes wrong itags (mapconcat 'identity itags " "))
;; we need to protect `this-command', to avoid kill-region sets it, ;; We first only copy, in case something goes wrong
;; which would lead to duplication of subtrees ;; we need to protect `this-command', to avoid kill-region sets it,
(let (this-command) (org-copy-subtree 1 nil t)) ;; which would lead to duplication of subtrees
(set-buffer buffer) (let (this-command) (org-copy-subtree 1 nil t))
;; Enforce org-mode for the archive buffer (set-buffer buffer)
(if (not (org-mode-p)) ;; Enforce org-mode for the archive buffer
;; Force the mode for future visits. (if (not (org-mode-p))
(let ((org-insert-mode-line-in-empty-file t) ;; Force the mode for future visits.
(org-inhibit-startup t)) (let ((org-insert-mode-line-in-empty-file t)
(call-interactively 'org-mode))) (org-inhibit-startup t))
(when newfile-p (call-interactively 'org-mode)))
(goto-char (point-max)) (when newfile-p
(insert (format "\nArchived entries from file %s\n\n" (goto-char (point-max))
(buffer-file-name this-buffer)))) (insert (format "\nArchived entries from file %s\n\n"
;; Force the TODO keywords of the original buffer (buffer-file-name this-buffer))))
(let ((org-todo-line-regexp tr-org-todo-line-regexp) ;; Force the TODO keywords of the original buffer
(org-todo-keywords-1 tr-org-todo-keywords-1) (let ((org-todo-line-regexp tr-org-todo-line-regexp)
(org-todo-kwd-alist tr-org-todo-kwd-alist) (org-todo-keywords-1 tr-org-todo-keywords-1)
(org-done-keywords tr-org-done-keywords) (org-todo-kwd-alist tr-org-todo-kwd-alist)
(org-todo-regexp tr-org-todo-regexp) (org-done-keywords tr-org-done-keywords)
(org-todo-line-regexp tr-org-todo-line-regexp) (org-todo-regexp tr-org-todo-regexp)
(org-odd-levels-only (org-todo-line-regexp tr-org-todo-line-regexp)
(if (local-variable-p 'org-odd-levels-only (current-buffer)) (org-odd-levels-only
org-odd-levels-only (if (local-variable-p 'org-odd-levels-only (current-buffer))
tr-org-odd-levels-only))) org-odd-levels-only
(goto-char (point-min)) tr-org-odd-levels-only)))
(show-all) (goto-char (point-min))
(if heading (show-all)
(progn (if heading
(if (re-search-forward (progn
(concat "^" (regexp-quote heading) (if (re-search-forward
(org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)")) (concat "^" (regexp-quote heading)
nil t) (org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
(goto-char (match-end 0)) nil t)
;; Heading not found, just insert it at the end (goto-char (match-end 0))
(goto-char (point-max)) ;; Heading not found, just insert it at the end
(or (bolp) (insert "\n")) (goto-char (point-max))
(insert "\n" heading "\n") (or (bolp) (insert "\n"))
(end-of-line 0)) (insert "\n" heading "\n")
;; Make the subtree visible (end-of-line 0))
(show-subtree) ;; Make the subtree visible
(if org-archive-reversed-order (show-subtree)
(progn (if org-archive-reversed-order
(org-back-to-heading t) (progn
(outline-next-heading)) (org-back-to-heading t)
(org-end-of-subtree t)) (outline-next-heading))
(skip-chars-backward " \t\r\n") (org-end-of-subtree t))
(and (looking-at "[ \t\r\n]*") (skip-chars-backward " \t\r\n")
(replace-match "\n\n"))) (and (looking-at "[ \t\r\n]*")
;; No specific heading, just go to end of file. (replace-match "\n\n")))
(goto-char (point-max)) (insert "\n")) ;; No specific heading, just go to end of file.
;; Paste (goto-char (point-max)) (insert "\n"))
(org-paste-subtree (org-get-valid-level level (and heading 1))) ;; Paste
;; Shall we append inherited tags? (org-paste-subtree (org-get-valid-level level (and heading 1)))
(and itags ;; Shall we append inherited tags?
(or (and (eq org-archive-subtree-add-inherited-tags 'infile) (and itags
infile-p) (or (and (eq org-archive-subtree-add-inherited-tags 'infile)
(eq org-archive-subtree-add-inherited-tags t)) infile-p)
(org-set-tags-to atags)) (eq org-archive-subtree-add-inherited-tags t))
;; Mark the entry as done (org-set-tags-to atags))
(when (and org-archive-mark-done ;; Mark the entry as done
(looking-at org-todo-line-regexp) (when (and org-archive-mark-done
(or (not (match-end 2)) (looking-at org-todo-line-regexp)
(not (member (match-string 2) org-done-keywords)))) (or (not (match-end 2))
(let (org-log-done org-todo-log-states) (not (member (match-string 2) org-done-keywords))))
(org-todo (let (org-log-done org-todo-log-states)
(car (or (member org-archive-mark-done org-done-keywords) (org-todo
org-done-keywords))))) (car (or (member org-archive-mark-done org-done-keywords)
org-done-keywords)))))
;; Add the context info
(when org-archive-save-context-info ;; Add the context info
(let ((l org-archive-save-context-info) e n v) (when org-archive-save-context-info
(while (setq e (pop l)) (let ((l org-archive-save-context-info) e n v)
(when (and (setq v (symbol-value e)) (while (setq e (pop l))
(stringp v) (string-match "\\S-" v)) (when (and (setq v (symbol-value e))
(setq n (concat "ARCHIVE_" (upcase (symbol-name e)))) (stringp v) (string-match "\\S-" v))
(org-entry-put (point) n v))))) (setq n (concat "ARCHIVE_" (upcase (symbol-name e))))
(org-entry-put (point) n v)))))
;; Save and kill the buffer, if it is not the same buffer.
(when (not (eq this-buffer buffer)) ;; Save and kill the buffer, if it is not the same buffer.
(save-buffer)) (when (not (eq this-buffer buffer))
)) (save-buffer))))
;; Here we are back in the original buffer. Everything seems to have ;; Here we are back in the original buffer. Everything seems to have
;; worked. So now cut the tree and finish up. ;; worked. So now cut the tree and finish up.
(let (this-command) (org-cut-subtree)) (let (this-command) (org-cut-subtree))
(when (featurep 'org-inlinetask) (when (featurep 'org-inlinetask)
(org-inlinetask-remove-END-maybe)) (org-inlinetask-remove-END-maybe))
(setq org-markers-to-move nil) (setq org-markers-to-move nil)
(message "Subtree archived %s" (message "Subtree archived %s"
(if (eq this-buffer buffer) (if (eq this-buffer buffer)
(concat "under heading: " heading) (concat "under heading: " heading)
(concat "in file: " (abbreviate-file-name afile)))))) (concat "in file: " (abbreviate-file-name afile))))))
(org-reveal) (org-reveal)
(if (looking-at "^[ \t]*$") (if (looking-at "^[ \t]*$")
(outline-next-visible-heading 1))) (outline-next-visible-heading 1))))
(defun org-archive-to-archive-sibling () (defun org-archive-to-archive-sibling ()
"Archive the current heading by moving it under the archive sibling. "Archive the current heading by moving it under the archive sibling.
@ -348,55 +348,56 @@ The archive sibling is a sibling of the heading with the heading name
`org-archive-sibling-heading' and an `org-archive-tag' tag. If this `org-archive-sibling-heading' and an `org-archive-tag' tag. If this
sibling does not exist, it will be created at the end of the subtree." sibling does not exist, it will be created at the end of the subtree."
(interactive) (interactive)
(save-restriction (org-loop-over-siblings-in-active-region
(widen) (save-restriction
(let (b e pos leader level) (widen)
(org-back-to-heading t) (let (b e pos leader level)
(looking-at org-outline-regexp) (org-back-to-heading t)
(setq leader (match-string 0) (looking-at outline-regexp)
level (funcall outline-level)) (setq leader (match-string 0)
(setq pos (point)) level (funcall outline-level))
(condition-case nil (setq pos (point))
(outline-up-heading 1 t) (condition-case nil
(error (setq e (point-max)) (goto-char (point-min)))) (outline-up-heading 1 t)
(setq b (point)) (error (setq e (point-max)) (goto-char (point-min))))
(unless e (setq b (point))
(condition-case nil (unless e
(org-end-of-subtree t t) (condition-case nil
(error (goto-char (point-max)))) (org-end-of-subtree t t)
(setq e (point))) (error (goto-char (point-max))))
(goto-char b) (setq e (point)))
(unless (re-search-forward (goto-char b)
(concat "^" (regexp-quote leader) (unless (re-search-forward
"[ \t]*" (concat "^" (regexp-quote leader)
org-archive-sibling-heading "[ \t]*"
"[ \t]*:" org-archive-sibling-heading
org-archive-tag ":") e t) "[ \t]*:"
(goto-char e) org-archive-tag ":") e t)
(or (bolp) (newline)) (goto-char e)
(insert leader org-archive-sibling-heading "\n") (or (bolp) (newline))
(beginning-of-line 0) (insert leader org-archive-sibling-heading "\n")
(org-toggle-tag org-archive-tag 'on)) (beginning-of-line 0)
(beginning-of-line 1) (org-toggle-tag org-archive-tag 'on))
(if org-archive-reversed-order (beginning-of-line 1)
(outline-next-heading) (if org-archive-reversed-order
(org-end-of-subtree t t)) (outline-next-heading)
(save-excursion (org-end-of-subtree t t))
(goto-char pos) (save-excursion
(let ((this-command this-command)) (org-cut-subtree))) (goto-char pos)
(org-paste-subtree (org-get-valid-level level 1)) (let ((this-command this-command)) (org-cut-subtree)))
(org-set-property (org-paste-subtree (org-get-valid-level level 1))
"ARCHIVE_TIME" (org-set-property
(format-time-string "ARCHIVE_TIME"
(substring (cdr org-time-stamp-formats) 1 -1) (format-time-string
(current-time))) (substring (cdr org-time-stamp-formats) 1 -1)
(outline-up-heading 1 t) (current-time)))
(hide-subtree) (outline-up-heading 1 t)
(org-cycle-show-empty-lines 'folded) (hide-subtree)
(goto-char pos))) (org-cycle-show-empty-lines 'folded)
(org-reveal) (goto-char pos)))
(if (looking-at "^[ \t]*$") (org-reveal)
(outline-next-visible-heading 1))) (if (looking-at "^[ \t]*$")
(outline-next-visible-heading 1))))
(defun org-archive-all-done (&optional tag) (defun org-archive-all-done (&optional tag)
"Archive sublevels of the current tree without open TODO items. "Archive sublevels of the current tree without open TODO items.
@ -447,15 +448,16 @@ When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag."
With prefix ARG, check all children of current headline and offer tagging With prefix ARG, check all children of current headline and offer tagging
the children that do not contain any open TODO items." the children that do not contain any open TODO items."
(interactive "P") (interactive "P")
(if find-done (org-loop-over-siblings-in-active-region
(org-archive-all-done 'tag) (if find-done
(let (set) (org-archive-all-done 'tag)
(save-excursion (let (set)
(org-back-to-heading t) (save-excursion
(setq set (org-toggle-tag org-archive-tag)) (org-back-to-heading t)
(when set (hide-subtree))) (setq set (org-toggle-tag org-archive-tag))
(and set (beginning-of-line 1)) (when set (hide-subtree)))
(message "Subtree %s" (if set "archived" "unarchived"))))) (and set (beginning-of-line 1))
(message "Subtree %s" (if set "archived" "unarchived"))))))
(defun org-archive-set-tag () (defun org-archive-set-tag ()
"Set the ARCHIVE tag." "Set the ARCHIVE tag."

View File

@ -367,6 +367,26 @@ The number of levels is controlled by `org-inlinetask-min-level'"
(format-seconds string seconds) (format-seconds string seconds)
(format-time-string string (seconds-to-time seconds)))) (format-time-string string (seconds-to-time seconds))))
(defmacro org-loop-over-siblings-in-active-region (&rest body)
"Execute BODY on possibly several headlines."
`(if (or (not (org-region-active-p))
(not org-loop-over-siblings-within-active-region-p))
,@body
(save-excursion
(let ((beg (region-beginning))
(end (region-end))
mrkrs mrkr nxt)
(goto-char beg)
(or (org-at-heading-p) (outline-next-heading))
(setq mrkrs (list (set-marker (make-marker) (point))))
(while (and (setq nxt (org-get-next-sibling)) (< nxt end))
(setq mrkrs
(append mrkrs (list (set-marker
(make-marker) (point))))))
(while (setq mrkr (pop mrkrs))
(goto-char mrkr)
,@body)))))
(provide 'org-macs) (provide 'org-macs)
;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668 ;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668

View File

@ -1971,12 +1971,22 @@ heading."
:group 'org-time) :group 'org-time)
(defvar org-todo-interpretation-widgets (defvar org-todo-interpretation-widgets
'( '((:tag "Sequence (cycling hits every state)" sequence)
(:tag "Sequence (cycling hits every state)" sequence)
(:tag "Type (cycling directly to DONE)" type)) (:tag "Type (cycling directly to DONE)" type))
"The available interpretation symbols for customizing `org-todo-keywords'. "The available interpretation symbols for customizing `org-todo-keywords'.
Interested libraries should add to this list.") Interested libraries should add to this list.")
(defcustom org-loop-over-siblings-within-active-region-p nil
"Shall some commands act upon siblings in the active region?
The list of commands is:
- `org-schedule'
- `org-deadline'
- `org-archive-subtree'
- `org-archive-to-archive-sibling'
- `org-archive-set-tag'"
:group 'org-todo
:group 'org-archive)
(defcustom org-todo-keywords '((sequence "TODO" "DONE")) (defcustom org-todo-keywords '((sequence "TODO" "DONE"))
"List of TODO entry keyword sequences and their interpretation. "List of TODO entry keyword sequences and their interpretation.
\\<org-mode-map>This is a list of sequences. \\<org-mode-map>This is a list of sequences.
@ -11664,39 +11674,40 @@ With argument REMOVE, remove any deadline from the item.
When TIME is set, it should be an internal time specification, and the When TIME is set, it should be an internal time specification, and the
scheduling will use the corresponding date." scheduling will use the corresponding date."
(interactive "P") (interactive "P")
(let* ((old-date (org-entry-get nil "DEADLINE")) (org-loop-over-siblings-in-active-region
(repeater (and old-date (let* ((old-date (org-entry-get nil "DEADLINE"))
(string-match (repeater (and old-date
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?" (string-match
old-date) "\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
(match-string 1 old-date)))) old-date)
(if remove (match-string 1 old-date))))
(progn (if remove
(when (and old-date org-log-redeadline) (progn
(org-add-log-setup 'deldeadline nil old-date 'findpos (when (and old-date org-log-redeadline)
org-log-redeadline)) (org-add-log-setup 'deldeadline nil old-date 'findpos
(org-remove-timestamp-with-keyword org-deadline-string) org-log-redeadline))
(message "Item no longer has a deadline.")) (org-remove-timestamp-with-keyword org-deadline-string)
(org-add-planning-info 'deadline time 'closed) (message "Item no longer has a deadline."))
(when (and old-date org-log-redeadline (org-add-planning-info 'deadline time 'closed)
(not (equal old-date (when (and old-date org-log-redeadline
(substring org-last-inserted-timestamp 1 -1)))) (not (equal old-date
(org-add-log-setup 'redeadline nil old-date 'findpos (substring org-last-inserted-timestamp 1 -1))))
org-log-redeadline)) (org-add-log-setup 'redeadline nil old-date 'findpos
(when repeater org-log-redeadline))
(save-excursion (when repeater
(org-back-to-heading t) (save-excursion
(when (re-search-forward (concat org-deadline-string " " (org-back-to-heading t)
org-last-inserted-timestamp) (when (re-search-forward (concat org-deadline-string " "
(save-excursion org-last-inserted-timestamp)
(outline-next-heading) (point)) t) (save-excursion
(goto-char (1- (match-end 0))) (outline-next-heading) (point)) t)
(insert " " repeater) (goto-char (1- (match-end 0)))
(setq org-last-inserted-timestamp (insert " " repeater)
(concat (substring org-last-inserted-timestamp 0 -1) (setq org-last-inserted-timestamp
" " repeater (concat (substring org-last-inserted-timestamp 0 -1)
(substring org-last-inserted-timestamp -1)))))) " " repeater
(message "Deadline on %s" org-last-inserted-timestamp)))) (substring org-last-inserted-timestamp -1))))))
(message "Deadline on %s" org-last-inserted-timestamp)))))
(defun org-schedule (&optional remove time) (defun org-schedule (&optional remove time)
"Insert the SCHEDULED: string with a timestamp to schedule a TODO item. "Insert the SCHEDULED: string with a timestamp to schedule a TODO item.
@ -11704,39 +11715,40 @@ With argument REMOVE, remove any scheduling date from the item.
When TIME is set, it should be an internal time specification, and the When TIME is set, it should be an internal time specification, and the
scheduling will use the corresponding date." scheduling will use the corresponding date."
(interactive "P") (interactive "P")
(let* ((old-date (org-entry-get nil "SCHEDULED")) (org-loop-over-siblings-in-active-region
(repeater (and old-date (let* ((old-date (org-entry-get nil "SCHEDULED"))
(string-match (repeater (and old-date
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?" (string-match
old-date) "\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
(match-string 1 old-date)))) old-date)
(if remove (match-string 1 old-date))))
(progn (if remove
(when (and old-date org-log-reschedule) (progn
(org-add-log-setup 'delschedule nil old-date 'findpos (when (and old-date org-log-reschedule)
org-log-reschedule)) (org-add-log-setup 'delschedule nil old-date 'findpos
(org-remove-timestamp-with-keyword org-scheduled-string) org-log-reschedule))
(message "Item is no longer scheduled.")) (org-remove-timestamp-with-keyword org-scheduled-string)
(org-add-planning-info 'scheduled time 'closed) (message "Item is no longer scheduled."))
(when (and old-date org-log-reschedule (org-add-planning-info 'scheduled time 'closed)
(not (equal old-date (when (and old-date org-log-reschedule
(substring org-last-inserted-timestamp 1 -1)))) (not (equal old-date
(org-add-log-setup 'reschedule nil old-date 'findpos (substring org-last-inserted-timestamp 1 -1))))
org-log-reschedule)) (org-add-log-setup 'reschedule nil old-date 'findpos
(when repeater org-log-reschedule))
(save-excursion (when repeater
(org-back-to-heading t) (save-excursion
(when (re-search-forward (concat org-scheduled-string " " (org-back-to-heading t)
org-last-inserted-timestamp) (when (re-search-forward (concat org-scheduled-string " "
(save-excursion org-last-inserted-timestamp)
(outline-next-heading) (point)) t) (save-excursion
(goto-char (1- (match-end 0))) (outline-next-heading) (point)) t)
(insert " " repeater) (goto-char (1- (match-end 0)))
(setq org-last-inserted-timestamp (insert " " repeater)
(concat (substring org-last-inserted-timestamp 0 -1) (setq org-last-inserted-timestamp
" " repeater (concat (substring org-last-inserted-timestamp 0 -1)
(substring org-last-inserted-timestamp -1)))))) " " repeater
(message "Scheduled to %s" org-last-inserted-timestamp)))) (substring org-last-inserted-timestamp -1))))))
(message "Scheduled to %s" org-last-inserted-timestamp)))))
(defun org-get-scheduled-time (pom &optional inherit) (defun org-get-scheduled-time (pom &optional inherit)
"Get the scheduled time as a time tuple, of a format suitable "Get the scheduled time as a time tuple, of a format suitable