>From 6315be9e7a83cd9837807c2eb87ed7b3c6b70997 Mon Sep 17 00:00:00 2001
From: Kyle Meyer
Date: Fri, 26 Jun 2015 21:33:34 -0400
Subject: [PATCH] org-add-planning-info: Improve deletion handling
* lisp/org.el (org-add-planning-info): Reset point before each
planning entry search. Clean up extra spaces.
* testing/lisp/test-org.el (test-org/add-planning-info): Add tests.
- Reposition save-excursion call to reset point every dolist
iteration. Otherwise, the order of the entries to be removed
matters, and a call like
(org-add-planning-info nil nil 'scheduled 'deadline)
on
DEADLINE: <2015-06-26 Fri> SCHEDULED: <2015-06-26 Fri>
will fail to remove the deadline entry.
- Delete leading white space even when at the beginning of the line so
that, when org-adapt-indentation is nil, a space is not inserted
when removing the leading planning info entry.
This prevents headings with repeating entries like
SCHEDULED: <2015-06-26 Fri +1w>
from being closed and recycled with an extra space in front of
SCHEDULED.
- Add leading white space to the planning info entry regexp to prevent
leftover white space when removing entries other than the first
entry.
---
lisp/org.el | 35 ++++++-----
testing/lisp/test-org.el | 159 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 178 insertions(+), 16 deletions(-)
diff --git a/lisp/org.el b/lisp/org.el
index 02f5c22..5a7d6d3 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -13478,23 +13478,26 @@ (defun org-add-planning-info (what &optional time &rest remove)
(skip-chars-forward " \t")
;; Check if we have to remove something.
(dolist (type (if what (cons what remove) remove))
- (when (save-excursion
- (re-search-forward
- (case type
- (closed org-closed-time-regexp)
- (deadline org-deadline-time-regexp)
- (scheduled org-scheduled-time-regexp)
- (otherwise (error "Invalid planning type: %s" type)))
- (line-end-position) t))
- (replace-match "")
- (when (looking-at "--+<[^>]+>") (replace-match ""))
- (when (and (not what) (eq type 'closed))
- (save-excursion
- (beginning-of-line)
- (if (looking-at "[ \t]*$")
- (delete-region (point) (1+ (point-at-eol)))))))
+ (save-excursion
+ (when (re-search-forward
+ (concat
+ " *"
+ (case type
+ (closed org-closed-time-regexp)
+ (deadline org-deadline-time-regexp)
+ (scheduled org-scheduled-time-regexp)
+ (otherwise
+ (error "Invalid planning type: %s" type))))
+ (line-end-position) t)
+ (replace-match "")
+ (when (looking-at "--+<[^>]+>") (replace-match ""))
+ (when (and (not what) (eq type 'closed))
+ (save-excursion
+ (beginning-of-line)
+ (if (looking-at "[ \t]*$")
+ (delete-region (point) (1+ (point-at-eol))))))))
;; Remove leading white spaces.
- (when (and (not (bolp)) (looking-at "[ \t]+")) (replace-match ""))))
+ (when (looking-at "[ \t]+") (replace-match ""))))
((not what) (throw 'exit nil)) ; Nothing to do.
(t (insert-before-markers "\n")
(backward-char 1)
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 35905d3..437b594 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -2858,6 +2858,165 @@ (ert-deftest test-org/at-planning-p ()
"* Headline\n*** Inlinetask\n*** END\nDEADLINE: <2014-03-04 tue.>"
(let ((org-inlinetask-min-level 3)) (org-at-planning-p))))))
+(ert-deftest test-org/add-planning-info ()
+ "Test `org-add-planning-info'."
+ ;; Create deadline when `org-adapt-indentation' is non-nil.
+ (should
+ (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "* H\nParagraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Create deadline when `org-adapt-indentation' is nil.
+ (should
+ (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "* H\nParagraph"
+ (let ((org-adapt-indentation nil))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Update deadline when `org-adapt-indentation' is non-nil.
+ (should
+ (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "\
+* H
+ DEADLINE: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Update deadline when `org-adapt-indentation' is nil.
+ (should
+ (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "\
+* H
+DEADLINE: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation nil))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Schedule when `org-adapt-indentation' is non-nil.
+ (should
+ (equal "* H\n SCHEDULED: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "* H\nParagraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info 'scheduled "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Schedule when `org-adapt-indentation' is nil.
+ (should
+ (equal "* H\nSCHEDULED: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "* H\nParagraph"
+ (let ((org-adapt-indentation nil))
+ (org-add-planning-info 'scheduled "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Add deadline when scheduled.
+ (should
+ (equal "\
+* H
+ DEADLINE: <2015-06-25> SCHEDULED: <2015-06-24>
+Paragraph"
+ (org-test-with-temp-text "\
+* H
+ SCHEDULED: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove middle entry.
+ (should
+ (equal "\
+* H
+ CLOSED: [2015-06-24] SCHEDULED: <2015-06-24>
+Paragraph"
+ (org-test-with-temp-text "\
+* H
+ CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info nil nil 'deadline))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove last entry and then middle entry (order should not
+ ;; matter).
+ (should
+ (equal "\
+* H
+ CLOSED: [2015-06-24]
+Paragraph"
+ (org-test-with-temp-text "\
+* H
+ CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info nil nil 'scheduled 'deadline))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove closed when `org-adapt-indentation' is non-nil.
+ (should
+ (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "\
+* H
+ CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info nil nil 'closed))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove closed when `org-adapt-indentation' is nil.
+ (should
+ (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "\
+* H
+CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu>
+Paragraph"
+ (let ((org-adapt-indentation nil))
+ (org-add-planning-info nil nil 'closed))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove closed entry and delete empty line.
+ (should
+ (equal "\
+* H
+Paragraph"
+ (org-test-with-temp-text "\
+* H
+ CLOSED: [2015-06-24 Wed]
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info nil nil 'closed))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1))))
+ ;; Remove one entry and update another.
+ (should
+ (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
+ (org-test-with-temp-text "\
+* H
+ SCHEDULED: <2015-06-23 Tue> DEADLINE: <2015-06-24 Wed>
+Paragraph"
+ (let ((org-adapt-indentation t))
+ (org-add-planning-info 'deadline "<2015-06-25 Thu>" 'scheduled))
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+ nil nil 1)))))
+
;;; Property API
--
2.4.4