diff options
| -rw-r--r-- | lisp/ChangeLog | 26 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 222 |
2 files changed, 96 insertions, 152 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index bd3e2b601ba..dc42aa7bb28 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,31 @@ | |||
| 1 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> | 1 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> |
| 2 | 2 | ||
| 3 | * calendar/todos.el (todos-ignore-archived-categories): | ||
| 4 | Revert last change; remove :initialize and :set functions; change | ||
| 5 | use and change users accordingly. | ||
| 6 | (todos-reset-categories, todos-categories-full) | ||
| 7 | (todos-truncate-categories-list): Remove. | ||
| 8 | (todos-set-categories, todos-update-categories-sexp): | ||
| 9 | Use todos-categories instead of todos-categories-full; remove use | ||
| 10 | of todos-ignore-archived-categories and | ||
| 11 | todos-truncate-categories-list. | ||
| 12 | (todos-check-format, todos-repair-categories-sexp): | ||
| 13 | Use todos-categories instead of todos-categories-full. | ||
| 14 | (todos-read-category): Improve last change. | ||
| 15 | (todos-validate-name): Use completing-read. | ||
| 16 | (todos-categories-category-number): Rename from | ||
| 17 | todos-category-number and adjust users. | ||
| 18 | (todos-update-categories-display, todos-mode-external-set) | ||
| 19 | (todos-delete-category, todos-move-category, todos-merge-category) | ||
| 20 | (todos-unarchive-items): Remove use of todos-categories-full and | ||
| 21 | todos-ignore-archived-categories. | ||
| 22 | (todos-modes-set-3, todos-add-category): Remove use of | ||
| 23 | todos-categories-full. | ||
| 24 | (todos-edit-mode): Fix typo. | ||
| 25 | (todos-forward-category): Use todos-ignore-archived-categories. | ||
| 26 | |||
| 27 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> | ||
| 28 | |||
| 3 | * calendar/todos.el: Doubts about todos-ignore-archived-categories. | 29 | * calendar/todos.el: Doubts about todos-ignore-archived-categories. |
| 4 | (todos-ignore-archived-categories): Change default value. | 30 | (todos-ignore-archived-categories): Change default value. |
| 5 | 31 | ||
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el index 7ecd4d03ade..aa935b5e9e0 100644 --- a/lisp/calendar/todos.el +++ b/lisp/calendar/todos.el | |||
| @@ -341,34 +341,16 @@ Done items from corresponding archive files are also included." | |||
| 341 | :type 'boolean | 341 | :type 'boolean |
| 342 | :group 'todos) | 342 | :group 'todos) |
| 343 | 343 | ||
| 344 | ;; FIXME: make this effect only navigation? | 344 | (defcustom todos-ignore-archived-categories nil |
| 345 | (defcustom todos-ignore-archived-categories t | 345 | "Non-nil to skip categories with only archived items when browsing. |
| 346 | "Non-nil to ignore categories with only archived items. | 346 | |
| 347 | When non-nil such categories are omitted from `todos-categories' | ||
| 348 | and hence from commands that use this variable. An exception is | ||
| 349 | \\[todos-display-categories], which displays all categories; but | 347 | \\[todos-display-categories], which displays all categories; but |
| 350 | those with only archived items are shown in `todos-archived-only' | 348 | those with only archived items are shown in `todos-archived-only' |
| 351 | face and clicking them in Todos Categories mode visits the | 349 | face and clicking them in Todos Categories mode visits the |
| 352 | archived categories." | 350 | archived categories." ;FIXME |
| 353 | :type 'boolean | 351 | :type 'boolean |
| 354 | :initialize 'custom-initialize-default | ||
| 355 | :set 'todos-reset-categories | ||
| 356 | :group 'todos) | 352 | :group 'todos) |
| 357 | 353 | ||
| 358 | ;; FIXME: if this is saved and todos.el is loaded before custom-file, | ||
| 359 | ;; categories mode does not show archived categories | ||
| 360 | (defun todos-reset-categories (symbol value) | ||
| 361 | "The :set function for `todos-ignore-archived-categories'." | ||
| 362 | (custom-set-default symbol value) | ||
| 363 | (dolist (f (funcall todos-files-function)) | ||
| 364 | (with-current-buffer (find-file-noselect f) | ||
| 365 | (if value | ||
| 366 | (setq todos-categories-full todos-categories | ||
| 367 | todos-categories (todos-truncate-categories-list)) | ||
| 368 | (setq todos-categories todos-categories-full | ||
| 369 | todos-categories-full nil)) | ||
| 370 | (todos-category-select)))) | ||
| 371 | |||
| 372 | (defcustom todos-use-only-highlighted-region t | 354 | (defcustom todos-use-only-highlighted-region t |
| 373 | "Non-nil to enable inserting only highlighted region as new item." | 355 | "Non-nil to enable inserting only highlighted region as new item." |
| 374 | :type 'boolean | 356 | :type 'boolean |
| @@ -910,26 +892,12 @@ This function is added to `pre-command-hook' when user option | |||
| 910 | (member major-mode '(todos-mode todos-archive-mode)) | 892 | (member major-mode '(todos-mode todos-archive-mode)) |
| 911 | (todos-category-select))) | 893 | (todos-category-select))) |
| 912 | 894 | ||
| 913 | ;; FIXME: This slows down C-x C-k, can it be optimized? E.g. make | 895 | ;; FIXME: this slows down killing Todos buffer noticeably |
| 914 | ;; todos-buffer-list as cache | ||
| 915 | (defun todos-reset-global-current-todos-file () | 896 | (defun todos-reset-global-current-todos-file () |
| 916 | "Update the value of `todos-global-current-todos-file'. | 897 | "Update the value of `todos-global-current-todos-file'. |
| 917 | This becomes the latest existing Todos file or, if there is none, | 898 | This becomes the latest existing Todos file or, if there is none, |
| 918 | the value of `todos-default-todos-file'. | 899 | the value of `todos-default-todos-file'. |
| 919 | This function is added to `kill-buffer-hook' in Todos mode." | 900 | This function is added to `kill-buffer-hook' in Todos mode." |
| 920 | ;; (let ((buflist (copy-sequence (buffer-list))) | ||
| 921 | ;; (cur todos-global-current-todos-file)) | ||
| 922 | ;; (catch 'done | ||
| 923 | ;; (while buflist | ||
| 924 | ;; (let* ((buf (pop buflist)) | ||
| 925 | ;; (bufname (buffer-file-name buf))) | ||
| 926 | ;; (when bufname (setq bufname (file-truename bufname))) | ||
| 927 | ;; (when (and (member bufname (funcall todos-files-function)) | ||
| 928 | ;; (not (eq buf (current-buffer)))) | ||
| 929 | ;; (setq todos-global-current-todos-file bufname) | ||
| 930 | ;; (throw 'done nil))))) | ||
| 931 | ;; (if (equal cur todos-global-current-todos-file) | ||
| 932 | ;; (setq todos-global-current-todos-file todos-default-todos-file)))) | ||
| 933 | (let ((todos-buffer-list (nreverse | 901 | (let ((todos-buffer-list (nreverse |
| 934 | (remove-if-not | 902 | (remove-if-not |
| 935 | (lambda (f) | 903 | (lambda (f) |
| @@ -938,11 +906,6 @@ This function is added to `kill-buffer-hook' in Todos mode." | |||
| 938 | (funcall todos-files-function)))) | 906 | (funcall todos-files-function)))) |
| 939 | (mapcar 'buffer-name (buffer-list))))) | 907 | (mapcar 'buffer-name (buffer-list))))) |
| 940 | latest) | 908 | latest) |
| 941 | ;; (while todos-buffer-list | ||
| 942 | ;; (let ((todos-bufname (pop todos-buffer-list))) | ||
| 943 | ;; (unless (string= todos-bufname (buffer-name)) | ||
| 944 | ;; (setq latest todos-bufname | ||
| 945 | ;; todos-buffer-list nil)))) | ||
| 946 | (setq latest (find-if-not (lambda (f) (string= f (buffer-name))) | 909 | (setq latest (find-if-not (lambda (f) (string= f (buffer-name))) |
| 947 | todos-buffer-list)) | 910 | todos-buffer-list)) |
| 948 | (setq todos-global-current-todos-file (or latest todos-default-todos-file)))) | 911 | (setq todos-global-current-todos-file (or latest todos-default-todos-file)))) |
| @@ -954,12 +917,6 @@ whose cdr is a vector of the category's item counts. These are, | |||
| 954 | in order, the numbers of todo items, of todo items included in | 917 | in order, the numbers of todo items, of todo items included in |
| 955 | the Diary, of done items and of archived items.") | 918 | the Diary, of done items and of archived items.") |
| 956 | 919 | ||
| 957 | (defvar todos-categories-full nil | ||
| 958 | "Variable holding non-truncated copy of `todos-categories'. | ||
| 959 | Set when `todos-ignore-archived-categories' is set to non-nil, to | ||
| 960 | restore full `todos-categories' list when | ||
| 961 | `todos-ignore-archived-categories' is reset to nil.") | ||
| 962 | |||
| 963 | (defvar todos-categories-with-marks nil | 920 | (defvar todos-categories-with-marks nil |
| 964 | "Alist of categories and number of marked items they contain.") | 921 | "Alist of categories and number of marked items they contain.") |
| 965 | 922 | ||
| @@ -1109,7 +1066,6 @@ number as its value." | |||
| 1109 | "Return count of TYPE items in CATEGORY. | 1066 | "Return count of TYPE items in CATEGORY. |
| 1110 | If CATEGORY is nil, default to the current category." | 1067 | If CATEGORY is nil, default to the current category." |
| 1111 | (let* ((cat (or category (todos-current-category))) | 1068 | (let* ((cat (or category (todos-current-category))) |
| 1112 | ;; FIXME: todos-categories-full? | ||
| 1113 | (counts (cdr (assoc cat todos-categories))) | 1069 | (counts (cdr (assoc cat todos-categories))) |
| 1114 | (idx (cond ((eq type 'todo) 0) | 1070 | (idx (cond ((eq type 'todo) 0) |
| 1115 | ((eq type 'diary) 1) | 1071 | ((eq type 'diary) 1) |
| @@ -1121,7 +1077,6 @@ If CATEGORY is nil, default to the current category." | |||
| 1121 | "Change count of TYPE items in CATEGORY by integer INCREMENT. | 1077 | "Change count of TYPE items in CATEGORY by integer INCREMENT. |
| 1122 | With nil or omitted CATEGORY, default to the current category." | 1078 | With nil or omitted CATEGORY, default to the current category." |
| 1123 | (let* ((cat (or category (todos-current-category))) | 1079 | (let* ((cat (or category (todos-current-category))) |
| 1124 | ;; FIXME: todos-categories-full? | ||
| 1125 | (counts (cdr (assoc cat todos-categories))) | 1080 | (counts (cdr (assoc cat todos-categories))) |
| 1126 | (idx (cond ((eq type 'todo) 0) | 1081 | (idx (cond ((eq type 'todo) 0) |
| 1127 | ((eq type 'diary) 1) | 1082 | ((eq type 'diary) 1) |
| @@ -1129,7 +1084,7 @@ With nil or omitted CATEGORY, default to the current category." | |||
| 1129 | ((eq type 'archived) 3)))) | 1084 | ((eq type 'archived) 3)))) |
| 1130 | (aset counts idx (+ increment (aref counts idx))))) | 1085 | (aset counts idx (+ increment (aref counts idx))))) |
| 1131 | 1086 | ||
| 1132 | (defun todos-set-categories () ;FIXME | 1087 | (defun todos-set-categories () ;FIXME: need this? |
| 1133 | "Set `todos-categories' from the sexp at the top of the file." | 1088 | "Set `todos-categories' from the sexp at the top of the file." |
| 1134 | ;; New archive files created by `todos-move-category' are empty, which would | 1089 | ;; New archive files created by `todos-move-category' are empty, which would |
| 1135 | ;; make the sexp test fail and raise an error, so in this case we skip it. | 1090 | ;; make the sexp test fail and raise an error, so in this case we skip it. |
| @@ -1138,18 +1093,12 @@ With nil or omitted CATEGORY, default to the current category." | |||
| 1138 | (save-restriction | 1093 | (save-restriction |
| 1139 | (widen) | 1094 | (widen) |
| 1140 | (goto-char (point-min)) | 1095 | (goto-char (point-min)) |
| 1141 | ;; todos-truncate-categories-list needs non-nil todos-categories. | 1096 | (setq todos-categories |
| 1142 | (setq todos-categories-full | ||
| 1143 | (if (looking-at "\(\(\"") | 1097 | (if (looking-at "\(\(\"") |
| 1144 | (read (buffer-substring-no-properties | 1098 | (read (buffer-substring-no-properties |
| 1145 | (line-beginning-position) | 1099 | (line-beginning-position) |
| 1146 | (line-end-position))) | 1100 | (line-end-position))) |
| 1147 | (error "Invalid or missing todos-categories sexp")) | 1101 | (error "Invalid or missing todos-categories sexp"))))))) |
| 1148 | todos-categories todos-categories-full))) | ||
| 1149 | (if (and todos-ignore-archived-categories | ||
| 1150 | (eq major-mode 'todos-mode)) | ||
| 1151 | (todos-truncate-categories-list) | ||
| 1152 | todos-categories-full))) | ||
| 1153 | 1102 | ||
| 1154 | (defun todos-update-categories-sexp () | 1103 | (defun todos-update-categories-sexp () |
| 1155 | "Update the `todos-categories' sexp at the top of the file." | 1104 | "Update the `todos-categories' sexp at the top of the file." |
| @@ -1165,15 +1114,11 @@ With nil or omitted CATEGORY, default to the current category." | |||
| 1165 | ;; categories variables in order e.g. to enable categories | 1114 | ;; categories variables in order e.g. to enable categories |
| 1166 | ;; display. | 1115 | ;; display. |
| 1167 | (setq todos-default-todos-file (buffer-file-name)) | 1116 | (setq todos-default-todos-file (buffer-file-name)) |
| 1168 | (setq todos-categories (todos-make-categories-list t)) | 1117 | (setq todos-categories (todos-make-categories-list t))) |
| 1169 | (when todos-ignore-archived-categories | ||
| 1170 | (setq todos-categories-full todos-categories))) | ||
| 1171 | ;; With empty buffer (e.g. with new archive in | 1118 | ;; With empty buffer (e.g. with new archive in |
| 1172 | ;; `todos-move-category') `kill-line' signals end of buffer. | 1119 | ;; `todos-move-category') `kill-line' signals end of buffer. |
| 1173 | (kill-region (line-beginning-position) (line-end-position))) | 1120 | (kill-region (line-beginning-position) (line-end-position))) |
| 1174 | ;; todos-categories-full is nil on adding first category. | 1121 | (prin1 todos-categories (current-buffer)))))) |
| 1175 | (prin1 (or todos-categories-full todos-categories) | ||
| 1176 | (current-buffer)))))) | ||
| 1177 | 1122 | ||
| 1178 | (defun todos-make-categories-list (&optional force) | 1123 | (defun todos-make-categories-list (&optional force) |
| 1179 | "Return an alist of Todos categories and their item counts. | 1124 | "Return an alist of Todos categories and their item counts. |
| @@ -1237,24 +1182,8 @@ the file." | |||
| 1237 | (line-end-position)))) | 1182 | (line-end-position)))) |
| 1238 | (goto-char (1- (point-max)))))) | 1183 | (goto-char (1- (point-max)))))) |
| 1239 | (forward-line))))) | 1184 | (forward-line))))) |
| 1240 | ;; FIXME: todos-categories-full? | ||
| 1241 | todos-categories) | 1185 | todos-categories) |
| 1242 | 1186 | ||
| 1243 | (defun todos-truncate-categories-list () | ||
| 1244 | "Return a truncated alist of Todos categories plus item counts. | ||
| 1245 | Categories containing only archived items are omitted. This list | ||
| 1246 | is used in Todos mode when `todos-ignore-archived-categories' is | ||
| 1247 | non-nil." | ||
| 1248 | (let (cats) | ||
| 1249 | (dolist (catcons todos-categories-full cats) | ||
| 1250 | (let ((cat (car catcons))) | ||
| 1251 | (setq cats | ||
| 1252 | (append cats | ||
| 1253 | (unless (and (zerop (todos-get-count 'todo cat)) | ||
| 1254 | (zerop (todos-get-count 'done cat)) | ||
| 1255 | (not (zerop (todos-get-count 'archived cat)))) | ||
| 1256 | (list catcons)))))))) | ||
| 1257 | |||
| 1258 | (defun todos-check-format () | 1187 | (defun todos-check-format () |
| 1259 | "Signal an error if the current Todos file is ill-formatted. | 1188 | "Signal an error if the current Todos file is ill-formatted. |
| 1260 | Otherwise return t. The error message gives the line number | 1189 | Otherwise return t. The error message gives the line number |
| @@ -1264,7 +1193,7 @@ where the invalid formatting was found." | |||
| 1264 | (widen) | 1193 | (widen) |
| 1265 | (goto-char (point-min)) | 1194 | (goto-char (point-min)) |
| 1266 | ;; Check for `todos-categories' sexp as the first line | 1195 | ;; Check for `todos-categories' sexp as the first line |
| 1267 | (let ((cats (prin1-to-string (or todos-categories-full todos-categories)))) | 1196 | (let ((cats (prin1-to-string todos-categories))) |
| 1268 | (unless (looking-at (regexp-quote cats)) | 1197 | (unless (looking-at (regexp-quote cats)) |
| 1269 | (error "Invalid or missing todos-categories sexp"))) | 1198 | (error "Invalid or missing todos-categories sexp"))) |
| 1270 | (forward-line) | 1199 | (forward-line) |
| @@ -1287,7 +1216,7 @@ where the invalid formatting was found." | |||
| 1287 | This should only be needed as a consequence of careless manual | 1216 | This should only be needed as a consequence of careless manual |
| 1288 | editing or a bug in todos.el." | 1217 | editing or a bug in todos.el." |
| 1289 | (interactive) | 1218 | (interactive) |
| 1290 | (let ((todos-categories-full (todos-make-categories-list t))) | 1219 | (let ((todos-categories (todos-make-categories-list t))) |
| 1291 | (todos-update-categories-sexp))) | 1220 | (todos-update-categories-sexp))) |
| 1292 | 1221 | ||
| 1293 | (defvar todos-item-start (concat "\\(" todos-date-string-start "\\|" | 1222 | (defvar todos-item-start (concat "\\(" todos-date-string-start "\\|" |
| @@ -1313,6 +1242,7 @@ editing or a bug in todos.el." | |||
| 1313 | ;; Items cannot end with a blank line. | 1242 | ;; Items cannot end with a blank line. |
| 1314 | (unless (looking-at "^$") | 1243 | (unless (looking-at "^$") |
| 1315 | (let ((done (todos-done-item-p))) | 1244 | (let ((done (todos-done-item-p))) |
| 1245 | ;; FIXME: don't use a command to define this function! | ||
| 1316 | (todos-forward-item) | 1246 | (todos-forward-item) |
| 1317 | ;; Adjust if item is last unfinished one before displayed done items. | 1247 | ;; Adjust if item is last unfinished one before displayed done items. |
| 1318 | (when (and (not done) (todos-done-item-p)) | 1248 | (when (and (not done) (todos-done-item-p)) |
| @@ -1452,7 +1382,7 @@ ask whether to add the category." | |||
| 1452 | (define-key map " " nil) | 1382 | (define-key map " " nil) |
| 1453 | ;; Make a copy of todos-categories in case history-delete-duplicates is | 1383 | ;; Make a copy of todos-categories in case history-delete-duplicates is |
| 1454 | ;; non-nil, which makes completing-read alter todos-categories. | 1384 | ;; non-nil, which makes completing-read alter todos-categories. |
| 1455 | (let* ((categories (copy-sequence todos-categories)) ;FIXME: todos-categories-full? | 1385 | (let* ((categories (copy-sequence todos-categories)) |
| 1456 | (history (cons 'todos-categories (1+ todos-category-number))) | 1386 | (history (cons 'todos-categories (1+ todos-category-number))) |
| 1457 | (completion-ignore-case todos-completion-ignore-case) | 1387 | (completion-ignore-case todos-completion-ignore-case) |
| 1458 | (cat (completing-read prompt todos-categories nil | 1388 | (cat (completing-read prompt todos-categories nil |
| @@ -1462,31 +1392,29 @@ ask whether to add the category." | |||
| 1462 | (if todos-categories | 1392 | (if todos-categories |
| 1463 | (todos-current-category) | 1393 | (todos-current-category) |
| 1464 | ;; Trigger prompt for initial category. | 1394 | ;; Trigger prompt for initial category. |
| 1465 | ""))) | 1395 | "")))) |
| 1466 | new) | 1396 | (unless (or mustmatch (assoc cat todos-categories)) |
| 1467 | (unless mustmatch | ||
| 1468 | (todos-validate-name cat 'category) | 1397 | (todos-validate-name cat 'category) |
| 1469 | (unless added | 1398 | (unless added |
| 1470 | (if (y-or-n-p (format (concat "There is no category \"%s\" in " | 1399 | (if (y-or-n-p (format (concat "There is no category \"%s\" in " |
| 1471 | "this file; add it? ") cat)) | 1400 | "this file; add it? ") cat)) |
| 1472 | (progn (todos-add-category cat) (setq new t)) | 1401 | (todos-add-category cat) |
| 1473 | (keyboard-quit))));) | 1402 | (keyboard-quit)))) |
| 1474 | ;; Restore the original value of todos-categories unless a new category | 1403 | ;; Restore the original value of todos-categories unless a new category |
| 1475 | ;; was added (since todos-add-category changes todos-categories). | 1404 | ;; was added (since todos-add-category changes todos-categories). |
| 1476 | (unless (or new added) (setq todos-categories categories)) | 1405 | (unless added (setq todos-categories categories)) |
| 1477 | cat))) | 1406 | cat))) |
| 1478 | 1407 | ||
| 1479 | ;; FIXME: use completing-read | ||
| 1480 | (defun todos-validate-name (name type) | 1408 | (defun todos-validate-name (name type) |
| 1481 | "Prompt for new NAME for TYPE until it is valid, then return it. | 1409 | "Prompt for new NAME for TYPE until it is valid, then return it. |
| 1482 | TYPE can be either a file or a category" | 1410 | TYPE can be either a file or a category" |
| 1483 | (let (;(categories todos-categories)) | 1411 | (let ((categories todos-categories) |
| 1484 | prompt file cat shortname) | 1412 | (files (mapcar 'todos-short-file-name todos-files)) |
| 1413 | prompt) | ||
| 1485 | (while | 1414 | (while |
| 1486 | (and (cond ((string= "" name) | 1415 | (and (cond ((string= "" name) |
| 1487 | (setq prompt | 1416 | (setq prompt |
| 1488 | (cond ((eq type 'file) | 1417 | (cond ((eq type 'file) |
| 1489 | ;; FIXME: just todos-files ? | ||
| 1490 | (if todos-files | 1418 | (if todos-files |
| 1491 | "Enter a non-empty file name: " | 1419 | "Enter a non-empty file name: " |
| 1492 | ;; Empty string passed by todos-show to | 1420 | ;; Empty string passed by todos-show to |
| @@ -1510,14 +1438,18 @@ TYPE can be either a file or a category" | |||
| 1510 | (setq prompt "Enter a non-existing category name: "))) | 1438 | (setq prompt "Enter a non-existing category name: "))) |
| 1511 | (setq name (if (or (and (eq type 'file) todos-files) | 1439 | (setq name (if (or (and (eq type 'file) todos-files) |
| 1512 | (and (eq type 'category) todos-categories)) | 1440 | (and (eq type 'category) todos-categories)) |
| 1513 | (read-from-minibuffer prompt) | 1441 | (completing-read prompt (cond ((eq type 'file) |
| 1442 | todos-files) | ||
| 1443 | ((eq type 'category) | ||
| 1444 | todos-categories))) | ||
| 1514 | ;; Offer default initial name. | 1445 | ;; Offer default initial name. |
| 1515 | (read-string prompt nil nil | 1446 | (completing-read prompt (if (eq type 'file) |
| 1516 | (cond ((eq type 'file) | 1447 | todos-files |
| 1517 | todos-initial-file) | 1448 | todos-categories) |
| 1518 | ((eq type 'category) | 1449 | nil nil (if (eq type 'file) |
| 1519 | todos-initial-category)))))))) | 1450 | todos-initial-file |
| 1520 | name) | 1451 | todos-initial-category)))))) |
| 1452 | name)) | ||
| 1521 | 1453 | ||
| 1522 | ;; Adapted from calendar-read-date and calendar-date-string. | 1454 | ;; Adapted from calendar-read-date and calendar-date-string. |
| 1523 | (defun todos-read-date () | 1455 | (defun todos-read-date () |
| @@ -1966,7 +1898,8 @@ LABEL determines which type of count is sorted." | |||
| 1966 | (mapcar 'cdr todos-categories)))) | 1898 | (mapcar 'cdr todos-categories)))) |
| 1967 | (list 0 1 2 3))) | 1899 | (list 0 1 2 3))) |
| 1968 | 1900 | ||
| 1969 | (defvar todos-category-number nil) | 1901 | (defvar todos-categories-category-number 0 |
| 1902 | "Variable for numbering categories in Todos Categories mode.") | ||
| 1970 | 1903 | ||
| 1971 | (defun todos-insert-category-line (cat &optional nonum) | 1904 | (defun todos-insert-category-line (cat &optional nonum) |
| 1972 | "Insert button with category CAT's name and item counts. | 1905 | "Insert button with category CAT's name and item counts. |
| @@ -1976,10 +1909,10 @@ The number and the category name are separated by the string | |||
| 1976 | which is the value of the user option | 1909 | which is the value of the user option |
| 1977 | `todos-categories-number-separator'." | 1910 | `todos-categories-number-separator'." |
| 1978 | (let ((archive (member todos-current-todos-file todos-archives)) | 1911 | (let ((archive (member todos-current-todos-file todos-archives)) |
| 1979 | (num todos-category-number) | 1912 | (num todos-categories-category-number) |
| 1980 | (str (todos-padded-string cat)) | 1913 | (str (todos-padded-string cat)) |
| 1981 | (opoint (point))) | 1914 | (opoint (point))) |
| 1982 | (setq num (1+ num) todos-category-number num) | 1915 | (setq num (1+ num) todos-categories-category-number num) |
| 1983 | (insert-button | 1916 | (insert-button |
| 1984 | (concat (if nonum | 1917 | (concat (if nonum |
| 1985 | (make-string (+ 4 (length todos-categories-number-separator)) | 1918 | (make-string (+ 4 (length todos-categories-number-separator)) |
| @@ -2068,14 +2001,10 @@ which is the value of the user option | |||
| 2068 | 2001 | ||
| 2069 | (defun todos-update-categories-display (sortkey) | 2002 | (defun todos-update-categories-display (sortkey) |
| 2070 | "" | 2003 | "" |
| 2071 | (let* ((cats0 (if (and todos-ignore-archived-categories | 2004 | (let* ((cats0 todos-categories) |
| 2072 | ;; FIXME: is this every true? | ||
| 2073 | (not (eq major-mode 'todos-categories-mode))) | ||
| 2074 | todos-categories-full | ||
| 2075 | todos-categories)) | ||
| 2076 | (cats (todos-sort cats0 sortkey)) | 2005 | (cats (todos-sort cats0 sortkey)) |
| 2077 | (archive (member todos-current-todos-file todos-archives)) | 2006 | (archive (member todos-current-todos-file todos-archives)) |
| 2078 | (todos-category-number 0) | 2007 | (todos-categories-category-number 0) |
| 2079 | ;; Find start of Category button if we just entered Todos Categories | 2008 | ;; Find start of Category button if we just entered Todos Categories |
| 2080 | ;; mode. | 2009 | ;; mode. |
| 2081 | (pt (if (eq (point) (point-max)) | 2010 | (pt (if (eq (point) (point-max)) |
| @@ -2117,6 +2046,7 @@ which is the value of the user option | |||
| 2117 | ;;; Todos insertion commands, key bindings and keymap | 2046 | ;;; Todos insertion commands, key bindings and keymap |
| 2118 | 2047 | ||
| 2119 | ;; Can either of these be included in Emacs? The originals are GFDL'd. | 2048 | ;; Can either of these be included in Emacs? The originals are GFDL'd. |
| 2049 | |||
| 2120 | ;; Slightly reformulated from | 2050 | ;; Slightly reformulated from |
| 2121 | ;; http://rosettacode.org/wiki/Power_set#Common_Lisp. | 2051 | ;; http://rosettacode.org/wiki/Power_set#Common_Lisp. |
| 2122 | (defun powerset-recursive (l) | 2052 | (defun powerset-recursive (l) |
| @@ -2127,6 +2057,7 @@ which is the value of the user option | |||
| 2127 | (append (mapcar (lambda (elt) (cons (car l) elt)) | 2057 | (append (mapcar (lambda (elt) (cons (car l) elt)) |
| 2128 | prev) | 2058 | prev) |
| 2129 | prev))))) | 2059 | prev))))) |
| 2060 | |||
| 2130 | ;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C | 2061 | ;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C |
| 2131 | (defun powerset-bitwise (l) | 2062 | (defun powerset-bitwise (l) |
| 2132 | (let ((binnum (lsh 1 (length l))) | 2063 | (let ((binnum (lsh 1 (length l))) |
| @@ -2329,7 +2260,7 @@ which is the value of the user option | |||
| 2329 | ;;("" . todos-edit-category-diary-nonmarking) | 2260 | ;;("" . todos-edit-category-diary-nonmarking) |
| 2330 | ("ec" . todos-done-item-add-or-edit-comment) ;FIXME: or just "c"? | 2261 | ("ec" . todos-done-item-add-or-edit-comment) ;FIXME: or just "c"? |
| 2331 | ("i" . ,todos-insertion-map) | 2262 | ("i" . ,todos-insertion-map) |
| 2332 | ("k" . todos-delete-item) | 2263 | ("k" . todos-delete-item) ;FIXME: not single letter? |
| 2333 | ("m" . todos-move-item) | 2264 | ("m" . todos-move-item) |
| 2334 | ("M" . todos-move-item-to-file) | 2265 | ("M" . todos-move-item-to-file) |
| 2335 | ;; FIXME: This binding prevents `-' from being used in a numerical prefix | 2266 | ;; FIXME: This binding prevents `-' from being used in a numerical prefix |
| @@ -2492,10 +2423,6 @@ which is the value of the user option | |||
| 2492 | map) | 2423 | map) |
| 2493 | "Todos Top Priorities mode keymap.") | 2424 | "Todos Top Priorities mode keymap.") |
| 2494 | 2425 | ||
| 2495 | ;; FIXME: remove when part of Emacs | ||
| 2496 | (add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode)) | ||
| 2497 | (add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode)) | ||
| 2498 | |||
| 2499 | (defun todos-modes-set-1 () | 2426 | (defun todos-modes-set-1 () |
| 2500 | "" | 2427 | "" |
| 2501 | (set (make-local-variable 'font-lock-defaults) '(todos-font-lock-keywords t)) | 2428 | (set (make-local-variable 'font-lock-defaults) '(todos-font-lock-keywords t)) |
| @@ -2511,8 +2438,7 @@ which is the value of the user option | |||
| 2511 | (cons (todos-item-start) (todos-item-end)))))) | 2438 | (cons (todos-item-start) (todos-item-end)))))) |
| 2512 | 2439 | ||
| 2513 | (defun todos-modes-set-3 () | 2440 | (defun todos-modes-set-3 () |
| 2514 | (set (make-local-variable 'todos-categories-full) nil) | 2441 | ;; FIXME: is this right? |
| 2515 | ;; todos-set-categories also sets todos-categories-full. | ||
| 2516 | (set (make-local-variable 'todos-categories) (todos-set-categories)) | 2442 | (set (make-local-variable 'todos-categories) (todos-set-categories)) |
| 2517 | (set (make-local-variable 'todos-category-number) 1) | 2443 | (set (make-local-variable 'todos-category-number) 1) |
| 2518 | (set (make-local-variable 'todos-first-visit) t) | 2444 | (set (make-local-variable 'todos-first-visit) t) |
| @@ -2577,16 +2503,14 @@ which is the value of the user option | |||
| 2577 | (set (make-local-variable 'todos-current-todos-file) | 2503 | (set (make-local-variable 'todos-current-todos-file) |
| 2578 | todos-global-current-todos-file) | 2504 | todos-global-current-todos-file) |
| 2579 | (let ((cats (with-current-buffer (get-file-buffer todos-current-todos-file) | 2505 | (let ((cats (with-current-buffer (get-file-buffer todos-current-todos-file) |
| 2580 | (if todos-ignore-archived-categories | 2506 | ;; FIXME: or just todos-categories? |
| 2581 | ;; FIXME: how will this be set? | 2507 | (todos-set-categories)))) |
| 2582 | todos-categories-full | ||
| 2583 | (todos-set-categories))))) | ||
| 2584 | (set (make-local-variable 'todos-categories) cats))) | 2508 | (set (make-local-variable 'todos-categories) cats))) |
| 2585 | 2509 | ||
| 2586 | (define-derived-mode todos-edit-mode text-mode "Todos-Ed" () | 2510 | (define-derived-mode todos-edit-mode text-mode "Todos-Ed" () |
| 2587 | "Major mode for editing multiline Todo items. | 2511 | "Major mode for editing multiline Todo items. |
| 2588 | 2512 | ||
| 2589 | \\{todos-edit-mode-map}"{ | 2513 | \\{todos-edit-mode-map}" |
| 2590 | (todos-modes-set-1) | 2514 | (todos-modes-set-1) |
| 2591 | (todos-mode-external-set)) | 2515 | (todos-mode-external-set)) |
| 2592 | 2516 | ||
| @@ -2676,7 +2600,7 @@ corresponding Todos file, displaying the corresponding category." | |||
| 2676 | ".todo")) | 2600 | ".todo")) |
| 2677 | (t | 2601 | (t |
| 2678 | ;; FIXME: If an archive is value of | 2602 | ;; FIXME: If an archive is value of |
| 2679 | ;; todos-current-todos-file, todos-show will revisit | 2603 | ;; todos-current-todos-file, todos-show will revisit it |
| 2680 | ;; rather than the corresponding todo file -- ok or make | 2604 | ;; rather than the corresponding todo file -- ok or make |
| 2681 | ;; it customizable? | 2605 | ;; it customizable? |
| 2682 | (or todos-current-todos-file | 2606 | (or todos-current-todos-file |
| @@ -3213,6 +3137,12 @@ category is the first)." | |||
| 3213 | (setq todos-category-number | 3137 | (setq todos-category-number |
| 3214 | (1+ (mod (- todos-category-number (if back 2 0)) | 3138 | (1+ (mod (- todos-category-number (if back 2 0)) |
| 3215 | (length todos-categories)))) | 3139 | (length todos-categories)))) |
| 3140 | (when todos-ignore-archived-categories | ||
| 3141 | (while (and (zerop (todos-get-count 'todo)) | ||
| 3142 | (zerop (todos-get-count 'done)) | ||
| 3143 | (not (zerop (todos-get-count 'archive)))) | ||
| 3144 | (setq todos-category-number | ||
| 3145 | (apply (if back '1- '1+) (list todos-category-number))))) | ||
| 3216 | (todos-category-select) | 3146 | (todos-category-select) |
| 3217 | (goto-char (point-min))) | 3147 | (goto-char (point-min))) |
| 3218 | 3148 | ||
| @@ -3328,6 +3258,9 @@ With numerical prefix COUNT, move point COUNT items downward," | |||
| 3328 | (if (re-search-forward todos-item-start nil t (or count 1)) | 3258 | (if (re-search-forward todos-item-start nil t (or count 1)) |
| 3329 | (goto-char (match-beginning 0)) | 3259 | (goto-char (match-beginning 0)) |
| 3330 | (goto-char (point-max))) | 3260 | (goto-char (point-max))) |
| 3261 | ;; FIXME: this is insufficient, since there could be no done items in this | ||
| 3262 | ;; category, so the search puts us on a todo item. Have to stop before | ||
| 3263 | ;; todos-done-separator when buffer is not narrowed. | ||
| 3331 | ;; If points advances by one from a todo to a done item, go back to the | 3264 | ;; If points advances by one from a todo to a done item, go back to the |
| 3332 | ;; space above todos-done-separator, since that is a legitimate place to | 3265 | ;; space above todos-done-separator, since that is a legitimate place to |
| 3333 | ;; insert an item. But skip this space if count > 1, since that should | 3266 | ;; insert an item. But skip this space if count > 1, since that should |
| @@ -3462,9 +3395,6 @@ the category name and the return value is the category number." | |||
| 3462 | (setq cat (todos-validate-name cat 'category)) ;FIXME: need this? | 3395 | (setq cat (todos-validate-name cat 'category)) ;FIXME: need this? |
| 3463 | (setq cat (todos-read-category "Enter new category name: " nil t))) | 3396 | (setq cat (todos-read-category "Enter new category name: " nil t))) |
| 3464 | (setq todos-categories (append todos-categories (list (cons cat counts)))) | 3397 | (setq todos-categories (append todos-categories (list (cons cat counts)))) |
| 3465 | (if todos-categories-full | ||
| 3466 | (setq todos-categories-full (append todos-categories-full | ||
| 3467 | (list (cons cat counts))))) | ||
| 3468 | (widen) | 3398 | (widen) |
| 3469 | (goto-char (point-max)) | 3399 | (goto-char (point-max)) |
| 3470 | (save-excursion ; Save point for todos-category-select. | 3400 | (save-excursion ; Save point for todos-category-select. |
| @@ -3560,12 +3490,8 @@ i.e. including all existing todo and done items." | |||
| 3560 | (delete-file file) | 3490 | (delete-file file) |
| 3561 | (kill-buffer) | 3491 | (kill-buffer) |
| 3562 | (message "Deleted Todos file %s." file)) | 3492 | (message "Deleted Todos file %s." file)) |
| 3563 | (setq todos-categories-full (delete (assoc cat todos-categories-full) | 3493 | (setq todos-categories (delete (assoc cat todos-categories) |
| 3564 | todos-categories-full)) | 3494 | todos-categories)) |
| 3565 | (setq todos-categories (if todos-ignore-archived-categories | ||
| 3566 | (delete (assoc cat todos-categories) | ||
| 3567 | todos-categories) | ||
| 3568 | todos-categories-full)) | ||
| 3569 | (todos-update-categories-sexp) | 3495 | (todos-update-categories-sexp) |
| 3570 | (setq todos-category-number | 3496 | (setq todos-category-number |
| 3571 | (1+ (mod todos-category-number (length todos-categories)))) | 3497 | (1+ (mod todos-category-number (length todos-categories)))) |
| @@ -3577,7 +3503,7 @@ i.e. including all existing todo and done items." | |||
| 3577 | "Raise priority of category point is on in Todos Categories buffer. | 3503 | "Raise priority of category point is on in Todos Categories buffer. |
| 3578 | With non-nil argument LOWER, lower the category's priority." | 3504 | With non-nil argument LOWER, lower the category's priority." |
| 3579 | (interactive) | 3505 | (interactive) |
| 3580 | (let ((num todos-category-number)) | 3506 | (let ((num todos-categories-category-number)) |
| 3581 | (save-excursion | 3507 | (save-excursion |
| 3582 | (forward-line 0) | 3508 | (forward-line 0) |
| 3583 | (skip-chars-forward " ") | 3509 | (skip-chars-forward " ") |
| @@ -3717,13 +3643,8 @@ archive of the file moved to, creating it if it does not exist." | |||
| 3717 | (kill-buffer) | 3643 | (kill-buffer) |
| 3718 | (when (member todos-current-todos-file todos-files) | 3644 | (when (member todos-current-todos-file todos-files) |
| 3719 | (todos-reevaluate-defcustoms))) | 3645 | (todos-reevaluate-defcustoms))) |
| 3720 | (setq todos-categories-full (delete (assoc cat | 3646 | (setq todos-categories (delete (assoc cat todos-categories) |
| 3721 | todos-categories-full) | 3647 | todos-categories)) |
| 3722 | todos-categories-full)) | ||
| 3723 | (setq todos-categories (if todos-ignore-archived-categories | ||
| 3724 | (delete (assoc cat todos-categories) | ||
| 3725 | todos-categories) | ||
| 3726 | todos-categories-full)) | ||
| 3727 | (todos-update-categories-sexp) | 3648 | (todos-update-categories-sexp) |
| 3728 | (todos-category-select))))) | 3649 | (todos-category-select))))) |
| 3729 | (set-window-buffer (selected-window) | 3650 | (set-window-buffer (selected-window) |
| @@ -3778,12 +3699,8 @@ deleted." | |||
| 3778 | (delete-region cbeg cend) | 3699 | (delete-region cbeg cend) |
| 3779 | (todos-update-count 'todo (todos-get-count 'todo cat) goal) | 3700 | (todos-update-count 'todo (todos-get-count 'todo cat) goal) |
| 3780 | (todos-update-count 'done (todos-get-count 'done cat) goal) | 3701 | (todos-update-count 'done (todos-get-count 'done cat) goal) |
| 3781 | (setq todos-categories-full (delete (assoc cat todos-categories-full) | 3702 | (setq todos-categories (delete (assoc cat todos-categories) |
| 3782 | todos-categories-full)) | 3703 | todos-categories)) |
| 3783 | (setq todos-categories (if todos-ignore-archived-categories | ||
| 3784 | (delete (assoc cat todos-categories) | ||
| 3785 | todos-categories) | ||
| 3786 | todos-categories-full)) | ||
| 3787 | (todos-update-categories-sexp) | 3704 | (todos-update-categories-sexp) |
| 3788 | (todos-category-number goal) | 3705 | (todos-category-number goal) |
| 3789 | (todos-category-select) | 3706 | (todos-category-select) |
| @@ -4933,10 +4850,8 @@ archive, the archive file is deleted." | |||
| 4933 | (delete-region beg end) | 4850 | (delete-region beg end) |
| 4934 | (setq todos-categories (delete (assoc cat todos-categories) | 4851 | (setq todos-categories (delete (assoc cat todos-categories) |
| 4935 | todos-categories)) | 4852 | todos-categories)) |
| 4936 | (setq todos-categories (if todos-ignore-archived-categories | 4853 | (setq todos-categories (delete (assoc cat todos-categories) |
| 4937 | (delete (assoc cat todos-categories) | 4854 | todos-categories)) |
| 4938 | todos-categories) | ||
| 4939 | todos-categories-full)) | ||
| 4940 | (todos-update-categories-sexp)))) | 4855 | (todos-update-categories-sexp)))) |
| 4941 | ;; Visit category in Todos file and show restored done items. | 4856 | ;; Visit category in Todos file and show restored done items. |
| 4942 | (let ((tfile (buffer-file-name tbuf)) | 4857 | (let ((tfile (buffer-file-name tbuf)) |
| @@ -4956,10 +4871,13 @@ archive, the archive file is deleted." | |||
| 4956 | 4871 | ||
| 4957 | ;;; todos.el ends here | 4872 | ;;; todos.el ends here |
| 4958 | 4873 | ||
| 4959 | |||
| 4960 | ;; --------------------------------------------------------------------------- | 4874 | ;; --------------------------------------------------------------------------- |
| 4961 | ;;; Addition to calendar.el | ||
| 4962 | 4875 | ||
| 4876 | ;; FIXME: remove when part of Emacs | ||
| 4877 | (add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode)) | ||
| 4878 | (add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode)) | ||
| 4879 | |||
| 4880 | ;;; Addition to calendar.el | ||
| 4963 | ;; FIXME: autoload when key-binding is defined in calendar.el | 4881 | ;; FIXME: autoload when key-binding is defined in calendar.el |
| 4964 | (defun todos-insert-item-from-calendar () | 4882 | (defun todos-insert-item-from-calendar () |
| 4965 | "" | 4883 | "" |