diff options
| -rw-r--r-- | lisp/calendar/todo-mode.el | 73 | ||||
| -rw-r--r-- | test/lisp/calendar/todo-mode-resources/todo-test-1.todo | 6 | ||||
| -rw-r--r-- | test/lisp/calendar/todo-mode-tests.el | 46 |
3 files changed, 98 insertions, 27 deletions
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index a49f428a3c8..4f513d33865 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el | |||
| @@ -1937,11 +1937,13 @@ their associated keys and their effects." | |||
| 1937 | (find-file-noselect file 'nowarn) | 1937 | (find-file-noselect file 'nowarn) |
| 1938 | (set-window-buffer (selected-window) | 1938 | (set-window-buffer (selected-window) |
| 1939 | (set-buffer (find-buffer-visiting file))) | 1939 | (set-buffer (find-buffer-visiting file))) |
| 1940 | ;; If this command was invoked outside of a Todo mode buffer, | 1940 | ;; If FILE is not in Todo mode, set it now, which also sets |
| 1941 | ;; the call to todo-current-category above returned nil. If | 1941 | ;; CAT to the file's first category. |
| 1942 | ;; we just entered Todo mode now, then cat was set to the | 1942 | (unless (derived-mode-p 'todo-mode) (todo-mode)) |
| 1943 | ;; file's first category, but if todo-mode was already | 1943 | ;; But if FILE was already in todo-mode and the item insertion |
| 1944 | ;; enabled, cat did not get set, so we have to do that. | 1944 | ;; command was invoked outside of a Todo mode buffer, the |
| 1945 | ;; above calls to todo-current-category returned nil, so we | ||
| 1946 | ;; have to explicitly set CAT to the current category. | ||
| 1945 | (unless cat | 1947 | (unless cat |
| 1946 | (setq cat (todo-current-category))) | 1948 | (setq cat (todo-current-category))) |
| 1947 | (setq todo-current-todo-file file) | 1949 | (setq todo-current-todo-file file) |
| @@ -2169,7 +2171,9 @@ the item at point." | |||
| 2169 | (if comment-delete | 2171 | (if comment-delete |
| 2170 | (when (todo-y-or-n-p "Delete comment? ") | 2172 | (when (todo-y-or-n-p "Delete comment? ") |
| 2171 | (delete-region (match-beginning 0) (match-end 0))) | 2173 | (delete-region (match-beginning 0) (match-end 0))) |
| 2172 | (replace-match (read-string prompt (cons (match-string 1) 1)) | 2174 | (replace-match (save-match-data |
| 2175 | (read-string prompt | ||
| 2176 | (cons (match-string 1) 1))) | ||
| 2173 | nil nil nil 1)) | 2177 | nil nil nil 1)) |
| 2174 | (if comment-delete | 2178 | (if comment-delete |
| 2175 | (user-error "There is no comment to delete") | 2179 | (user-error "There is no comment to delete") |
| @@ -2348,25 +2352,35 @@ made in the number or names of categories." | |||
| 2348 | ((or (string= omonth "*") (= mm 13)) | 2352 | ((or (string= omonth "*") (= mm 13)) |
| 2349 | (user-error "Cannot increment *")) | 2353 | (user-error "Cannot increment *")) |
| 2350 | (t | 2354 | (t |
| 2351 | (let ((mminc (+ mm inc (if (< inc 0) 12 0)))) | 2355 | (let* ((mmo mm) |
| 2352 | ;; Increment or decrement month by INC | 2356 | ;; Change by 12 or more months? |
| 2353 | ;; modulo 12. | 2357 | (bigincp (>= (abs inc) 12)) |
| 2354 | (setq mm (% mminc 12)) | 2358 | ;; Month number is in range 1..12. |
| 2355 | ;; If result is 0, make month December. | 2359 | (mminc (+ mm (% inc 12))) |
| 2356 | (setq mm (if (= mm 0) 12 (abs mm))) | 2360 | (mm (% (+ mminc 12) 12)) |
| 2361 | ;; 12n mod 12 = 0, so 0 is December. | ||
| 2362 | (mm (if (= mm 0) 12 mm)) | ||
| 2363 | ;; Does change in month cross year? | ||
| 2364 | (mmcmp (cond ((< inc 0) (> mm mmo)) | ||
| 2365 | ((> inc 0) (< mm mmo)))) | ||
| 2366 | (yyadjust (if bigincp | ||
| 2367 | (+ (abs (/ inc 12)) | ||
| 2368 | (if mmcmp 1 0)) | ||
| 2369 | 1))) | ||
| 2357 | ;; Adjust year if necessary. | 2370 | ;; Adjust year if necessary. |
| 2358 | (setq year (or (and (cond ((> mminc 12) | 2371 | (setq yy (cond ((and (< inc 0) |
| 2359 | (+ yy (/ mminc 12))) | 2372 | (or mmcmp bigincp)) |
| 2360 | ((< mminc 1) | 2373 | (- yy yyadjust)) |
| 2361 | (- yy (/ mminc 12) 1)) | 2374 | ((and (> inc 0) |
| 2362 | (t yy)) | 2375 | (or mmcmp bigincp)) |
| 2363 | (number-to-string yy)) | 2376 | (+ yy yyadjust)) |
| 2364 | oyear))) | 2377 | (t yy))) |
| 2365 | ;; Return the changed numerical month as | 2378 | (setq year (number-to-string yy)) |
| 2366 | ;; a string or the corresponding month name. | 2379 | ;; Return the changed numerical month as |
| 2367 | (if omonth | 2380 | ;; a string or the corresponding month name. |
| 2368 | (number-to-string mm) | 2381 | (if omonth |
| 2369 | (aref tma-array (1- mm)))))) | 2382 | (number-to-string mm) |
| 2383 | (aref tma-array (1- mm))))))) | ||
| 2370 | ;; Since the number corresponding to the arbitrary | 2384 | ;; Since the number corresponding to the arbitrary |
| 2371 | ;; month name "*" is out of the range of | 2385 | ;; month name "*" is out of the range of |
| 2372 | ;; calendar-last-day-of-month, set it to 1 | 2386 | ;; calendar-last-day-of-month, set it to 1 |
| @@ -5923,8 +5937,15 @@ categories from `todo-category-completions-files'." | |||
| 5923 | (todo-absolute-file-name | 5937 | (todo-absolute-file-name |
| 5924 | (let ((files (mapcar #'todo-short-file-name catfil))) | 5938 | (let ((files (mapcar #'todo-short-file-name catfil))) |
| 5925 | (completing-read (format str cat) files))))))) | 5939 | (completing-read (format str cat) files))))))) |
| 5926 | ;; Default to the current file. | 5940 | ;; When called without arg FILE, use fallback todo file. |
| 5927 | (unless file0 (setq file0 todo-current-todo-file)) | 5941 | (unless file0 (setq file0 (or todo-current-todo-file |
| 5942 | ;; If we're outside of todo-mode | ||
| 5943 | ;; but there is a current todo | ||
| 5944 | ;; file, use it. | ||
| 5945 | todo-global-current-todo-file | ||
| 5946 | ;; Else, use the default todo file. | ||
| 5947 | (todo-absolute-file-name | ||
| 5948 | todo-default-todo-file)))) | ||
| 5928 | ;; First validate only a name passed interactively from | 5949 | ;; First validate only a name passed interactively from |
| 5929 | ;; todo-add-category, which must be of a nonexistent category. | 5950 | ;; todo-add-category, which must be of a nonexistent category. |
| 5930 | (unless (and (assoc cat categories) (not add)) | 5951 | (unless (and (assoc cat categories) (not add)) |
diff --git a/test/lisp/calendar/todo-mode-resources/todo-test-1.todo b/test/lisp/calendar/todo-mode-resources/todo-test-1.todo index 598d487cad9..557134fd454 100644 --- a/test/lisp/calendar/todo-mode-resources/todo-test-1.todo +++ b/test/lisp/calendar/todo-mode-resources/todo-test-1.todo | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | (("testcat1" . [2 0 2 1]) ("testcat2" . [3 0 1 1]) ("testcat3" . [0 0 0 0])) | 1 | (("testcat1" . [2 0 2 1]) ("testcat2" . [3 0 1 1]) ("testcat3" . [0 0 0 0]) ("testcat4" . [1 0 0 0])) |
| 2 | --==-- testcat1 | 2 | --==-- testcat1 |
| 3 | [May 29, 2017] testcat1 item3 | 3 | [May 29, 2017] testcat1 item3 |
| 4 | has more than one line | 4 | has more than one line |
| @@ -18,3 +18,7 @@ | |||
| 18 | --==-- testcat3 | 18 | --==-- testcat3 |
| 19 | 19 | ||
| 20 | ==--== DONE | 20 | ==--== DONE |
| 21 | --==-- testcat4 | ||
| 22 | [Jan 1, 2020] testcat4 item1 | ||
| 23 | |||
| 24 | ==--== DONE | ||
diff --git a/test/lisp/calendar/todo-mode-tests.el b/test/lisp/calendar/todo-mode-tests.el index d65f94d4f31..a19612ee562 100644 --- a/test/lisp/calendar/todo-mode-tests.el +++ b/test/lisp/calendar/todo-mode-tests.el | |||
| @@ -848,6 +848,52 @@ should display the previously current (or default) todo file." | |||
| 848 | (should (equal todo-current-todo-file todo-test-file-1)) | 848 | (should (equal todo-current-todo-file todo-test-file-1)) |
| 849 | (delete-file (concat file "~"))))) | 849 | (delete-file (concat file "~"))))) |
| 850 | 850 | ||
| 851 | (ert-deftest todo-test-edit-item-date-month () | ||
| 852 | "Test incrementing and decrementing the month of an item's date. | ||
| 853 | If the change in month crosses a year boundary, the year of the | ||
| 854 | item's date should be adjusted accordingly." | ||
| 855 | (with-todo-test | ||
| 856 | (todo-test--show 4) | ||
| 857 | (let ((current-prefix-arg t) ; For todo-edit-item--header. | ||
| 858 | (get-date (lambda () | ||
| 859 | (save-excursion | ||
| 860 | (todo-date-string-matcher (line-end-position)) | ||
| 861 | (buffer-substring-no-properties (match-beginning 1) | ||
| 862 | (match-end 0)))))) | ||
| 863 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 864 | (todo-edit-item--header 'month 0) | ||
| 865 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 866 | (todo-edit-item--header 'month 1) | ||
| 867 | (should (equal (funcall get-date) "Feb 1, 2020")) | ||
| 868 | (todo-edit-item--header 'month -1) | ||
| 869 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 870 | (todo-edit-item--header 'month -1) | ||
| 871 | (should (equal (funcall get-date) "Dec 1, 2019")) | ||
| 872 | (todo-edit-item--header 'month 1) | ||
| 873 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 874 | (todo-edit-item--header 'month 12) | ||
| 875 | (should (equal (funcall get-date) "Jan 1, 2021")) | ||
| 876 | (todo-edit-item--header 'month -12) | ||
| 877 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 878 | (todo-edit-item--header 'month -13) | ||
| 879 | (should (equal (funcall get-date) "Dec 1, 2018")) | ||
| 880 | (todo-edit-item--header 'month 7) | ||
| 881 | (should (equal (funcall get-date) "Jul 1, 2019")) | ||
| 882 | (todo-edit-item--header 'month 6) | ||
| 883 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 884 | (todo-edit-item--header 'month 23) | ||
| 885 | (should (equal (funcall get-date) "Dec 1, 2021")) | ||
| 886 | (todo-edit-item--header 'month -23) | ||
| 887 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 888 | (todo-edit-item--header 'month 24) | ||
| 889 | (should (equal (funcall get-date) "Jan 1, 2022")) | ||
| 890 | (todo-edit-item--header 'month -24) | ||
| 891 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 892 | (todo-edit-item--header 'month 25) | ||
| 893 | (should (equal (funcall get-date) "Feb 1, 2022")) | ||
| 894 | (todo-edit-item--header 'month -25) | ||
| 895 | (should (equal (funcall get-date) "Jan 1, 2020")) | ||
| 896 | ))) | ||
| 851 | 897 | ||
| 852 | (provide 'todo-mode-tests) | 898 | (provide 'todo-mode-tests) |
| 853 | ;;; todo-mode-tests.el ends here | 899 | ;;; todo-mode-tests.el ends here |