Fix `org-read-date-prefer-future' when rescheduling

* lisp/org.el (org-read-date-analyze): When
  `org-read-date-prefer-future', offer a date in the future even if
  default date is different from now.

* testing/lisp/test-org.el (test-org/org-read-date): Add tests.

Reported-by: Rasmus <rasmus@gmx.us>
<http://permalink.gmane.org/gmane.emacs.orgmode/93805>
This commit is contained in:
Nicolas Goaziou 2015-01-06 23:19:42 +01:00
parent 9231460ac0
commit 85c55d453b
2 changed files with 110 additions and 11 deletions

View File

@ -16936,16 +16936,35 @@ user."
(setq tl (parse-time-string ans)
day (or (nth 3 tl) (nth 3 org-defdecode))
month (or (nth 4 tl)
(if (and org-read-date-prefer-future
(nth 3 tl) (< (nth 3 tl) (nth 3 nowdecode)))
(prog1 (1+ (nth 4 nowdecode)) (setq futurep t))
(nth 4 org-defdecode)))
year (or (and (not kill-year) (nth 5 tl))
(if (and org-read-date-prefer-future
(nth 4 tl) (< (nth 4 tl) (nth 4 nowdecode)))
(prog1 (1+ (nth 5 nowdecode)) (setq futurep t))
(nth 5 org-defdecode)))
month
(cond ((nth 4 tl))
((not org-read-date-prefer-future) (nth 4 org-defdecode))
;; Day was specified. Make sure DAY+MONTH
;; combination happens in the future.
((nth 3 tl)
(setq futurep t)
(if (< day (nth 3 nowdecode)) (1+ (nth 4 nowdecode))
(nth 4 nowdecode)))
(t (nth 4 org-defdecode)))
year
(cond ((and (not kill-year) (nth 5 tl)))
((not org-read-date-prefer-future) (nth 5 org-defdecode))
;; Month was guessed in the future and is at least
;; equal to NOWDECODE's. Fix year accordingly.
(futurep
(if (or (> month (nth 4 nowdecode))
(>= day (nth 3 nowdecode)))
(nth 5 nowdecode)
(1+ (nth 5 nowdecode))))
;; Month was specified. Make sure MONTH+YEAR
;; combination happens in the future.
((nth 4 tl)
(setq futurep t)
(cond ((> month (nth 4 nowdecode)) (nth 5 nowdecode))
((< month (nth 5 nowdecode)) (1+ (nth 5 nowdecode)))
((< day (nth 3 nowdecode)) (1+ (nth 5 nowdecode)))
(t (nth 5 nowdecode))))
(t (nth 5 org-defdecode)))
hour (or (nth 2 tl) (nth 2 org-defdecode))
minute (or (nth 1 tl) (nth 1 org-defdecode))
second (or (nth 0 tl) 0)

View File

@ -191,7 +191,87 @@
;; Parse Europeans dates without year.
(should (string-match "2[0-9]\\{3\\}-03-29 16:40"
(let ((org-time-was-given t))
(org-read-date t nil "29.03. 16:40")))))
(org-read-date t nil "29.03. 16:40"))))
;; Relative date applied to current time if there is single
;; plus/minus, or to default date when there are two of them.
(should
(equal
"2015-03-04"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2014-03-04"))))
(org-read-date
t nil "+1y" nil
(apply #'encode-time (org-parse-time-string "2012-03-29"))))))
(should
(equal
"2013-03-29"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2014-03-04"))))
(org-read-date
t nil "++1y" nil
(apply #'encode-time (org-parse-time-string "2012-03-29"))))))
;; When `org-read-date-prefer-future' is non-nil, prefer future
;; dates (relatively to now) when incomplete. Otherwise, use
;; default date.
(should
(equal
"2014-04-01"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2014-03-04"))))
(let ((org-read-date-prefer-future t))
(org-read-date t nil "1")))))
(should
(equal
"2013-03-04"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2012-03-29"))))
(let ((org-read-date-prefer-future t))
(org-read-date t nil "3-4")))))
(should
(equal
"2012-03-04"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2012-03-29"))))
(let ((org-read-date-prefer-future nil))
(org-read-date t nil "3-4")))))
;; When set to `org-read-date-prefer-future' is set to `time', read
;; day is moved to tomorrow if specified hour is before current
;; time. However, it only happens in no other part of the date is
;; specified.
(should
(equal
"2012-03-30"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2012-03-29 16:40"))))
(let ((org-read-date-prefer-future 'time))
(org-read-date t nil "00:40" nil)))))
(should-not
(equal
"2012-03-30"
(flet ((current-time () (apply #'encode-time
(org-parse-time-string "2012-03-29 16:40"))))
(let ((org-read-date-prefer-future 'time))
(org-read-date t nil "29 00:40" nil)))))
;; Caveat: `org-read-date-prefer-future' always refers to current
;; time, not default time, when they differ.
(should
(equal
"2014-04-01"
(flet ((current-time
() (apply #'encode-time (org-parse-time-string "2014-03-04"))))
(let ((org-read-date-prefer-future t))
(org-read-date
t nil "1" nil
(apply #'encode-time (org-parse-time-string "2012-03-29")))))))
(should
(equal
"2014-03-25"
(flet ((current-time
() (apply #'encode-time (org-parse-time-string "2014-03-04"))))
(let ((org-read-date-prefer-future t))
(org-read-date
t nil "25" nil
(apply #'encode-time (org-parse-time-string "2012-03-29"))))))))
(ert-deftest test-org/org-parse-time-string ()
"Test `org-parse-time-string'."