aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2013-05-31 15:08:21 +0200
committerStephen Berman2013-05-31 15:08:21 +0200
commita9b0e28e232e4043267f3ee3d739e12c04c7a170 (patch)
tree9a2b6154d5b5d875908d26ad960bbc7202d43fc9
parent27139cd5e8e4348a754873b5f2d8f5472db964b5 (diff)
downloademacs-a9b0e28e232e4043267f3ee3d739e12c04c7a170.tar.gz
emacs-a9b0e28e232e4043267f3ee3d739e12c04c7a170.zip
* todos.el: Clean up code. Uncapitalize file name in first line.
Require cl-lib instead of cl. Add section title separators. Reindent some code and comments. Comment out Todos mode menu definition. (todos-basic-insert-item): Rename from todos-insert-item-1 and adjust uses. (todos-basic-edit-item-header): Rename from todos-edit-item-header-1 and adjust uses. (todos-display-categories): Rename from todos-display-categories-1 and adjust uses. (todos-show, todos-basic-insert-item) (todos-basic-edit-item-header, todos-set-item-priority) (todos-item-undone, todos-convert-legacy-files) (todos-check-format, todos-filter-items-1): Use user-error instead of error. (todos-add-file, todos-basic-insert-item, todos-mark) (todos-button, todos-sorted-column, todos-archived-only) (todos-search, todos-category-string) (todos-top-priorities-overrides) (todos-insertion-commands-args-genlist, todos-filter-items) (todos-filter-items-1, todos-filtered-items-mode-map): Correct or improve document string. (todos-edit-file) (todos-sort-categories-alphabetically-or-by-priority) (todos-sort-categories-by-todo, todos-sort-categories-by-diary) (todos-sort-categories-by-done) (todos-sort-categories-by-archived, todos-next-button) (todos-previous-button, todos-gen-arglists) (todos-define-insertion-command) (todos-insertion-commands-arg-key-list) (todos-insertion-key-bindings, todos-update-categories-display): Add document string. (todos-powerset-recursive): Rename from powerset-recursive and reformulate slightly. (todos-powerset-iterative): Rename from powerset-bitwise and reformulate. (todos-insertion-commands-args): Use cl-remove-duplicates instead of remove-duplicates. (todos-define-insertion-command): Improve doc string of generated defun. (todos-adjusted-category-label-length) (todos-insert-category-line, todos-update-categories-display): Call cl-oddp instead of inlining its definition. (todos-key-bindings): Remove, replacing by the following. (todos-key-bindings-t, todos-key-bindings-t+a+f) (todos-key-bindings-t+a, todos-key-bindings-t+f): New variables. (todos-mode-map): Use new key-binding variables. (todos-archive-mode-map, todos-filtered-items-mode-map): Use new key-binding variables. Don't suppress digit keys. (todos-categories-mode-map): Don't suppress digit keys. (todos-modes-set-1, todos-modes-set-2, todos-modes-set-3) (todos-mode, todos-archive-mode, todos-mode-external-set): Use setq-local instead of make-local-variable.
-rw-r--r--lisp/calendar/ChangeLog55
-rw-r--r--lisp/calendar/todos.el831
2 files changed, 497 insertions, 389 deletions
diff --git a/lisp/calendar/ChangeLog b/lisp/calendar/ChangeLog
index f26cc337729..fe8f83e2df2 100644
--- a/lisp/calendar/ChangeLog
+++ b/lisp/calendar/ChangeLog
@@ -1,3 +1,58 @@
12013-05-31 Stephen Berman <stephen.berman@gmx.net>
2
3 * todos.el: Clean up code. Uncapitalize file name in first line.
4 Require cl-lib instead of cl. Add section title separators.
5 Reindent some code and comments. Comment out Todos mode menu
6 definition.
7 (todos-basic-insert-item): Rename from todos-insert-item-1 and
8 adjust uses.
9 (todos-basic-edit-item-header): Rename from
10 todos-edit-item-header-1 and adjust uses.
11 (todos-display-categories): Rename from todos-display-categories-1
12 and adjust uses.
13 (todos-show, todos-basic-insert-item)
14 (todos-basic-edit-item-header, todos-set-item-priority)
15 (todos-item-undone, todos-convert-legacy-files)
16 (todos-check-format, todos-filter-items-1):
17 Use user-error instead of error.
18 (todos-add-file, todos-basic-insert-item, todos-mark)
19 (todos-button, todos-sorted-column, todos-archived-only)
20 (todos-search, todos-category-string)
21 (todos-top-priorities-overrides)
22 (todos-insertion-commands-args-genlist, todos-filter-items)
23 (todos-filter-items-1, todos-filtered-items-mode-map):
24 Correct or improve document string.
25 (todos-edit-file)
26 (todos-sort-categories-alphabetically-or-by-priority)
27 (todos-sort-categories-by-todo, todos-sort-categories-by-diary)
28 (todos-sort-categories-by-done)
29 (todos-sort-categories-by-archived, todos-next-button)
30 (todos-previous-button, todos-gen-arglists)
31 (todos-define-insertion-command)
32 (todos-insertion-commands-arg-key-list)
33 (todos-insertion-key-bindings, todos-update-categories-display):
34 Add document string.
35 (todos-powerset-recursive): Rename from powerset-recursive and
36 reformulate slightly.
37 (todos-powerset-iterative): Rename from powerset-bitwise and
38 reformulate.
39 (todos-insertion-commands-args): Use cl-remove-duplicates instead
40 of remove-duplicates.
41 (todos-define-insertion-command): Improve doc string of generated defun.
42 (todos-adjusted-category-label-length)
43 (todos-insert-category-line, todos-update-categories-display):
44 Call cl-oddp instead of inlining its definition.
45 (todos-key-bindings): Remove, replacing by the following.
46 (todos-key-bindings-t, todos-key-bindings-t+a+f)
47 (todos-key-bindings-t+a, todos-key-bindings-t+f): New variables.
48 (todos-mode-map): Use new key-binding variables.
49 (todos-archive-mode-map, todos-filtered-items-mode-map): Use new
50 key-binding variables. Don't suppress digit keys.
51 (todos-categories-mode-map): Don't suppress digit keys.
52 (todos-modes-set-1, todos-modes-set-2, todos-modes-set-3)
53 (todos-mode, todos-archive-mode, todos-mode-external-set):
54 Use setq-local instead of make-local-variable.
55
12013-05-24 Stephen Berman <stephen.berman@gmx.net> 562013-05-24 Stephen Berman <stephen.berman@gmx.net>
2 57
3 * todos.el: Reorganize file structure. 58 * todos.el: Reorganize file structure.
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index 22126a43bd1..2e28e9e9bfc 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -1,4 +1,4 @@
1;;; Todos.el --- facilities for making and maintaining Todo lists 1;;; todos.el --- facilities for making and maintaining todo lists
2 2
3;; Copyright (C) 1997, 1999, 2001-2012 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 1999, 2001-2012 Free Software Foundation, Inc.
4 4
@@ -28,14 +28,15 @@
28;;; Code: 28;;; Code:
29 29
30(require 'diary-lib) 30(require 'diary-lib)
31;; For remove-duplicates in todos-insertion-commands-args. 31;; For cl-remove-duplicates in todos-insertion-commands-args and cl-oddp.
32(eval-when-compile (require 'cl)) 32(require 'cl-lib)
33 33
34;; --------------------------------------------------------------------------- 34;; =============================================================================
35;;; User interface 35;;; User interface
36;; --------------------------------------------------------------------------- 36;; =============================================================================
37 37;; -----------------------------------------------------------------------------
38;;; Options for file and category selection 38;;; Options for file and category selection
39;; -----------------------------------------------------------------------------
39 40
40;; These definitions have to precede `todos-filter-files'. 41;; These definitions have to precede `todos-filter-files'.
41 42
@@ -125,7 +126,9 @@ Otherwise, `todos-show' always visits `todos-default-todos-file'."
125 :type 'boolean 126 :type 'boolean
126 :group 'todos) 127 :group 'todos)
127 128
129;; -----------------------------------------------------------------------------
128;;; Entering and exiting Todos mode 130;;; Entering and exiting Todos mode
131;; -----------------------------------------------------------------------------
129 132
130;;;###autoload 133;;;###autoload
131(defun todos-show (&optional solicit-file) 134(defun todos-show (&optional solicit-file)
@@ -172,7 +175,7 @@ corresponding Todos file, displaying the corresponding category."
172 (if (funcall todos-files-function) 175 (if (funcall todos-files-function)
173 (todos-read-file-name "Choose a Todos file to visit: " 176 (todos-read-file-name "Choose a Todos file to visit: "
174 nil t) 177 nil t)
175 (error "There are no Todos files"))) 178 (user-error "There are no Todos files")))
176 ((and (eq major-mode 'todos-archive-mode) 179 ((and (eq major-mode 'todos-archive-mode)
177 ;; Called noninteractively via todos-quit 180 ;; Called noninteractively via todos-quit
178 ;; to jump to corresponding category in 181 ;; to jump to corresponding category in
@@ -275,7 +278,9 @@ buries it and restores state as needed."
275 (set-buffer (other-buffer))) 278 (set-buffer (other-buffer)))
276 (bury-buffer buf))))) 279 (bury-buffer buf)))))
277 280
281;; -----------------------------------------------------------------------------
278;;; Navigation commands 282;;; Navigation commands
283;; -----------------------------------------------------------------------------
279 284
280(defun todos-forward-category (&optional back) 285(defun todos-forward-category (&optional back)
281 "Visit the numerically next category in this Todos file. 286 "Visit the numerically next category in this Todos file.
@@ -401,19 +406,24 @@ empty line above the done items separator."
401 (when (> (line-number-at-pos) 1) 406 (when (> (line-number-at-pos) 1)
402 ;; It's not worth the trouble to allow prefix arg value < 1, since we have 407 ;; It's not worth the trouble to allow prefix arg value < 1, since we have
403 ;; the corresponding command. 408 ;; the corresponding command.
404 (cond ((and current-prefix-arg (< count 1)) 409 (cond ((and current-prefix-arg (< count 1))
405 (user-error "The prefix argument must be a positive number")) 410 (user-error "The prefix argument must be a positive number"))
406 (current-prefix-arg 411 (current-prefix-arg
407 (todos-backward-item count)) 412 (todos-backward-item count))
408 (t 413 (t
409 (todos-backward-item))))) 414 (todos-backward-item)))))
410 415
416;; -----------------------------------------------------------------------------
411;;; File editing commands 417;;; File editing commands
418;; -----------------------------------------------------------------------------
412 419
413(defun todos-add-file () 420(defun todos-add-file ()
414 "Name and add a new Todos file. 421 "Name and initialize a new Todos file.
415Interactively, prompt for a category and display it. 422Interactively, prompt for a category and display it.
416Noninteractively, return the name of the new file." 423Noninteractively, return the name of the new file.
424
425This command does not save the file to disk; to do that type
426\\[todos-save] or \\[todos-quit]."
417 (interactive) 427 (interactive)
418 (let ((prompt (concat "Enter name of new Todos file " 428 (let ((prompt (concat "Enter name of new Todos file "
419 "(TAB or SPC to see current names): ")) 429 "(TAB or SPC to see current names): "))
@@ -436,7 +446,15 @@ Noninteractively, return the name of the new file."
436 "Name of current buffer in Todos Edit mode.") 446 "Name of current buffer in Todos Edit mode.")
437 447
438(defun todos-edit-file (&optional item) 448(defun todos-edit-file (&optional item)
439 "" ;FIXME 449 "Put current buffer in `todos-edit-mode'.
450This makes the entire file visible and the buffer writeable and
451you can use the self-insertion keys and standard Emacs editing
452commands to make changes. To return to Todos mode, type
453\\[todos-edit-quit]. This runs a file format check, signalling
454an error if the format has become invalid. However, this check
455cannot tell if the number of items changed, which could result in
456the file containing inconsistent information. For this reason
457this command should be used with caution."
440 (interactive) 458 (interactive)
441 (widen) 459 (widen)
442 (todos-edit-mode) 460 (todos-edit-mode)
@@ -445,7 +463,9 @@ Noninteractively, return the name of the new file."
445 (concat "Type \\[todos-edit-quit] to check file format " 463 (concat "Type \\[todos-edit-quit] to check file format "
446 "validity and return to Todos mode.\n")))) 464 "validity and return to Todos mode.\n"))))
447 465
466;; -----------------------------------------------------------------------------
448;;; Category editing commands 467;;; Category editing commands
468;; -----------------------------------------------------------------------------
449 469
450(defun todos-add-category (&optional file cat) 470(defun todos-add-category (&optional file cat)
451 "Add a new category to a Todos file. 471 "Add a new category to a Todos file.
@@ -828,7 +848,9 @@ category."
828 (goto-char here))) 848 (goto-char here)))
829 (set-marker here nil))) 849 (set-marker here nil)))
830 850
851;; -----------------------------------------------------------------------------
831;;; Item marking 852;;; Item marking
853;; -----------------------------------------------------------------------------
832 854
833(defcustom todos-item-mark "*" 855(defcustom todos-item-mark "*"
834 "String used to mark items. 856 "String used to mark items.
@@ -906,7 +928,9 @@ marking of the next N items."
906 (todos-forward-item)))) 928 (todos-forward-item))))
907 (setq todos-categories-with-marks (delq marks todos-categories-with-marks)))) 929 (setq todos-categories-with-marks (delq marks todos-categories-with-marks))))
908 930
931;; -----------------------------------------------------------------------------
909;;; Item editing options 932;;; Item editing options
933;; -----------------------------------------------------------------------------
910 934
911(defcustom todos-include-in-diary nil 935(defcustom todos-include-in-diary nil
912 "Non-nil to allow new Todo items to be included in the diary." 936 "Non-nil to allow new Todo items to be included in the diary."
@@ -954,16 +978,33 @@ means prompt user and omit comment only on confirmation."
954 (const :tag "Ask" ask)) 978 (const :tag "Ask" ask))
955 :group 'todos) 979 :group 'todos)
956 980
981;; -----------------------------------------------------------------------------
957;;; Item editing commands 982;;; Item editing commands
983;; -----------------------------------------------------------------------------
958 984
959;;;###autoload 985;;;###autoload
960(defun todos-insert-item-1 (&optional arg diary nonmarking date-type time 986(defun todos-basic-insert-item (&optional arg diary nonmarking date-type time
961 region-or-here) 987 region-or-here)
962 "Add a new Todo item to a category. 988 "Insert a new Todo item into a category.
963\(See the note at the end of this document string about key 989This is the function from which the generated Todos item
964bindings and convenience commands derived from this command.) 990insertion commands derive.
965 991
966With no (or nil) prefix argument ARG, add the item to the current 992The generated commands have mnenomic key bindings based on the
993arguments' values and their order in the command's argument list,
994as follows: (1) for DIARY `d', (2) for NONMARKING `k', (3) for
995DATE-TYPE either `c' for calendar or `d' for date or `n' for
996weekday name, (4) for TIME `t', (5) for REGION-OR-HERE either `r'
997for region or `h' for here. Sequences of these keys are appended
998to the insertion prefix key `i'. Keys that allow a following
999key (i.e., any but `r' or `h') must be doubled when used finally.
1000For example, the command bound to the key sequence `i y h' will
1001insert a new item with today's date, marked according to the
1002DIARY argument described below, and with priority according to
1003the HERE argument; `i y y' does the same except that the priority
1004is not given by HERE but by prompting.
1005
1006In command invocations, ARG is passed as a prefix argument as
1007follows. With no prefix argument, add the item to the current
967category; with one prefix argument (C-u), prompt for a category 1008category; with one prefix argument (C-u), prompt for a category
968from the current Todos file; with two prefix arguments (C-u C-u), 1009from the current Todos file; with two prefix arguments (C-u C-u),
969first prompt for a Todos file, then a category in that file. If 1010first prompt for a Todos file, then a category in that file. If
@@ -971,6 +1012,10 @@ a non-existing category is entered, ask whether to add it to the
971Todos file; if answered affirmatively, add the category and 1012Todos file; if answered affirmatively, add the category and
972insert the item there. 1013insert the item there.
973 1014
1015The remaining arguments are set or left nil by the generated item
1016insertion commands; their meanings are described in the follows
1017paragraphs.
1018
974When argument DIARY is non-nil, this overrides the intent of the 1019When argument DIARY is non-nil, this overrides the intent of the
975user option `todos-include-in-diary' for this item: if 1020user option `todos-include-in-diary' for this item: if
976`todos-include-in-diary' is nil, include the item in the Fancy 1021`todos-include-in-diary' is nil, include the item in the Fancy
@@ -1016,16 +1061,15 @@ omit the current time string according as
1016 1061
1017The argument REGION-OR-HERE determines the source and location of 1062The argument REGION-OR-HERE determines the source and location of
1018the new item: 1063the new item:
1019- If the REGION-OR-HERE is the symbol `here', prompt for the text 1064- If the REGION-OR-HERE is the symbol `here', prompt for the text of
1020 of the new item and, if the command was invoked in the current 1065 the new item and, if the command was invoked with point in the todo
1021 category, insert it directly above the todo item at 1066 items section of the current category, give the new item the
1022 point (hence lowering the priority of the remaining items), or 1067 priority of the item at point, lowering the latter's priority and
1023 if point is on the empty line below the last todo item, insert 1068 the priority of the remaining items. If point is in the done items
1024 the new item there. If point is in the done items section of 1069 section of the category, insert the new item as the first todo item
1025 the category, insert the new item as the first todo item in the 1070 in the category. Likewise, if the command with `here' is invoked
1026 category. Likewise, if the command with `here' is invoked 1071 outside of the current category, jump to the chosen category and
1027 outside of the current category, jump to the chosen category 1072 insert the new item as the first item in the category.
1028 and insert the new item as the first item in the category.
1029- If REGION-OR-HERE is the symbol `region', use the region of the 1073- If REGION-OR-HERE is the symbol `region', use the region of the
1030 current buffer as the text of the new item, depending on the 1074 current buffer as the text of the new item, depending on the
1031 value of user option `todos-use-only-highlighted-region': if 1075 value of user option `todos-use-only-highlighted-region': if
@@ -1037,24 +1081,7 @@ the new item:
1037 items in the category), and insert the item accordingly. 1081 items in the category), and insert the item accordingly.
1038- If REGION-OR-HERE has any other value (in particular, nil or 1082- If REGION-OR-HERE has any other value (in particular, nil or
1039 none), prompt for the text and the item's priority, and insert 1083 none), prompt for the text and the item's priority, and insert
1040 the item accordingly. 1084 the item accordingly."
1041
1042To facilitate using these arguments when inserting a new todo
1043item, convenience commands have been defined for all admissible
1044combinations together with mnenomic key bindings based on on the
1045name of the arguments and their order in the command's argument
1046list: diar_y_ - nonmar_k_ing - _c_alendar or _d_ate or day_n_ame
1047- _t_ime - _r_egion or _h_ere. These key combinations are
1048appended to the basic insertion key (i) and keys that allow a
1049following key must be doubled when used finally. For example,
1050`iyh' will insert a new item with today's date, marked according
1051to the DIARY argument described above, and with priority
1052according to the HERE argument; while `iyy' does the same except
1053the priority is not given by HERE but by prompting."
1054;; An alternative interface for customizing key
1055;; binding is also provided with the function
1056;; `todos-insertion-bindings'." ;FIXME
1057 ;; (interactive "P")
1058 ;; If invoked outside of Todos mode and there is not yet any Todos 1085 ;; If invoked outside of Todos mode and there is not yet any Todos
1059 ;; file, initialize one. 1086 ;; file, initialize one.
1060 (if (null todos-files) 1087 (if (null todos-files)
@@ -1064,7 +1091,7 @@ the priority is not given by HERE but by prompting."
1064 (when region 1091 (when region
1065 (let (use-empty-active-region) 1092 (let (use-empty-active-region)
1066 (unless (and todos-use-only-highlighted-region (use-region-p)) 1093 (unless (and todos-use-only-highlighted-region (use-region-p))
1067 (error "There is no active region")))) 1094 (user-error "There is no active region"))))
1068 (let* ((obuf (current-buffer)) 1095 (let* ((obuf (current-buffer))
1069 (ocat (todos-current-category)) 1096 (ocat (todos-current-category))
1070 (opoint (point)) 1097 (opoint (point))
@@ -1392,7 +1419,7 @@ in the number or names of categories."
1392 (todos-category-select) 1419 (todos-category-select)
1393 (goto-char (point-min)))))) 1420 (goto-char (point-min))))))
1394 1421
1395(defun todos-edit-item-header-1 (what &optional inc) 1422(defun todos-basic-edit-item-header (what &optional inc)
1396 "Function underlying commands to edit item date/time header. 1423 "Function underlying commands to edit item date/time header.
1397 1424
1398The argument WHAT (passed by invoking commands) specifies what 1425The argument WHAT (passed by invoking commands) specifies what
@@ -1483,7 +1510,7 @@ otherwise, edit just the item at point."
1483 year (cond ((not current-prefix-arg) 1510 year (cond ((not current-prefix-arg)
1484 (todos-read-date 'year)) 1511 (todos-read-date 'year))
1485 ((string= oyear "*") 1512 ((string= oyear "*")
1486 (error "Cannot increment *")) 1513 (user-error "Cannot increment *"))
1487 (t 1514 (t
1488 (number-to-string (+ yy inc)))))) 1515 (number-to-string (+ yy inc))))))
1489 ((eq what 'month) 1516 ((eq what 'month)
@@ -1495,7 +1522,7 @@ otherwise, edit just the item at point."
1495 (cond ((not current-prefix-arg) 1522 (cond ((not current-prefix-arg)
1496 (todos-read-date 'month)) 1523 (todos-read-date 'month))
1497 ((or (string= omonth "*") (= mm 13)) 1524 ((or (string= omonth "*") (= mm 13))
1498 (error "Cannot increment *")) 1525 (user-error "Cannot increment *"))
1499 (t 1526 (t
1500 (let ((mminc (+ mm inc))) 1527 (let ((mminc (+ mm inc)))
1501 ;; Increment or decrement month by INC 1528 ;; Increment or decrement month by INC
@@ -1524,7 +1551,7 @@ otherwise, edit just the item at point."
1524 (mm (if (= mm 13) 1 mm))) 1551 (mm (if (= mm 13) 1 mm)))
1525 (if (> (string-to-number day) 1552 (if (> (string-to-number day)
1526 (calendar-last-day-of-month mm yy)) 1553 (calendar-last-day-of-month mm yy))
1527 (error "%s %s does not have %s days" 1554 (user-error "%s %s does not have %s days"
1528 (aref tmn-array (1- mm)) 1555 (aref tmn-array (1- mm))
1529 (if (= mm 2) yy "") day)))) 1556 (if (= mm 2) yy "") day))))
1530 ((eq what 'day) 1557 ((eq what 'day)
@@ -1535,11 +1562,11 @@ otherwise, edit just the item at point."
1535 ((not current-prefix-arg) 1562 ((not current-prefix-arg)
1536 (todos-read-date 'day mm oyear)) 1563 (todos-read-date 'day mm oyear))
1537 ((string= oday "*") 1564 ((string= oday "*")
1538 (error "Cannot increment *")) 1565 (user-error "Cannot increment *"))
1539 ((or (string= omonth "*") (string= omonthname "*")) 1566 ((or (string= omonth "*") (string= omonthname "*"))
1540 (setq dd (+ dd inc)) 1567 (setq dd (+ dd inc))
1541 (if (> dd 31) 1568 (if (> dd 31)
1542 (error "A month cannot have more than 31 days") 1569 (user-error "A month cannot have more than 31 days")
1543 (number-to-string dd))) 1570 (number-to-string dd)))
1544 ;; Increment or decrement day by INC, 1571 ;; Increment or decrement day by INC,
1545 ;; adjusting month and year if necessary 1572 ;; adjusting month and year if necessary
@@ -1587,50 +1614,50 @@ otherwise, edit just the item at point."
1587If user option `todos-always-add-time-string' is non-nil, also 1614If user option `todos-always-add-time-string' is non-nil, also
1588edit item's time string." 1615edit item's time string."
1589 (interactive) 1616 (interactive)
1590 (todos-edit-item-header-1 'date) 1617 (todos-basic-edit-item-header 'date)
1591 (when todos-always-add-time-string 1618 (when todos-always-add-time-string
1592 (todos-edit-item-time))) 1619 (todos-edit-item-time)))
1593 1620
1594(defun todos-edit-item-time () 1621(defun todos-edit-item-time ()
1595 "Interactively edit the time string of item's date/time header." 1622 "Interactively edit the time string of item's date/time header."
1596 (interactive) 1623 (interactive)
1597 (todos-edit-item-header-1 'time)) 1624 (todos-basic-edit-item-header 'time))
1598 1625
1599(defun todos-edit-item-date-from-calendar () 1626(defun todos-edit-item-date-from-calendar ()
1600 "Interactively edit item's date using the Calendar." 1627 "Interactively edit item's date using the Calendar."
1601 (interactive) 1628 (interactive)
1602 (todos-edit-item-header-1 'calendar)) 1629 (todos-basic-edit-item-header 'calendar))
1603 1630
1604(defun todos-edit-item-date-to-today () 1631(defun todos-edit-item-date-to-today ()
1605 "Set item's date to today's date." 1632 "Set item's date to today's date."
1606 (interactive) 1633 (interactive)
1607 (todos-edit-item-header-1 'today)) 1634 (todos-basic-edit-item-header 'today))
1608 1635
1609(defun todos-edit-item-date-day-name () 1636(defun todos-edit-item-date-day-name ()
1610 "Replace item's date with the name of a day of the week." 1637 "Replace item's date with the name of a day of the week."
1611 (interactive) 1638 (interactive)
1612 (todos-edit-item-header-1 'dayname)) 1639 (todos-basic-edit-item-header 'dayname))
1613 1640
1614(defun todos-edit-item-date-year (&optional inc) 1641(defun todos-edit-item-date-year (&optional inc)
1615 "Interactively edit the year of item's date string. 1642 "Interactively edit the year of item's date string.
1616With prefix argument INC a positive or negative integer, 1643With prefix argument INC a positive or negative integer,
1617increment or decrement the year by INC." 1644increment or decrement the year by INC."
1618 (interactive "p") 1645 (interactive "p")
1619 (todos-edit-item-header-1 'year inc)) 1646 (todos-basic-edit-item-header 'year inc))
1620 1647
1621(defun todos-edit-item-date-month (&optional inc) 1648(defun todos-edit-item-date-month (&optional inc)
1622 "Interactively edit the month of item's date string. 1649 "Interactively edit the month of item's date string.
1623With prefix argument INC a positive or negative integer, 1650With prefix argument INC a positive or negative integer,
1624increment or decrement the month by INC." 1651increment or decrement the month by INC."
1625 (interactive "p") 1652 (interactive "p")
1626 (todos-edit-item-header-1 'month inc)) 1653 (todos-basic-edit-item-header 'month inc))
1627 1654
1628(defun todos-edit-item-date-day (&optional inc) 1655(defun todos-edit-item-date-day (&optional inc)
1629 "Interactively edit the day of the month of item's date string. 1656 "Interactively edit the day of the month of item's date string.
1630With prefix argument INC a positive or negative integer, 1657With prefix argument INC a positive or negative integer,
1631increment or decrement the day by INC." 1658increment or decrement the day by INC."
1632 (interactive "p") 1659 (interactive "p")
1633 (todos-edit-item-header-1 'day inc)) 1660 (todos-basic-edit-item-header 'day inc))
1634 1661
1635(defun todos-edit-item-diary-inclusion () 1662(defun todos-edit-item-diary-inclusion ()
1636 "Change diary status of one or more todo items in this category. 1663 "Change diary status of one or more todo items in this category.
@@ -1766,7 +1793,7 @@ The new priority is set either interactively by prompt or by a
1766numerical prefix argument, or noninteractively by argument ARG, 1793numerical prefix argument, or noninteractively by argument ARG,
1767whose value can be either of the symbols `raise' or `lower', 1794whose value can be either of the symbols `raise' or `lower',
1768meaning to raise or lower the item's priority by one." 1795meaning to raise or lower the item's priority by one."
1769 (interactive) ;FIXME: Prefix arg? 1796 (interactive)
1770 (unless (and (called-interactively-p 'any) 1797 (unless (and (called-interactively-p 'any)
1771 (or (todos-done-item-p) (looking-at "^$"))) 1798 (or (todos-done-item-p) (looking-at "^$")))
1772 (let* ((item (or item (todos-item-string))) 1799 (let* ((item (or item (todos-item-string)))
@@ -1854,7 +1881,7 @@ meaning to raise or lower the item's priority by one."
1854 (when (re-search-forward regexp2 end t) 1881 (when (re-search-forward regexp2 end t)
1855 (match-string-no-properties 1))))))) 1882 (match-string-no-properties 1)))))))
1856 (when match 1883 (when match
1857 (error (concat "Cannot reprioritize items from the same " 1884 (user-error (concat "Cannot reprioritize items from the same "
1858 "category in this mode, only in Todos mode"))))) 1885 "category in this mode, only in Todos mode")))))
1859 ;; Interactively or with non-nil ARG, relocate the item within its 1886 ;; Interactively or with non-nil ARG, relocate the item within its
1860 ;; category. 1887 ;; category.
@@ -2187,7 +2214,7 @@ comments without asking."
2187 (while (not (eobp)) 2214 (while (not (eobp))
2188 (when (or (not marked) (and marked (todos-marked-item-p))) 2215 (when (or (not marked) (and marked (todos-marked-item-p)))
2189 (if (not (todos-done-item-p)) 2216 (if (not (todos-done-item-p))
2190 (error "Only done items can be undone") 2217 (user-error "Only done items can be undone")
2191 (todos-item-start) 2218 (todos-item-start)
2192 (unless marked 2219 (unless marked
2193 (setq ov (make-overlay (save-excursion (todos-item-start)) 2220 (setq ov (make-overlay (save-excursion (todos-item-start))
@@ -2257,7 +2284,9 @@ comments without asking."
2257 (goto-char npoint))) 2284 (goto-char npoint)))
2258 (set-marker omark nil))))) 2285 (set-marker omark nil)))))
2259 2286
2287;; -----------------------------------------------------------------------------
2260;;; Done Item Archives 2288;;; Done Item Archives
2289;; -----------------------------------------------------------------------------
2261 2290
2262(defcustom todos-skip-archived-categories nil 2291(defcustom todos-skip-archived-categories nil
2263 "Non-nil to handle categories with only archived items specially. 2292 "Non-nil to handle categories with only archived items specially.
@@ -2493,14 +2522,6 @@ the only category in the archive, the archive file is deleted."
2493 (re-search-forward 2522 (re-search-forward
2494 (concat "^" (regexp-quote todos-category-done)) nil t) 2523 (concat "^" (regexp-quote todos-category-done)) nil t)
2495 (forward-line) 2524 (forward-line)
2496 ;; FIXME: delete after checking
2497 ;; ;; Put point below newly added category beginning,
2498 ;; ;; otherwise the following search wrongly succeeds.
2499 ;; (forward-line))
2500 ;; (if (re-search-forward (concat "^" (regexp-quote todos-category-beg))
2501 ;; nil t)
2502 ;; (goto-char (match-beginning 0))
2503 ;; (goto-char (point-max)))
2504 (cond (marked 2525 (cond (marked
2505 (insert marked-items) 2526 (insert marked-items)
2506 (todos-update-count 'done marked-count cat) 2527 (todos-update-count 'done marked-count cat)
@@ -2565,7 +2586,9 @@ and jump to any category in the current archive."
2565 (interactive "P") 2586 (interactive "P")
2566 (todos-jump-to-category file 'archive)) 2587 (todos-jump-to-category file 'archive))
2567 2588
2589;; -----------------------------------------------------------------------------
2568;;; Todos mode display options 2590;;; Todos mode display options
2591;; -----------------------------------------------------------------------------
2569 2592
2570(defcustom todos-prefix "" 2593(defcustom todos-prefix ""
2571 "String prefixed to todo items for visual distinction." 2594 "String prefixed to todo items for visual distinction."
@@ -2665,7 +2688,9 @@ shown in the Fancy Diary display."
2665 "Indent from point to `todos-indent-to-here'." 2688 "Indent from point to `todos-indent-to-here'."
2666 (indent-to todos-indent-to-here todos-indent-to-here)) 2689 (indent-to todos-indent-to-here todos-indent-to-here))
2667 2690
2691;; -----------------------------------------------------------------------------
2668;;; Display Commands 2692;;; Display Commands
2693;; -----------------------------------------------------------------------------
2669 2694
2670(defun todos-toggle-prefix-numbers () 2695(defun todos-toggle-prefix-numbers ()
2671 "Hide item numbering if shown, show if hidden." 2696 "Hide item numbering if shown, show if hidden."
@@ -2740,7 +2765,9 @@ the the original date-time string."
2740 (overlay-put ov 'display "")) 2765 (overlay-put ov 'display ""))
2741 (todos-forward-item)))))) 2766 (todos-forward-item))))))
2742 2767
2768;; -----------------------------------------------------------------------------
2743;;; Faces 2769;;; Faces
2770;; -----------------------------------------------------------------------------
2744 2771
2745(defface todos-prefix-string 2772(defface todos-prefix-string
2746 ;; '((t :inherit font-lock-constant-face)) 2773 ;; '((t :inherit font-lock-constant-face))
@@ -2797,7 +2824,7 @@ less than or equal the category's top priority setting."
2797 (:foreground "red")) 2824 (:foreground "red"))
2798 (t 2825 (t
2799 (:weight bold :inverse-video t))) 2826 (:weight bold :inverse-video t)))
2800 "Face for marks on Todos items." 2827 "Face for marks on marked items."
2801 :group 'todos-faces) 2828 :group 'todos-faces)
2802 2829
2803(defface todos-button 2830(defface todos-button
@@ -2812,7 +2839,7 @@ less than or equal the category's top priority setting."
2812 (:background "dim gray")) 2839 (:background "dim gray"))
2813 (t 2840 (t
2814 (:slant italic))) 2841 (:slant italic)))
2815 "Face for buttons in todos-display-categories." 2842 "Face for buttons in table of categories."
2816 :group 'todos-faces) 2843 :group 'todos-faces)
2817 2844
2818(defface todos-sorted-column 2845(defface todos-sorted-column
@@ -2826,7 +2853,7 @@ less than or equal the category's top priority setting."
2826 (:background "grey85" :foreground "grey10")) 2853 (:background "grey85" :foreground "grey10"))
2827 (t 2854 (t
2828 (:background "gray"))) 2855 (:background "gray")))
2829 "Face for buttons in todos-display-categories." 2856 "Face for sorted column in table of categories."
2830 :group 'todos-faces) 2857 :group 'todos-faces)
2831 2858
2832(defface todos-archived-only 2859(defface todos-archived-only
@@ -2839,7 +2866,7 @@ less than or equal the category's top priority setting."
2839 (:foreground "grey70")) 2866 (:foreground "grey70"))
2840 (t 2867 (t
2841 (:foreground "gray"))) 2868 (:foreground "gray")))
2842 "Face for archived-only categories in todos-display-categories." 2869 "Face for archived-only category names in table of categories."
2843 :group 'todos-faces) 2870 :group 'todos-faces)
2844 2871
2845(defface todos-search 2872(defface todos-search
@@ -2865,7 +2892,7 @@ less than or equal the category's top priority setting."
2865 (:inverse-video t)) 2892 (:inverse-video t))
2866 (t 2893 (t
2867 (:background "gray"))) 2894 (:background "gray")))
2868 "Face for matches found by todos-search." 2895 "Face for matches found by `todos-search'."
2869 :group 'todos-faces) 2896 :group 'todos-faces)
2870 2897
2871(defface todos-diary-expired 2898(defface todos-diary-expired
@@ -2884,14 +2911,17 @@ less than or equal the category's top priority setting."
2884 (t :inverse-video t)) 2911 (t :inverse-video t))
2885 "Face for expired dates of diary items." 2912 "Face for expired dates of diary items."
2886 :group 'todos-faces) 2913 :group 'todos-faces)
2914
2887(defface todos-date 2915(defface todos-date
2888 '((t :inherit diary)) 2916 '((t :inherit diary))
2889 "Face for the date string of a Todos item." 2917 "Face for the date string of a Todos item."
2890 :group 'todos-faces) 2918 :group 'todos-faces)
2919
2891(defface todos-time 2920(defface todos-time
2892 '((t :inherit diary-time)) 2921 '((t :inherit diary-time))
2893 "Face for the time string of a Todos item." 2922 "Face for the time string of a Todos item."
2894 :group 'todos-faces) 2923 :group 'todos-faces)
2924
2895(defface todos-nondiary 2925(defface todos-nondiary
2896 ;; '((t :inherit font-lock-type-face)) 2926 ;; '((t :inherit font-lock-type-face))
2897 '((((class grayscale) (background light)) :foreground "Gray90" :weight bold) 2927 '((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
@@ -2904,6 +2934,7 @@ less than or equal the category's top priority setting."
2904 (t :weight bold :underline t)) 2934 (t :weight bold :underline t))
2905 "Face for non-diary markers around todo item date/time header." 2935 "Face for non-diary markers around todo item date/time header."
2906 :group 'todos-faces) 2936 :group 'todos-faces)
2937
2907(defface todos-category-string 2938(defface todos-category-string
2908 ;; '((t :inherit font-lock-type-face)) 2939 ;; '((t :inherit font-lock-type-face))
2909 '((((class grayscale) (background light)) :foreground "Gray90" :weight bold) 2940 '((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
@@ -2914,8 +2945,9 @@ less than or equal the category's top priority setting."
2914 (((class color) (min-colors 16) (background dark)) :foreground "PaleGreen") 2945 (((class color) (min-colors 16) (background dark)) :foreground "PaleGreen")
2915 (((class color) (min-colors 8)) :foreground "green") 2946 (((class color) (min-colors 8)) :foreground "green")
2916 (t :weight bold :underline t)) 2947 (t :weight bold :underline t))
2917 "Face for category file names in Todos Filtered Item." 2948 "Face for category-file header in Todos Filtered Items mode."
2918 :group 'todos-faces) 2949 :group 'todos-faces)
2950
2919(defface todos-done 2951(defface todos-done
2920 ;; '((t :inherit font-lock-keyword-face)) 2952 ;; '((t :inherit font-lock-keyword-face))
2921 '((((class grayscale) (background light)) :foreground "LightGray" :weight bold) 2953 '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
@@ -2928,6 +2960,7 @@ less than or equal the category's top priority setting."
2928 (t :weight bold)) 2960 (t :weight bold))
2929 "Face for done Todos item header string." 2961 "Face for done Todos item header string."
2930 :group 'todos-faces) 2962 :group 'todos-faces)
2963
2931(defface todos-comment 2964(defface todos-comment
2932 ;; '((t :inherit font-lock-comment-face)) 2965 ;; '((t :inherit font-lock-comment-face))
2933 '((((class grayscale) (background light)) 2966 '((((class grayscale) (background light))
@@ -2949,6 +2982,7 @@ less than or equal the category's top priority setting."
2949 (t :weight bold :slant italic)) 2982 (t :weight bold :slant italic))
2950 "Face for comments appended to done Todos items." 2983 "Face for comments appended to done Todos items."
2951 :group 'todos-faces) 2984 :group 'todos-faces)
2985
2952(defface todos-done-sep 2986(defface todos-done-sep
2953 ;; '((t :inherit font-lock-builtin-face)) 2987 ;; '((t :inherit font-lock-builtin-face))
2954 '((((class grayscale) (background light)) :foreground "LightGray" :weight bold) 2988 '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
@@ -2961,7 +2995,10 @@ less than or equal the category's top priority setting."
2961 (t :weight bold)) 2995 (t :weight bold))
2962 "Face for separator string bewteen done and not done Todos items." 2996 "Face for separator string bewteen done and not done Todos items."
2963 :group 'todos-faces) 2997 :group 'todos-faces)
2998
2999;; -----------------------------------------------------------------------------
2964;;; Todos Categories mode options 3000;;; Todos Categories mode options
3001;; -----------------------------------------------------------------------------
2965 3002
2966(defcustom todos-categories-category-label "Category" 3003(defcustom todos-categories-category-label "Category"
2967 "Category button label in Todos Categories mode." 3004 "Category button label in Todos Categories mode."
@@ -3005,7 +3042,9 @@ categories display according to priority."
3005 :type '(radio (const left) (const center) (const right)) 3042 :type '(radio (const left) (const center) (const right))
3006 :group 'todos-categories) 3043 :group 'todos-categories)
3007 3044
3045;; -----------------------------------------------------------------------------
3008;;; Entering and using Todos Categories mode 3046;;; Entering and using Todos Categories mode
3047;; -----------------------------------------------------------------------------
3009 3048
3010(defun todos-show-categories-table () 3049(defun todos-show-categories-table ()
3011 "Display a table of the current file's categories and item counts. 3050 "Display a table of the current file's categories and item counts.
@@ -3033,12 +3072,12 @@ containing only archived items, provided user option
3033`todos-skip-archived-categories' is non-nil. These categories 3072`todos-skip-archived-categories' is non-nil. These categories
3034are shown in `todos-archived-only' face." 3073are shown in `todos-archived-only' face."
3035 (interactive) 3074 (interactive)
3036 (todos-display-categories-1) 3075 (todos-display-categories)
3037 (let (sortkey) 3076 (let (sortkey)
3038 (todos-update-categories-display sortkey))) 3077 (todos-update-categories-display sortkey)))
3039 3078
3040(defun todos-sort-categories-alphabetically-or-by-priority () 3079(defun todos-sort-categories-alphabetically-or-by-priority ()
3041 "" 3080 "Sort table of categories alphabetically or numerically."
3042 (interactive) 3081 (interactive)
3043 (save-excursion 3082 (save-excursion
3044 (goto-char (point-min)) 3083 (goto-char (point-min))
@@ -3051,7 +3090,7 @@ are shown in `todos-archived-only' face."
3051 (todos-update-categories-display 'alpha)))) 3090 (todos-update-categories-display 'alpha))))
3052 3091
3053(defun todos-sort-categories-by-todo () 3092(defun todos-sort-categories-by-todo ()
3054 "" 3093 "Sort table of categories by number of todo items."
3055 (interactive) 3094 (interactive)
3056 (save-excursion 3095 (save-excursion
3057 (goto-char (point-min)) 3096 (goto-char (point-min))
@@ -3059,7 +3098,7 @@ are shown in `todos-archived-only' face."
3059 (todos-update-categories-display 'todo))) 3098 (todos-update-categories-display 'todo)))
3060 3099
3061(defun todos-sort-categories-by-diary () 3100(defun todos-sort-categories-by-diary ()
3062 "" 3101 "Sort table of categories by number of diary items."
3063 (interactive) 3102 (interactive)
3064 (save-excursion 3103 (save-excursion
3065 (goto-char (point-min)) 3104 (goto-char (point-min))
@@ -3067,7 +3106,7 @@ are shown in `todos-archived-only' face."
3067 (todos-update-categories-display 'diary))) 3106 (todos-update-categories-display 'diary)))
3068 3107
3069(defun todos-sort-categories-by-done () 3108(defun todos-sort-categories-by-done ()
3070 "" 3109 "Sort table of categories by number of non-archived done items."
3071 (interactive) 3110 (interactive)
3072 (save-excursion 3111 (save-excursion
3073 (goto-char (point-min)) 3112 (goto-char (point-min))
@@ -3075,7 +3114,7 @@ are shown in `todos-archived-only' face."
3075 (todos-update-categories-display 'done))) 3114 (todos-update-categories-display 'done)))
3076 3115
3077(defun todos-sort-categories-by-archived () 3116(defun todos-sort-categories-by-archived ()
3078 "" 3117 "Sort table of categories by number of archived items."
3079 (interactive) 3118 (interactive)
3080 (save-excursion 3119 (save-excursion
3081 (goto-char (point-min)) 3120 (goto-char (point-min))
@@ -3083,7 +3122,7 @@ are shown in `todos-archived-only' face."
3083 (todos-update-categories-display 'archived))) 3122 (todos-update-categories-display 'archived)))
3084 3123
3085(defun todos-next-button (n &optional wrap display-message) 3124(defun todos-next-button (n &optional wrap display-message)
3086 "" 3125 "Move point to the next button in the table of categories."
3087 (interactive "p\nd\nd") 3126 (interactive "p\nd\nd")
3088 (forward-button n wrap display-message) 3127 (forward-button n wrap display-message)
3089 (and (bolp) (button-at (point)) 3128 (and (bolp) (button-at (point))
@@ -3091,7 +3130,7 @@ are shown in `todos-archived-only' face."
3091 (forward-char (+ 4 (length todos-categories-number-separator))))) 3130 (forward-char (+ 4 (length todos-categories-number-separator)))))
3092 3131
3093(defun todos-previous-button (n &optional wrap display-message) 3132(defun todos-previous-button (n &optional wrap display-message)
3094 "" 3133 "Move point to the previous button in the table of categories."
3095 (interactive "p\nd\nd") 3134 (interactive "p\nd\nd")
3096 (backward-button n wrap display-message) 3135 (backward-button n wrap display-message)
3097 (and (bolp) (button-at (point)) 3136 (and (bolp) (button-at (point))
@@ -3162,7 +3201,9 @@ raise or lower the category's priority by one."
3162 (interactive) 3201 (interactive)
3163 (todos-set-category-priority 'lower)) 3202 (todos-set-category-priority 'lower))
3164 3203
3204;; -----------------------------------------------------------------------------
3165;;; Searching 3205;;; Searching
3206;; -----------------------------------------------------------------------------
3166 3207
3167(defun todos-search () 3208(defun todos-search ()
3168 "Search for a regular expression in this Todos file. 3209 "Search for a regular expression in this Todos file.
@@ -3230,20 +3271,25 @@ face."
3230 (interactive) 3271 (interactive)
3231 (remove-overlays 1 (1+ (buffer-size)) 'face 'todos-search)) 3272 (remove-overlays 1 (1+ (buffer-size)) 'face 'todos-search))
3232 3273
3274;; -----------------------------------------------------------------------------
3233;;; Item filtering options 3275;;; Item filtering options
3276;; -----------------------------------------------------------------------------
3277
3278(defcustom todos-top-priorities-overrides nil
3279 "List of rules specifying number of top priority items to show.
3280These rules override `todos-top-priorities' on invocations of
3281`\\[todos-filter-top-priorities]' and
3282`\\[todos-filter-top-priorities-multifile]'. Each rule is a list
3283of the form (FILE NUM ALIST), where FILE is a member of
3284`todos-files', NUM is a number specifying the default number of
3285top priority items for each category in that file, and ALIST,
3286when non-nil, consists of conses of a category name in FILE and a
3287number specifying the default number of top priority items in
3288that category, which overrides NUM.
3234 3289
3235(defcustom todos-top-priorities-overrides nil ;FIXME: doc string
3236 "List of rules giving how many items `todos-filter-top-priorities' shows.
3237This variable should be set interactively by 3290This variable should be set interactively by
3238`\\[todos-set-top-priorities-in-file]' or 3291`\\[todos-set-top-priorities-in-file]' or
3239`\\[todos-set-top-priorities-in-category]'. 3292`\\[todos-set-top-priorities-in-category]'."
3240
3241Each rule is a list of the form (FILE NUM ALIST), where FILE is a
3242member of `todos-files', NUM is a number specifying the default
3243number of top priority items for each category in that file, and
3244ALIST, when non-nil, consists of conses of a category name in
3245FILE and a number specifying the default number of top priority
3246items in that category, which overrides NUM."
3247 :type 'sexp 3293 :type 'sexp
3248 :group 'todos-filtered) 3294 :group 'todos-filtered)
3249 3295
@@ -3265,7 +3311,9 @@ Done items from corresponding archive files are also included."
3265 :type 'boolean 3311 :type 'boolean
3266 :group 'todos-filtered) 3312 :group 'todos-filtered)
3267 3313
3314;; -----------------------------------------------------------------------------
3268;;; Item filtering commands 3315;;; Item filtering commands
3316;; -----------------------------------------------------------------------------
3269 3317
3270(defun todos-set-top-priorities-in-file () 3318(defun todos-set-top-priorities-in-file ()
3271 "Set number of top priorities for this file. 3319 "Set number of top priorities for this file.
@@ -3417,7 +3465,9 @@ regexp items."
3417 (todos-category-select)) 3465 (todos-category-select))
3418 (goto-char (car found))))) 3466 (goto-char (car found)))))
3419 3467
3468;; -----------------------------------------------------------------------------
3420;;; Printing Todos Buffers 3469;;; Printing Todos Buffers
3470;; -----------------------------------------------------------------------------
3421 3471
3422(defcustom todos-print-buffer-function 'ps-print-buffer-with-faces 3472(defcustom todos-print-buffer-function 'ps-print-buffer-with-faces
3423 "Function called to print buffer content; see `todos-print-buffer'." 3473 "Function called to print buffer content; see `todos-print-buffer'."
@@ -3482,7 +3532,9 @@ otherwise, send it to the default printer."
3482 (interactive) 3532 (interactive)
3483 (todos-print-buffer t)) 3533 (todos-print-buffer t))
3484 3534
3535;; -----------------------------------------------------------------------------
3485;;; Legacy Todo Mode Files 3536;;; Legacy Todo Mode Files
3537;; -----------------------------------------------------------------------------
3486 3538
3487(defcustom todos-todo-mode-date-time-regexp 3539(defcustom todos-todo-mode-date-time-regexp
3488 (concat "\\(?1:[0-9]\\{4\\}\\)-\\(?2:[0-9]\\{2\\}\\)-" 3540 (concat "\\(?1:[0-9]\\{4\\}\\)-\\(?2:[0-9]\\{2\\}\\)-"
@@ -3521,7 +3573,7 @@ saved (the latter as a Todos Archive file) with a new name in
3521 (interactive) 3573 (interactive)
3522 (if (fboundp 'todo-mode) 3574 (if (fboundp 'todo-mode)
3523 (require 'todo-mode) 3575 (require 'todo-mode)
3524 (error "Void function `todo-mode'")) 3576 (user-error "Void function `todo-mode'"))
3525 ;; Convert `todo-file-do'. 3577 ;; Convert `todo-file-do'.
3526 (if (file-exists-p todo-file-do) 3578 (if (file-exists-p todo-file-do)
3527 (let ((default "todo-do-conv") 3579 (let ((default "todo-do-conv")
@@ -3655,13 +3707,15 @@ saved (the latter as a Todos Archive file) with a new name in
3655 (write-region (point-min) (point-max) file nil 'nomessage))) 3707 (write-region (point-min) (point-max) file nil 'nomessage)))
3656 (todos-reevaluate-filelist-defcustoms) 3708 (todos-reevaluate-filelist-defcustoms)
3657 (message "Format conversion done.")) 3709 (message "Format conversion done."))
3658 (error "No legacy Todo file exists"))) 3710 (user-error "No legacy Todo file exists")))
3659 3711
3660;; --------------------------------------------------------------------------- 3712;; =============================================================================
3661;;; Todos infrastructure 3713;;; Todos utilities and internals
3662;; --------------------------------------------------------------------------- 3714;; =============================================================================
3663 3715
3664;;; Todos files infrastructure 3716;; -----------------------------------------------------------------------------
3717;;; File-level global variables and support functions
3718;; -----------------------------------------------------------------------------
3665 3719
3666(defvar todos-files (funcall todos-files-function) 3720(defvar todos-files (funcall todos-files-function)
3667 "List of truenames of user's Todos files.") 3721 "List of truenames of user's Todos files.")
@@ -3716,7 +3770,7 @@ but the categories sexp differs from the current value of
3716 (unless (and (stringp (car c)) 3770 (unless (and (stringp (car c))
3717 (vectorp v) 3771 (vectorp v)
3718 (= 4 (length v))) 3772 (= 4 (length v)))
3719 (error "Invalid or missing todos-categories sexp")))) 3773 (user-error "Invalid or missing todos-categories sexp"))))
3720 (forward-line) 3774 (forward-line)
3721 ;; Check well-formedness of categories. 3775 ;; Check well-formedness of categories.
3722 (let ((legit (concat "\\(^" (regexp-quote todos-category-beg) "\\)" 3776 (let ((legit (concat "\\(^" (regexp-quote todos-category-beg) "\\)"
@@ -3727,7 +3781,7 @@ but the categories sexp differs from the current value of
3727 "\\|\\(" todos-done-string-start "\\)"))) 3781 "\\|\\(" todos-done-string-start "\\)")))
3728 (while (not (eobp)) 3782 (while (not (eobp))
3729 (unless (looking-at legit) 3783 (unless (looking-at legit)
3730 (error "Illegitimate Todos file format at line %d" 3784 (user-error "Illegitimate Todos file format at line %d"
3731 (line-number-at-pos (point)))) 3785 (line-number-at-pos (point))))
3732 (forward-line))) 3786 (forward-line)))
3733 ;; Warn user if categories sexp has changed. 3787 ;; Warn user if categories sexp has changed.
@@ -3781,7 +3835,9 @@ Called after adding or deleting a Todos file."
3781 (funcall todos-files-function)))) 3835 (funcall todos-files-function))))
3782 :group 'todos))) 3836 :group 'todos)))
3783 3837
3784;;; Todos categories infrastructure 3838;; -----------------------------------------------------------------------------
3839;;; Category-level global variables and support functions
3840;; -----------------------------------------------------------------------------
3785 3841
3786(defun todos-category-number (cat) 3842(defun todos-category-number (cat)
3787 "Return the number of category CAT in this Todos file. 3843 "Return the number of category CAT in this Todos file.
@@ -4026,7 +4082,9 @@ changes made in Todos Categories mode will have to be made again."
4026 (let ((todos-categories (todos-make-categories-list t))) 4082 (let ((todos-categories (todos-make-categories-list t)))
4027 (todos-update-categories-sexp))) 4083 (todos-update-categories-sexp)))
4028 4084
4029;;; Todos items infrastructure 4085;; -----------------------------------------------------------------------------
4086;;; Item-level global variables and support functions
4087;; -----------------------------------------------------------------------------
4030 4088
4031(defconst todos-month-name-array 4089(defconst todos-month-name-array
4032 (vconcat calendar-month-name-array (vector "*")) 4090 (vconcat calendar-month-name-array (vector "*"))
@@ -4138,16 +4196,17 @@ The final element is \"*\", indicating an unspecified month.")
4138 (if (re-search-forward todos-item-start nil t (or count 1)) 4196 (if (re-search-forward todos-item-start nil t (or count 1))
4139 (goto-char (match-beginning 0)) 4197 (goto-char (match-beginning 0))
4140 (goto-char (point-max))) 4198 (goto-char (point-max)))
4141 ;; If points advances by one from a todo to a done item, go back to the 4199 ;; If points advances by one from a todo to a done item, go back
4142 ;; space above todos-done-separator, since that is a legitimate place to 4200 ;; to the space above todos-done-separator, since that is a
4143 ;; insert an item. But skip this space if count > 1, since that should 4201 ;; legitimate place to insert an item. But skip this space if
4144 ;; only stop on an item. 4202 ;; count > 1, since that should only stop on an item.
4145 (when (and not-done (todos-done-item-p) (not count)) 4203 (when (and not-done (todos-done-item-p) (not count))
4146 ;; (if (or (not count) (= count 1)) 4204 ;; (if (or (not count) (= count 1))
4147 (re-search-backward "^$" start t))));) 4205 (re-search-backward "^$" start t))));)
4148 ;; FIXME: The preceding sexp is insufficient when buffer is not narrowed, 4206 ;; The preceding sexp is insufficient when buffer is not narrowed,
4149 ;; since there could be no done items in this category, so the search puts 4207 ;; since there could be no done items in this category, so the
4150 ;; us on first todo item of next category. Does this ever happen? If so: 4208 ;; search puts us on first todo item of next category. Does this
4209 ;; ever happen? If so:
4151 ;; (let ((opoint) (point)) 4210 ;; (let ((opoint) (point))
4152 ;; (forward-line -1) 4211 ;; (forward-line -1)
4153 ;; (when (or (not count) (= count 1)) 4212 ;; (when (or (not count) (= count 1))
@@ -4306,43 +4365,45 @@ of each other."
4306 prefix)))) 4365 prefix))))
4307 (forward-line))))) 4366 (forward-line)))))
4308 4367
4309;;; Item insertion command and key binding infrastructure 4368;; -----------------------------------------------------------------------------
4369;;; Generation of item insertion commands and key bindings
4370;; -----------------------------------------------------------------------------
4310 4371
4311;; Can either of these be included in Emacs? The originals are GFDL'd. 4372;; Can either of these be included in Emacs? The originals are GFDL'd.
4312 4373
4313;; Slightly reformulated from 4374;; Reformulation of http://rosettacode.org/wiki/Power_set#Common_Lisp.
4314;; http://rosettacode.org/wiki/Power_set#Common_Lisp. 4375(defun todos-powerset-recursive (list)
4315(defun powerset-recursive (l) 4376 (cond ((null list)
4316 (cond ((null l)
4317 (list nil)) 4377 (list nil))
4318 (t 4378 (t
4319 (let ((prev (powerset-recursive (cdr l)))) 4379 (let ((recur (todos-powerset-recursive (cdr list)))
4320 (append (mapcar (lambda (elt) (cons (car l) elt)) 4380 pset)
4321 prev) 4381 (dolist (elt recur pset)
4322 prev))))) 4382 (push (cons (car list) elt) pset))
4323 4383 (append pset recur)))))
4324;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C 4384
4325(defun powerset-bitwise (l) 4385;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C.
4326 (let ((binnum (lsh 1 (length l))) 4386(defun todos-powerset-iterative (list)
4387 (let ((card (expt 2 (length list)))
4327 pset elt) 4388 pset elt)
4328 (dotimes (i binnum) 4389 (dotimes (n card)
4329 (let ((bits i) 4390 (let ((i n)
4330 (ll l)) 4391 (l list))
4331 (while (not (zerop bits)) 4392 (while (not (zerop i))
4332 (let ((arg (pop ll))) 4393 (let ((arg (pop l)))
4333 (unless (zerop (logand bits 1)) 4394 (when (cl-oddp i)
4334 (setq elt (append elt (list arg)))) 4395 (setq elt (append elt (list arg))))
4335 (setq bits (lsh bits -1)))) 4396 (setq i (/ i 2))))
4336 (setq pset (append pset (list elt))) 4397 (setq pset (append pset (list elt)))
4337 (setq elt nil))) 4398 (setq elt nil)))
4338 pset)) 4399 pset))
4339 4400
4340;; (defalias 'todos-powerset 'powerset-recursive) 4401;; (defalias 'todos-powerset 'todos-powerset-recursive)
4341(defalias 'todos-powerset 'powerset-bitwise) 4402(defalias 'todos-powerset 'todos-powerset-iterative)
4342 4403
4343;; Return list of lists of non-nil atoms produced from ARGLIST. The elements
4344;; of ARGLIST may be atoms or lists.
4345(defun todos-gen-arglists (arglist) 4404(defun todos-gen-arglists (arglist)
4405 "Return list of lists of non-nil atoms produced from ARGLIST.
4406The elements of ARGLIST may be atoms or lists."
4346 (let (arglists) 4407 (let (arglists)
4347 (while arglist 4408 (while arglist
4348 (let ((arg (pop arglist))) 4409 (let ((arg (pop arglist)))
@@ -4361,12 +4422,12 @@ of each other."
4361 4422
4362(defvar todos-insertion-commands-args-genlist 4423(defvar todos-insertion-commands-args-genlist
4363 '(diary nonmarking (calendar date dayname) time (here region)) 4424 '(diary nonmarking (calendar date dayname) time (here region))
4364 "Generator list for argument lists of Todos insertion commands.") 4425 "Generator list for argument lists of item insertion commands.")
4365 4426
4366(defvar todos-insertion-commands-args 4427(defvar todos-insertion-commands-args
4367 (let ((argslist (todos-gen-arglists todos-insertion-commands-args-genlist)) 4428 (let ((argslist (todos-gen-arglists todos-insertion-commands-args-genlist))
4368 res new) 4429 res new)
4369 (setq res (remove-duplicates 4430 (setq res (cl-remove-duplicates
4370 (apply 'append (mapcar 'todos-powerset argslist)) :test 'equal)) 4431 (apply 'append (mapcar 'todos-powerset argslist)) :test 'equal))
4371 (dolist (l res) 4432 (dolist (l res)
4372 (unless (= 5 (length l)) 4433 (unless (= 5 (length l))
@@ -4408,6 +4469,7 @@ of each other."
4408 "List of names of Todos item insertion commands.") 4469 "List of names of Todos item insertion commands.")
4409 4470
4410(defmacro todos-define-insertion-command (&rest args) 4471(defmacro todos-define-insertion-command (&rest args)
4472 "Generate item insertion command definitions from ARGS."
4411 (let ((name (intern (todos-insertion-command-name args))) 4473 (let ((name (intern (todos-insertion-command-name args)))
4412 (arg0 (nth 0 args)) 4474 (arg0 (nth 0 args))
4413 (arg1 (nth 1 args)) 4475 (arg1 (nth 1 args))
@@ -4415,9 +4477,11 @@ of each other."
4415 (arg3 (nth 3 args)) 4477 (arg3 (nth 3 args))
4416 (arg4 (nth 4 args))) 4478 (arg4 (nth 4 args)))
4417 `(defun ,name (&optional arg &rest args) 4479 `(defun ,name (&optional arg &rest args)
4418 "Todos item insertion command generated from ARGS." 4480 "Todos item insertion command generated from ARGS.
4481For descriptions of the individual arguments, their values, and
4482their relation to key bindings, see `todos-basic-insert-item'."
4419 (interactive (list current-prefix-arg)) 4483 (interactive (list current-prefix-arg))
4420 (todos-insert-item-1 arg ',arg0 ',arg1 ',arg2 ',arg3 ',arg4)))) 4484 (todos-basic-insert-item arg ',arg0 ',arg1 ',arg2 ',arg3 ',arg4))))
4421 4485
4422(defvar todos-insertion-commands 4486(defvar todos-insertion-commands
4423 (mapcar (lambda (c) 4487 (mapcar (lambda (c)
@@ -4434,10 +4498,10 @@ of each other."
4434 ("time" "t" "tt") 4498 ("time" "t" "tt")
4435 ("here" "h" "h") 4499 ("here" "h" "h")
4436 ("region" "r" "r")) 4500 ("region" "r" "r"))
4437 "") ;FIXME 4501 "List of mappings of insertion command arguments to key sequences.")
4438 4502
4439(defun todos-insertion-key-bindings (map) 4503(defun todos-insertion-key-bindings (map)
4440 "" ;FIXME 4504 "Generate key binding definitions for item insertion commands."
4441 (dolist (c todos-insertion-commands) 4505 (dolist (c todos-insertion-commands)
4442 (let* ((key "") 4506 (let* ((key "")
4443 (cname (symbol-name c))) 4507 (cname (symbol-name c)))
@@ -4450,12 +4514,13 @@ of each other."
4450 (if (string-match (concat (regexp-quote arg) ".+") cname) 4514 (if (string-match (concat (regexp-quote arg) ".+") cname)
4451 (setq key (concat key key1))))) 4515 (setq key (concat key key1)))))
4452 todos-insertion-commands-arg-key-list) 4516 todos-insertion-commands-arg-key-list)
4453 ;; (if (string-match (concat (regexp-quote "todos-item-insert") "\\_>") cname)
4454 (if (string-match (concat (regexp-quote "todos-insert-item") "\\_>") cname) 4517 (if (string-match (concat (regexp-quote "todos-insert-item") "\\_>") cname)
4455 (setq key (concat key "i"))) 4518 (setq key (concat key "i")))
4456 (define-key map key c)))) 4519 (define-key map key c))))
4457 4520
4521;; -----------------------------------------------------------------------------
4458;;; Todos minibuffer completion 4522;;; Todos minibuffer completion
4523;; -----------------------------------------------------------------------------
4459 4524
4460(defun todos-category-completions (&optional archive) 4525(defun todos-category-completions (&optional archive)
4461 "Return a list of completions for `todos-read-category'. 4526 "Return a list of completions for `todos-read-category'.
@@ -4777,7 +4842,9 @@ the empty string (i.e., no time string)."
4777 (setq valid t))) 4842 (setq valid t)))
4778 answer)) 4843 answer))
4779 4844
4780;;; Todos Categories mode infrastructure 4845;; -----------------------------------------------------------------------------
4846;;; Todos Categories mode tabulation and sorting
4847;; -----------------------------------------------------------------------------
4781 4848
4782(defvar todos-categories-buffer "*Todos Categories*" 4849(defvar todos-categories-buffer "*Todos Categories*"
4783 "Name of buffer in Todos Categories mode.") 4850 "Name of buffer in Todos Categories mode.")
@@ -4796,8 +4863,7 @@ Categories mode."
4796 (longest (todos-longest-category-name-length categories)) 4863 (longest (todos-longest-category-name-length categories))
4797 (catlablen (length todos-categories-category-label)) 4864 (catlablen (length todos-categories-category-label))
4798 (lc-diff (- longest catlablen))) 4865 (lc-diff (- longest catlablen)))
4799 (if (and (natnump lc-diff) 4866 (if (and (natnump lc-diff) (cl-oddp lc-diff))
4800 (eq (logand lc-diff 1) 1)) ; oddp from cl.el
4801 (1+ longest) 4867 (1+ longest)
4802 (max longest catlablen)))) 4868 (max longest catlablen))))
4803 4869
@@ -4923,9 +4989,8 @@ which is the value of the user option
4923 (concat 4989 (concat
4924 (make-string (1+ (/ (length (car elt)) 2)) 32) ; label 4990 (make-string (1+ (/ (length (car elt)) 2)) 32) ; label
4925 (format "%3d" (todos-get-count (cdr elt) cat)) ; count 4991 (format "%3d" (todos-get-count (cdr elt) cat)) ; count
4926 ;; Add an extra space if label length is odd 4992 ;; Add an extra space if label length is odd.
4927 ;; (using def of oddp from cl.el). 4993 (when (cl-oddp (length (car elt))) " ")))
4928 (if (eq (logand (length (car elt)) 1) 1) " ")))
4929 (if archive 4994 (if archive
4930 (list (cons todos-categories-done-label 'done)) 4995 (list (cons todos-categories-done-label 'done))
4931 (list (cons todos-categories-todo-label 'todo) 4996 (list (cons todos-categories-todo-label 'todo)
@@ -4967,7 +5032,7 @@ which is the value of the user option
4967 (overlay-put ovl 'face 'todos-sorted-column))) 5032 (overlay-put ovl 'face 'todos-sorted-column)))
4968 (newline))) 5033 (newline)))
4969 5034
4970(defun todos-display-categories-1 () 5035(defun todos-display-categories ()
4971 "Prepare buffer for displaying table of categories and item counts." 5036 "Prepare buffer for displaying table of categories and item counts."
4972 (unless (eq major-mode 'todos-categories-mode) 5037 (unless (eq major-mode 'todos-categories-mode)
4973 (setq todos-global-current-todos-file 5038 (setq todos-global-current-todos-file
@@ -5005,7 +5070,7 @@ which is the value of the user option
5005 (newline 2)))) 5070 (newline 2))))
5006 5071
5007(defun todos-update-categories-display (sortkey) 5072(defun todos-update-categories-display (sortkey)
5008 "" 5073 "Populate table of categories and sort by SORTKEY."
5009 (let* ((cats0 todos-categories) 5074 (let* ((cats0 todos-categories)
5010 (cats (todos-sort cats0 sortkey)) 5075 (cats (todos-sort cats0 sortkey))
5011 (archive (member todos-current-todos-file todos-archives)) 5076 (archive (member todos-current-todos-file todos-archives))
@@ -5033,9 +5098,8 @@ which is the value of the user option
5033 (concat 5098 (concat
5034 (make-string (1+ (/ (length (car elt)) 2)) 32) 5099 (make-string (1+ (/ (length (car elt)) 2)) 32)
5035 (format "%3d" (nth (cdr elt) (todos-total-item-counts))) 5100 (format "%3d" (nth (cdr elt) (todos-total-item-counts)))
5036 ;; Add an extra space if label length is odd (using 5101 ;; Add an extra space if label length is odd.
5037 ;; definition of oddp from cl.el). 5102 (when (cl-oddp (length (car elt))) " ")))
5038 (if (eq (logand (length (car elt)) 1) 1) " ")))
5039 (if archive 5103 (if archive
5040 (list (cons todos-categories-done-label 2)) 5104 (list (cons todos-categories-done-label 2))
5041 (list (cons todos-categories-todo-label 0) 5105 (list (cons todos-categories-todo-label 0)
@@ -5047,7 +5111,9 @@ which is the value of the user option
5047 (if pt (goto-char pt)) 5111 (if pt (goto-char pt))
5048 (setq buffer-read-only t))) 5112 (setq buffer-read-only t)))
5049 5113
5050;;; Item filtering infrastructure 5114;; -----------------------------------------------------------------------------
5115;;; Item filtering selection and display
5116;; -----------------------------------------------------------------------------
5051 5117
5052(defvar todos-multiple-filter-files nil 5118(defvar todos-multiple-filter-files nil
5053 "List of files selected from `todos-multiple-filter-files' widget.") 5119 "List of files selected from `todos-multiple-filter-files' widget.")
@@ -5096,7 +5162,7 @@ which is the value of the user option
5096 (recursive-edit)) 5162 (recursive-edit))
5097 5163
5098(defun todos-filter-items (filter &optional new multifile) 5164(defun todos-filter-items (filter &optional new multifile)
5099 "Internal routine for displaying items that satisfy FILTER. 5165 "Display a cross-categorial list of items filtered by FILTER.
5100The values of FILTER can be `top' for top priority items, a cons 5166The values of FILTER can be `top' for top priority items, a cons
5101of `top' and a number passed by the caller, `diary' for diary 5167of `top' and a number passed by the caller, `diary' for diary
5102items, or `regexp' for items matching a regular expresion entered 5168items, or `regexp' for items matching a regular expresion entered
@@ -5106,9 +5172,10 @@ is nil, visit an appropriate file containing the list of filtered
5106items; if there is no such file, or with non-nil NEW, build the 5172items; if there is no such file, or with non-nil NEW, build the
5107list and display it. 5173list and display it.
5108 5174
5109See the document strings of the commands `todos-filter-top-priorities', 5175See the document strings of the commands
5110`todos-filter-diary-items', `todos-filter-regexp-items', and those of the 5176`todos-filter-top-priorities', `todos-filter-diary-items',
5111corresponding multifile commands for further details. " 5177`todos-filter-regexp-items', and those of the corresponding
5178multifile commands for further details."
5112 (let* ((top (eq filter 'top)) 5179 (let* ((top (eq filter 'top))
5113 (diary (eq filter 'diary)) 5180 (diary (eq filter 'diary))
5114 (regexp (eq filter 'regexp)) 5181 (regexp (eq filter 'regexp))
@@ -5151,14 +5218,15 @@ corresponding multifile commands for further details. "
5151 " \"%s\"") buf fname)))) 5218 " \"%s\"") buf fname))))
5152 5219
5153(defun todos-filter-items-1 (filter file-list) 5220(defun todos-filter-items-1 (filter file-list)
5154 "Internal subroutine called by `todos-filter-items'. 5221 "Build a list of items by applying FILTER to FILE-LIST.
5155The values of FILTER and FILE-LIST are passed from the caller." 5222Internal subroutine called by `todos-filter-items', which passes
5223the values of FILTER and FILE-LIST."
5156 (let ((num (if (consp filter) (cdr filter) todos-top-priorities)) 5224 (let ((num (if (consp filter) (cdr filter) todos-top-priorities))
5157 (buf (get-buffer-create todos-filtered-items-buffer)) 5225 (buf (get-buffer-create todos-filtered-items-buffer))
5158 (multifile (> (length file-list) 1)) 5226 (multifile (> (length file-list) 1))
5159 regexp fname bufstr cat beg end done) 5227 regexp fname bufstr cat beg end done)
5160 (if (null file-list) 5228 (if (null file-list)
5161 (error "No files have been chosen for filtering") 5229 (user-error "No files have been chosen for filtering")
5162 (with-current-buffer buf 5230 (with-current-buffer buf
5163 (erase-buffer) 5231 (erase-buffer)
5164 (kill-all-local-variables) 5232 (kill-all-local-variables)
@@ -5484,7 +5552,9 @@ If the file already exists, overwrite it only on confirmation."
5484 (let ((filename (or (buffer-file-name) (todos-filter-items-filename)))) 5552 (let ((filename (or (buffer-file-name) (todos-filter-items-filename))))
5485 (write-file filename t))) 5553 (write-file filename t)))
5486 5554
5555;; -----------------------------------------------------------------------------
5487;;; Customization groups and set functions 5556;;; Customization groups and set functions
5557;; -----------------------------------------------------------------------------
5488 5558
5489(defgroup todos nil 5559(defgroup todos nil
5490 "Create and maintain categorized lists of todo items." 5560 "Create and maintain categorized lists of todo items."
@@ -5641,23 +5711,9 @@ If the file already exists, overwrite it only on confirmation."
5641 (hl-line-mode 1) 5711 (hl-line-mode 1)
5642 (hl-line-mode -1))))))))) 5712 (hl-line-mode -1)))))))))
5643 5713
5714;; -----------------------------------------------------------------------------
5644;;; Font locking 5715;;; Font locking
5645 5716;; -----------------------------------------------------------------------------
5646(defvar todos-diary-expired-face 'todos-diary-expired)
5647
5648(defvar todos-date-face 'todos-date)
5649
5650(defvar todos-time-face 'todos-time)
5651
5652(defvar todos-nondiary-face 'todos-nondiary)
5653
5654(defvar todos-category-string-face 'todos-category-string)
5655
5656(defvar todos-done-face 'todos-done)
5657
5658(defvar todos-comment-face 'todos-comment)
5659
5660(defvar todos-done-sep-face 'todos-done-sep)
5661 5717
5662(defun todos-date-string-matcher (lim) 5718(defun todos-date-string-matcher (lim)
5663 "Search for Todos date string within LIM for font-locking." 5719 "Search for Todos date string within LIM for font-locking."
@@ -5741,6 +5797,15 @@ Filtered Items mode following todo (not done) items."
5741 "\\)? \\(?1:\\[.+\\]\\)") 5797 "\\)? \\(?1:\\[.+\\]\\)")
5742 lim t))) 5798 lim t)))
5743 5799
5800(defvar todos-diary-expired-face 'todos-diary-expired)
5801(defvar todos-date-face 'todos-date)
5802(defvar todos-time-face 'todos-time)
5803(defvar todos-nondiary-face 'todos-nondiary)
5804(defvar todos-category-string-face 'todos-category-string)
5805(defvar todos-done-face 'todos-done)
5806(defvar todos-comment-face 'todos-comment)
5807(defvar todos-done-sep-face 'todos-done-sep)
5808
5744(defvar todos-font-lock-keywords 5809(defvar todos-font-lock-keywords
5745 (list 5810 (list
5746 '(todos-nondiary-marker-matcher 1 todos-nondiary-face t) 5811 '(todos-nondiary-marker-matcher 1 todos-nondiary-face t)
@@ -5758,7 +5823,9 @@ Filtered Items mode following todo (not done) items."
5758 ) 5823 )
5759 "Font-locking for Todos modes.") 5824 "Font-locking for Todos modes.")
5760 5825
5826;; -----------------------------------------------------------------------------
5761;;; Key maps and menus 5827;;; Key maps and menus
5828;; -----------------------------------------------------------------------------
5762 5829
5763(defvar todos-insertion-map 5830(defvar todos-insertion-map
5764 (let ((map (make-keymap))) 5831 (let ((map (make-keymap)))
@@ -5767,176 +5834,120 @@ Filtered Items mode following todo (not done) items."
5767 map) 5834 map)
5768 "Keymap for Todos mode item insertion commands.") 5835 "Keymap for Todos mode item insertion commands.")
5769 5836
5770;; --------------------------------------------------------------------------- 5837(defvar todos-key-bindings-t
5771(defvar todos-key-bindings
5772 `( 5838 `(
5773 ("Af" . todos-find-archive) 5839 ("Af" todos-find-archive)
5774 ("Ac" . todos-choose-archive) 5840 ("Ac" todos-choose-archive)
5775 ("Ad" . todos-archive-done-item) 5841 ("Ad" todos-archive-done-item)
5776 ("C*" . todos-mark-category) 5842 ("Cv" todos-toggle-view-done-items)
5777 ("Cu" . todos-unmark-category) 5843 ("v" todos-toggle-view-done-items)
5778 ("Cv" . todos-toggle-view-done-items) 5844 ("Ca" todos-add-category)
5779 ("v" . todos-toggle-view-done-items) 5845 ("Cr" todos-rename-category)
5780 ("Ca" . todos-add-category) 5846 ("Cg" todos-merge-category)
5781 ("Cr" . todos-rename-category) 5847 ("Cm" todos-move-category)
5782 ("Cg" . todos-merge-category) 5848 ("Ck" todos-delete-category)
5783 ("Cm" . todos-move-category) 5849 ("Cts" todos-set-top-priorities-in-category)
5784 ("Ck" . todos-delete-category) 5850 ("Cey" todos-edit-category-diary-inclusion)
5785 ("Cts" . todos-set-top-priorities-in-category) 5851 ("Cek" todos-edit-category-diary-nonmarking)
5786 ("Cey" . todos-edit-category-diary-inclusion) 5852 ("Fa" todos-add-file)
5787 ("Cek" . todos-edit-category-diary-nonmarking) 5853 ("Ff" todos-find-filtered-items-file)
5788 ("Fa" . todos-add-file) 5854 ("FV" todos-toggle-view-done-only)
5789 ("Fc" . todos-show-categories-table) 5855 ("V" todos-toggle-view-done-only)
5790 ("Ff" . todos-find-filtered-items-file) 5856 ("Ftt" todos-filter-top-priorities)
5791 ("Fh" . todos-toggle-item-header) 5857 ("Ftm" todos-filter-top-priorities-multifile)
5792 ("h" . todos-toggle-item-header) 5858 ("Fts" todos-set-top-priorities-in-file)
5793 ("Fe" . todos-edit-file) 5859 ("Fyy" todos-filter-diary-items)
5794 ("FH" . todos-toggle-item-highlighting) 5860 ("Fym" todos-filter-diary-items-multifile)
5795 ("H" . todos-toggle-item-highlighting) 5861 ("Frr" todos-filter-regexp-items)
5796 ("FN" . todos-toggle-prefix-numbers) 5862 ("Frm" todos-filter-regexp-items-multifile)
5797 ("N" . todos-toggle-prefix-numbers) 5863 ("ee" todos-edit-item)
5798 ("FV" . todos-toggle-view-done-only) 5864 ("em" todos-edit-multiline-item)
5799 ("V" . todos-toggle-view-done-only) 5865 ("edt" todos-edit-item-header)
5800 ("Ftt" . todos-filter-top-priorities) 5866 ("edc" todos-edit-item-date-from-calendar)
5801 ("Ftm" . todos-filter-top-priorities-multifile) 5867 ("eda" todos-edit-item-date-to-today)
5802 ("Fts" . todos-set-top-priorities-in-file) 5868 ("edn" todos-edit-item-date-day-name)
5803 ("Fyy" . todos-filter-diary-items) 5869 ("edy" todos-edit-item-date-year)
5804 ("Fym" . todos-filter-diary-items-multifile) 5870 ("edm" todos-edit-item-date-month)
5805 ("Frr" . todos-filter-regexp-items) 5871 ("edd" todos-edit-item-date-day)
5806 ("Frm" . todos-filter-regexp-items-multifile) 5872 ("et" todos-edit-item-time)
5807 ("PB" . todos-print-buffer) 5873 ("eyy" todos-edit-item-diary-inclusion)
5808 ("PF" . todos-print-buffer-to-file) 5874 ("eyk" todos-edit-item-diary-nonmarking)
5809 ("S" . todos-search) 5875 ("ec" todos-done-item-add-edit-or-delete-comment)
5810 ("X" . todos-clear-matches) 5876 ("d" todos-item-done)
5811 ("ee" . todos-edit-item) 5877 ("i" ,todos-insertion-map)
5812 ("em" . todos-edit-multiline-item) 5878 ("k" todos-delete-item)
5813 ("edt" . todos-edit-item-header) 5879 ("m" todos-move-item)
5814 ("edc" . todos-edit-item-date-from-calendar) 5880 ("u" todos-item-undone)
5815 ("eda" . todos-edit-item-date-to-today) 5881 ([remap newline] newline-and-indent)
5816 ("edn" . todos-edit-item-date-day-name)
5817 ("edy" . todos-edit-item-date-year)
5818 ("edm" . todos-edit-item-date-month)
5819 ("edd" . todos-edit-item-date-day)
5820 ("et" . todos-edit-item-time)
5821 ("eyy" . todos-edit-item-diary-inclusion)
5822 ("eyk" . todos-edit-item-diary-nonmarking)
5823 ("ec" . todos-done-item-add-edit-or-delete-comment)
5824 ("b" . todos-backward-category)
5825 ("d" . todos-item-done)
5826 ("f" . todos-forward-category)
5827 ("i" . ,todos-insertion-map)
5828 ("j" . todos-jump-to-category)
5829 ("k" . todos-delete-item) ;FIXME: not single letter?
5830 ("l" . todos-lower-item-priority)
5831 ("m" . todos-move-item)
5832 ("n" . todos-next-item)
5833 ("p" . todos-previous-item)
5834 ("q" . todos-quit)
5835 ("r" . todos-raise-item-priority)
5836 ("s" . todos-save)
5837 ("t" . todos-show)
5838 ("u" . todos-item-undone)
5839 ("#" . todos-set-item-priority)
5840 ("*" . todos-toggle-mark-item)
5841 ([remap newline] . newline-and-indent)
5842 ) 5882 )
5843 "Alist pairing keys defined in Todos modes and their bindings.") 5883 "List of key bindings for Todos mode only.")
5884
5885(defvar todos-key-bindings-t+a+f
5886 `(
5887 ("C*" todos-mark-category)
5888 ("Cu" todos-unmark-category)
5889 ("Fh" todos-toggle-item-header)
5890 ("h" todos-toggle-item-header)
5891 ("Fe" todos-edit-file)
5892 ("FH" todos-toggle-item-highlighting)
5893 ("H" todos-toggle-item-highlighting)
5894 ("FN" todos-toggle-prefix-numbers)
5895 ("N" todos-toggle-prefix-numbers)
5896 ("PB" todos-print-buffer)
5897 ("PF" todos-print-buffer-to-file)
5898 ("b" todos-backward-category)
5899 ("d" todos-item-done)
5900 ("f" todos-forward-category)
5901 ("j" todos-jump-to-category)
5902 ("n" todos-next-item)
5903 ("p" todos-previous-item)
5904 ("q" todos-quit)
5905 ("s" todos-save)
5906 ("t" todos-show)
5907 )
5908 "List of key bindings for Todos, Archive, and Filtered Items modes.")
5909
5910(defvar todos-key-bindings-t+a
5911 `(
5912 ("Fc" todos-show-categories-table)
5913 ("S" todos-search)
5914 ("X" todos-clear-matches)
5915 ("*" todos-toggle-mark-item)
5916 )
5917 "List of key bindings for Todos and Todos Archive modes.")
5918
5919(defvar todos-key-bindings-t+f
5920 `(
5921 ("l" todos-lower-item-priority)
5922 ("r" todos-raise-item-priority)
5923 ("#" todos-set-item-priority)
5924 )
5925 "List of key bindings for Todos and Todos Filtered Items modes.")
5844 5926
5845(defvar todos-mode-map 5927(defvar todos-mode-map
5846 (let ((map (make-keymap))) 5928 (let ((map (make-keymap)))
5847 ;; Don't suppress digit keys, so they can supply prefix arguments. 5929 ;; Don't suppress digit keys, so they can supply prefix arguments.
5848 (suppress-keymap map) 5930 (suppress-keymap map)
5849 (dolist (ck todos-key-bindings) 5931 (dolist (kb todos-key-bindings-t)
5850 (define-key map (car ck) (cdr ck))) 5932 (define-key map (nth 0 kb) (nth 1 kb)))
5933 (dolist (kb todos-key-bindings-t+a+f)
5934 (define-key map (nth 0 kb) (nth 1 kb)))
5935 (dolist (kb todos-key-bindings-t+a)
5936 (define-key map (nth 0 kb) (nth 1 kb)))
5937 (dolist (kb todos-key-bindings-t+f)
5938 (define-key map (nth 0 kb) (nth 1 kb)))
5851 map) 5939 map)
5852 "Todos mode keymap.") 5940 "Todos mode keymap.")
5853 5941
5854(easy-menu-define
5855 todos-menu todos-mode-map "Todos Menu"
5856 '("Todos"
5857 ("Navigation"
5858 ["Next Item" todos-forward-item t]
5859 ["Previous Item" todos-backward-item t]
5860 "---"
5861 ["Next Category" todos-forward-category t]
5862 ["Previous Category" todos-backward-category t]
5863 ["Jump to Category" todos-jump-to-category t]
5864 "---"
5865 ["Search Todos File" todos-search t]
5866 ["Clear Highlighting on Search Matches" todos-category-done t])
5867 ("Display"
5868 ["List Current Categories" todos-show-categories-table t]
5869 ;; ["List Categories Alphabetically" todos-display-categories-alphabetically t]
5870 ["Turn Item Highlighting on/off" todos-toggle-item-highlighting t]
5871 ["Turn Item Numbering on/off" todos-toggle-prefix-numbers t]
5872 ["Turn Item Time Stamp on/off" todos-toggle-item-header t]
5873 ["View/Hide Done Items" todos-toggle-view-done-items t]
5874 "---"
5875 ["View Diary Items" todos-filter-diary-items t]
5876 ["View Top Priority Items" todos-filter-top-priorities t]
5877 ["View Multifile Top Priority Items" todos-filter-top-priorities-multifile t]
5878 "---"
5879 ["Print Category" todos-print-buffer t])
5880 ("Editing"
5881 ["Insert New Item" todos-insert-item t]
5882 ["Insert Item Here" todos-insert-item-here t]
5883 ("More Insertion Commands")
5884 ["Edit Item" todos-edit-item t]
5885 ["Edit Multiline Item" todos-edit-multiline-item t]
5886 ["Edit Item Header" todos-edit-item-header t]
5887 ["Edit Item Date" todos-edit-item-date t]
5888 ["Edit Item Time" todos-edit-item-time t]
5889 "---"
5890 ["Lower Item Priority" todos-lower-item-priority t]
5891 ["Raise Item Priority" todos-raise-item-priority t]
5892 ["Set Item Priority" todos-set-item-priority t]
5893 ["Move (Recategorize) Item" todos-move-item t]
5894 ["Delete Item" todos-delete-item t]
5895 ["Undo Done Item" todos-item-undone t]
5896 ["Mark/Unmark Item for Diary" todos-toggle-item-diary-inclusion t]
5897 ["Mark/Unmark Items for Diary" todos-edit-item-diary-inclusion t]
5898 ["Mark & Hide Done Item" todos-item-done t]
5899 ["Archive Done Items" todos-archive-category-done-items t]
5900 "---"
5901 ["Add New Todos File" todos-add-file t]
5902 ["Add New Category" todos-add-category t]
5903 ["Delete Current Category" todos-delete-category t]
5904 ["Rename Current Category" todos-rename-category t]
5905 "---"
5906 ["Save Todos File" todos-save t]
5907 )
5908 "---"
5909 ["Quit" todos-quit t]
5910 ))
5911
5912(defvar todos-archive-mode-map 5942(defvar todos-archive-mode-map
5913 (let ((map (make-sparse-keymap))) 5943 (let ((map (make-sparse-keymap)))
5914 (suppress-keymap map t) 5944 (suppress-keymap map)
5915 (define-key map "C*" 'todos-mark-category) 5945 (dolist (kb todos-key-bindings-t+a+f)
5916 (define-key map "Cu" 'todos-unmark-category) 5946 (define-key map (nth 0 kb) (nth 1 kb)))
5917 (define-key map "Fc" 'todos-show-categories-table) 5947 (dolist (kb todos-key-bindings-t+a)
5918 (define-key map "Ff" 'todos-find-filtered-items-file) 5948 (define-key map (nth 0 kb) (nth 1 kb)))
5919 (define-key map "FH" 'todos-toggle-item-highlighting)
5920 (define-key map "H" 'todos-toggle-item-highlighting)
5921 (define-key map "FN" 'todos-toggle-prefix-numbers)
5922 (define-key map "N" 'todos-toggle-prefix-numbers)
5923 (define-key map "Fh" 'todos-toggle-item-header)
5924 (define-key map "h" 'todos-toggle-item-header)
5925 (define-key map "PB" 'todos-print-buffer)
5926 (define-key map "PF" 'todos-print-buffer-to-file)
5927 (define-key map "S" 'todos-search)
5928 (define-key map "X" 'todos-clear-matches)
5929 (define-key map "a" 'todos-jump-to-archive-category) 5949 (define-key map "a" 'todos-jump-to-archive-category)
5930 (define-key map "b" 'todos-backward-category)
5931 (define-key map "f" 'todos-forward-category)
5932 (define-key map "j" 'todos-jump-to-category)
5933 (define-key map "n" 'todos-next-item)
5934 (define-key map "p" 'todos-previous-item)
5935 (define-key map "q" 'todos-quit)
5936 (define-key map "s" 'todos-save)
5937 (define-key map "t" 'todos-show)
5938 (define-key map "u" 'todos-unarchive-items) 5950 (define-key map "u" 'todos-unarchive-items)
5939 (define-key map "*" 'todos-toggle-mark-item)
5940 map) 5951 map)
5941 "Todos Archive mode keymap.") 5952 "Todos Archive mode keymap.")
5942 5953
@@ -5949,7 +5960,7 @@ Filtered Items mode following todo (not done) items."
5949 5960
5950(defvar todos-categories-mode-map 5961(defvar todos-categories-mode-map
5951 (let ((map (make-sparse-keymap))) 5962 (let ((map (make-sparse-keymap)))
5952 (suppress-keymap map t) 5963 (suppress-keymap map)
5953 (define-key map "c" 'todos-sort-categories-alphabetically-or-by-priority) 5964 (define-key map "c" 'todos-sort-categories-alphabetically-or-by-priority)
5954 (define-key map "t" 'todos-sort-categories-by-todo) 5965 (define-key map "t" 'todos-sort-categories-by-todo)
5955 (define-key map "y" 'todos-sort-categories-by-diary) 5966 (define-key map "y" 'todos-sort-categories-by-diary)
@@ -5963,40 +5974,82 @@ Filtered Items mode following todo (not done) items."
5963 (define-key map [tab] 'todos-next-button) 5974 (define-key map [tab] 'todos-next-button)
5964 (define-key map [backtab] 'todos-previous-button) 5975 (define-key map [backtab] 'todos-previous-button)
5965 (define-key map "q" 'todos-quit) 5976 (define-key map "q" 'todos-quit)
5966 ;; (define-key map "A" 'todos-add-category)
5967 ;; (define-key map "D" 'todos-delete-category)
5968 ;; (define-key map "R" 'todos-rename-category)
5969 map) 5977 map)
5970 "Todos Categories mode keymap.") 5978 "Todos Categories mode keymap.")
5971 5979
5972(defvar todos-filtered-items-mode-map 5980(defvar todos-filtered-items-mode-map
5973 (let ((map (make-keymap))) 5981 (let ((map (make-sparse-keymap)))
5974 (suppress-keymap map t) 5982 (suppress-keymap map)
5975 (define-key map "Ff" 'todos-find-filtered-items-file) 5983 (dolist (kb todos-key-bindings-t+a+f)
5976 (define-key map "FH" 'todos-toggle-item-highlighting) 5984 (define-key map (nth 0 kb) (nth 1 kb)))
5977 (define-key map "H" 'todos-toggle-item-highlighting) 5985 (dolist (kb todos-key-bindings-t+f)
5978 (define-key map "FN" 'todos-toggle-prefix-numbers) 5986 (define-key map (nth 0 kb) (nth 1 kb)))
5979 (define-key map "N" 'todos-toggle-prefix-numbers) 5987 ("g" 'todos-go-to-source-item)
5980 (define-key map "Fh" 'todos-toggle-item-header) 5988 ([remap newline] 'todos-go-to-source-item)
5981 (define-key map "h" 'todos-toggle-item-header)
5982 (define-key map "PB" 'todos-print-buffer)
5983 (define-key map "PF" 'todos-print-buffer-to-file)
5984 (define-key map "g" 'todos-go-to-source-item)
5985 (define-key map "j" 'todos-jump-to-category)
5986 (define-key map "l" 'todos-lower-item-priority)
5987 (define-key map "n" 'todos-next-item)
5988 (define-key map "p" 'todos-previous-item)
5989 (define-key map "q" 'todos-quit)
5990 (define-key map "r" 'todos-raise-item-priority)
5991 (define-key map "s" 'todos-save)
5992 (define-key map "t" 'todos-show)
5993 (define-key map "#" 'todos-set-item-priority)
5994 (define-key map [remap newline] 'todos-go-to-source-item)
5995 map) 5989 map)
5996 "Todos Top Priorities mode keymap.") 5990 "Todos Filtered Items mode keymap.")
5997 5991
5998;; --------------------------------------------------------------------------- 5992;; (easy-menu-define
5993;; todos-menu todos-mode-map "Todos Menu"
5994;; '("Todos"
5995;; ("Navigation"
5996;; ["Next Item" todos-forward-item t]
5997;; ["Previous Item" todos-backward-item t]
5998;; "---"
5999;; ["Next Category" todos-forward-category t]
6000;; ["Previous Category" todos-backward-category t]
6001;; ["Jump to Category" todos-jump-to-category t]
6002;; "---"
6003;; ["Search Todos File" todos-search t]
6004;; ["Clear Highlighting on Search Matches" todos-category-done t])
6005;; ("Display"
6006;; ["List Current Categories" todos-show-categories-table t]
6007;; ;; ["List Categories Alphabetically" todos-display-categories-alphabetically t]
6008;; ["Turn Item Highlighting on/off" todos-toggle-item-highlighting t]
6009;; ["Turn Item Numbering on/off" todos-toggle-prefix-numbers t]
6010;; ["Turn Item Time Stamp on/off" todos-toggle-item-header t]
6011;; ["View/Hide Done Items" todos-toggle-view-done-items t]
6012;; "---"
6013;; ["View Diary Items" todos-filter-diary-items t]
6014;; ["View Top Priority Items" todos-filter-top-priorities t]
6015;; ["View Multifile Top Priority Items" todos-filter-top-priorities-multifile t]
6016;; "---"
6017;; ["Print Category" todos-print-buffer t])
6018;; ("Editing"
6019;; ["Insert New Item" todos-insert-item t]
6020;; ["Insert Item Here" todos-insert-item-here t]
6021;; ("More Insertion Commands")
6022;; ["Edit Item" todos-edit-item t]
6023;; ["Edit Multiline Item" todos-edit-multiline-item t]
6024;; ["Edit Item Header" todos-edit-item-header t]
6025;; ["Edit Item Date" todos-edit-item-date t]
6026;; ["Edit Item Time" todos-edit-item-time t]
6027;; "---"
6028;; ["Lower Item Priority" todos-lower-item-priority t]
6029;; ["Raise Item Priority" todos-raise-item-priority t]
6030;; ["Set Item Priority" todos-set-item-priority t]
6031;; ["Move (Recategorize) Item" todos-move-item t]
6032;; ["Delete Item" todos-delete-item t]
6033;; ["Undo Done Item" todos-item-undone t]
6034;; ["Mark/Unmark Item for Diary" todos-toggle-item-diary-inclusion t]
6035;; ["Mark/Unmark Items for Diary" todos-edit-item-diary-inclusion t]
6036;; ["Mark & Hide Done Item" todos-item-done t]
6037;; ["Archive Done Items" todos-archive-category-done-items t]
6038;; "---"
6039;; ["Add New Todos File" todos-add-file t]
6040;; ["Add New Category" todos-add-category t]
6041;; ["Delete Current Category" todos-delete-category t]
6042;; ["Rename Current Category" todos-rename-category t]
6043;; "---"
6044;; ["Save Todos File" todos-save t]
6045;; )
6046;; "---"
6047;; ["Quit" todos-quit t]
6048;; ))
6049
6050;; -----------------------------------------------------------------------------
5999;;; Mode local variables and hook functions 6051;;; Mode local variables and hook functions
6052;; -----------------------------------------------------------------------------
6000 6053
6001(defvar todos-current-todos-file nil 6054(defvar todos-current-todos-file nil
6002 "Variable holding the name of the currently active Todos file.") 6055 "Variable holding the name of the currently active Todos file.")
@@ -6067,13 +6120,15 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6067 (setq todos-done-separator (todos-done-separator)) 6120 (setq todos-done-separator (todos-done-separator))
6068 (save-match-data (todos-reset-done-separator sep))))) 6121 (save-match-data (todos-reset-done-separator sep)))))
6069 6122
6123;; -----------------------------------------------------------------------------
6070;;; Mode definitions 6124;;; Mode definitions
6125;; -----------------------------------------------------------------------------
6071 6126
6072(defun todos-modes-set-1 () 6127(defun todos-modes-set-1 ()
6073 "" 6128 ""
6074 (set (make-local-variable 'font-lock-defaults) '(todos-font-lock-keywords t)) 6129 (setq-local font-lock-defaults '(todos-font-lock-keywords t))
6075 (set (make-local-variable 'tab-width) todos-indent-to-here) 6130 (setq-local tab-width todos-indent-to-here)
6076 (set (make-local-variable 'indent-line-function) 'todos-indent) 6131 (setq-local indent-line-function 'todos-indent)
6077 (when todos-wrap-lines 6132 (when todos-wrap-lines
6078 (visual-line-mode) 6133 (visual-line-mode)
6079 (setq wrap-prefix (make-string todos-indent-to-here 32)))) 6134 (setq wrap-prefix (make-string todos-indent-to-here 32))))
@@ -6082,15 +6137,15 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6082 "" 6137 ""
6083 (add-to-invisibility-spec 'todos) 6138 (add-to-invisibility-spec 'todos)
6084 (setq buffer-read-only t) 6139 (setq buffer-read-only t)
6085 (set (make-local-variable 'hl-line-range-function) 6140 (setq-local hl-line-range-function (lambda() (save-excursion
6086 (lambda() (save-excursion 6141 (when (todos-item-end)
6087 (when (todos-item-end) 6142 (cons (todos-item-start)
6088 (cons (todos-item-start) (todos-item-end))))))) 6143 (todos-item-end)))))))
6089 6144
6090(defun todos-modes-set-3 () 6145(defun todos-modes-set-3 ()
6091 "" 6146 ""
6092 (set (make-local-variable 'todos-categories) (todos-set-categories)) 6147 (setq-local todos-categories (todos-set-categories))
6093 (set (make-local-variable 'todos-category-number) 1) 6148 (setq-local todos-category-number 1)
6094 (add-hook 'find-file-hook 'todos-display-as-todos-file nil t)) 6149 (add-hook 'find-file-hook 'todos-display-as-todos-file nil t))
6095 6150
6096(put 'todos-mode 'mode-class 'special) 6151(put 'todos-mode 'mode-class 'special)
@@ -6106,10 +6161,9 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6106 ;; Initialize todos-current-todos-file. 6161 ;; Initialize todos-current-todos-file.
6107 (when (member (file-truename (buffer-file-name)) 6162 (when (member (file-truename (buffer-file-name))
6108 (funcall todos-files-function)) 6163 (funcall todos-files-function))
6109 (set (make-local-variable 'todos-current-todos-file) 6164 (setq-local todos-current-todos-file (file-truename (buffer-file-name))))
6110 (file-truename (buffer-file-name)))) 6165 (setq-local todos-show-done-only nil)
6111 (set (make-local-variable 'todos-show-done-only) nil) 6166 (setq-local todos-categories-with-marks nil)
6112 (set (make-local-variable 'todos-categories-with-marks) nil)
6113 (add-hook 'find-file-hook 'todos-add-to-buffer-list nil t) 6167 (add-hook 'find-file-hook 'todos-add-to-buffer-list nil t)
6114 (add-hook 'post-command-hook 'todos-update-buffer-list nil t) 6168 (add-hook 'post-command-hook 'todos-update-buffer-list nil t)
6115 (when todos-show-current-file 6169 (when todos-show-current-file
@@ -6129,14 +6183,12 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6129 (todos-modes-set-1) 6183 (todos-modes-set-1)
6130 (todos-modes-set-2) 6184 (todos-modes-set-2)
6131 (todos-modes-set-3) 6185 (todos-modes-set-3)
6132 (set (make-local-variable 'todos-current-todos-file) 6186 (setq-local todos-current-todos-file (file-truename (buffer-file-name)))
6133 (file-truename (buffer-file-name))) 6187 (setq-local todos-show-done-only t))
6134 (set (make-local-variable 'todos-show-done-only) t))
6135 6188
6136(defun todos-mode-external-set () 6189(defun todos-mode-external-set ()
6137 "" 6190 ""
6138 (set (make-local-variable 'todos-current-todos-file) 6191 (setq-local todos-current-todos-file todos-global-current-todos-file)
6139 todos-global-current-todos-file)
6140 (let ((cats (with-current-buffer 6192 (let ((cats (with-current-buffer
6141 ;; Can't use find-buffer-visiting when 6193 ;; Can't use find-buffer-visiting when
6142 ;; `todos-show-categories-table' is called on first 6194 ;; `todos-show-categories-table' is called on first
@@ -6152,7 +6204,7 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6152 (read (buffer-substring-no-properties 6204 (read (buffer-substring-no-properties
6153 (line-beginning-position) 6205 (line-beginning-position)
6154 (line-end-position)))))))) 6206 (line-end-position))))))))
6155 (set (make-local-variable 'todos-categories) cats))) 6207 (setq-local todos-categories cats)))
6156 6208
6157(define-derived-mode todos-edit-mode text-mode "Todos-Ed" 6209(define-derived-mode todos-edit-mode text-mode "Todos-Ed"
6158 "Major mode for editing multiline Todo items. 6210 "Major mode for editing multiline Todo items.
@@ -6179,12 +6231,13 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6179 (todos-modes-set-1) 6231 (todos-modes-set-1)
6180 (todos-modes-set-2)) 6232 (todos-modes-set-2))
6181 6233
6182;; --------------------------------------------------------------------------- 6234;; -----------------------------------------------------------------------------
6183(provide 'todos) 6235(provide 'todos)
6236
6184;;; todos.el ends here 6237;;; todos.el ends here
6185 6238
6186;; FIXME: remove when part of Emacs 6239;; FIXME: remove when part of Emacs
6187;; --------------------------------------------------------------------------- 6240;; -----------------------------------------------------------------------------
6188(add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode)) 6241(add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode))
6189(add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode)) 6242(add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode))
6190(add-to-list 'auto-mode-alist '("\\.tod[tyr]\\'" . todos-filtered-items-mode)) 6243(add-to-list 'auto-mode-alist '("\\.tod[tyr]\\'" . todos-filtered-items-mode))