diff options
| author | Stephen Berman | 2012-05-19 01:21:36 +0100 |
|---|---|---|
| committer | Stephen Berman | 2012-05-19 01:21:36 +0100 |
| commit | 520d912ec42980b1c543a87179e293e3dcbd2d55 (patch) | |
| tree | 8c73747cbb1c970e4698d2fa2cb3fcf4e2d4cc30 /lisp | |
| parent | 0e89c3fc75c7de33bcb625c325600af227d2b1d1 (diff) | |
| download | emacs-520d912ec42980b1c543a87179e293e3dcbd2d55.tar.gz emacs-520d912ec42980b1c543a87179e293e3dcbd2d55.zip | |
* calendar/todos.el: Add and revise further doc strings and
comments.
(todos-filter-function, todos-custom-items)
(todos-custom-items-multifile): Remove.
(todos-filter-done-items): New defcustom.
(todos-item-end, todos-backward-item): Handle todos-filter-items-mode.
(todos-filter-items): Check return value of caller first; tag
archived items for todos-jump-to-item; delete categories sexp
before processing filter; check todos-filter-done-items for
whether to leave done items; remove custom filter; fix regexp for
file and category tags; don't invoke buffer fontification.
(powerset-recursive): Fix typo.
(todos-key-bindings): Remove unused bindings.
(todos-top-priorities-multifile, todos-diary-items-multifile)
(todos-regexp-items-multifile): Use variable todos-multiple-files.
(todos-jump-to-item): Fix regexp; handle archive tags; take
todos-filter-done-items into account.
(todos-insert-item-from-calendar): Relocate to end of file
together with key-binding as addition to calendar.el.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 24 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 379 |
2 files changed, 223 insertions, 180 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1933b7cea01..1675c86684d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,6 +1,28 @@ | |||
| 1 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> | ||
| 2 | |||
| 3 | * calendar/todos.el: Add and revise further doc strings and | ||
| 4 | comments. | ||
| 5 | (todos-filter-function, todos-custom-items) | ||
| 6 | (todos-custom-items-multifile): Remove. | ||
| 7 | (todos-filter-done-items): New defcustom. | ||
| 8 | (todos-item-end, todos-backward-item): Handle todos-filter-items-mode. | ||
| 9 | (todos-filter-items): Check return value of caller first; tag | ||
| 10 | archived items for todos-jump-to-item; delete categories sexp | ||
| 11 | before processing filter; check todos-filter-done-items for | ||
| 12 | whether to leave done items; remove custom filter; fix regexp for | ||
| 13 | file and category tags; don't invoke buffer fontification. | ||
| 14 | (powerset-recursive): Fix typo. | ||
| 15 | (todos-key-bindings): Remove unused bindings. | ||
| 16 | (todos-top-priorities-multifile, todos-diary-items-multifile) | ||
| 17 | (todos-regexp-items-multifile): Use variable todos-multiple-files. | ||
| 18 | (todos-jump-to-item): Fix regexp; handle archive tags; take | ||
| 19 | todos-filter-done-items into account. | ||
| 20 | (todos-insert-item-from-calendar): Relocate to end of file | ||
| 21 | together with key-binding as addition to calendar.el. | ||
| 22 | |||
| 1 | 2012-09-20 Stephen Berman <stephen.berman@gmx.net> | 23 | 2012-09-20 Stephen Berman <stephen.berman@gmx.net> |
| 2 | 24 | ||
| 3 | * calendar/todos.el Add and revise further doc strings and | 25 | * calendar/todos.el: Add and revise further doc strings and |
| 4 | comments; major code rearrangement. | 26 | comments; major code rearrangement. |
| 5 | (todos-merged-files, todos-prompt-merged-files) | 27 | (todos-merged-files, todos-prompt-merged-files) |
| 6 | (todos-print-priorities, todos-tmp-buffer-name) | 28 | (todos-print-priorities, todos-tmp-buffer-name) |
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el index b6b62808613..88a19b60a57 100644 --- a/lisp/calendar/todos.el +++ b/lisp/calendar/todos.el | |||
| @@ -262,11 +262,12 @@ Todos category. The resulting control becomes the local value of | |||
| 262 | :group 'todos) | 262 | :group 'todos) |
| 263 | 263 | ||
| 264 | (defun todos-special-buffer-name (buffer-type file-list) | 264 | (defun todos-special-buffer-name (buffer-type file-list) |
| 265 | "Rename Todos special buffer. | 265 | "Rename Todos special buffer using BUFFER-TYPE and FILE-LIST. |
| 266 | The new name is concatenated from the string BUFFER-TYPE and the | 266 | |
| 267 | names of the files in FILE-LIST. Used in the mode-list of | 267 | The new name is constructed from the string BUFFER-TYPE, which |
| 268 | buffers displaying top priorities, diary items, regexp items | 268 | refers to one of the top priorities, diary or regexp item |
| 269 | etc. for single and multiple files." | 269 | filters, and the names of the filtered files in FILE-LIST. Used |
| 270 | in Todos Filter Items mode." | ||
| 270 | (let* ((flist (if (listp file-list) file-list (list file-list))) | 271 | (let* ((flist (if (listp file-list) file-list (list file-list))) |
| 271 | (multi (> (length flist) 1)) | 272 | (multi (> (length flist) 1)) |
| 272 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) | 273 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) |
| @@ -275,27 +276,22 @@ etc. for single and multiple files." | |||
| 275 | " \"%s\"") buffer-type fnames)))) | 276 | " \"%s\"") buffer-type fnames)))) |
| 276 | 277 | ||
| 277 | (defcustom todos-filter-buffer "Todos filtered items" | 278 | (defcustom todos-filter-buffer "Todos filtered items" |
| 278 | "Initial name of buffer in Todos Filter mode." | 279 | "Initial name of buffer in Todos Filter Items mode." |
| 279 | :type 'string | 280 | :type 'string |
| 280 | :group 'todos) | 281 | :group 'todos) |
| 281 | 282 | ||
| 282 | (defcustom todos-top-priorities-buffer "Todos top priorities" | 283 | (defcustom todos-top-priorities-buffer "Todos top priorities" |
| 283 | "Name of buffer displaying top priorities in Todos Filter mode." | 284 | "Buffer type string for `todos-special-buffer-name'." |
| 284 | :type 'string | 285 | :type 'string |
| 285 | :group 'todos) | 286 | :group 'todos) |
| 286 | 287 | ||
| 287 | (defcustom todos-diary-items-buffer "Todos diary items" | 288 | (defcustom todos-diary-items-buffer "Todos diary items" |
| 288 | "Name of buffer displaying diary items in Todos Filter mode." | 289 | "Buffer type string for `todos-special-buffer-name'." |
| 289 | :type 'string | 290 | :type 'string |
| 290 | :group 'todos) | 291 | :group 'todos) |
| 291 | 292 | ||
| 292 | (defcustom todos-regexp-items-buffer "Todos regexp items" | 293 | (defcustom todos-regexp-items-buffer "Todos regexp items" |
| 293 | "Name of buffer displaying regexp items in Todos Filter mode." | 294 | "Buffer type string for `todos-special-buffer-name'." |
| 294 | :type 'string | ||
| 295 | :group 'todos) | ||
| 296 | |||
| 297 | (defcustom todos-custom-items-buffer "Todos custom items" | ||
| 298 | "Name of buffer displaying custom items in Todos Filter mode." | ||
| 299 | :type 'string | 295 | :type 'string |
| 300 | :group 'todos) | 296 | :group 'todos) |
| 301 | 297 | ||
| @@ -319,11 +315,6 @@ items in that category, which overrides NUM." | |||
| 319 | :type 'integer | 315 | :type 'integer |
| 320 | :group 'todos) | 316 | :group 'todos) |
| 321 | 317 | ||
| 322 | (defcustom todos-filter-function nil | ||
| 323 | "" | ||
| 324 | :type 'function | ||
| 325 | :group 'todos) | ||
| 326 | |||
| 327 | (defcustom todos-filter-files nil | 318 | (defcustom todos-filter-files nil |
| 328 | "List of default files for multifile item filtering." | 319 | "List of default files for multifile item filtering." |
| 329 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | 320 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) |
| @@ -342,6 +333,12 @@ Called after adding or deleting a Todos file." | |||
| 342 | (funcall todos-files-function)))) | 333 | (funcall todos-files-function)))) |
| 343 | :group 'todos))) | 334 | :group 'todos))) |
| 344 | 335 | ||
| 336 | (defcustom todos-filter-done-items nil | ||
| 337 | "Non-nil to include done items when processing regexp filters. | ||
| 338 | Done items from corresponding archive files are also included." | ||
| 339 | :type 'boolean | ||
| 340 | :group 'todos) | ||
| 341 | |||
| 345 | (defcustom todos-ignore-archived-categories nil | 342 | (defcustom todos-ignore-archived-categories nil |
| 346 | "Non-nil to ignore categories with only archived items. | 343 | "Non-nil to ignore categories with only archived items. |
| 347 | When non-nil such categories are omitted from `todos-categories' | 344 | When non-nil such categories are omitted from `todos-categories' |
| @@ -784,8 +781,6 @@ categories display according to priority." | |||
| 784 | 781 | ||
| 785 | (defvar todos-font-lock-keywords | 782 | (defvar todos-font-lock-keywords |
| 786 | (list | 783 | (list |
| 787 | ;; '(todos-nondiary-marker-matcher 1 todos-nondiary-face t) | ||
| 788 | ;; '(todos-nondiary-marker-matcher 2 todos-nondiary-face t) | ||
| 789 | '(todos-nondiary-marker-matcher 1 todos-done-sep-face t) | 784 | '(todos-nondiary-marker-matcher 1 todos-done-sep-face t) |
| 790 | '(todos-nondiary-marker-matcher 2 todos-done-sep-face t) | 785 | '(todos-nondiary-marker-matcher 2 todos-done-sep-face t) |
| 791 | ;; This is the face used by diary-lib.el. | 786 | ;; This is the face used by diary-lib.el. |
| @@ -1083,7 +1078,7 @@ number as its value." | |||
| 1083 | (overlay-put ov-sep 'display done-sep)))) | 1078 | (overlay-put ov-sep 'display done-sep)))) |
| 1084 | (narrow-to-region (point-min) done-start) | 1079 | (narrow-to-region (point-min) done-start) |
| 1085 | ;; Loading this from todos-mode, or adding it to the mode hook, causes | 1080 | ;; Loading this from todos-mode, or adding it to the mode hook, causes |
| 1086 | ;; Emacs to hang in todos-item-start, at looking-at. | 1081 | ;; Emacs to hang in todos-item-start, at (looking-at todos-item-start). |
| 1087 | (when todos-highlight-item | 1082 | (when todos-highlight-item |
| 1088 | (require 'hl-line) | 1083 | (require 'hl-line) |
| 1089 | (hl-line-mode 1))))) | 1084 | (hl-line-mode 1))))) |
| @@ -1099,6 +1094,7 @@ If CATEGORY is nil, default to the current category." | |||
| 1099 | ((eq type 'archived) 3)))) | 1094 | ((eq type 'archived) 3)))) |
| 1100 | (aref counts idx))) | 1095 | (aref counts idx))) |
| 1101 | 1096 | ||
| 1097 | ;; FIXME: rename to todos-increment-count | ||
| 1102 | (defun todos-set-count (type increment &optional category) | 1098 | (defun todos-set-count (type increment &optional category) |
| 1103 | "Increment count of TYPE items in CATEGORY by INCREMENT. | 1099 | "Increment count of TYPE items in CATEGORY by INCREMENT. |
| 1104 | If CATEGORY is nil, default to the current category." | 1100 | If CATEGORY is nil, default to the current category." |
| @@ -1255,7 +1251,9 @@ where the invalid formatting was found." | |||
| 1255 | t) | 1251 | t) |
| 1256 | 1252 | ||
| 1257 | (defun todos-repair-categories-sexp () | 1253 | (defun todos-repair-categories-sexp () |
| 1258 | "Repair corrupt Todos categories sexp." | 1254 | "Repair corrupt Todos categories sexp. |
| 1255 | This should only be needed as a consequence of careless manual | ||
| 1256 | editing or a bug in todos.el." | ||
| 1259 | (interactive) | 1257 | (interactive) |
| 1260 | (let ((todos-categories-full (todos-make-categories-list t))) | 1258 | (let ((todos-categories-full (todos-make-categories-list t))) |
| 1261 | (todos-update-categories-sexp))) | 1259 | (todos-update-categories-sexp))) |
| @@ -1284,10 +1282,11 @@ where the invalid formatting was found." | |||
| 1284 | (unless (looking-at "^$") | 1282 | (unless (looking-at "^$") |
| 1285 | (let ((done (todos-done-item-p))) | 1283 | (let ((done (todos-done-item-p))) |
| 1286 | (todos-forward-item) | 1284 | (todos-forward-item) |
| 1287 | ;; Adjust if item is last unfinished one before displayed done items. | 1285 | (unless (eq major-mode 'todos-filter-items-mode) |
| 1288 | (when (and (not done) (todos-done-item-p)) | 1286 | ;; Adjust if item is last unfinished one before displayed done items. |
| 1289 | (forward-line -1)) | 1287 | (when (and (not done) (todos-done-item-p)) |
| 1290 | (backward-char)) | 1288 | (forward-line -1)) |
| 1289 | (backward-char))) | ||
| 1291 | (point))) | 1290 | (point))) |
| 1292 | 1291 | ||
| 1293 | (defun todos-item-string () | 1292 | (defun todos-item-string () |
| @@ -1572,7 +1571,7 @@ Helper function for `todos-convert-legacy-files'." | |||
| 1572 | ;;; Item filtering | 1571 | ;;; Item filtering |
| 1573 | 1572 | ||
| 1574 | (defvar todos-multiple-files nil | 1573 | (defvar todos-multiple-files nil |
| 1575 | "List of files returned by `todos-multiple-files' widget.") | 1574 | "List of files selected from `todos-multiple-files' widget.") |
| 1576 | 1575 | ||
| 1577 | (defvar todos-multiple-files-widget nil | 1576 | (defvar todos-multiple-files-widget nil |
| 1578 | "Variable holding widget created by `todos-multiple-files'.") | 1577 | "Variable holding widget created by `todos-multiple-files'.") |
| @@ -1582,50 +1581,48 @@ Helper function for `todos-convert-legacy-files'." | |||
| 1582 | (require 'widget) | 1581 | (require 'widget) |
| 1583 | (eval-when-compile | 1582 | (eval-when-compile |
| 1584 | (require 'wid-edit)) | 1583 | (require 'wid-edit)) |
| 1585 | (with-current-buffer (get-buffer-create "*Todos Filter Files*") | 1584 | (with-current-buffer (get-buffer-create "*Todos Filter Files*") |
| 1586 | (pop-to-buffer (current-buffer)) | 1585 | (pop-to-buffer (current-buffer)) |
| 1587 | (erase-buffer) | 1586 | (erase-buffer) |
| 1588 | (kill-all-local-variables) | 1587 | (kill-all-local-variables) |
| 1589 | (widget-insert "Select files for generating the top priorities list.\n\n") | 1588 | (widget-insert "Select files for generating the top priorities list.\n\n") |
| 1590 | (setq todos-multiple-files-widget | 1589 | (setq todos-multiple-files-widget |
| 1591 | (widget-create | 1590 | (widget-create |
| 1592 | `(set ,@(mapcar (lambda (x) (list 'const x)) | 1591 | `(set ,@(mapcar (lambda (x) (list 'const x)) |
| 1593 | (mapcar 'todos-short-file-name | 1592 | (mapcar 'todos-short-file-name |
| 1594 | (funcall todos-files-function)))))) | 1593 | (funcall todos-files-function)))))) |
| 1595 | (widget-insert "\n") | 1594 | (widget-insert "\n") |
| 1596 | (widget-create 'push-button | 1595 | (widget-create 'push-button |
| 1597 | :notify (lambda (widget &rest ignore) | 1596 | :notify (lambda (widget &rest ignore) |
| 1598 | (setq todos-multiple-files 'quit) | 1597 | (setq todos-multiple-files 'quit) |
| 1599 | (quit-window t) | 1598 | (quit-window t) |
| 1600 | (exit-recursive-edit)) | 1599 | (exit-recursive-edit)) |
| 1601 | "Cancel") | 1600 | "Cancel") |
| 1602 | (widget-insert " ") | 1601 | (widget-insert " ") |
| 1603 | (widget-create 'push-button | 1602 | (widget-create 'push-button |
| 1604 | :notify (lambda (&rest ignore) | 1603 | :notify (lambda (&rest ignore) |
| 1605 | (setq todos-multiple-files | 1604 | (setq todos-multiple-files |
| 1606 | (mapcar (lambda (f) | 1605 | (mapcar (lambda (f) |
| 1607 | (concat todos-files-directory | 1606 | (concat todos-files-directory |
| 1608 | f ".todo")) | 1607 | f ".todo")) |
| 1609 | (widget-value | 1608 | (widget-value |
| 1610 | todos-multiple-files-widget))) | 1609 | todos-multiple-files-widget))) |
| 1611 | (quit-window t) | 1610 | (quit-window t) |
| 1612 | (exit-recursive-edit)) | 1611 | (exit-recursive-edit)) |
| 1613 | "Apply") | 1612 | "Apply") |
| 1614 | (use-local-map widget-keymap) | 1613 | (use-local-map widget-keymap) |
| 1615 | (widget-setup)) | 1614 | (widget-setup)) |
| 1616 | (message "Click \"Apply\" after selecting files.") | 1615 | (message "Click \"Apply\" after selecting files.") |
| 1617 | (recursive-edit)) | 1616 | (recursive-edit)) |
| 1618 | 1617 | ||
| 1619 | ;; FIXME: should done and archived items be included? Maybe just for regexp | ||
| 1620 | ;; and custom filters? | ||
| 1621 | (defun todos-filter-items (filter &optional multifile) | 1618 | (defun todos-filter-items (filter &optional multifile) |
| 1622 | "Build and display a list of items from different categories. | 1619 | "Build and display a list of items from different categories. |
| 1623 | 1620 | ||
| 1624 | The items are selected according to the value of FILTER, which | 1621 | The items are selected according to the value of FILTER, which |
| 1625 | can be `top' for top priority items, `diary' for diary items, | 1622 | can be `top' for top priority items, `diary' for diary items, |
| 1626 | `regexp' for items matching a regular expresion entered by the | 1623 | `regexp' for items matching a regular expresion entered by the |
| 1627 | user, or `custom' for items chosen by user-defined function | 1624 | user, or a cons cell of one of these symbols and a number set by |
| 1628 | `todos-filter-function'. | 1625 | the calling command, which overrides `todos-show-priorities'. |
| 1629 | 1626 | ||
| 1630 | With non-nil argument MULTIFILE list top priorities of multiple | 1627 | With non-nil argument MULTIFILE list top priorities of multiple |
| 1631 | Todos files, by default those in `todos-filter-files'." | 1628 | Todos files, by default those in `todos-filter-files'." |
| @@ -1634,9 +1631,11 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1634 | (files (list todos-current-todos-file)) | 1631 | (files (list todos-current-todos-file)) |
| 1635 | regexp fname bufstr cat beg end done) | 1632 | regexp fname bufstr cat beg end done) |
| 1636 | (when multifile | 1633 | (when multifile |
| 1637 | (setq files (if (or (consp filter) (null todos-filter-files)) | 1634 | (setq files (or todos-multiple-files ; Passed from todos-*-multifile. |
| 1638 | (progn (todos-multiple-files) todos-multiple-files) | 1635 | (if (or (consp filter) |
| 1639 | todos-filter-files) | 1636 | (null todos-filter-files)) |
| 1637 | (progn (todos-multiple-files) todos-multiple-files) | ||
| 1638 | todos-filter-files)) | ||
| 1640 | todos-multiple-files nil)) | 1639 | todos-multiple-files nil)) |
| 1641 | (if (eq files 'quit) (keyboard-quit)) | 1640 | (if (eq files 'quit) (keyboard-quit)) |
| 1642 | (if (null files) | 1641 | (if (null files) |
| @@ -1656,16 +1655,40 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1656 | (with-current-buffer bf (save-buffer)))) | 1655 | (with-current-buffer bf (save-buffer)))) |
| 1657 | (setq fname (todos-short-file-name f)) | 1656 | (setq fname (todos-short-file-name f)) |
| 1658 | (with-temp-buffer | 1657 | (with-temp-buffer |
| 1658 | (when (and todos-filter-done-items (eq filter 'regexp)) | ||
| 1659 | ;; If there is a corresponding archive file for the Todos file, | ||
| 1660 | ;; insert it first and add identifiers for todos-jump-to-item. | ||
| 1661 | (let ((arch (concat (file-name-sans-extension f) ".toda"))) | ||
| 1662 | (when (file-exists-p arch) | ||
| 1663 | (insert-file-contents arch) | ||
| 1664 | ;; Delete Todos archive file categories sexp. | ||
| 1665 | (delete-region (line-beginning-position) | ||
| 1666 | (1+ (line-end-position))) | ||
| 1667 | (save-excursion | ||
| 1668 | (while (not (eobp)) | ||
| 1669 | (when (re-search-forward | ||
| 1670 | (concat (if todos-filter-done-items | ||
| 1671 | (concat "\\(?:" todos-done-string-start | ||
| 1672 | "\\|" todos-date-string-start | ||
| 1673 | "\\)") | ||
| 1674 | todos-date-string-start) | ||
| 1675 | todos-date-pattern "\\(?: " | ||
| 1676 | diary-time-regexp "\\)?" | ||
| 1677 | (if todos-filter-done-items | ||
| 1678 | "\\]" | ||
| 1679 | (regexp-quote todos-nondiary-end)) "?") | ||
| 1680 | nil t) | ||
| 1681 | (insert "(archive) ")) | ||
| 1682 | (forward-line)))))) | ||
| 1659 | (insert-file-contents f) | 1683 | (insert-file-contents f) |
| 1660 | (goto-char (point-min)) | 1684 | ;; Delete Todos file categories sexp. |
| 1685 | (delete-region (line-beginning-position) (1+ (line-end-position))) | ||
| 1661 | (let (fnum) | 1686 | (let (fnum) |
| 1662 | ;; Unless the number of items to show was supplied by prefix | 1687 | ;; Unless the number of items to show was supplied by prefix |
| 1663 | ;; argument of caller, override `todos-show-priorities' with the | 1688 | ;; argument of caller, override `todos-show-priorities' with the |
| 1664 | ;; file-wide value from `todos-priorities-rules'. | 1689 | ;; file-wide value from `todos-priorities-rules'. |
| 1665 | (unless (consp filter) | 1690 | (unless (consp filter) |
| 1666 | (setq fnum (nth 1 (assoc f todos-priorities-rules)))) | 1691 | (setq fnum (nth 1 (assoc f todos-priorities-rules)))) |
| 1667 | (unless (looking-at (concat "^" (regexp-quote todos-category-beg))) | ||
| 1668 | (kill-line 1)) | ||
| 1669 | (while (re-search-forward | 1692 | (while (re-search-forward |
| 1670 | (concat "^" (regexp-quote todos-category-beg) "\\(.+\\)\n") | 1693 | (concat "^" (regexp-quote todos-category-beg) "\\(.+\\)\n") |
| 1671 | nil t) | 1694 | nil t) |
| @@ -1683,7 +1706,7 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1683 | ;; FIXME: need this? | 1706 | ;; FIXME: need this? |
| 1684 | todos-show-priorities)))) | 1707 | todos-show-priorities)))) |
| 1685 | (delete-region (match-beginning 0) (match-end 0)) | 1708 | (delete-region (match-beginning 0) (match-end 0)) |
| 1686 | (setq beg (point)) ; Start of first item. | 1709 | (setq beg (point)) ; First item in the current category. |
| 1687 | (setq end (if (re-search-forward | 1710 | (setq end (if (re-search-forward |
| 1688 | (concat "^" (regexp-quote todos-category-beg)) | 1711 | (concat "^" (regexp-quote todos-category-beg)) |
| 1689 | nil t) | 1712 | nil t) |
| @@ -1696,12 +1719,11 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1696 | end t) | 1719 | end t) |
| 1697 | (match-beginning 0) | 1720 | (match-beginning 0) |
| 1698 | end)) | 1721 | end)) |
| 1699 | ;; Leave done items only with regexp filter. | 1722 | (unless (and todos-filter-done-items (eq filter 'regexp)) |
| 1700 | ;; FIXME: and custom filter? | 1723 | ;; Leave done items. |
| 1701 | (unless (eq filter 'regexp) | ||
| 1702 | (delete-region done end) | 1724 | (delete-region done end) |
| 1703 | (setq end done)) | 1725 | (setq end done)) |
| 1704 | (narrow-to-region beg end) ; Process current category. | 1726 | (narrow-to-region beg end) ; Process only current category. |
| 1705 | (goto-char (point-min)) | 1727 | (goto-char (point-min)) |
| 1706 | ;; Apply the filter. | 1728 | ;; Apply the filter. |
| 1707 | (cond ((eq filter 'diary) | 1729 | (cond ((eq filter 'diary) |
| @@ -1723,53 +1745,49 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1723 | ;; there are no following done items, | 1745 | ;; there are no following done items, |
| 1724 | ;; todos-category-done string is left dangling, | 1746 | ;; todos-category-done string is left dangling, |
| 1725 | ;; because todos-forward-item jumps over it. | 1747 | ;; because todos-forward-item jumps over it. |
| 1726 | (if (and (eobp) (looking-back | 1748 | (if (and (eobp) |
| 1727 | (concat (regexp-quote todos-done-string) | 1749 | (looking-back |
| 1728 | "\n"))) | 1750 | (concat (regexp-quote todos-done-string) |
| 1751 | "\n"))) | ||
| 1729 | (delete-region (point) (progn | 1752 | (delete-region (point) (progn |
| 1730 | (forward-line -2) | 1753 | (forward-line -2) |
| 1731 | (point)))))) | 1754 | (point)))))) |
| 1732 | ((eq filter 'custom) | ||
| 1733 | (if todos-filter-function | ||
| 1734 | (funcall todos-filter-function) | ||
| 1735 | (error "No custom filter function has been defined"))) | ||
| 1736 | (t ; Filter top priority items. | 1755 | (t ; Filter top priority items. |
| 1737 | (setq num (or cnum fnum num)) | 1756 | (setq num (or cnum fnum num)) |
| 1738 | (unless (zerop num) | 1757 | (unless (zerop num) |
| 1739 | (todos-forward-item num)))) | 1758 | (todos-forward-item num)))) |
| 1740 | (setq beg (point)) | 1759 | (setq beg (point)) |
| 1741 | (unless (member filter '(diary regexp custom)) | 1760 | ;; Delete non-top-priority items. |
| 1761 | (unless (member filter '(diary regexp)) | ||
| 1742 | (delete-region beg end)) | 1762 | (delete-region beg end)) |
| 1743 | (goto-char (point-min)) | 1763 | (goto-char (point-min)) |
| 1744 | ;; Add file (if using multiple files) and category tags to | 1764 | ;; Add file (if using multiple files) and category tags to |
| 1745 | ;; item. | 1765 | ;; item. |
| 1746 | (while (not (eobp)) | 1766 | (while (not (eobp)) |
| 1747 | (when (re-search-forward | 1767 | (when (re-search-forward |
| 1748 | (concat "\\(" todos-done-string-start | 1768 | (concat (if todos-filter-done-items |
| 1749 | todos-date-pattern "\\( " diary-time-regexp | 1769 | (concat "\\(?:" todos-done-string-start |
| 1750 | "\\)?]\\)\\|\\(" | 1770 | "\\|" todos-date-string-start |
| 1751 | ;; todos-date-string-start doesn't work | 1771 | "\\)") |
| 1752 | ;; here because of `^' | 1772 | todos-date-string-start) |
| 1753 | "\\(" (regexp-quote todos-nondiary-start) | 1773 | todos-date-pattern "\\(?: " diary-time-regexp |
| 1754 | "\\|" (regexp-quote diary-nonmarking-symbol) | 1774 | "\\)?" (if todos-filter-done-items |
| 1755 | "\\)?" todos-date-pattern "\\( " | 1775 | "\\]" |
| 1756 | diary-time-regexp "\\)?" | 1776 | (regexp-quote todos-nondiary-end)) |
| 1757 | (regexp-quote todos-nondiary-end) "?\\)") | 1777 | "?") |
| 1758 | nil t) | 1778 | nil t) |
| 1759 | (insert (concat " [" (if multifile (concat fname ":")) | 1779 | (insert " [") |
| 1760 | cat "]"))) | 1780 | (when (looking-at "(archive) ") (goto-char (match-end 0))) |
| 1781 | (insert (if multifile (concat fname ":") "") cat "]")) | ||
| 1761 | (forward-line)) | 1782 | (forward-line)) |
| 1762 | (widen))) | 1783 | (widen))) |
| 1763 | (setq bufstr (buffer-string)) | 1784 | (setq bufstr (buffer-string)) |
| 1764 | (with-current-buffer buf | 1785 | (with-current-buffer buf |
| 1765 | (let (buffer-read-only) | 1786 | (let (buffer-read-only) |
| 1766 | (insert bufstr))))))) | 1787 | (insert bufstr))))))) |
| 1767 | ;; FIXME: let-bind todos-mode-line-control according to FILTER? | ||
| 1768 | (set-window-buffer (selected-window) (set-buffer buf)) | 1788 | (set-window-buffer (selected-window) (set-buffer buf)) |
| 1769 | (todos-prefix-overlays) | 1789 | (todos-prefix-overlays) |
| 1770 | (goto-char (point-min)) | 1790 | (goto-char (point-min))))) |
| 1771 | ;; FIXME: this is necessary -- why? | ||
| 1772 | (font-lock-fontify-buffer)))) | ||
| 1773 | 1791 | ||
| 1774 | (defun todos-set-top-priorities (&optional arg) | 1792 | (defun todos-set-top-priorities (&optional arg) |
| 1775 | "Set number of top priorities shown by `todos-top-priorities'. | 1793 | "Set number of top priorities shown by `todos-top-priorities'. |
| @@ -2070,8 +2088,9 @@ which is the value of the user option | |||
| 2070 | (cond ((null l) | 2088 | (cond ((null l) |
| 2071 | (list nil)) | 2089 | (list nil)) |
| 2072 | (t | 2090 | (t |
| 2073 | (let ((prev (todos-powerset (cdr l)))) | 2091 | (let ((prev (powerset-recursive (cdr l)))) |
| 2074 | (append (mapcar (lambda (elt) (cons (car l) elt)) prev) | 2092 | (append (mapcar (lambda (elt) (cons (car l) elt)) |
| 2093 | prev) | ||
| 2075 | prev))))) | 2094 | prev))))) |
| 2076 | ;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C | 2095 | ;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C |
| 2077 | (defun powerset-bitwise (l) | 2096 | (defun powerset-bitwise (l) |
| @@ -2244,8 +2263,6 @@ which is the value of the user option | |||
| 2244 | ("Fym" . todos-diary-items-multifile) | 2263 | ("Fym" . todos-diary-items-multifile) |
| 2245 | ("Fxx" . todos-regexp-items) | 2264 | ("Fxx" . todos-regexp-items) |
| 2246 | ("Fxm" . todos-regexp-items-multifile) | 2265 | ("Fxm" . todos-regexp-items-multifile) |
| 2247 | ("Fcc" . todos-custom-items) | ||
| 2248 | ("Fcm" . todos-custom-items-multifile) | ||
| 2249 | ;;("" . todos-save-top-priorities) | 2266 | ;;("" . todos-save-top-priorities) |
| 2250 | ;; navigation | 2267 | ;; navigation |
| 2251 | ("f" . todos-forward-category) | 2268 | ("f" . todos-forward-category) |
| @@ -2879,7 +2896,8 @@ list in each category." | |||
| 2879 | (cons 'top arg) | 2896 | (cons 'top arg) |
| 2880 | (setq files (if (or (consp arg) | 2897 | (setq files (if (or (consp arg) |
| 2881 | (null todos-filter-files)) | 2898 | (null todos-filter-files)) |
| 2882 | (todos-multiple-files) | 2899 | (progn (todos-multiple-files) |
| 2900 | todos-multiple-files) | ||
| 2883 | todos-filter-files)) | 2901 | todos-filter-files)) |
| 2884 | (if (equal arg '(16)) | 2902 | (if (equal arg '(16)) |
| 2885 | (cons 'top (read-number | 2903 | (cons 'top (read-number |
| @@ -2903,7 +2921,8 @@ The files are those listed in `todos-filter-files'." | |||
| 2903 | (interactive "P") | 2921 | (interactive "P") |
| 2904 | (let ((buf todos-diary-items-buffer) | 2922 | (let ((buf todos-diary-items-buffer) |
| 2905 | (files (if (or arg (null todos-filter-files)) | 2923 | (files (if (or arg (null todos-filter-files)) |
| 2906 | (todos-multiple-files) | 2924 | (progn (todos-multiple-files) |
| 2925 | todos-multiple-files) | ||
| 2907 | todos-filter-files))) | 2926 | todos-filter-files))) |
| 2908 | (todos-filter-items 'diary t) | 2927 | (todos-filter-items 'diary t) |
| 2909 | (todos-special-buffer-name buf files))) | 2928 | (todos-special-buffer-name buf files))) |
| @@ -2923,31 +2942,12 @@ The items are those in the files listed in `todos-filter-files'." | |||
| 2923 | (interactive "P") | 2942 | (interactive "P") |
| 2924 | (let ((buf todos-regexp-items-buffer) | 2943 | (let ((buf todos-regexp-items-buffer) |
| 2925 | (files (if (or arg (null todos-filter-files)) | 2944 | (files (if (or arg (null todos-filter-files)) |
| 2926 | (todos-multiple-files) | 2945 | (progn (todos-multiple-files) |
| 2946 | todos-multiple-files) | ||
| 2927 | todos-filter-files))) | 2947 | todos-filter-files))) |
| 2928 | (todos-filter-items 'regexp t) | 2948 | (todos-filter-items 'regexp t) |
| 2929 | (todos-special-buffer-name buf files))) | 2949 | (todos-special-buffer-name buf files))) |
| 2930 | 2950 | ||
| 2931 | (defun todos-custom-items () | ||
| 2932 | "Display todo items filtered by `todos-filter-function'. | ||
| 2933 | The items are those in the current Todos file." | ||
| 2934 | (interactive) | ||
| 2935 | (let ((buf todos-custom-items-buffer) | ||
| 2936 | (file todos-current-todos-file)) | ||
| 2937 | (todos-filter-items 'custom) | ||
| 2938 | (todos-special-buffer-name buf file))) | ||
| 2939 | |||
| 2940 | (defun todos-custom-items-multifile (&optional arg) | ||
| 2941 | "Display todo items filtered by `todos-filter-function'. | ||
| 2942 | The items are those in the files listed in `todos-filter-files'." | ||
| 2943 | (interactive "P") | ||
| 2944 | (let ((buf todos-custom-items-buffer) | ||
| 2945 | (files (if (or arg (null todos-filter-files)) | ||
| 2946 | (todos-multiple-files) | ||
| 2947 | todos-filter-files))) | ||
| 2948 | (todos-filter-items 'custom t) | ||
| 2949 | (todos-special-buffer-name buf files))) | ||
| 2950 | |||
| 2951 | (defun todos-print (&optional to-file) | 2951 | (defun todos-print (&optional to-file) |
| 2952 | "Produce a printable version of the current Todos buffer. | 2952 | "Produce a printable version of the current Todos buffer. |
| 2953 | This converts overlays and soft line wrapping and, depending on | 2953 | This converts overlays and soft line wrapping and, depending on |
| @@ -3183,7 +3183,8 @@ file, otherwise jump within the current Todos file." | |||
| 3183 | (interactive) | 3183 | (interactive) |
| 3184 | (let ((file (or (and other-file | 3184 | (let ((file (or (and other-file |
| 3185 | (todos-read-file-name "Choose a Todos file: " nil t)) | 3185 | (todos-read-file-name "Choose a Todos file: " nil t)) |
| 3186 | ;; Jump to archived-only Categories from Todos Categories mode. | 3186 | ;; Jump to archived-only Categories from Todos Categories |
| 3187 | ;; mode. | ||
| 3187 | (and cat | 3188 | (and cat |
| 3188 | todos-ignore-archived-categories | 3189 | todos-ignore-archived-categories |
| 3189 | (zerop (todos-get-count 'todo cat)) | 3190 | (zerop (todos-get-count 'todo cat)) |
| @@ -3192,25 +3193,26 @@ file, otherwise jump within the current Todos file." | |||
| 3192 | (concat (file-name-sans-extension | 3193 | (concat (file-name-sans-extension |
| 3193 | todos-current-todos-file) ".toda")) | 3194 | todos-current-todos-file) ".toda")) |
| 3194 | todos-current-todos-file | 3195 | todos-current-todos-file |
| 3195 | ;; If invoked from outside of Todos mode before todos-show... | 3196 | ;; If invoked from outside of Todos mode before |
| 3197 | ;; todos-show... | ||
| 3196 | todos-default-todos-file))) | 3198 | todos-default-todos-file))) |
| 3197 | (with-current-buffer (find-file-noselect file) | 3199 | (with-current-buffer (find-file-noselect file) |
| 3198 | (and other-file (setq todos-current-todos-file file)) | 3200 | (and other-file (setq todos-current-todos-file file)) |
| 3199 | (let ((category (or (and (assoc cat todos-categories) cat) | 3201 | (let ((category (or (and (assoc cat todos-categories) cat) |
| 3200 | (todos-read-category "Jump to category: ")))) | 3202 | (todos-read-category "Jump to category: ")))) |
| 3201 | ;; Clean up after selecting category in Todos Categories mode. | 3203 | ;; Clean up after selecting category in Todos Categories mode. |
| 3202 | (if (string= (buffer-name) todos-categories-buffer) | 3204 | (if (string= (buffer-name) todos-categories-buffer) |
| 3203 | (kill-buffer)) | 3205 | (kill-buffer)) |
| 3204 | (if (or cat other-file) | 3206 | (if (or cat other-file) |
| 3205 | (set-window-buffer (selected-window) | 3207 | (set-window-buffer (selected-window) |
| 3206 | (set-buffer (get-file-buffer file)))) | 3208 | (set-buffer (get-file-buffer file)))) |
| 3207 | (unless todos-global-current-todos-file | 3209 | (unless todos-global-current-todos-file |
| 3208 | (setq todos-global-current-todos-file todos-current-todos-file)) | 3210 | (setq todos-global-current-todos-file todos-current-todos-file)) |
| 3209 | (todos-category-number category) | 3211 | (todos-category-number category) |
| 3210 | (if (> todos-category-number (length todos-categories)) | 3212 | (if (> todos-category-number (length todos-categories)) |
| 3211 | (setq todos-category-number (todos-add-category category))) | 3213 | (setq todos-category-number (todos-add-category category))) |
| 3212 | (todos-category-select) | 3214 | (todos-category-select) |
| 3213 | (goto-char (point-min)))))) | 3215 | (goto-char (point-min)))))) |
| 3214 | 3216 | ||
| 3215 | (defun todos-jump-to-category-other-file () | 3217 | (defun todos-jump-to-category-other-file () |
| 3216 | "Jump to a category in another Todos file. | 3218 | "Jump to a category in another Todos file. |
| @@ -3223,17 +3225,28 @@ The category is chosen by prompt, with TAB completion." | |||
| 3223 | (interactive) | 3225 | (interactive) |
| 3224 | (let ((str (todos-item-string)) | 3226 | (let ((str (todos-item-string)) |
| 3225 | (buf (current-buffer)) | 3227 | (buf (current-buffer)) |
| 3226 | cat file beg) | 3228 | cat file archive beg) |
| 3227 | (string-match (concat todos-date-string-start todos-date-pattern | 3229 | (string-match (concat (if todos-filter-done-items |
| 3228 | "\\(?: " diary-time-regexp "\\)?" | 3230 | (concat "\\(?:" todos-done-string-start "\\|" |
| 3229 | (regexp-quote todos-nondiary-end) "?" | 3231 | todos-date-string-start "\\)") |
| 3230 | "\\(?3: \\[\\(?2:.*:\\)?\\(?1:.*\\)\\]\\).*$") str) | 3232 | todos-date-string-start) |
| 3233 | todos-date-pattern "\\(?: " diary-time-regexp "\\)?" | ||
| 3234 | (if todos-filter-done-items | ||
| 3235 | "\\]" | ||
| 3236 | (regexp-quote todos-nondiary-end)) "?" | ||
| 3237 | "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?" | ||
| 3238 | "\\(?1:.*\\)\\]\\).*$") str) | ||
| 3231 | (setq cat (match-string 1 str)) | 3239 | (setq cat (match-string 1 str)) |
| 3232 | (setq file (match-string 2 str)) | 3240 | (setq file (match-string 2 str)) |
| 3233 | (setq str (replace-match "" nil nil str 3)) | 3241 | (setq archive (string= (match-string 3 str) "(archive) ")) |
| 3242 | (setq str (replace-match "" nil nil str 4)) | ||
| 3234 | (setq file (if file | 3243 | (setq file (if file |
| 3235 | (concat todos-files-directory (substring file 0 -1) ".todo") | 3244 | (concat todos-files-directory (substring file 0 -1) |
| 3236 | todos-global-current-todos-file)) | 3245 | (if archive ".toda" ".todo")) |
| 3246 | (if archive | ||
| 3247 | (concat (file-name-sans-extension | ||
| 3248 | todos-global-current-todos-file) ".toda") | ||
| 3249 | todos-global-current-todos-file))) | ||
| 3237 | (find-file-noselect file) | 3250 | (find-file-noselect file) |
| 3238 | (with-current-buffer (get-file-buffer file) | 3251 | (with-current-buffer (get-file-buffer file) |
| 3239 | (widen) | 3252 | (widen) |
| @@ -3246,7 +3259,9 @@ The category is chosen by prompt, with TAB completion." | |||
| 3246 | (set-window-buffer (selected-window) (set-buffer (get-file-buffer file))) | 3259 | (set-window-buffer (selected-window) (set-buffer (get-file-buffer file))) |
| 3247 | (setq todos-current-todos-file file) | 3260 | (setq todos-current-todos-file file) |
| 3248 | (setq todos-category-number (todos-category-number cat)) | 3261 | (setq todos-category-number (todos-category-number cat)) |
| 3249 | (todos-category-select) | 3262 | (let ((todos-show-with-done (if todos-filter-done-items t |
| 3263 | todos-show-with-done))) | ||
| 3264 | (todos-category-select)) | ||
| 3250 | (goto-char beg))) | 3265 | (goto-char beg))) |
| 3251 | 3266 | ||
| 3252 | ;; FIXME ? disallow prefix arg value < 1 (re-search-* allows these) | 3267 | ;; FIXME ? disallow prefix arg value < 1 (re-search-* allows these) |
| @@ -3277,14 +3292,15 @@ With numerical prefix COUNT, move point COUNT items upward," | |||
| 3277 | (todos-item-start) | 3292 | (todos-item-start) |
| 3278 | (unless (bobp) | 3293 | (unless (bobp) |
| 3279 | (re-search-backward todos-item-start nil t (or count 1))) | 3294 | (re-search-backward todos-item-start nil t (or count 1))) |
| 3280 | ;; If points advances by one from a done to a todo item, go back to the | 3295 | (unless (eq major-mode 'todos-filter-items-mode) |
| 3281 | ;; space above todos-done-separator, since that is a legitimate place to | 3296 | ;; If points advances by one from a done to a todo item, go back to the |
| 3282 | ;; insert an item. But skip this space if count > 1, since that should | 3297 | ;; space above todos-done-separator, since that is a legitimate place to |
| 3283 | ;; only stop on an item (FIXME: or not?) | 3298 | ;; insert an item. But skip this space if count > 1, since that should |
| 3284 | (when (and done (not (todos-done-item-p)) | 3299 | ;; only stop on an item (FIXME: or not?) |
| 3285 | (or (not count) (= count 1))) | 3300 | (when (and done (not (todos-done-item-p)) |
| 3286 | (re-search-forward (concat "^" (regexp-quote todos-category-done)) nil t) | 3301 | (or (not count) (= count 1))) |
| 3287 | (forward-line -1)))) | 3302 | (re-search-forward (concat "^" (regexp-quote todos-category-done)) nil t) |
| 3303 | (forward-line -1))))) | ||
| 3288 | 3304 | ||
| 3289 | ;; FIXME: (i) Extend search to other Todos files. (ii) Allow navigating among | 3305 | ;; FIXME: (i) Extend search to other Todos files. (ii) Allow navigating among |
| 3290 | ;; hits. | 3306 | ;; hits. |
| @@ -3906,30 +3922,14 @@ same except the priority is not given by HERE but by prompting." | |||
| 3906 | ;; *Calendar* is now current buffer. | 3922 | ;; *Calendar* is now current buffer. |
| 3907 | (local-set-key (kbd "RET") 'exit-recursive-edit) | 3923 | (local-set-key (kbd "RET") 'exit-recursive-edit) |
| 3908 | (message "Put cursor on a date and type <return> to set it.") | 3924 | (message "Put cursor on a date and type <return> to set it.") |
| 3909 | ;; FIXME: is there a better way than recursive-edit? | 3925 | ;; FIXME: is there a better way than recursive-edit? Use unwind-protect? |
| 3910 | ;; FIXME: use unwind-protect? Check recursive-depth? | 3926 | ;; Check recursive-depth? |
| 3911 | (recursive-edit) | 3927 | (recursive-edit) |
| 3912 | (setq todos-date-from-calendar | 3928 | (setq todos-date-from-calendar |
| 3913 | (calendar-date-string (calendar-cursor-to-date t) t t)) | 3929 | (calendar-date-string (calendar-cursor-to-date t) t t)) |
| 3914 | (calendar-exit) | 3930 | (calendar-exit) |
| 3915 | todos-date-from-calendar)) | 3931 | todos-date-from-calendar)) |
| 3916 | 3932 | ||
| 3917 | ;; FIXME: autoload when key-binding is defined in calendar.el | ||
| 3918 | (defun todos-insert-item-from-calendar () | ||
| 3919 | "" | ||
| 3920 | (interactive) | ||
| 3921 | ;; FIXME: todos-current-todos-file is nil here, better to solicit Todos file? | ||
| 3922 | ;; FIXME: t-g-c-t-f is nil if no Todos file has been visited | ||
| 3923 | (pop-to-buffer (file-name-nondirectory todos-global-current-todos-file)) | ||
| 3924 | (todos-show) | ||
| 3925 | ;; FIXME: this now calls todos-set-date-from-calendar | ||
| 3926 | (todos-insert-item t 'calendar)) | ||
| 3927 | |||
| 3928 | ;; FIXME: calendar is loaded before todos | ||
| 3929 | ;; (add-hook 'calendar-load-hook | ||
| 3930 | ;; (lambda () | ||
| 3931 | (define-key calendar-mode-map "it" 'todos-insert-item-from-calendar);)) | ||
| 3932 | |||
| 3933 | (defun todos-delete-item () | 3933 | (defun todos-delete-item () |
| 3934 | "Delete at least one item in this category. | 3934 | "Delete at least one item in this category. |
| 3935 | 3935 | ||
| @@ -4828,6 +4828,27 @@ archive, the archive file is deleted." | |||
| 4828 | 4828 | ||
| 4829 | ;;; todos.el ends here | 4829 | ;;; todos.el ends here |
| 4830 | 4830 | ||
| 4831 | |||
| 4832 | ;; --------------------------------------------------------------------------- | ||
| 4833 | ;;; Addition to calendar.el | ||
| 4834 | |||
| 4835 | ;; FIXME: autoload when key-binding is defined in calendar.el | ||
| 4836 | (defun todos-insert-item-from-calendar () | ||
| 4837 | "" | ||
| 4838 | (interactive) | ||
| 4839 | ;; FIXME: todos-current-todos-file is nil here, better to solicit Todos | ||
| 4840 | ;; file? todos-global-current-todos-file is nil if no Todos file has been | ||
| 4841 | ;; visited | ||
| 4842 | (pop-to-buffer (file-name-nondirectory todos-global-current-todos-file)) | ||
| 4843 | (todos-show) | ||
| 4844 | ;; FIXME: this now calls todos-set-date-from-calendar | ||
| 4845 | (todos-insert-item t 'calendar)) | ||
| 4846 | |||
| 4847 | ;; FIXME: calendar is loaded before todos | ||
| 4848 | ;; (add-hook 'calendar-load-hook | ||
| 4849 | ;; (lambda () | ||
| 4850 | (define-key calendar-mode-map "it" 'todos-insert-item-from-calendar);)) | ||
| 4851 | |||
| 4831 | ;; --------------------------------------------------------------------------- | 4852 | ;; --------------------------------------------------------------------------- |
| 4832 | ;;; necessitated adaptations to diary-lib.el | 4853 | ;;; necessitated adaptations to diary-lib.el |
| 4833 | 4854 | ||