diff options
| -rw-r--r-- | lisp/ChangeLog | 65 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 654 |
2 files changed, 367 insertions, 352 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0bcb61c3712..fc8bbbac000 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,68 @@ | |||
| 1 | 2012-09-14 Stephen Berman <stephen.berman@gmx.net> | ||
| 2 | |||
| 3 | * calendar/todos.el Remove lots of commented out code; add various | ||
| 4 | comments; further code rearrangement. | ||
| 5 | (todos-insert-item-here-ask-date-time) | ||
| 6 | (todos-insert-item-ask-date-time) | ||
| 7 | (todos-insert-item-ask-dayname-time) | ||
| 8 | (todos-insert-item-for-diary) | ||
| 9 | (todos-insert-item-for-diary-ask-date-time) | ||
| 10 | (todos-make-categories-alist, todos-categories-alist): Remove. | ||
| 11 | (todos-categories-list): Comment out. | ||
| 12 | (todos-make-categories-list): New function replacing | ||
| 13 | todos-make-categories-alist, using category plists to get item | ||
| 14 | counts and taking archive into account. | ||
| 15 | (todos-current-todos-file): New variable. | ||
| 16 | (todos-mode-map): Update key bindings. | ||
| 17 | (todos-save): Add as comment code to make sure todos-categories | ||
| 18 | sexp is current on saving. | ||
| 19 | (todos-quit): Call todos-show on quitting Todos archive buffer. | ||
| 20 | (todos-show): If todos-current-todos-file is not set to Todos | ||
| 21 | file, set it as a new file; set todos-categories from | ||
| 22 | todos-make-categories-alist. | ||
| 23 | (todos-display-categories): Use a different display format for | ||
| 24 | archive file; put point initially on the first button. | ||
| 25 | (todos-toggle-view-done-items): Check the category's `done' | ||
| 26 | property to determine if there are done items. | ||
| 27 | (todos-view-archive): Set todos-current-todos-file to the archive | ||
| 28 | file; jump from the Todos file to the same category in the | ||
| 29 | archive, if it exists, else jump to the first category; use | ||
| 30 | message instead of error. | ||
| 31 | (todos-add-category): Intern a special symbol for the new category | ||
| 32 | and set its property list to holds counts of the numbers of todo, | ||
| 33 | done and archived items in the category; assign the new category | ||
| 34 | the current highest category number. | ||
| 35 | (todos-rename-category): Don't use todos-categories-alist. | ||
| 36 | (todos-delete-category): Check the category's `todo' and `done' | ||
| 37 | properties to determine if it is empty; ensure that the end of the | ||
| 38 | last category is found; after deleting the category, empty its | ||
| 39 | plist and unintern its special symbol. | ||
| 40 | (todos-insert-item-here): Fix argument list of todos-insert-item. | ||
| 41 | (todos-delete-item, todos-raise-item, todos-lower-item): | ||
| 42 | Use message instead of error. | ||
| 43 | (todos-move-item): If the category to be moved to does not exist, | ||
| 44 | add it as a new category. | ||
| 45 | (todos-item-done, todos-reset-separator): | ||
| 46 | Use todos-category-select instead of todos-show. | ||
| 47 | (todos-archive-done-items): Make buffer writeable; conditionalize | ||
| 48 | search for end of category; save after adding to archive in case | ||
| 49 | the file is new, so it can be found. | ||
| 50 | (todos-category-select): Wrap search in if instead of or+and; | ||
| 51 | don't hide done items in an archive. | ||
| 52 | (todos-set-item-priority): Check the category's `todo' | ||
| 53 | property to determine if there are not done todo items. | ||
| 54 | (todos-jump-to-category-noninteractively): Just switch to buffer | ||
| 55 | visiting todos-current-todos-file, since this can be either a | ||
| 56 | Todos file or an archive. | ||
| 57 | (todos-item-counts): Use category's plist instead of an alist. | ||
| 58 | (todos-longest-category-name-length): Argument is now a list of | ||
| 59 | category names, not an alist, so just test each element, not each | ||
| 60 | element's the car. | ||
| 61 | (todos-padded-string): Use todos-categories instead of | ||
| 62 | todos-categories-alist. | ||
| 63 | (todos-insert-category-name): Use category plist to get item | ||
| 64 | counts; take archived items into account. | ||
| 65 | |||
| 1 | 2012-09-13 Stephen Berman <stephen.berman@gmx.net> | 66 | 2012-09-13 Stephen Berman <stephen.berman@gmx.net> |
| 2 | 67 | ||
| 3 | * calendar/todos.el: Numerous spelling and comment fixes, doc | 68 | * calendar/todos.el: Numerous spelling and comment fixes, doc |
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el index 7ec54e0f2e9..427056e6e26 100644 --- a/lisp/calendar/todos.el +++ b/lisp/calendar/todos.el | |||
| @@ -481,6 +481,9 @@ Automatically generated when `todos-save-top-priorities' is non-nil." | |||
| 481 | ;; --------------------------------------------------------------------------- | 481 | ;; --------------------------------------------------------------------------- |
| 482 | ;;; Mode setup | 482 | ;;; Mode setup |
| 483 | 483 | ||
| 484 | (defvar todos-current-todos-file nil | ||
| 485 | "") | ||
| 486 | |||
| 484 | (defvar todos-categories nil | 487 | (defvar todos-categories nil |
| 485 | "TODO categories.") | 488 | "TODO categories.") |
| 486 | 489 | ||
| @@ -496,12 +499,14 @@ Automatically generated when `todos-save-top-priorities' is non-nil." | |||
| 496 | (define-key map "S" 'todos-search) | 499 | (define-key map "S" 'todos-search) |
| 497 | ;; display commands | 500 | ;; display commands |
| 498 | (define-key map "C" 'todos-display-categories) | 501 | (define-key map "C" 'todos-display-categories) |
| 502 | ;; (define-key map "" 'todos-display-categories-alphabetically) | ||
| 499 | (define-key map "h" 'todos-highlight-item) | 503 | (define-key map "h" 'todos-highlight-item) |
| 500 | (define-key map "N" 'todos-toggle-item-numbering) | 504 | (define-key map "N" 'todos-toggle-item-numbering) |
| 501 | ;; (define-key map "" 'todos-toggle-display-date-time) | 505 | ;; (define-key map "" 'todos-toggle-display-date-time) |
| 502 | (define-key map "P" 'todos-print) | 506 | (define-key map "P" 'todos-print) |
| 503 | (define-key map "q" 'todos-quit) | 507 | (define-key map "q" 'todos-quit) |
| 504 | (define-key map "s" 'todos-save) | 508 | (define-key map "s" 'todos-save) |
| 509 | (define-key map "V" 'todos-view-archive) | ||
| 505 | (define-key map "v" 'todos-toggle-view-done-items) | 510 | (define-key map "v" 'todos-toggle-view-done-items) |
| 506 | (define-key map "Y" 'todos-diary-items) | 511 | (define-key map "Y" 'todos-diary-items) |
| 507 | ;; (define-key map "S" 'todos-save-top-priorities) | 512 | ;; (define-key map "S" 'todos-save-top-priorities) |
| @@ -514,7 +519,6 @@ Automatically generated when `todos-save-top-priorities' is non-nil." | |||
| 514 | (define-key map "e" 'todos-edit-item) | 519 | (define-key map "e" 'todos-edit-item) |
| 515 | (define-key map "E" 'todos-edit-multiline) | 520 | (define-key map "E" 'todos-edit-multiline) |
| 516 | ;; (define-key map "" 'todos-change-date) | 521 | ;; (define-key map "" 'todos-change-date) |
| 517 | ;; (define-key map "f" 'todos-file-item) | ||
| 518 | (define-key map "ii" 'todos-insert-item) | 522 | (define-key map "ii" 'todos-insert-item) |
| 519 | (define-key map "ih" 'todos-insert-item-here) | 523 | (define-key map "ih" 'todos-insert-item-here) |
| 520 | (define-key map "ia" 'todos-insert-item-ask-date-time) | 524 | (define-key map "ia" 'todos-insert-item-ask-date-time) |
| @@ -684,19 +688,27 @@ Automatically generated when `todos-save-top-priorities' is non-nil." | |||
| 684 | (defun todos-save () | 688 | (defun todos-save () |
| 685 | "Save the TODO list." | 689 | "Save the TODO list." |
| 686 | (interactive) | 690 | (interactive) |
| 687 | (save-excursion | 691 | (let (buffer-read-only) |
| 688 | (save-restriction | 692 | (save-excursion |
| 689 | (save-buffer))) | 693 | (save-restriction |
| 690 | ;; (if todos-save-top-priorities-too (todos-save-top-priorities))) | 694 | ;; (widen) |
| 691 | ) | 695 | ;; (goto-char (point-min)) |
| 696 | ;; (unless (looking-at (concat "^" (regexp-quote todos-category-beg))) | ||
| 697 | ;; (kill-line)) | ||
| 698 | ;; (prin1 todos-categories (current-buffer)) | ||
| 699 | (save-buffer))) | ||
| 700 | ;; (if todos-save-top-priorities-too (todos-save-top-priorities))) | ||
| 701 | )) | ||
| 692 | 702 | ||
| 693 | (defun todos-quit () | 703 | (defun todos-quit () |
| 694 | "Done with TODO list for now." | 704 | "Done with TODO list for now." |
| 695 | (interactive) | 705 | (interactive) |
| 696 | (widen) | 706 | (widen) |
| 697 | (todos-save) | 707 | (todos-save) |
| 698 | (message "") | 708 | ;; (message "") |
| 699 | (bury-buffer)) | 709 | (if (eq major-mode 'todos-archive-mode) |
| 710 | (todos-show) | ||
| 711 | (bury-buffer))) | ||
| 700 | 712 | ||
| 701 | ;; --------------------------------------------------------------------------- | 713 | ;; --------------------------------------------------------------------------- |
| 702 | ;;; Commands | 714 | ;;; Commands |
| @@ -722,14 +734,14 @@ Automatically generated when `todos-save-top-priorities' is non-nil." | |||
| 722 | (find-file todos-file-do) | 734 | (find-file todos-file-do) |
| 723 | (todos-initial-setup)) | 735 | (todos-initial-setup)) |
| 724 | (unless (eq major-mode 'todos-mode) (todos-mode)) | 736 | (unless (eq major-mode 'todos-mode) (todos-mode)) |
| 725 | (unless todos-categories-alist | 737 | (unless (string= todos-current-todos-file todos-file-do) |
| 726 | (setq todos-categories-alist (todos-make-categories-alist))) | 738 | (setq todos-current-todos-file todos-file-do) |
| 739 | (setq todos-category-number 0) | ||
| 740 | (setq todos-categories nil)) | ||
| 727 | (unless todos-categories | 741 | (unless todos-categories |
| 728 | (setq todos-categories (mapcar 'car todos-categories-alist))) | 742 | (setq todos-categories (todos-make-categories-list))) |
| 729 | (save-excursion | 743 | (save-excursion |
| 730 | (todos-category-select) | 744 | (todos-category-select)))) |
| 731 | ;; (todos-show-paren-hack) | ||
| 732 | ))) | ||
| 733 | 745 | ||
| 734 | (defun todos-display-categories (&optional alpha) | 746 | (defun todos-display-categories (&optional alpha) |
| 735 | "Display a numbered list of the Todos category names. | 747 | "Display a numbered list of the Todos category names. |
| @@ -755,9 +767,15 @@ the category in Todos mode." | |||
| 755 | (insert "Press a button to display the corresponding category.\n\n") | 767 | (insert "Press a button to display the corresponding category.\n\n") |
| 756 | ;; FIXME: abstract format from here and todos-insert-category-name | 768 | ;; FIXME: abstract format from here and todos-insert-category-name |
| 757 | (insert (make-string 4 32) (todos-padded-string "Category") | 769 | (insert (make-string 4 32) (todos-padded-string "Category") |
| 758 | (make-string 7 32) "Todos Done\n\n") | 770 | (if (string= todos-current-todos-file todos-archive-file) |
| 771 | (concat (make-string 6 32) | ||
| 772 | (format "%s" "Archived")) | ||
| 773 | (concat (make-string 7 32) | ||
| 774 | (format "%-7s%-7s%s" "Todo" "Done" "Archived"))) | ||
| 775 | "\n\n") | ||
| 759 | (save-excursion | 776 | (save-excursion |
| 760 | (mapc '(lambda (cat) (todos-insert-category-name cat alpha)) categories))) | 777 | (mapc '(lambda (cat) (todos-insert-category-name cat alpha)) categories))) |
| 778 | (goto-char (next-single-char-property-change (point) 'button)) | ||
| 761 | (todos-categories-mode)))) | 779 | (todos-categories-mode)))) |
| 762 | 780 | ||
| 763 | (defun todos-display-categories-alphabetically () | 781 | (defun todos-display-categories-alphabetically () |
| @@ -775,25 +793,41 @@ the category in Todos mode." | |||
| 775 | (interactive) | 793 | (interactive) |
| 776 | (save-excursion | 794 | (save-excursion |
| 777 | (goto-char (point-min)) | 795 | (goto-char (point-min)) |
| 778 | (let ((todos-show-with-done | 796 | (let* ((todos-show-with-done |
| 779 | (if (re-search-forward (concat "\n\\(\\[" (regexp-quote todos-done-string) | 797 | (if (re-search-forward (concat "\n\\(\\[" |
| 780 | "\\)") nil t) | 798 | (regexp-quote todos-done-string) |
| 781 | nil | 799 | "\\)") nil t) |
| 782 | t))) | 800 | nil |
| 783 | (todos-category-select)))) | 801 | t)) |
| 802 | (cat (todos-current-category)) | ||
| 803 | (catsym (intern-soft (concat "todos-" cat)))) | ||
| 804 | (todos-category-select) | ||
| 805 | (when (zerop (get catsym 'done)) | ||
| 806 | (message "There are no done items in this category."))))) | ||
| 784 | 807 | ||
| 785 | (defun todos-view-archive (&optional cat) | 808 | (defun todos-view-archive (&optional cat) |
| 786 | "" | 809 | "" |
| 787 | (interactive) | 810 | (interactive) |
| 788 | (if (file-exists-p todos-archive-file) | 811 | (if (file-exists-p todos-archive-file) |
| 789 | (progn | 812 | (progn ;let ((todos-show-with-done t)) |
| 790 | (find-file todos-archive-file) | 813 | (find-file todos-archive-file) |
| 814 | (todos-archive-mode) | ||
| 815 | (unless (string= todos-current-todos-file todos-archive-file) | ||
| 816 | (setq todos-current-todos-file todos-archive-file) | ||
| 817 | (setq todos-categories nil)) | ||
| 818 | (unless todos-categories | ||
| 819 | (setq todos-categories (todos-make-categories-list))) | ||
| 791 | (if cat | 820 | (if cat |
| 792 | (if (member cat (todos-categories-list (current-buffer))) | 821 | (if (member cat (todos-categories)) |
| 793 | (todos-jump-to-category-noninteractively cat) | 822 | (progn |
| 794 | (error "No archived items from this category")) | 823 | (setq todos-category-number |
| 824 | (- (length todos-categories) | ||
| 825 | (length (member cat todos-categories)))) | ||
| 826 | (todos-jump-to-category-noninteractively cat)) | ||
| 827 | (message "No archived items from this category")) | ||
| 828 | (setq todos-category-number 0) | ||
| 795 | (todos-category-select))) | 829 | (todos-category-select))) |
| 796 | (error "There is currently no Todos archive"))) | 830 | (message "There is currently no Todos archive"))) |
| 797 | 831 | ||
| 798 | ;; FIXME: slow | 832 | ;; FIXME: slow |
| 799 | (defun todos-diary-items () | 833 | (defun todos-diary-items () |
| @@ -806,7 +840,6 @@ the category in Todos mode." | |||
| 806 | (widen) | 840 | (widen) |
| 807 | (copy-to-buffer bufname (point-min) (point-max)))) | 841 | (copy-to-buffer bufname (point-min) (point-max)))) |
| 808 | (with-current-buffer bufname | 842 | (with-current-buffer bufname |
| 809 | ;; (todos-mode) | ||
| 810 | (goto-char (point-min)) | 843 | (goto-char (point-min)) |
| 811 | (while (not (eobp)) | 844 | (while (not (eobp)) |
| 812 | (setq opoint (point)) | 845 | (setq opoint (point)) |
| @@ -866,12 +899,10 @@ the category in Todos mode." | |||
| 866 | "\\( " diary-time-regexp "\\)?\\]? ") | 899 | "\\( " diary-time-regexp "\\)?\\]? ") |
| 867 | ; FIXME: this space in header? ^ | 900 | ; FIXME: this space in header? ^ |
| 868 | nil t) | 901 | nil t) |
| 902 | ;; FIXME: wrong match data if search fails | ||
| 869 | (setq ov (make-overlay (match-beginning 0) (match-end 0) nil t)) | 903 | (setq ov (make-overlay (match-beginning 0) (match-end 0) nil t)) |
| 870 | (overlay-put ov 'display "") | 904 | (overlay-put ov 'display "") |
| 871 | (forward-line))) | 905 | (forward-line)))))) |
| 872 | ;; FIXME: need this? | ||
| 873 | ;; (todos-update-numbered-prefix) | ||
| 874 | ))) | ||
| 875 | 906 | ||
| 876 | ;;;###autoload | 907 | ;;;###autoload |
| 877 | (defun todos-top-priorities (&optional nof-priorities category-pr-page show-done) | 908 | (defun todos-top-priorities (&optional nof-priorities category-pr-page show-done) |
| @@ -972,7 +1003,6 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 972 | (- (length todos-categories) | 1003 | (- (length todos-categories) |
| 973 | (length (member category todos-categories))) | 1004 | (length (member category todos-categories))) |
| 974 | (todos-add-category category))) | 1005 | (todos-add-category category))) |
| 975 | ;; (todos-show))) | ||
| 976 | (todos-category-select))) | 1006 | (todos-category-select))) |
| 977 | 1007 | ||
| 978 | ;; FIXME ? todos-{backward,forward}-item skip over empty line between done and | 1008 | ;; FIXME ? todos-{backward,forward}-item skip over empty line between done and |
| @@ -1013,7 +1043,7 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 1013 | (forward-line)) | 1043 | (forward-line)) |
| 1014 | (if found | 1044 | (if found |
| 1015 | (progn | 1045 | (progn |
| 1016 | (setq found (match-beginning 0)) | 1046 | (setq found (match-beginning 0)) ;FIXME: ok if looking-at returns nil? |
| 1017 | (todos-item-start) | 1047 | (todos-item-start) |
| 1018 | (when (looking-at (concat "^\\[" (regexp-quote todos-done-string))) | 1048 | (when (looking-at (concat "^\\[" (regexp-quote todos-done-string))) |
| 1019 | (setq in-done t)) | 1049 | (setq in-done t)) |
| @@ -1035,7 +1065,8 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 1035 | "Add new category CAT to the TODO list." | 1065 | "Add new category CAT to the TODO list." |
| 1036 | (interactive) | 1066 | (interactive) |
| 1037 | (let ((buffer-read-only) | 1067 | (let ((buffer-read-only) |
| 1038 | (buf (find-file-noselect todos-file-do t))) | 1068 | (buf (find-file-noselect todos-file-do t)) |
| 1069 | catsym) | ||
| 1039 | (unless (zerop (buffer-size buf)) | 1070 | (unless (zerop (buffer-size buf)) |
| 1040 | (and (null todos-categories) | 1071 | (and (null todos-categories) |
| 1041 | (error "Error in %s: File is non-empty but contains no category" | 1072 | (error "Error in %s: File is non-empty but contains no category" |
| @@ -1045,9 +1076,11 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 1045 | (setq cat (todos-check-category-name cat)) | 1076 | (setq cat (todos-check-category-name cat)) |
| 1046 | ;; initialize a newly created Todo buffer for Todo mode | 1077 | ;; initialize a newly created Todo buffer for Todo mode |
| 1047 | (unless (file-exists-p todos-file-do) (todos-mode)) | 1078 | (unless (file-exists-p todos-file-do) (todos-mode)) |
| 1048 | (push cat todos-categories) | 1079 | (setq catsym (intern (concat "todos-" cat))) |
| 1049 | (push (list cat (cons 0 0)) todos-categories-alist) | 1080 | (setplist catsym (list 'todo 0 'done 0 'archived 0)) |
| 1081 | (nconc todos-categories (list cat)) ;FIXME: is this TRTD? | ||
| 1050 | (widen) | 1082 | (widen) |
| 1083 | ;; FIXME: make this (point-max) | ||
| 1051 | (goto-char (point-min)) | 1084 | (goto-char (point-min)) |
| 1052 | ;; make sure file does not begin with empty lines (shouldn't, but may be | 1085 | ;; make sure file does not begin with empty lines (shouldn't, but may be |
| 1053 | ;; added by mistake), otherwise new categories will contain them, so | 1086 | ;; added by mistake), otherwise new categories will contain them, so |
| @@ -1056,8 +1089,9 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 1056 | (insert todos-category-beg cat "\n") | 1089 | (insert todos-category-beg cat "\n") |
| 1057 | (if (interactive-p) | 1090 | (if (interactive-p) |
| 1058 | ;; properly display the newly added category | 1091 | ;; properly display the newly added category |
| 1059 | (progn (setq todos-category-number 0) (todos-show)) | 1092 | (progn (setq todos-category-number (1- (length todos-categories))) |
| 1060 | 0)))) | 1093 | (todos-category-select)) |
| 1094 | (1- (length todos-categories)))))) | ||
| 1061 | 1095 | ||
| 1062 | (defun todos-rename-category () | 1096 | (defun todos-rename-category () |
| 1063 | "Rename current Todos category." | 1097 | "Rename current Todos category." |
| @@ -1069,7 +1103,6 @@ With non-nil SHOW-DONE, include done items in the listing." | |||
| 1069 | (setq new (todos-check-category-name new)) | 1103 | (setq new (todos-check-category-name new)) |
| 1070 | (aset vec todos-category-number new) | 1104 | (aset vec todos-category-number new) |
| 1071 | (setq todos-categories (append vec nil)) | 1105 | (setq todos-categories (append vec nil)) |
| 1072 | (setcar (assoc cat todos-categories-alist) new) | ||
| 1073 | (save-excursion | 1106 | (save-excursion |
| 1074 | (widen) | 1107 | (widen) |
| 1075 | (re-search-backward (concat (regexp-quote todos-category-beg) "\\(" | 1108 | (re-search-backward (concat (regexp-quote todos-category-beg) "\\(" |
| @@ -1085,28 +1118,31 @@ With ARG non-nil delete the category unconditionally, | |||
| 1085 | i.e. including all existing entries." | 1118 | i.e. including all existing entries." |
| 1086 | (interactive "P") | 1119 | (interactive "P") |
| 1087 | (let* ((cat (todos-current-category)) | 1120 | (let* ((cat (todos-current-category)) |
| 1088 | (not-done (car (todos-item-counts cat))) | 1121 | (catsym (intern-soft (concat "todos-" cat))) |
| 1089 | (done (cdr (todos-item-counts cat))) | 1122 | (todo (get catsym 'todo)) |
| 1123 | (done (get catsym 'done)) | ||
| 1090 | beg end) | 1124 | beg end) |
| 1091 | (if (and (null arg) | 1125 | (if (and (null arg) |
| 1092 | (or (> not-done 0) (> done 0))) | 1126 | (or (> todo 0) (> done 0))) |
| 1093 | (message "To delete a non-empty category, type C-u D.") | 1127 | (message "To delete a non-empty category, type C-u D.") |
| 1094 | (when (y-or-n-p (concat "Permanently remove category \"" cat | 1128 | (when (y-or-n-p (concat "Permanently remove category \"" cat |
| 1095 | "\"" (and arg " and all its entries") "? ")) | 1129 | "\"" (and arg " and all its entries") "? ")) |
| 1096 | (let ((buffer-read-only)) | 1130 | (let ((buffer-read-only)) |
| 1097 | (widen) | 1131 | (widen) |
| 1098 | (setq beg (re-search-backward (concat "^" (regexp-quote todos-category-beg) | 1132 | (setq beg (re-search-backward (concat "^" (regexp-quote todos-category-beg) |
| 1099 | cat "\n") nil t) | 1133 | cat "\n") nil t)) |
| 1100 | end (progn | 1134 | (setq end (if (re-search-forward (concat "\n\\(" |
| 1101 | (re-search-forward (concat "\n\\(" | 1135 | (regexp-quote todos-category-beg) |
| 1102 | (regexp-quote todos-category-beg) | 1136 | ".*\n\\)") nil t) |
| 1103 | ".*\n\\)") nil t) | 1137 | (match-beginning 1) |
| 1104 | (match-beginning 1))) | 1138 | (point-max))) |
| 1105 | (remove-overlays beg end) | 1139 | (remove-overlays beg end) |
| 1106 | (kill-region beg end) | 1140 | (kill-region beg end) |
| 1107 | (setq todos-categories (delete cat todos-categories)) | 1141 | (setq todos-categories (delete cat todos-categories)) |
| 1108 | (setq todos-categories-alist | 1142 | (setplist catsym nil) |
| 1109 | (delete (assoc cat todos-categories-alist) todos-categories-alist)) | 1143 | (unintern catsym) |
| 1144 | (setq todos-category-number | ||
| 1145 | (mod todos-category-number (length todos-categories))) | ||
| 1110 | (todos-category-select) | 1146 | (todos-category-select) |
| 1111 | (message "Deleted category %s" cat)))))) | 1147 | (message "Deleted category %s" cat)))))) |
| 1112 | 1148 | ||
| @@ -1180,7 +1216,7 @@ there." | |||
| 1180 | (interactive "P") | 1216 | (interactive "P") |
| 1181 | (unless (or (todos-done-item-p) | 1217 | (unless (or (todos-done-item-p) |
| 1182 | (save-excursion (forward-line -1) (todos-done-item-p))) | 1218 | (save-excursion (forward-line -1) (todos-done-item-p))) |
| 1183 | (if (not (derived-mode-p 'todos-mode)) (todos-show)) | 1219 | (when (not (derived-mode-p 'todos-mode)) (todos-show)) |
| 1184 | (let* ((buffer-read-only) | 1220 | (let* ((buffer-read-only) |
| 1185 | (date-string (cond | 1221 | (date-string (cond |
| 1186 | ((eq date-type 'ask-date) | 1222 | ((eq date-type 'ask-date) |
| @@ -1192,7 +1228,7 @@ there." | |||
| 1192 | (with-current-buffer "*Calendar*" | 1228 | (with-current-buffer "*Calendar*" |
| 1193 | (calendar-date-string (calendar-cursor-to-date t) t t))) | 1229 | (calendar-date-string (calendar-cursor-to-date t) t t))) |
| 1194 | (t (calendar-date-string (calendar-current-date) t t)))) | 1230 | (t (calendar-date-string (calendar-current-date) t t)))) |
| 1195 | (time-string (cond ((eq time 'omit) nil) | 1231 | (time-string (cond ((eq time 'omit) nil) ;FIXME: delete |
| 1196 | ((eq time 'ask-time) | 1232 | ((eq time 'ask-time) |
| 1197 | (todos-read-time)) | 1233 | (todos-read-time)) |
| 1198 | (todos-always-add-time-string | 1234 | (todos-always-add-time-string |
| @@ -1208,88 +1244,55 @@ there." | |||
| 1208 | "\\(\n\\)[^[:blank:]]" | 1244 | "\\(\n\\)[^[:blank:]]" |
| 1209 | (concat "\n" (make-string todos-indent-to-here 32)) new-item | 1245 | (concat "\n" (make-string todos-indent-to-here 32)) new-item |
| 1210 | nil nil 1)) | 1246 | nil nil 1)) |
| 1211 | ;; (if here | ||
| 1212 | ;; (todos-insert-with-overlays new-item) | ||
| 1213 | ;; (todos-add-item-non-interactively new-item cat)) | ||
| 1214 | (unless here (todos-set-item-priority new-item cat)) | 1247 | (unless here (todos-set-item-priority new-item cat)) |
| 1215 | (todos-insert-with-overlays new-item) | 1248 | (todos-insert-with-overlays new-item) |
| 1216 | (todos-item-counts cat 'insert)))) | 1249 | (todos-item-counts cat 'insert)))) |
| 1217 | 1250 | ||
| 1218 | ;; FIXME: make insertion options customizable per category | 1251 | ;; FIXME: make insertion options customizable per category |
| 1219 | ;; date-type: d n (c) - time - diary - here | ||
| 1220 | ;; idd inn itt iyy ih | ||
| 1221 | ;; idtt idyy idh intt inyy inh ityy iyh | ||
| 1222 | ;; idtyy idyh intyy inyh ityh | ||
| 1223 | ;; idtyh intyh | ||
| 1224 | ;; idth inth | ||
| 1225 | |||
| 1226 | ;; todos-insert-item | ||
| 1227 | ;; todos-insert-item-ask-date | ||
| 1228 | ;; todos-insert-item-ask-date-time | ||
| 1229 | ;; todos-insert-item-ask-dayname | ||
| 1230 | ;; todos-insert-item-ask-dayname-time | ||
| 1231 | ;; todos-insert-item-ask-time | ||
| 1232 | ;; todos-insert-item-for-diary | ||
| 1233 | ;; todos-insert-item-for-diary-ask-date | ||
| 1234 | ;; todos-insert-item-for-diary-ask-date-time | ||
| 1235 | ;; todos-insert-item-for-diary-ask-dayname | ||
| 1236 | ;; todos-insert-item-for-diary-ask-dayname-time | ||
| 1237 | ;; todos-insert-item-for-diary-ask-time | ||
| 1238 | ;; todos-insert-item-here | ||
| 1239 | ;; todos-insert-item-here-ask-date | ||
| 1240 | ;; todos-insert-item-here-ask-date-time | ||
| 1241 | ;; todos-insert-item-here-ask-dayname | ||
| 1242 | ;; todos-insert-item-here-ask-dayname-time | ||
| 1243 | ;; todos-insert-item-here-ask-time | ||
| 1244 | ;; todos-insert-item-here-ask-time-diary | ||
| 1245 | ;; todos-insert-item-here-for-diary | ||
| 1246 | ;; todos-insert-item-here-for-diary-ask-date-time | ||
| 1247 | ;; todos-insert-item-here-for-diary-ask-time | ||
| 1248 | ;; todos-insert-item-here-for-diary-ask-dayname-time | ||
| 1249 | 1252 | ||
| 1250 | (defun todos-insert-item-here () | 1253 | ;; current date ~ current day ~ ask date ~ ask day |
| 1251 | "" | 1254 | ;; current time ~ ask time ~ no time |
| 1252 | (interactive) | 1255 | ;; for diary ~ not for diary |
| 1253 | (todos-insert-item nil nil nil t)) | 1256 | ;; here ~ ask priority |
| 1254 | |||
| 1255 | (defun todos-insert-item-here-ask-date-time () | ||
| 1256 | "" | ||
| 1257 | (interactive) | ||
| 1258 | (todos-insert-item nil 'ask-date 'ask-time t)) | ||
| 1259 | 1257 | ||
| 1260 | ;; (defun todos-insert-item-no-time () | 1258 | ;; date-type: d n (c) - time - diary - here |
| 1261 | ;; "" | ||
| 1262 | ;; (interactive) | ||
| 1263 | ;; (todos-insert-item nil nil 'omit t)) | ||
| 1264 | 1259 | ||
| 1265 | (defun todos-insert-item-ask-date-time (&optional arg) | 1260 | ;; ii todos-insert-item |
| 1266 | "" | 1261 | ;; idd todos-insert-item-ask-date |
| 1267 | (interactive "P") | 1262 | ;; idtt todos-insert-item-ask-date-time |
| 1268 | (todos-insert-item arg 'ask-date 'ask-time)) | 1263 | ;; idtyy todos-insert-item-ask-date-time-for-diary |
| 1264 | ;; idtyh todos-insert-item-ask-date-time-for-diary-here | ||
| 1265 | ;; idth todos-insert-item-ask-date-time-here | ||
| 1266 | ;; idyy todos-insert-item-ask-date-for-diary | ||
| 1267 | ;; idyh todos-insert-item-ask-date-for-diary-here | ||
| 1268 | ;; idh todos-insert-item-ask-date-here | ||
| 1269 | ;; inn todos-insert-item-ask-dayname | ||
| 1270 | ;; intt todos-insert-item-ask-dayname-time | ||
| 1271 | ;; intyy todos-insert-item-ask-dayname-time-for-diary | ||
| 1272 | ;; intyh todos-insert-item-ask-dayname-time-for-diary-here | ||
| 1273 | ;; inth todos-insert-item-ask-dayname-time-here | ||
| 1274 | ;; inyy todos-insert-item-ask-dayname-for-diary | ||
| 1275 | ;; inyh todos-insert-item-ask-dayname-for-diary-here | ||
| 1276 | ;; inh todos-insert-item-ask-dayname-here | ||
| 1277 | ;; itt todos-insert-item-time | ||
| 1278 | ;; ityy todos-insert-item-time-for-diary | ||
| 1279 | ;; ityh todos-insert-item-time-for-diary-here | ||
| 1280 | ;; ith todos-insert-item-time-here | ||
| 1281 | ;; iyy todos-insert-item-for-diary | ||
| 1282 | ;; iyh todos-insert-item-for-diary-here | ||
| 1283 | ;; ih todos-insert-item-here | ||
| 1269 | 1284 | ||
| 1270 | (defun todos-insert-item-ask-dayname-time (&optional arg) | 1285 | (defun todos-insert-item-here () |
| 1271 | "" | 1286 | "" |
| 1272 | (interactive) | 1287 | (interactive) |
| 1273 | (todos-insert-item arg 'ask-dayname 'ask-time)) | 1288 | (todos-insert-item nil nil nil nil t)) |
| 1274 | |||
| 1275 | (defun todos-insert-item-for-diary (&optional arg) | ||
| 1276 | "" | ||
| 1277 | (interactive "P") | ||
| 1278 | (let ((todos-include-in-diary t)) | ||
| 1279 | (todos-insert-item arg))) | ||
| 1280 | |||
| 1281 | (defun todos-insert-item-for-diary-ask-date-time (&optional arg) | ||
| 1282 | "" | ||
| 1283 | (interactive "P") | ||
| 1284 | (let ((todos-include-in-diary t)) | ||
| 1285 | (todos-insert-item arg 'ask-dayname 'ask-time))) | ||
| 1286 | 1289 | ||
| 1287 | ;; FIXME: autoload when key-binding is defined in calendar.el | 1290 | ;; FIXME: autoload when key-binding is defined in calendar.el |
| 1288 | (defun todos-insert-item-from-calendar () | 1291 | (defun todos-insert-item-from-calendar () |
| 1289 | "" | 1292 | "" |
| 1290 | (interactive) | 1293 | (interactive) |
| 1291 | (pop-to-buffer (file-name-nondirectory todos-file-do)) | 1294 | (pop-to-buffer (file-name-nondirectory todos-file-do)) |
| 1292 | (todos-show) | 1295 | (todos-show) ;FIXME: todos-category-select ? |
| 1293 | (todos-insert-item t 'calendar)) | 1296 | (todos-insert-item t 'calendar)) |
| 1294 | 1297 | ||
| 1295 | ;; FIXME: calendar is loaded before todos | 1298 | ;; FIXME: calendar is loaded before todos |
| @@ -1312,12 +1315,8 @@ there." | |||
| 1312 | (< (point-min) (point-max))) | 1315 | (< (point-min) (point-max))) |
| 1313 | (todos-backward-item)) | 1316 | (todos-backward-item)) |
| 1314 | (todos-item-counts (todos-current-category) 'delete) | 1317 | (todos-item-counts (todos-current-category) 'delete) |
| 1315 | ;; FIXME: is todos-prefix-overlays part of if-sexp, and is it needed | 1318 | (todos-prefix-overlays))) |
| 1316 | ;; at all? | 1319 | (message "No TODO list entry to delete"))) ;FIXME: better message |
| 1317 | ;; (if todos-number-prefix | ||
| 1318 | ;; (todos-update-numbered-prefix) | ||
| 1319 | (todos-prefix-overlays)));) | ||
| 1320 | (error "No TODO list entry to delete"))) | ||
| 1321 | 1320 | ||
| 1322 | (defun todos-edit-item () | 1321 | (defun todos-edit-item () |
| 1323 | "Edit current TODO list entry." | 1322 | "Edit current TODO list entry." |
| @@ -1382,23 +1381,14 @@ there." | |||
| 1382 | (todos-remove-item) | 1381 | (todos-remove-item) |
| 1383 | (todos-backward-item) | 1382 | (todos-backward-item) |
| 1384 | (todos-insert-with-overlays item)) | 1383 | (todos-insert-with-overlays item)) |
| 1385 | (error "No TODO list entry to raise"))))) | 1384 | (message "No TODO list entry to raise"))))) ;FIXME: better message |
| 1386 | 1385 | ||
| 1387 | (defun todos-lower-item () | 1386 | (defun todos-lower-item () |
| 1388 | "Lower priority of current entry." | 1387 | "Lower priority of current entry." |
| 1389 | (interactive) | 1388 | (interactive) |
| 1390 | (unless (or (todos-done-item-p) | 1389 | (unless (or (todos-done-item-p) |
| 1391 | (looking-at "^$")) ; between done and not done items | 1390 | (looking-at "^$")) ; between done and not done items |
| 1392 | (let* ((buffer-read-only) | 1391 | (let* ((buffer-read-only)) |
| 1393 | ;; (end (save-excursion (todos-forward-item) (point))) | ||
| 1394 | ;; (done (save-excursion | ||
| 1395 | ;; (if (re-search-forward (concat "\n\n\\\[" | ||
| 1396 | ;; (regexp-quote todos-done-string)) | ||
| 1397 | ;; nil t) | ||
| 1398 | ;; (match-beginning 0) | ||
| 1399 | ;; (point-max)))) | ||
| 1400 | ) | ||
| 1401 | ;; (if (> (count-lines (point) done) 1) | ||
| 1402 | (if (save-excursion | 1392 | (if (save-excursion |
| 1403 | ;; can only lower non-final unfinished item | 1393 | ;; can only lower non-final unfinished item |
| 1404 | (todos-forward-item) | 1394 | (todos-forward-item) |
| @@ -1410,7 +1400,7 @@ there." | |||
| 1410 | (todos-forward-item) | 1400 | (todos-forward-item) |
| 1411 | (when (todos-done-item-p) (forward-line -1)) | 1401 | (when (todos-done-item-p) (forward-line -1)) |
| 1412 | (todos-insert-with-overlays item)) | 1402 | (todos-insert-with-overlays item)) |
| 1413 | (error "No TODO list entry to lower"))))) ;FIXME: better message | 1403 | (message "No TODO list entry to lower"))))) ;FIXME: better message |
| 1414 | 1404 | ||
| 1415 | (defun todos-move-item () | 1405 | (defun todos-move-item () |
| 1416 | "Move the current todo item to another, interactively named, category. | 1406 | "Move the current todo item to another, interactively named, category. |
| @@ -1429,12 +1419,10 @@ it is created and the item becomes the first entry in that category." | |||
| 1429 | (orig-mrk (progn (todos-item-start) (point-marker))) | 1419 | (orig-mrk (progn (todos-item-start) (point-marker))) |
| 1430 | moved) | 1420 | moved) |
| 1431 | (todos-remove-item) | 1421 | (todos-remove-item) |
| 1432 | ;; numbered prefix isn't cached (see todos-remove-item) so have to update | ||
| 1433 | ;; (if todos-number-prefix (todos-update-numbered-prefix)) | ||
| 1434 | (unwind-protect | 1422 | (unwind-protect |
| 1435 | (progn | 1423 | (progn |
| 1436 | ;; (todos-add-item-non-interactively item newcat) | 1424 | (unless (member newcat todos-categories) (todos-add-category newcat)) |
| 1437 | (todos-set-item-priority item newcat) | 1425 | (todos-set-item-priority item newcat) |
| 1438 | (todos-insert-with-overlays item) | 1426 | (todos-insert-with-overlays item) |
| 1439 | (setq moved t) | 1427 | (setq moved t) |
| 1440 | (todos-item-counts oldcat 'delete) | 1428 | (todos-item-counts oldcat 'delete) |
| @@ -1444,8 +1432,6 @@ it is created and the item becomes the first entry in that category." | |||
| 1444 | (goto-char orig-mrk) | 1432 | (goto-char orig-mrk) |
| 1445 | (todos-insert-with-overlays item) | 1433 | (todos-insert-with-overlays item) |
| 1446 | (setq todos-category-number oldnum) | 1434 | (setq todos-category-number oldnum) |
| 1447 | ;; (todos-item-counts oldcat 'move-failed) | ||
| 1448 | ;; (todos-item-counts newcat 'move-failed) | ||
| 1449 | (todos-category-select) | 1435 | (todos-category-select) |
| 1450 | ;; FIXME: does this work? | 1436 | ;; FIXME: does this work? |
| 1451 | (goto-char opoint)) | 1437 | (goto-char opoint)) |
| @@ -1484,19 +1470,22 @@ it is created and the item becomes the first entry in that category." | |||
| 1484 | (newline)) | 1470 | (newline)) |
| 1485 | (todos-insert-with-overlays done-item))) | 1471 | (todos-insert-with-overlays done-item))) |
| 1486 | (todos-item-counts (todos-current-category) 'done) | 1472 | (todos-item-counts (todos-current-category) 'done) |
| 1487 | (todos-show))) | 1473 | (todos-category-select))) |
| 1488 | 1474 | ||
| 1489 | (defun todos-archive-done-items () | 1475 | (defun todos-archive-done-items () |
| 1490 | "Archive the done items in the current category." | 1476 | "Archive the done items in the current category." |
| 1491 | (interactive) | 1477 | (interactive) |
| 1492 | (let ((archive (find-file-noselect todos-archive-file t)) | 1478 | (let ((archive (find-file-noselect todos-archive-file t)) |
| 1493 | (cat (todos-current-category)) | 1479 | (cat (todos-current-category)) |
| 1480 | (buffer-read-only) | ||
| 1494 | beg end) | 1481 | beg end) |
| 1495 | (save-excursion | 1482 | (save-excursion |
| 1496 | (save-restriction | 1483 | (save-restriction |
| 1497 | (widen) | 1484 | (widen) |
| 1498 | (re-search-forward (concat "^" (regexp-quote todos-category-beg)) nil t) | 1485 | (setq end (if (re-search-forward |
| 1499 | (setq end (or (match-beginning 0) (point-max))) | 1486 | (concat "^" (regexp-quote todos-category-beg)) nil t) |
| 1487 | (match-beginning 0) | ||
| 1488 | (point-max))) | ||
| 1500 | (re-search-backward (concat "^" (regexp-quote todos-category-beg) | 1489 | (re-search-backward (concat "^" (regexp-quote todos-category-beg) |
| 1501 | (regexp-quote cat)) | 1490 | (regexp-quote cat)) |
| 1502 | nil t) | 1491 | nil t) |
| @@ -1512,7 +1501,8 @@ it is created and the item becomes the first entry in that category." | |||
| 1512 | nil t) | 1501 | nil t) |
| 1513 | (forward-char) | 1502 | (forward-char) |
| 1514 | (insert todos-category-beg cat "\n")) | 1503 | (insert todos-category-beg cat "\n")) |
| 1515 | (insert done)) | 1504 | (insert done) |
| 1505 | (save-buffer)) | ||
| 1516 | (delete-region beg end) | 1506 | (delete-region beg end) |
| 1517 | (remove-overlays beg end) | 1507 | (remove-overlays beg end) |
| 1518 | (kill-line -1) | 1508 | (kill-line -1) |
| @@ -1532,10 +1522,8 @@ it is created and the item becomes the first entry in that category." | |||
| 1532 | (item (buffer-substring start (todos-item-end))) | 1522 | (item (buffer-substring start (todos-item-end))) |
| 1533 | undone) | 1523 | undone) |
| 1534 | (todos-remove-item) | 1524 | (todos-remove-item) |
| 1535 | ;; (if todos-number-prefix (todos-update-numbered-prefix)) | ||
| 1536 | (unwind-protect | 1525 | (unwind-protect |
| 1537 | (progn | 1526 | (progn |
| 1538 | ;; (todos-add-item-non-interactively item cat) | ||
| 1539 | (todos-set-item-priority item cat) | 1527 | (todos-set-item-priority item cat) |
| 1540 | (todos-insert-with-overlays item) | 1528 | (todos-insert-with-overlays item) |
| 1541 | (setq undone t) | 1529 | (setq undone t) |
| @@ -1544,7 +1532,6 @@ it is created and the item becomes the first entry in that category." | |||
| 1544 | (widen) | 1532 | (widen) |
| 1545 | (goto-char orig-mrk) | 1533 | (goto-char orig-mrk) |
| 1546 | (todos-insert-with-overlays done-item) | 1534 | (todos-insert-with-overlays done-item) |
| 1547 | ;; (todos-item-counts cat 'done) | ||
| 1548 | (let ((todos-show-with-done t)) | 1535 | (let ((todos-show-with-done t)) |
| 1549 | (todos-category-select) | 1536 | (todos-category-select) |
| 1550 | (goto-char opoint))) | 1537 | (goto-char opoint))) |
| @@ -1679,7 +1666,6 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1679 | (make-local-variable 'word-wrap) | 1666 | (make-local-variable 'word-wrap) |
| 1680 | (setq word-wrap t) | 1667 | (setq word-wrap t) |
| 1681 | (make-local-variable 'wrap-prefix) | 1668 | (make-local-variable 'wrap-prefix) |
| 1682 | ;; (setq wrap-prefix (make-string (+ 5 (length todos-prefix)) 32)) | ||
| 1683 | (setq wrap-prefix (make-string todos-indent-to-here 32)) | 1669 | (setq wrap-prefix (make-string todos-indent-to-here 32)) |
| 1684 | (unless (member '(continuation) fringe-indicator-alist) | 1670 | (unless (member '(continuation) fringe-indicator-alist) |
| 1685 | (push '(continuation) fringe-indicator-alist))) | 1671 | (push '(continuation) fringe-indicator-alist))) |
| @@ -1688,53 +1674,6 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1688 | "" | 1674 | "" |
| 1689 | (indent-to todos-indent-to-here todos-indent-to-here)) | 1675 | (indent-to todos-indent-to-here todos-indent-to-here)) |
| 1690 | 1676 | ||
| 1691 | (defun todos-reset-prefix (symbol value) | ||
| 1692 | "Set SYMBOL's value to VALUE, and ." ; FIXME | ||
| 1693 | (let ((oldvalue (symbol-value symbol))) | ||
| 1694 | (custom-set-default symbol value) | ||
| 1695 | (when (not (equal value oldvalue)) | ||
| 1696 | (save-window-excursion | ||
| 1697 | (todos-show) | ||
| 1698 | (save-excursion | ||
| 1699 | (widen) | ||
| 1700 | (goto-char (point-min)) | ||
| 1701 | (while (not (eobp)) | ||
| 1702 | (remove-overlays (point) (point)); 'before-string prefix) | ||
| 1703 | (forward-line))) | ||
| 1704 | ;; activate the prefix setting (save-restriction does not help) | ||
| 1705 | ;; (todos-show) | ||
| 1706 | (todos-category-select) | ||
| 1707 | )))) | ||
| 1708 | |||
| 1709 | ;; FIXME: ??? with todos-lower-item leaves overlay of lower item if this is | ||
| 1710 | ;; the third or greater item number -- but not in edebug | ||
| 1711 | ;; (defun todos-update-numbered-prefix () | ||
| 1712 | ;; "Update consecutive item numbering in the current category." | ||
| 1713 | ;; (save-excursion | ||
| 1714 | ;; (goto-char (point-min)) | ||
| 1715 | ;; (while (not (eobp)) | ||
| 1716 | ;; (let ((ov (car (overlays-in (point) (point)))) | ||
| 1717 | ;; val) | ||
| 1718 | ;; (when ov | ||
| 1719 | ;; (setq val (overlay-get ov 'before-string)) | ||
| 1720 | ;; (remove-overlays (point) (point) 'before-string val))) | ||
| 1721 | ;; (todos-forward-item)) | ||
| 1722 | ;; (todos-show))) | ||
| 1723 | |||
| 1724 | ;; (defun todos-update-numbered-prefix () | ||
| 1725 | ;; "Update consecutive item numbering in the current category." | ||
| 1726 | ;; (save-excursion | ||
| 1727 | ;; (goto-char (point-min)) | ||
| 1728 | ;; (while (not (eobp)) | ||
| 1729 | ;; (remove-overlays (point) (point)) | ||
| 1730 | ;; (todos-forward-item)) | ||
| 1731 | ;; ;; FIXME: is todos-prefix-overlays enough? | ||
| 1732 | ;; (todos-show))) | ||
| 1733 | |||
| 1734 | ;; (defvar todos-item-start-overlays nil "") | ||
| 1735 | |||
| 1736 | ;; (defvar todos-done-overlays nil "") | ||
| 1737 | |||
| 1738 | (defun todos-prefix-overlays () | 1677 | (defun todos-prefix-overlays () |
| 1739 | "" | 1678 | "" |
| 1740 | (when (or todos-number-prefix | 1679 | (when (or todos-number-prefix |
| @@ -1750,31 +1689,16 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1750 | (when todos-number-prefix | 1689 | (when todos-number-prefix |
| 1751 | (setq num (1+ num)) | 1690 | (setq num (1+ num)) |
| 1752 | ;; reset number for done items | 1691 | ;; reset number for done items |
| 1753 | (when ;; (or | 1692 | (when |
| 1754 | ;; ;; FIXME: really need this? | 1693 | ;; FIXME: really need this? |
| 1755 | ;; (looking-at (concat "\n\\[" (regexp-quote todos-done-string))) | ||
| 1756 | ;; if last not done item is multiline, then | 1694 | ;; if last not done item is multiline, then |
| 1757 | ;; todos-done-string-match skips empty line, so have | 1695 | ;; todos-done-string-match skips empty line, so have |
| 1758 | ;; to look back. | 1696 | ;; to look back. |
| 1759 | (and (looking-at (concat "^\\[" (regexp-quote todos-done-string))) | 1697 | (and (looking-at (concat "^\\[" (regexp-quote todos-done-string))) |
| 1760 | (looking-back "\n\n"));) | 1698 | (looking-back "\n\n")) |
| 1761 | (setq num 1)) | 1699 | (setq num 1)) |
| 1762 | (setq prefix (propertize (concat (number-to-string num) " ") | 1700 | (setq prefix (propertize (concat (number-to-string num) " ") |
| 1763 | 'face 'todos-prefix-string))) | 1701 | 'face 'todos-prefix-string))) |
| 1764 | ;; (let ((ovs (overlays-in (point) (point)))) | ||
| 1765 | ;; (or (and (setq ov-pref (car ovs)) | ||
| 1766 | ;; ;; when done-separator overlay is in front of prefix overlay | ||
| 1767 | ;; (if (and (> (length ovs) 1) | ||
| 1768 | ;; (not (equal (overlay-get ov-pref 'before-string) | ||
| 1769 | ;; prefix))) | ||
| 1770 | ;; (setq ov-pref (cadr ovs)) | ||
| 1771 | ;; t) | ||
| 1772 | ;; (equal (overlay-get ov-pref 'before-string) prefix)) | ||
| 1773 | ;; ;; non-numerical prefix | ||
| 1774 | ;; (and (setq ov-pref (pop todos-item-start-overlays)) | ||
| 1775 | ;; (move-overlay ov-pref (point) (point))) | ||
| 1776 | ;; (and (setq ov-pref (make-overlay (point) (point))) | ||
| 1777 | ;; (overlay-put ov-pref 'before-string prefix)))) | ||
| 1778 | (let* ((ovs (overlays-in (point) (point))) | 1702 | (let* ((ovs (overlays-in (point) (point))) |
| 1779 | (ov-pref (car ovs)) | 1703 | (ov-pref (car ovs)) |
| 1780 | (val (when ov-pref (overlay-get ov-pref 'before-string)))) | 1704 | (val (when ov-pref (overlay-get ov-pref 'before-string)))) |
| @@ -1782,17 +1706,32 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1782 | (not (equal val prefix))) | 1706 | (not (equal val prefix))) |
| 1783 | (setq ov-pref (cadr ovs))) | 1707 | (setq ov-pref (cadr ovs))) |
| 1784 | (when (not (equal val prefix)) | 1708 | (when (not (equal val prefix)) |
| 1785 | ;; (delete-overlay ov-pref) | 1709 | ;; (delete-overlay ov-pref) ; why doesn't this work ??? |
| 1786 | (remove-overlays (point) (point)); 'before-string val) | 1710 | (remove-overlays (point) (point)); 'before-string val) ; or this ??? |
| 1787 | (setq ov-pref (make-overlay (point) (point))) | 1711 | (setq ov-pref (make-overlay (point) (point))) |
| 1788 | (overlay-put ov-pref 'before-string prefix)))) | 1712 | (overlay-put ov-pref 'before-string prefix)))) |
| 1789 | (forward-line)))))) | 1713 | (forward-line)))))) |
| 1790 | 1714 | ||
| 1715 | (defun todos-reset-prefix (symbol value) | ||
| 1716 | "Set SYMBOL's value to VALUE, and ." ; FIXME | ||
| 1717 | (let ((oldvalue (symbol-value symbol))) | ||
| 1718 | (custom-set-default symbol value) | ||
| 1719 | (when (not (equal value oldvalue)) | ||
| 1720 | (save-window-excursion | ||
| 1721 | (todos-show) | ||
| 1722 | (save-excursion | ||
| 1723 | (widen) | ||
| 1724 | (goto-char (point-min)) | ||
| 1725 | (while (not (eobp)) | ||
| 1726 | (remove-overlays (point) (point)); 'before-string prefix) | ||
| 1727 | (forward-line))) | ||
| 1728 | ;; activate the prefix setting (save-restriction does not help) | ||
| 1729 | (todos-category-select))))) | ||
| 1730 | |||
| 1791 | (defun todos-reset-separator (symbol value) | 1731 | (defun todos-reset-separator (symbol value) |
| 1792 | "Set SYMBOL's value to VALUE, and ." ; FIXME | 1732 | "Set SYMBOL's value to VALUE, and ." ; FIXME |
| 1793 | (let ((oldvalue (symbol-value symbol))) | 1733 | (let ((oldvalue (symbol-value symbol))) |
| 1794 | (custom-set-default symbol value) | 1734 | (custom-set-default symbol value) |
| 1795 | ;; (setq todos-done-overlays nil) | ||
| 1796 | (when (not (equal value oldvalue)) | 1735 | (when (not (equal value oldvalue)) |
| 1797 | (save-window-excursion | 1736 | (save-window-excursion |
| 1798 | (todos-show) | 1737 | (todos-show) |
| @@ -1802,7 +1741,7 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1802 | nil t) | 1741 | nil t) |
| 1803 | (remove-overlays (point) (point)))) | 1742 | (remove-overlays (point) (point)))) |
| 1804 | ;; activate the prefix setting (save-restriction does not help) | 1743 | ;; activate the prefix setting (save-restriction does not help) |
| 1805 | (todos-show))))) | 1744 | (todos-category-select))))) |
| 1806 | 1745 | ||
| 1807 | ;; FIXME: should be defsubst? | 1746 | ;; FIXME: should be defsubst? |
| 1808 | (defun todos-category-number (cat) | 1747 | (defun todos-category-number (cat) |
| @@ -1823,75 +1762,50 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1823 | (concat "^" (regexp-quote (concat todos-category-beg name)) | 1762 | (concat "^" (regexp-quote (concat todos-category-beg name)) |
| 1824 | "$")) | 1763 | "$")) |
| 1825 | (let ((begin (1+ (line-end-position))) | 1764 | (let ((begin (1+ (line-end-position))) |
| 1826 | (end (or (and (re-search-forward (concat "^" todos-category-beg) nil t) | 1765 | (end (if (re-search-forward (concat "^" todos-category-beg) nil t) |
| 1827 | (match-beginning 0)) | 1766 | (match-beginning 0) |
| 1828 | (point-max)))) | 1767 | (point-max)))) |
| 1829 | (narrow-to-region begin end) | 1768 | (narrow-to-region begin end) |
| 1830 | (goto-char (point-min)))) | 1769 | (goto-char (point-min)))) |
| 1831 | (todos-prefix-overlays) | 1770 | (todos-prefix-overlays) |
| 1832 | ;; display or hide done items as per todos-show-with-done | 1771 | (unless (eq major-mode 'todos-archive-mode) |
| 1833 | (save-excursion | 1772 | ;; display or hide done items as per todos-show-with-done |
| 1834 | (when (re-search-forward (concat "\n\\(\\[" (regexp-quote todos-done-string) | 1773 | (save-excursion |
| 1835 | "\\)") nil t) | 1774 | (when (re-search-forward (concat "\n\\(\\[" (regexp-quote todos-done-string) |
| 1836 | (let (done end done-sep prefix ov-pref ov-done) | 1775 | "\\)") nil t) |
| 1837 | (setq done (match-beginning 1) | 1776 | (let (done end done-sep prefix ov-pref ov-done) |
| 1838 | end (match-beginning 0)) | 1777 | (setq done (match-beginning 1) |
| 1839 | (if todos-show-with-done | 1778 | end (match-beginning 0)) |
| 1840 | (progn | 1779 | (if todos-show-with-done |
| 1841 | (setq done-sep todos-done-separator) | 1780 | (progn |
| 1842 | (unless (string-match "^[[:space:]]*$" todos-done-separator) | 1781 | (setq done-sep todos-done-separator) |
| 1843 | (setq done-sep (propertize (concat todos-done-separator "\n") | 1782 | (unless (string-match "^[[:space:]]*$" todos-done-separator) |
| 1844 | 'face 'todos-done-sep)) | 1783 | (setq done-sep (propertize (concat todos-done-separator "\n") |
| 1845 | (setq prefix (propertize | 1784 | 'face 'todos-done-sep)) |
| 1846 | (concat (if todos-number-prefix "1" todos-prefix) " ") | 1785 | (setq prefix (propertize (concat (if todos-number-prefix |
| 1847 | 'face 'todos-prefix-string)) | 1786 | "1" |
| 1848 | ;; FIXME? Just deleting done-sep overlay results in bad | 1787 | todos-prefix) " ") |
| 1849 | ;; display (except when stepping though in edebug) | 1788 | 'face 'todos-prefix-string)) |
| 1850 | (remove-overlays done done) | 1789 | ;; FIXME? Just deleting done-sep overlay results in bad |
| 1851 | ;; must make separator overlay after making prefix overlay to get | 1790 | ;; display (except when stepping though in edebug) |
| 1852 | ;; the order separator before prefix | 1791 | (remove-overlays done done) |
| 1853 | (setq ov-pref (make-overlay done done) | 1792 | ;; must make separator overlay after making prefix overlay to get |
| 1854 | ov-done (make-overlay done done)) | 1793 | ;; the order separator before prefix |
| 1855 | (overlay-put ov-pref 'before-string prefix) | 1794 | (setq ov-pref (make-overlay done done) |
| 1856 | (overlay-put ov-done 'before-string done-sep))) | 1795 | ov-done (make-overlay done done)) |
| 1857 | (narrow-to-region (point-min) end)))))) | 1796 | (overlay-put ov-pref 'before-string prefix) |
| 1858 | 1797 | (overlay-put ov-done 'before-string done-sep))) | |
| 1859 | ;; FIXME: why autoload? | 1798 | (narrow-to-region (point-min) end))))))) |
| 1860 | ;;;###autoload | ||
| 1861 | ;; (defun todos-add-item-non-interactively (item category) | ||
| 1862 | ;; "Insert item ITEM into category CATEGORY and set its priority." | ||
| 1863 | ;; (todos-category-number category) | ||
| 1864 | ;; (todos-show) ; now at point-min | ||
| 1865 | ;; (unless (or (eq (point-min) (point-max)) ; no unfinished items | ||
| 1866 | ;; (when (re-search-forward (concat "^\\[" | ||
| 1867 | ;; (regexp-quote todos-done-string)) | ||
| 1868 | ;; nil t) | ||
| 1869 | ;; (forward-line -1) | ||
| 1870 | ;; (bobp))) ; there are done items but no unfinished items | ||
| 1871 | ;; (let* ((maxnum (1+ (car (todos-item-counts category)))) | ||
| 1872 | ;; priority candidate prompt) | ||
| 1873 | ;; (while (null priority) | ||
| 1874 | ;; (setq candidate | ||
| 1875 | ;; (string-to-number (read-from-minibuffer | ||
| 1876 | ;; (concat prompt | ||
| 1877 | ;; (format "Set item priority (1-%d): " | ||
| 1878 | ;; maxnum))))) | ||
| 1879 | ;; (setq prompt | ||
| 1880 | ;; (when (or (< candidate 1) (> candidate maxnum)) | ||
| 1881 | ;; (format "Priority must be an integer between 1 and %d.\n" maxnum))) | ||
| 1882 | ;; (unless prompt (setq priority candidate))) | ||
| 1883 | ;; (goto-char (point-min)) | ||
| 1884 | ;; (unless (= priority 1) (todos-forward-item (1- priority))))) | ||
| 1885 | ;; (todos-insert-with-overlays item)) | ||
| 1886 | 1799 | ||
| 1887 | (defun todos-set-item-priority (item cat) | 1800 | (defun todos-set-item-priority (item cat) |
| 1888 | "Set the priority of unfinished item ITEM in category CAT." | 1801 | "Set the priority of unfinished item ITEM in category CAT." |
| 1889 | (todos-category-number cat) | 1802 | (todos-category-number cat) |
| 1890 | (todos-category-select) | 1803 | (todos-category-select) |
| 1891 | (let* ((not-done (car (todos-item-counts cat))) | 1804 | (let* ((catsym (intern-soft (concat "todos-" cat))) |
| 1892 | (maxnum (1+ not-done)) | 1805 | (todo (get catsym 'todo)) |
| 1806 | (maxnum (1+ todo)) | ||
| 1893 | priority candidate prompt) | 1807 | priority candidate prompt) |
| 1894 | (unless (zerop not-done) | 1808 | (unless (zerop todo) |
| 1895 | (while (null priority) | 1809 | (while (null priority) |
| 1896 | (setq candidate | 1810 | (setq candidate |
| 1897 | (string-to-number (read-from-minibuffer | 1811 | (string-to-number (read-from-minibuffer |
| @@ -1907,13 +1821,14 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1907 | 1821 | ||
| 1908 | (defun todos-jump-to-category-noninteractively (cat) | 1822 | (defun todos-jump-to-category-noninteractively (cat) |
| 1909 | "" | 1823 | "" |
| 1910 | (let ((bufname (buffer-name))) | 1824 | ;; (let ((bufname (buffer-name))) |
| 1911 | (cond ((string= bufname todos-categories-buffer) | 1825 | ;; (cond ((string= bufname todos-categories-buffer) |
| 1912 | (switch-to-buffer (file-name-nondirectory todos-file-do))) | 1826 | ;; (switch-to-buffer (file-name-nondirectory todos-file-do))) |
| 1913 | ((string= bufname todos-archived-categories-buffer) | 1827 | ;; ((string= bufname todos-archived-categories-buffer) |
| 1914 | ;; FIXME: is pop-to-buffer better for this case? | 1828 | ;; ;; FIXME: is pop-to-buffer better for this case? |
| 1915 | (switch-to-buffer (file-name-nondirectory todos-archive-file)))) | 1829 | ;; (switch-to-buffer (file-name-nondirectory todos-archive-file)))) |
| 1916 | (kill-buffer bufname)) | 1830 | ;; (kill-buffer bufname)) |
| 1831 | (switch-to-buffer (file-name-nondirectory todos-current-todos-file)) | ||
| 1917 | (widen) | 1832 | (widen) |
| 1918 | (goto-char (point-min)) | 1833 | (goto-char (point-min)) |
| 1919 | (todos-category-number cat) | 1834 | (todos-category-number cat) |
| @@ -1924,9 +1839,7 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1924 | (todos-item-start) | 1839 | (todos-item-start) |
| 1925 | (insert item "\n") | 1840 | (insert item "\n") |
| 1926 | (todos-backward-item) | 1841 | (todos-backward-item) |
| 1927 | ;; (if todos-number-prefix | 1842 | (todos-prefix-overlays)) |
| 1928 | ;; (todos-update-numbered-prefix) | ||
| 1929 | (todos-prefix-overlays));) | ||
| 1930 | 1843 | ||
| 1931 | (defun todos-item-string-start () | 1844 | (defun todos-item-string-start () |
| 1932 | "Return the start of this TODO list entry as a string." | 1845 | "Return the start of this TODO list entry as a string." |
| @@ -1966,10 +1879,6 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1966 | (end (progn (todos-item-end) (1+ (point)))) | 1879 | (end (progn (todos-item-end) (1+ (point)))) |
| 1967 | (ov-start (car (overlays-in beg beg)))) | 1880 | (ov-start (car (overlays-in beg beg)))) |
| 1968 | (when ov-start | 1881 | (when ov-start |
| 1969 | ;; ;; don't cache numbers, since they can be popped out of order in | ||
| 1970 | ;; ;; todos-prefix-overlays | ||
| 1971 | ;; (unless todos-number-prefix | ||
| 1972 | ;; (push ov-start todos-item-start-overlays)) | ||
| 1973 | (delete-overlay ov-start)) | 1882 | (delete-overlay ov-start)) |
| 1974 | (delete-region beg end))) | 1883 | (delete-region beg end))) |
| 1975 | 1884 | ||
| @@ -1983,65 +1892,79 @@ Number of entries for each category is given by `todos-print-priorities'." | |||
| 1983 | (todos-item-start) | 1892 | (todos-item-start) |
| 1984 | (looking-at (concat "^\\[" (regexp-quote todos-done-string))))) | 1893 | (looking-at (concat "^\\[" (regexp-quote todos-done-string))))) |
| 1985 | 1894 | ||
| 1986 | 1895 | (defun todos-make-categories-list () | |
| 1987 | (defvar todos-categories-alist nil | 1896 | "Return a list of Todos categories and set their property lists. |
| 1988 | "Variable for storing the result of todos-make-categories-alist.") | 1897 | The properties are at least the category number and the numbers |
| 1989 | (defun todos-make-categories-alist () | 1898 | of todo items, done items and archived items in the category." |
| 1990 | "Return an alist of categories and some of their properties. | 1899 | (let (catlist) |
| 1991 | The properties are at least the numbers of the unfinished and | ||
| 1992 | done items in the category." | ||
| 1993 | (let (todos-categories-alist) | ||
| 1994 | (save-excursion | 1900 | (save-excursion |
| 1995 | (save-restriction | 1901 | (save-restriction |
| 1996 | (widen) | 1902 | (widen) |
| 1997 | (goto-char (point-min)) | 1903 | (goto-char (point-min)) |
| 1998 | (let ((not-done 0) | 1904 | (let ((num 0) |
| 1999 | (done 0) | 1905 | cat catsym archive-check) |
| 2000 | category beg end) | ||
| 2001 | (while (not (eobp)) | 1906 | (while (not (eobp)) |
| 2002 | (cond ((looking-at (concat (regexp-quote todos-category-beg) | 1907 | (cond ((looking-at (concat (regexp-quote todos-category-beg) |
| 2003 | "\\(.*\\)\n")) | 1908 | "\\(.*\\)\n")) |
| 2004 | (setq not-done 0 done 0) | 1909 | (setq cat (match-string-no-properties 1)) |
| 2005 | (push (list (match-string-no-properties 1) (cons not-done done)) | 1910 | (setq num (1+ num)) |
| 2006 | todos-categories-alist)) | 1911 | (setq archive-check nil) |
| 1912 | ;; FIXME: ok to intern in global obarray? | ||
| 1913 | (setq catsym (intern (concat "todos-" cat))) | ||
| 1914 | (setplist catsym (list 'catnum num 'todo 0 'done 0 'archived 0)) | ||
| 1915 | (push cat catlist)) | ||
| 2007 | ((looking-at (concat "^\\[" (regexp-quote todos-done-string))) | 1916 | ((looking-at (concat "^\\[" (regexp-quote todos-done-string))) |
| 2008 | (setq done (1+ done)) | 1917 | (put catsym 'done (1+ (get catsym 'done)))) |
| 2009 | (setcdr (cadr (car todos-categories-alist)) done)) | ||
| 2010 | ((looking-at (concat "^\\[?" todos-date-pattern)) | 1918 | ((looking-at (concat "^\\[?" todos-date-pattern)) |
| 2011 | (setq not-done (1+ not-done)) | 1919 | (put catsym 'todo (1+ (get catsym 'todo))))) |
| 2012 | (setcar (cadr (car todos-categories-alist)) not-done))) | 1920 | (unless (or archive-check |
| 1921 | (string= (buffer-file-name) | ||
| 1922 | (expand-file-name todos-archive-file))) | ||
| 1923 | (let ((archive (find-file-noselect todos-archive-file))) | ||
| 1924 | (with-current-buffer archive | ||
| 1925 | (goto-char (point-min)) | ||
| 1926 | (when (re-search-forward | ||
| 1927 | (concat (regexp-quote todos-category-beg) cat) | ||
| 1928 | (point-max) t) | ||
| 1929 | (forward-line) | ||
| 1930 | (while (not (or (looking-at | ||
| 1931 | (concat (regexp-quote todos-category-beg) | ||
| 1932 | "\\(.*\\)\n")) | ||
| 1933 | (eobp))) | ||
| 1934 | (when (looking-at | ||
| 1935 | (concat "^\\[" (regexp-quote todos-done-string))) | ||
| 1936 | (put catsym 'archived (1+ (get catsym 'archived)))) | ||
| 1937 | (forward-line))))) | ||
| 1938 | (setq archive-check t)) | ||
| 2013 | (forward-line))))) | 1939 | (forward-line))))) |
| 2014 | todos-categories-alist)) | 1940 | catlist)) |
| 2015 | 1941 | ||
| 2016 | (defun todos-item-counts (cat &optional how) | 1942 | (defun todos-item-counts (cat &optional how) |
| 2017 | "" | 1943 | "" |
| 2018 | (let* ((counts (cadr (assoc cat todos-categories-alist))) | 1944 | (let ((catsym (intern-soft (concat "todos-" cat)))) |
| 2019 | (not-done (car counts)) | 1945 | ;; FIXME: need this? |
| 2020 | (done (cdr counts))) | 1946 | ;; (when catsym |
| 2021 | (cond ((eq how 'insert) | 1947 | (cond ((eq how 'insert) |
| 2022 | (setcar counts (1+ not-done))) | 1948 | (put catsym 'todo (1+ (get catsym 'todo)))) |
| 2023 | ((eq how 'delete) | 1949 | ((eq how 'delete) |
| 2024 | (if (todos-done-item-p) ;FIXME: fails if last done item was deleted | 1950 | (if (todos-done-item-p) ;FIXME: fails if last done item was deleted |
| 2025 | (setcdr counts (1- done)) | 1951 | (put catsym 'done (1- (get catsym 'done))) |
| 2026 | (setcar counts (1- not-done)))) | 1952 | (put catsym 'todo (1- (get catsym 'todo))))) |
| 2027 | ;; ((eq how 'move-failed) | ||
| 2028 | ;; (setcar counts not-done)) | ||
| 2029 | ((eq how 'done) | 1953 | ((eq how 'done) |
| 2030 | (setcar counts (1- not-done)) | 1954 | (put catsym 'todo (1- (get catsym 'todo))) |
| 2031 | (setcdr counts (1+ done))) | 1955 | (put catsym 'done (1+ (get catsym 'done)))) |
| 2032 | ((eq how 'undo) | 1956 | ((eq how 'undo) |
| 2033 | (setcar counts (1+ not-done)) | 1957 | (put catsym 'todo (1+ (get catsym 'todo))) |
| 2034 | (setcdr counts (1- done))) | 1958 | (put catsym 'done (1- (get catsym 'done)))) |
| 2035 | ((eq how 'archive) | 1959 | ((eq how 'archive) |
| 2036 | (setcdr counts 0)) | 1960 | (put catsym 'archived (+ (get catsym 'done) (get catsym 'archived))) |
| 2037 | (t | 1961 | (put catsym 'done 0))))) |
| 2038 | (cons not-done done))))) | ||
| 2039 | 1962 | ||
| 2040 | (defun todos-longest-category-name-length (categories) | 1963 | (defun todos-longest-category-name-length (categories) |
| 2041 | "" | 1964 | "" |
| 2042 | (let ((longest 0)) | 1965 | (let ((longest 0)) |
| 2043 | (dolist (c categories longest) | 1966 | (dolist (c categories longest) |
| 2044 | (setq longest (max longest (length (car c))))))) | 1967 | (setq longest (max longest (length c)))))) |
| 2045 | 1968 | ||
| 2046 | (defun todos-string-count-lines (string) | 1969 | (defun todos-string-count-lines (string) |
| 2047 | "Return the number of lines STRING spans." | 1970 | "Return the number of lines STRING spans." |
| @@ -2052,7 +1975,7 @@ done items in the category." | |||
| 2052 | (> (todos-string-count-lines string) 1)) | 1975 | (> (todos-string-count-lines string) 1)) |
| 2053 | 1976 | ||
| 2054 | (defun todos-read-category () | 1977 | (defun todos-read-category () |
| 2055 | "Return an existing category name, with tab completion." | 1978 | "Return a category name (existing names with tab completion)." |
| 2056 | ;; allow SPC to insert spaces, for adding new category names with | 1979 | ;; allow SPC to insert spaces, for adding new category names with |
| 2057 | ;; todos-move-item | 1980 | ;; todos-move-item |
| 2058 | (let ((map minibuffer-local-completion-map)) | 1981 | (let ((map minibuffer-local-completion-map)) |
| @@ -2076,7 +1999,8 @@ done items in the category." | |||
| 2076 | (while (and (cond ((string= "" cat) | 1999 | (while (and (cond ((string= "" cat) |
| 2077 | (setq prompt "Enter a non-empty category name: ")) | 2000 | (setq prompt "Enter a non-empty category name: ")) |
| 2078 | ((string-match "\\`\\s-+\\'" cat) | 2001 | ((string-match "\\`\\s-+\\'" cat) |
| 2079 | (setq prompt "Enter a category name that is not only white space: ")) | 2002 | (setq prompt |
| 2003 | "Enter a category name that is not only white space: ")) | ||
| 2080 | ((member cat todos-categories) | 2004 | ((member cat todos-categories) |
| 2081 | (setq prompt "Enter a non-existing category name: "))) | 2005 | (setq prompt "Enter a non-existing category name: "))) |
| 2082 | (setq cat (read-from-minibuffer prompt))))) | 2006 | (setq cat (read-from-minibuffer prompt))))) |
| @@ -2120,28 +2044,28 @@ done items in the category." | |||
| 2120 | (let (valid answer) | 2044 | (let (valid answer) |
| 2121 | (while (not valid) | 2045 | (while (not valid) |
| 2122 | (setq answer (read-from-minibuffer | 2046 | (setq answer (read-from-minibuffer |
| 2123 | "Enter a clock time: ")) | 2047 | "Enter a clock time (or return for none): ")) |
| 2124 | (when (or (string= "" answer) | 2048 | (when (or (string= "" answer) |
| 2125 | (string-match diary-time-regexp answer)) | 2049 | (string-match diary-time-regexp answer)) |
| 2126 | (setq valid t))) | 2050 | (setq valid t))) |
| 2127 | answer)) | 2051 | answer)) |
| 2128 | 2052 | ||
| 2129 | (defun todos-categories-list (buf) | 2053 | ;; (defun todos-categories-list (buf) |
| 2130 | "Return a list of the Todo mode categories in buffer BUF." | 2054 | ;; "Return a list of the Todo mode categories in buffer BUF." |
| 2131 | (let (categories) | 2055 | ;; (let (categories) |
| 2132 | (with-current-buffer buf | 2056 | ;; (with-current-buffer buf |
| 2133 | (save-excursion | 2057 | ;; (save-excursion |
| 2134 | (save-restriction | 2058 | ;; (save-restriction |
| 2135 | (widen) | 2059 | ;; (widen) |
| 2136 | (goto-char (point-max)) | 2060 | ;; (goto-char (point-max)) |
| 2137 | (while (re-search-backward (concat "^" (regexp-quote todos-category-beg) | 2061 | ;; (while (re-search-backward (concat "^" (regexp-quote todos-category-beg) |
| 2138 | "\\(.*\\)\n") nil t) | 2062 | ;; "\\(.*\\)\n") nil t) |
| 2139 | (push (match-string-no-properties 1) categories))))) | 2063 | ;; (push (match-string-no-properties 1) categories))))) |
| 2140 | categories)) | 2064 | ;; categories)) |
| 2141 | 2065 | ||
| 2142 | (defun todos-padded-string (str) | 2066 | (defun todos-padded-string (str) |
| 2143 | "" | 2067 | "" |
| 2144 | (let* ((len (todos-longest-category-name-length todos-categories-alist)) | 2068 | (let* ((len (todos-longest-category-name-length todos-categories)) |
| 2145 | (strlen (length str)) | 2069 | (strlen (length str)) |
| 2146 | (strlen-odd (eq (logand strlen 1) 1)) ; oddp from cl.el | 2070 | (strlen-odd (eq (logand strlen 1) 1)) ; oddp from cl.el |
| 2147 | (padding (/ (- len strlen) 2))) | 2071 | (padding (/ (- len strlen) 2))) |
| @@ -2150,9 +2074,8 @@ done items in the category." | |||
| 2150 | 2074 | ||
| 2151 | (defun todos-insert-category-name (cat &optional nonum) | 2075 | (defun todos-insert-category-name (cat &optional nonum) |
| 2152 | "" | 2076 | "" |
| 2153 | (let* ((buf (get-buffer (file-name-nondirectory todos-file-do))) | 2077 | (let ((catsym (intern-soft (concat "todos-" cat))) |
| 2154 | (cat-alist todos-categories-alist) | 2078 | (archive (string= todos-current-todos-file todos-archive-file))) |
| 2155 | (counts (todos-item-counts cat))) | ||
| 2156 | ;; num is declared in caller | 2079 | ;; num is declared in caller |
| 2157 | (setq num (1+ num)) | 2080 | (setq num (1+ num)) |
| 2158 | (if nonum | 2081 | (if nonum |
| @@ -2163,11 +2086,17 @@ done items in the category." | |||
| 2163 | 'action | 2086 | 'action |
| 2164 | `(lambda (button) | 2087 | `(lambda (button) |
| 2165 | (todos-jump-to-category-noninteractively ,cat))) | 2088 | (todos-jump-to-category-noninteractively ,cat))) |
| 2166 | (insert (make-string 8 32) | 2089 | (insert (concat (make-string 8 32) |
| 2167 | (format "%2d" (car counts)) | 2090 | (unless archive |
| 2168 | (make-string 5 32) | 2091 | (concat |
| 2169 | (format "%2d" (cdr counts))) | 2092 | (format "%2d" (get catsym 'todo)) |
| 2170 | (newline))) | 2093 | (make-string 5 32))) |
| 2094 | (format "%2d" (get catsym 'done)) | ||
| 2095 | (unless archive | ||
| 2096 | (concat | ||
| 2097 | (make-string 5 32) | ||
| 2098 | (format "%2d" (get catsym 'archived)))) | ||
| 2099 | "\n")))) | ||
| 2171 | 2100 | ||
| 2172 | (defun todos-initial-setup () | 2101 | (defun todos-initial-setup () |
| 2173 | "Set up things to work properly in TODO mode." | 2102 | "Set up things to work properly in TODO mode." |
| @@ -2178,4 +2107,25 @@ done items in the category." | |||
| 2178 | 2107 | ||
| 2179 | (provide 'todos) | 2108 | (provide 'todos) |
| 2180 | 2109 | ||
| 2110 | ;;; UI | ||
| 2111 | ;; - display | ||
| 2112 | ;; - show todos in cat | ||
| 2113 | ;; - show done in cat | ||
| 2114 | ;; - show catlist | ||
| 2115 | ;; - show top priorities in all cats | ||
| 2116 | ;; - show archived | ||
| 2117 | ;; - navigation | ||
| 2118 | ;; - | ||
| 2119 | ;; - editing | ||
| 2120 | ;; | ||
| 2121 | ;;; Internals | ||
| 2122 | ;; - cat props: name, number, todos, done, archived | ||
| 2123 | ;; - item props: priority, date-time, status? | ||
| 2124 | ;; - file format | ||
| 2125 | ;; - cat begin | ||
| 2126 | ;; - todo items 0...n | ||
| 2127 | ;; - empty line | ||
| 2128 | ;; - done-separator | ||
| 2129 | ;; - done item 0...n | ||
| 2130 | |||
| 2181 | ;;; todos.el ends here | 2131 | ;;; todos.el ends here |