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:
parent
52fd747983
commit
366254217a
|
@ -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
|
||||
this heading."
|
||||
(interactive "P")
|
||||
(if find-done
|
||||
(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)
|
||||
(tr-org-todo-kwd-alist org-todo-kwd-alist)
|
||||
(tr-org-done-keywords org-done-keywords)
|
||||
(tr-org-todo-regexp org-todo-regexp)
|
||||
(tr-org-todo-line-regexp org-todo-line-regexp)
|
||||
(tr-org-odd-levels-only org-odd-levels-only)
|
||||
(this-buffer (current-buffer))
|
||||
;; start of variables that will be used for saving context
|
||||
;; The compiler complains about them - keep them anyway!
|
||||
(file (abbreviate-file-name (buffer-file-name)))
|
||||
(olpath (mapconcat 'identity (org-get-outline-path) "/"))
|
||||
(time (format-time-string
|
||||
(substring (cdr org-time-stamp-formats) 1 -1)
|
||||
(current-time)))
|
||||
category todo priority ltags itags atags
|
||||
;; 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)
|
||||
afile (org-extract-archive-file location)
|
||||
heading (org-extract-archive-heading location)
|
||||
infile-p (equal file (abbreviate-file-name afile)))
|
||||
(unless afile
|
||||
(error "Invalid `org-archive-location'"))
|
||||
|
||||
(if (> (length afile) 0)
|
||||
(setq newfile-p (not (file-exists-p afile))
|
||||
visiting (find-buffer-visiting afile)
|
||||
buffer (or visiting (find-file-noselect afile)))
|
||||
(setq buffer (current-buffer)))
|
||||
(unless buffer
|
||||
(error "Cannot access file \"%s\"" afile))
|
||||
(if (and (> (length heading) 0)
|
||||
(string-match "^\\*+" heading))
|
||||
(setq level (match-end 0))
|
||||
(setq heading nil level 0))
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
;; Get context information that will be lost by moving the tree
|
||||
(setq category (org-get-category nil 'force-refresh)
|
||||
todo (and (looking-at org-todo-line-regexp)
|
||||
(match-string 2))
|
||||
priority (org-get-priority
|
||||
(if (match-end 3) (match-string 3) ""))
|
||||
ltags (org-get-tags)
|
||||
itags (org-delete-all ltags (org-get-tags-at))
|
||||
atags (org-get-tags-at))
|
||||
(setq ltags (mapconcat 'identity ltags " ")
|
||||
itags (mapconcat 'identity itags " "))
|
||||
;; We first only copy, in case something goes wrong
|
||||
;; we need to protect `this-command', to avoid kill-region sets it,
|
||||
;; which would lead to duplication of subtrees
|
||||
(let (this-command) (org-copy-subtree 1 nil t))
|
||||
(set-buffer buffer)
|
||||
;; Enforce org-mode for the archive buffer
|
||||
(if (not (org-mode-p))
|
||||
;; Force the mode for future visits.
|
||||
(let ((org-insert-mode-line-in-empty-file t)
|
||||
(org-inhibit-startup t))
|
||||
(call-interactively 'org-mode)))
|
||||
(when newfile-p
|
||||
(goto-char (point-max))
|
||||
(insert (format "\nArchived entries from file %s\n\n"
|
||||
(buffer-file-name this-buffer))))
|
||||
;; Force the TODO keywords of the original buffer
|
||||
(let ((org-todo-line-regexp tr-org-todo-line-regexp)
|
||||
(org-todo-keywords-1 tr-org-todo-keywords-1)
|
||||
(org-todo-kwd-alist tr-org-todo-kwd-alist)
|
||||
(org-done-keywords tr-org-done-keywords)
|
||||
(org-todo-regexp tr-org-todo-regexp)
|
||||
(org-todo-line-regexp tr-org-todo-line-regexp)
|
||||
(org-odd-levels-only
|
||||
(if (local-variable-p 'org-odd-levels-only (current-buffer))
|
||||
org-odd-levels-only
|
||||
tr-org-odd-levels-only)))
|
||||
(goto-char (point-min))
|
||||
(show-all)
|
||||
(if heading
|
||||
(progn
|
||||
(if (re-search-forward
|
||||
(concat "^" (regexp-quote heading)
|
||||
(org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
|
||||
nil t)
|
||||
(goto-char (match-end 0))
|
||||
;; Heading not found, just insert it at the end
|
||||
(goto-char (point-max))
|
||||
(or (bolp) (insert "\n"))
|
||||
(insert "\n" heading "\n")
|
||||
(end-of-line 0))
|
||||
;; Make the subtree visible
|
||||
(show-subtree)
|
||||
(if org-archive-reversed-order
|
||||
(progn
|
||||
(org-back-to-heading t)
|
||||
(outline-next-heading))
|
||||
(org-end-of-subtree t))
|
||||
(skip-chars-backward " \t\r\n")
|
||||
(and (looking-at "[ \t\r\n]*")
|
||||
(replace-match "\n\n")))
|
||||
;; No specific heading, just go to end of file.
|
||||
(goto-char (point-max)) (insert "\n"))
|
||||
;; Paste
|
||||
(org-paste-subtree (org-get-valid-level level (and heading 1)))
|
||||
;; Shall we append inherited tags?
|
||||
(and itags
|
||||
(or (and (eq org-archive-subtree-add-inherited-tags 'infile)
|
||||
infile-p)
|
||||
(eq org-archive-subtree-add-inherited-tags t))
|
||||
(org-set-tags-to atags))
|
||||
;; Mark the entry as done
|
||||
(when (and org-archive-mark-done
|
||||
(looking-at org-todo-line-regexp)
|
||||
(or (not (match-end 2))
|
||||
(not (member (match-string 2) org-done-keywords))))
|
||||
(let (org-log-done org-todo-log-states)
|
||||
(org-todo
|
||||
(car (or (member org-archive-mark-done org-done-keywords)
|
||||
org-done-keywords)))))
|
||||
|
||||
;; Add the context info
|
||||
(when org-archive-save-context-info
|
||||
(let ((l org-archive-save-context-info) e n v)
|
||||
(while (setq e (pop l))
|
||||
(when (and (setq v (symbol-value e))
|
||||
(stringp v) (string-match "\\S-" 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-buffer))
|
||||
))
|
||||
;; Here we are back in the original buffer. Everything seems to have
|
||||
;; worked. So now cut the tree and finish up.
|
||||
(let (this-command) (org-cut-subtree))
|
||||
(when (featurep 'org-inlinetask)
|
||||
(org-inlinetask-remove-END-maybe))
|
||||
(setq org-markers-to-move nil)
|
||||
(message "Subtree archived %s"
|
||||
(if (eq this-buffer buffer)
|
||||
(concat "under heading: " heading)
|
||||
(concat "in file: " (abbreviate-file-name afile))))))
|
||||
(org-reveal)
|
||||
(if (looking-at "^[ \t]*$")
|
||||
(outline-next-visible-heading 1)))
|
||||
(org-loop-over-siblings-in-active-region
|
||||
(if find-done
|
||||
(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)
|
||||
(tr-org-todo-kwd-alist org-todo-kwd-alist)
|
||||
(tr-org-done-keywords org-done-keywords)
|
||||
(tr-org-todo-regexp org-todo-regexp)
|
||||
(tr-org-todo-line-regexp org-todo-line-regexp)
|
||||
(tr-org-odd-levels-only org-odd-levels-only)
|
||||
(this-buffer (current-buffer))
|
||||
;; start of variables that will be used for saving context
|
||||
;; The compiler complains about them - keep them anyway!
|
||||
(file (abbreviate-file-name (buffer-file-name)))
|
||||
(olpath (mapconcat 'identity (org-get-outline-path) "/"))
|
||||
(time (format-time-string
|
||||
(substring (cdr org-time-stamp-formats) 1 -1)
|
||||
(current-time)))
|
||||
category todo priority ltags itags atags
|
||||
;; 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)
|
||||
afile (org-extract-archive-file location)
|
||||
heading (org-extract-archive-heading location)
|
||||
infile-p (equal file (abbreviate-file-name afile)))
|
||||
(unless afile
|
||||
(error "Invalid `org-archive-location'"))
|
||||
|
||||
(if (> (length afile) 0)
|
||||
(setq newfile-p (not (file-exists-p afile))
|
||||
visiting (find-buffer-visiting afile)
|
||||
buffer (or visiting (find-file-noselect afile)))
|
||||
(setq buffer (current-buffer)))
|
||||
(unless buffer
|
||||
(error "Cannot access file \"%s\"" afile))
|
||||
(if (and (> (length heading) 0)
|
||||
(string-match "^\\*+" heading))
|
||||
(setq level (match-end 0))
|
||||
(setq heading nil level 0))
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
;; Get context information that will be lost by moving the tree
|
||||
(setq category (org-get-category nil 'force-refresh)
|
||||
todo (and (looking-at org-todo-line-regexp)
|
||||
(match-string 2))
|
||||
priority (org-get-priority
|
||||
(if (match-end 3) (match-string 3) ""))
|
||||
ltags (org-get-tags)
|
||||
itags (org-delete-all ltags (org-get-tags-at))
|
||||
atags (org-get-tags-at))
|
||||
(setq ltags (mapconcat 'identity ltags " ")
|
||||
itags (mapconcat 'identity itags " "))
|
||||
;; We first only copy, in case something goes wrong
|
||||
;; we need to protect `this-command', to avoid kill-region sets it,
|
||||
;; which would lead to duplication of subtrees
|
||||
(let (this-command) (org-copy-subtree 1 nil t))
|
||||
(set-buffer buffer)
|
||||
;; Enforce org-mode for the archive buffer
|
||||
(if (not (org-mode-p))
|
||||
;; Force the mode for future visits.
|
||||
(let ((org-insert-mode-line-in-empty-file t)
|
||||
(org-inhibit-startup t))
|
||||
(call-interactively 'org-mode)))
|
||||
(when newfile-p
|
||||
(goto-char (point-max))
|
||||
(insert (format "\nArchived entries from file %s\n\n"
|
||||
(buffer-file-name this-buffer))))
|
||||
;; Force the TODO keywords of the original buffer
|
||||
(let ((org-todo-line-regexp tr-org-todo-line-regexp)
|
||||
(org-todo-keywords-1 tr-org-todo-keywords-1)
|
||||
(org-todo-kwd-alist tr-org-todo-kwd-alist)
|
||||
(org-done-keywords tr-org-done-keywords)
|
||||
(org-todo-regexp tr-org-todo-regexp)
|
||||
(org-todo-line-regexp tr-org-todo-line-regexp)
|
||||
(org-odd-levels-only
|
||||
(if (local-variable-p 'org-odd-levels-only (current-buffer))
|
||||
org-odd-levels-only
|
||||
tr-org-odd-levels-only)))
|
||||
(goto-char (point-min))
|
||||
(show-all)
|
||||
(if heading
|
||||
(progn
|
||||
(if (re-search-forward
|
||||
(concat "^" (regexp-quote heading)
|
||||
(org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
|
||||
nil t)
|
||||
(goto-char (match-end 0))
|
||||
;; Heading not found, just insert it at the end
|
||||
(goto-char (point-max))
|
||||
(or (bolp) (insert "\n"))
|
||||
(insert "\n" heading "\n")
|
||||
(end-of-line 0))
|
||||
;; Make the subtree visible
|
||||
(show-subtree)
|
||||
(if org-archive-reversed-order
|
||||
(progn
|
||||
(org-back-to-heading t)
|
||||
(outline-next-heading))
|
||||
(org-end-of-subtree t))
|
||||
(skip-chars-backward " \t\r\n")
|
||||
(and (looking-at "[ \t\r\n]*")
|
||||
(replace-match "\n\n")))
|
||||
;; No specific heading, just go to end of file.
|
||||
(goto-char (point-max)) (insert "\n"))
|
||||
;; Paste
|
||||
(org-paste-subtree (org-get-valid-level level (and heading 1)))
|
||||
;; Shall we append inherited tags?
|
||||
(and itags
|
||||
(or (and (eq org-archive-subtree-add-inherited-tags 'infile)
|
||||
infile-p)
|
||||
(eq org-archive-subtree-add-inherited-tags t))
|
||||
(org-set-tags-to atags))
|
||||
;; Mark the entry as done
|
||||
(when (and org-archive-mark-done
|
||||
(looking-at org-todo-line-regexp)
|
||||
(or (not (match-end 2))
|
||||
(not (member (match-string 2) org-done-keywords))))
|
||||
(let (org-log-done org-todo-log-states)
|
||||
(org-todo
|
||||
(car (or (member org-archive-mark-done org-done-keywords)
|
||||
org-done-keywords)))))
|
||||
|
||||
;; Add the context info
|
||||
(when org-archive-save-context-info
|
||||
(let ((l org-archive-save-context-info) e n v)
|
||||
(while (setq e (pop l))
|
||||
(when (and (setq v (symbol-value e))
|
||||
(stringp v) (string-match "\\S-" 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-buffer))))
|
||||
;; Here we are back in the original buffer. Everything seems to have
|
||||
;; worked. So now cut the tree and finish up.
|
||||
(let (this-command) (org-cut-subtree))
|
||||
(when (featurep 'org-inlinetask)
|
||||
(org-inlinetask-remove-END-maybe))
|
||||
(setq org-markers-to-move nil)
|
||||
(message "Subtree archived %s"
|
||||
(if (eq this-buffer buffer)
|
||||
(concat "under heading: " heading)
|
||||
(concat "in file: " (abbreviate-file-name afile))))))
|
||||
(org-reveal)
|
||||
(if (looking-at "^[ \t]*$")
|
||||
(outline-next-visible-heading 1))))
|
||||
|
||||
(defun org-archive-to-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
|
||||
sibling does not exist, it will be created at the end of the subtree."
|
||||
(interactive)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let (b e pos leader level)
|
||||
(org-back-to-heading t)
|
||||
(looking-at org-outline-regexp)
|
||||
(setq leader (match-string 0)
|
||||
level (funcall outline-level))
|
||||
(setq pos (point))
|
||||
(condition-case nil
|
||||
(outline-up-heading 1 t)
|
||||
(error (setq e (point-max)) (goto-char (point-min))))
|
||||
(setq b (point))
|
||||
(unless e
|
||||
(condition-case nil
|
||||
(org-end-of-subtree t t)
|
||||
(error (goto-char (point-max))))
|
||||
(setq e (point)))
|
||||
(goto-char b)
|
||||
(unless (re-search-forward
|
||||
(concat "^" (regexp-quote leader)
|
||||
"[ \t]*"
|
||||
org-archive-sibling-heading
|
||||
"[ \t]*:"
|
||||
org-archive-tag ":") e t)
|
||||
(goto-char e)
|
||||
(or (bolp) (newline))
|
||||
(insert leader org-archive-sibling-heading "\n")
|
||||
(beginning-of-line 0)
|
||||
(org-toggle-tag org-archive-tag 'on))
|
||||
(beginning-of-line 1)
|
||||
(if org-archive-reversed-order
|
||||
(outline-next-heading)
|
||||
(org-end-of-subtree t t))
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(let ((this-command this-command)) (org-cut-subtree)))
|
||||
(org-paste-subtree (org-get-valid-level level 1))
|
||||
(org-set-property
|
||||
"ARCHIVE_TIME"
|
||||
(format-time-string
|
||||
(substring (cdr org-time-stamp-formats) 1 -1)
|
||||
(current-time)))
|
||||
(outline-up-heading 1 t)
|
||||
(hide-subtree)
|
||||
(org-cycle-show-empty-lines 'folded)
|
||||
(goto-char pos)))
|
||||
(org-reveal)
|
||||
(if (looking-at "^[ \t]*$")
|
||||
(outline-next-visible-heading 1)))
|
||||
(org-loop-over-siblings-in-active-region
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let (b e pos leader level)
|
||||
(org-back-to-heading t)
|
||||
(looking-at outline-regexp)
|
||||
(setq leader (match-string 0)
|
||||
level (funcall outline-level))
|
||||
(setq pos (point))
|
||||
(condition-case nil
|
||||
(outline-up-heading 1 t)
|
||||
(error (setq e (point-max)) (goto-char (point-min))))
|
||||
(setq b (point))
|
||||
(unless e
|
||||
(condition-case nil
|
||||
(org-end-of-subtree t t)
|
||||
(error (goto-char (point-max))))
|
||||
(setq e (point)))
|
||||
(goto-char b)
|
||||
(unless (re-search-forward
|
||||
(concat "^" (regexp-quote leader)
|
||||
"[ \t]*"
|
||||
org-archive-sibling-heading
|
||||
"[ \t]*:"
|
||||
org-archive-tag ":") e t)
|
||||
(goto-char e)
|
||||
(or (bolp) (newline))
|
||||
(insert leader org-archive-sibling-heading "\n")
|
||||
(beginning-of-line 0)
|
||||
(org-toggle-tag org-archive-tag 'on))
|
||||
(beginning-of-line 1)
|
||||
(if org-archive-reversed-order
|
||||
(outline-next-heading)
|
||||
(org-end-of-subtree t t))
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(let ((this-command this-command)) (org-cut-subtree)))
|
||||
(org-paste-subtree (org-get-valid-level level 1))
|
||||
(org-set-property
|
||||
"ARCHIVE_TIME"
|
||||
(format-time-string
|
||||
(substring (cdr org-time-stamp-formats) 1 -1)
|
||||
(current-time)))
|
||||
(outline-up-heading 1 t)
|
||||
(hide-subtree)
|
||||
(org-cycle-show-empty-lines 'folded)
|
||||
(goto-char pos)))
|
||||
(org-reveal)
|
||||
(if (looking-at "^[ \t]*$")
|
||||
(outline-next-visible-heading 1))))
|
||||
|
||||
(defun org-archive-all-done (&optional tag)
|
||||
"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
|
||||
the children that do not contain any open TODO items."
|
||||
(interactive "P")
|
||||
(if find-done
|
||||
(org-archive-all-done 'tag)
|
||||
(let (set)
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(setq set (org-toggle-tag org-archive-tag))
|
||||
(when set (hide-subtree)))
|
||||
(and set (beginning-of-line 1))
|
||||
(message "Subtree %s" (if set "archived" "unarchived")))))
|
||||
(org-loop-over-siblings-in-active-region
|
||||
(if find-done
|
||||
(org-archive-all-done 'tag)
|
||||
(let (set)
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(setq set (org-toggle-tag org-archive-tag))
|
||||
(when set (hide-subtree)))
|
||||
(and set (beginning-of-line 1))
|
||||
(message "Subtree %s" (if set "archived" "unarchived"))))))
|
||||
|
||||
(defun org-archive-set-tag ()
|
||||
"Set the ARCHIVE tag."
|
||||
|
|
|
@ -367,6 +367,26 @@ The number of levels is controlled by `org-inlinetask-min-level'"
|
|||
(format-seconds string 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)
|
||||
|
||||
;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668
|
||||
|
|
148
lisp/org.el
148
lisp/org.el
|
@ -1971,12 +1971,22 @@ heading."
|
|||
:group 'org-time)
|
||||
|
||||
(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))
|
||||
"The available interpretation symbols for customizing `org-todo-keywords'.
|
||||
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"))
|
||||
"List of TODO entry keyword sequences and their interpretation.
|
||||
\\<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
|
||||
scheduling will use the corresponding date."
|
||||
(interactive "P")
|
||||
(let* ((old-date (org-entry-get nil "DEADLINE"))
|
||||
(repeater (and old-date
|
||||
(string-match
|
||||
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
|
||||
old-date)
|
||||
(match-string 1 old-date))))
|
||||
(if remove
|
||||
(progn
|
||||
(when (and old-date org-log-redeadline)
|
||||
(org-add-log-setup 'deldeadline nil old-date 'findpos
|
||||
org-log-redeadline))
|
||||
(org-remove-timestamp-with-keyword org-deadline-string)
|
||||
(message "Item no longer has a deadline."))
|
||||
(org-add-planning-info 'deadline time 'closed)
|
||||
(when (and old-date org-log-redeadline
|
||||
(not (equal old-date
|
||||
(substring org-last-inserted-timestamp 1 -1))))
|
||||
(org-add-log-setup 'redeadline nil old-date 'findpos
|
||||
org-log-redeadline))
|
||||
(when repeater
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(when (re-search-forward (concat org-deadline-string " "
|
||||
org-last-inserted-timestamp)
|
||||
(save-excursion
|
||||
(outline-next-heading) (point)) t)
|
||||
(goto-char (1- (match-end 0)))
|
||||
(insert " " repeater)
|
||||
(setq org-last-inserted-timestamp
|
||||
(concat (substring org-last-inserted-timestamp 0 -1)
|
||||
" " repeater
|
||||
(substring org-last-inserted-timestamp -1))))))
|
||||
(message "Deadline on %s" org-last-inserted-timestamp))))
|
||||
(org-loop-over-siblings-in-active-region
|
||||
(let* ((old-date (org-entry-get nil "DEADLINE"))
|
||||
(repeater (and old-date
|
||||
(string-match
|
||||
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
|
||||
old-date)
|
||||
(match-string 1 old-date))))
|
||||
(if remove
|
||||
(progn
|
||||
(when (and old-date org-log-redeadline)
|
||||
(org-add-log-setup 'deldeadline nil old-date 'findpos
|
||||
org-log-redeadline))
|
||||
(org-remove-timestamp-with-keyword org-deadline-string)
|
||||
(message "Item no longer has a deadline."))
|
||||
(org-add-planning-info 'deadline time 'closed)
|
||||
(when (and old-date org-log-redeadline
|
||||
(not (equal old-date
|
||||
(substring org-last-inserted-timestamp 1 -1))))
|
||||
(org-add-log-setup 'redeadline nil old-date 'findpos
|
||||
org-log-redeadline))
|
||||
(when repeater
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(when (re-search-forward (concat org-deadline-string " "
|
||||
org-last-inserted-timestamp)
|
||||
(save-excursion
|
||||
(outline-next-heading) (point)) t)
|
||||
(goto-char (1- (match-end 0)))
|
||||
(insert " " repeater)
|
||||
(setq org-last-inserted-timestamp
|
||||
(concat (substring org-last-inserted-timestamp 0 -1)
|
||||
" " repeater
|
||||
(substring org-last-inserted-timestamp -1))))))
|
||||
(message "Deadline on %s" org-last-inserted-timestamp)))))
|
||||
|
||||
(defun org-schedule (&optional remove time)
|
||||
"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
|
||||
scheduling will use the corresponding date."
|
||||
(interactive "P")
|
||||
(let* ((old-date (org-entry-get nil "SCHEDULED"))
|
||||
(repeater (and old-date
|
||||
(string-match
|
||||
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
|
||||
old-date)
|
||||
(match-string 1 old-date))))
|
||||
(if remove
|
||||
(progn
|
||||
(when (and old-date org-log-reschedule)
|
||||
(org-add-log-setup 'delschedule nil old-date 'findpos
|
||||
org-log-reschedule))
|
||||
(org-remove-timestamp-with-keyword org-scheduled-string)
|
||||
(message "Item is no longer scheduled."))
|
||||
(org-add-planning-info 'scheduled time 'closed)
|
||||
(when (and old-date org-log-reschedule
|
||||
(not (equal old-date
|
||||
(substring org-last-inserted-timestamp 1 -1))))
|
||||
(org-add-log-setup 'reschedule nil old-date 'findpos
|
||||
org-log-reschedule))
|
||||
(when repeater
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(when (re-search-forward (concat org-scheduled-string " "
|
||||
org-last-inserted-timestamp)
|
||||
(save-excursion
|
||||
(outline-next-heading) (point)) t)
|
||||
(goto-char (1- (match-end 0)))
|
||||
(insert " " repeater)
|
||||
(setq org-last-inserted-timestamp
|
||||
(concat (substring org-last-inserted-timestamp 0 -1)
|
||||
" " repeater
|
||||
(substring org-last-inserted-timestamp -1))))))
|
||||
(message "Scheduled to %s" org-last-inserted-timestamp))))
|
||||
(org-loop-over-siblings-in-active-region
|
||||
(let* ((old-date (org-entry-get nil "SCHEDULED"))
|
||||
(repeater (and old-date
|
||||
(string-match
|
||||
"\\([.+-]+[0-9]+[dwmy]\\(?:[/ ][-+]?[0-9]+[dwmy]\\)?\\) ?"
|
||||
old-date)
|
||||
(match-string 1 old-date))))
|
||||
(if remove
|
||||
(progn
|
||||
(when (and old-date org-log-reschedule)
|
||||
(org-add-log-setup 'delschedule nil old-date 'findpos
|
||||
org-log-reschedule))
|
||||
(org-remove-timestamp-with-keyword org-scheduled-string)
|
||||
(message "Item is no longer scheduled."))
|
||||
(org-add-planning-info 'scheduled time 'closed)
|
||||
(when (and old-date org-log-reschedule
|
||||
(not (equal old-date
|
||||
(substring org-last-inserted-timestamp 1 -1))))
|
||||
(org-add-log-setup 'reschedule nil old-date 'findpos
|
||||
org-log-reschedule))
|
||||
(when repeater
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(when (re-search-forward (concat org-scheduled-string " "
|
||||
org-last-inserted-timestamp)
|
||||
(save-excursion
|
||||
(outline-next-heading) (point)) t)
|
||||
(goto-char (1- (match-end 0)))
|
||||
(insert " " repeater)
|
||||
(setq org-last-inserted-timestamp
|
||||
(concat (substring org-last-inserted-timestamp 0 -1)
|
||||
" " repeater
|
||||
(substring org-last-inserted-timestamp -1))))))
|
||||
(message "Scheduled to %s" org-last-inserted-timestamp)))))
|
||||
|
||||
(defun org-get-scheduled-time (pom &optional inherit)
|
||||
"Get the scheduled time as a time tuple, of a format suitable
|
||||
|
|
Loading…
Reference in New Issue