aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2009-11-07 21:27:40 +0100
committerStephen Berman2009-11-07 21:27:40 +0100
commitb28025eddc48b2a17a0b1c011ef97eea77917acc (patch)
tree58eb49fb2fc9543f5b4f88419a649696897a8f6a
parent98c97dee7675f6028a82340e9c495c8759cd6b8e (diff)
downloademacs-b28025eddc48b2a17a0b1c011ef97eea77917acc.tar.gz
emacs-b28025eddc48b2a17a0b1c011ef97eea77917acc.zip
* calendar/todos.el: Comment out time-stamp require; require
calendar and diary-lib. (todos-prefix): Change default value and doc string to reflect new meaning; add :initialize and :set functions. (todos-time-string-format, todos-entry-prefix-function) (todos-initials, todos-entry-timestamp-initials) (todos-prefix-face, todos-category-sep, todos-category-end) (todos-cp): Comment out. (todos-prefix-string): Inherit from font-lock-comment-face. (todos-item-header, todos-item-header-face): Remove. (todos-date, todos-time): New faces. (todos-date-face, todos-time-face): Corresponding new variables. (todos-add-time-string, todos-include-in-diary) (todos-exclusion-start, todos-exclusion-end, todos-number-prefix): New defcustoms. (todos-item-end, todos-item-start-overlays) (todos-item-end-overlays): New variables. (todos-date-string-match, todos-time-string-match): New functions. (todos-font-lock-keywords): Use them. (todos-current-date, todos-date-string, todos-time-string) (todos-toggle-item-diary-inclusion, todos-toggle-diary-inclusion) (todos-reset-prefix, todos-update-numbered-prefix) (todos-check-overlay, todos-item-overlays) (todos-insert-with-overlays, todos-show-paren-hack): New functions. (todos-highlight-item): New command. (todos-category-beg): Change value. (todos-category-select): Use todos-category-beg and todos-item-overlays. (todos-backward-item): Add optional count argument; use it and todos-item-start. (todos-forward-item): Use todos-check-overlay, todos-item-start and variable todos-item-end. (todos-edit-item, todos-delete-item): Use todos-number-prefix, todos-update-numbered-prefix, todos-item-overlays. (todos-add-category, todos-rename-category) (todos-list-categories): Use new category format. (todos-delete-category): Allow deleting non-empty category; use new category format. (todos-add-item-non-interactively): Comment out unnecessary save-excursion; use todos-insert-with-overlays. (todos-insert-item): Comment out unnecessary save-excursion; use new item format for date/time header and diary inclusion marking. (todos-insert-item-here): Use new item format for date/time header and diary inclusion marking; use todos-insert-with-overlays. (todos-raise-item): Make a no-op if point is on an empty line; use todos-insert-with-overlays. (todos-lower-item): Use todos-insert-with-overlays. (todos-top-priorities): Move call to todos-show inside save-excursion; add save-current-buffer after save-restriction. (todos-item-start): Use variable todos-item-end. (todos-item-end): Use todos-check-overlay and variable todos-item-end. (todos-remove-item): Take item overlays into account. (todos-mode): Change calculation of wrap-prefix; make hl-line-range-function a local variable and set it to highlight todo item. (todos-show): Ensure point stays at top of category.
-rw-r--r--lisp/ChangeLog58
-rw-r--r--lisp/calendar/todos.el634
2 files changed, 509 insertions, 183 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 21821505339..4110a4ad087 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,63 @@
12012-09-12 Stephen Berman <stephen.berman@gmx.net> 12012-09-12 Stephen Berman <stephen.berman@gmx.net>
2 2
3 * calendar/todos.el: Comment out time-stamp require; require
4 calendar and diary-lib.
5 (todos-prefix): Change default value and doc string to reflect new
6 meaning; add :initialize and :set functions.
7 (todos-time-string-format, todos-entry-prefix-function)
8 (todos-initials, todos-entry-timestamp-initials)
9 (todos-prefix-face, todos-category-sep, todos-category-end)
10 (todos-cp): Comment out.
11 (todos-prefix-string): Inherit from font-lock-comment-face.
12 (todos-item-header, todos-item-header-face): Remove.
13 (todos-date, todos-time): New faces.
14 (todos-date-face, todos-time-face): Corresponding new variables.
15 (todos-add-time-string, todos-include-in-diary)
16 (todos-exclusion-start, todos-exclusion-end, todos-number-prefix):
17 New defcustoms.
18 (todos-item-end, todos-item-start-overlays)
19 (todos-item-end-overlays): New variables.
20 (todos-date-string-match, todos-time-string-match): New functions.
21 (todos-font-lock-keywords): Use them.
22 (todos-current-date, todos-date-string, todos-time-string)
23 (todos-toggle-item-diary-inclusion, todos-toggle-diary-inclusion)
24 (todos-reset-prefix, todos-update-numbered-prefix)
25 (todos-check-overlay, todos-item-overlays)
26 (todos-insert-with-overlays, todos-show-paren-hack): New functions.
27 (todos-highlight-item): New command.
28 (todos-category-beg): Change value.
29 (todos-category-select): Use todos-category-beg and todos-item-overlays.
30 (todos-backward-item): Add optional count argument; use it and
31 todos-item-start.
32 (todos-forward-item): Use todos-check-overlay, todos-item-start
33 and variable todos-item-end.
34 (todos-edit-item, todos-delete-item): Use todos-number-prefix,
35 todos-update-numbered-prefix, todos-item-overlays.
36 (todos-add-category, todos-rename-category)
37 (todos-list-categories): Use new category format.
38 (todos-delete-category): Allow deleting non-empty category;
39 use new category format.
40 (todos-add-item-non-interactively): Comment out unnecessary
41 save-excursion; use todos-insert-with-overlays.
42 (todos-insert-item): Comment out unnecessary save-excursion; use
43 new item format for date/time header and diary inclusion marking.
44 (todos-insert-item-here): Use new item format for date/time header
45 and diary inclusion marking; use todos-insert-with-overlays.
46 (todos-raise-item): Make a no-op if point is on an empty line; use
47 todos-insert-with-overlays.
48 (todos-lower-item): Use todos-insert-with-overlays.
49 (todos-top-priorities): Move call to todos-show inside
50 save-excursion; add save-current-buffer after save-restriction.
51 (todos-item-start): Use variable todos-item-end.
52 (todos-item-end): Use todos-check-overlay and variable todos-item-end.
53 (todos-remove-item): Take item overlays into account.
54 (todos-mode): Change calculation of wrap-prefix; make
55 hl-line-range-function a local variable and set it to highlight
56 todo item.
57 (todos-show): Ensure point stays at top of category.
58
592012-09-12 Stephen Berman <stephen.berman@gmx.net>
60
3 * calendar/todos.el (todos-window-configuration): Comment out. 61 * calendar/todos.el (todos-window-configuration): Comment out.
4 (todos-display-categories): Comment out use of 62 (todos-display-categories): Comment out use of
5 todos-window-configuration; use switch-to-buffer instead of 63 todos-window-configuration; use switch-to-buffer instead of
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index eaf4b92f5c8..5e1a3cda104 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -168,6 +168,14 @@
168;; todo list is already established is not as simple as changing 168;; todo list is already established is not as simple as changing
169;; the variable - the todo files have to be changed by hand. 169;; the variable - the todo files have to be changed by hand.
170;; 170;;
171;; FIXME: eliminate variable todos-prefix, use overlays:
172;; (defun todos-prefix ()
173;; "Display a Todo prefix string as an overlay."
174;; (let (ov)
175;; (setq ov (make-overlay (line-beginning-position) (line-end-position)))
176;; (overlay-put ov 'before-string
177;; (propertize todos-prefix 'face 'todos-prefix-string))))
178;;
171;; Variable todos-file-do 179;; Variable todos-file-do
172;; 180;;
173;; This variable is fairly self-explanatory. You have to store 181;; This variable is fairly self-explanatory. You have to store
@@ -256,8 +264,9 @@
256 264
257;;; Code: 265;;; Code:
258 266
259(require 'time-stamp) 267;; (require 'time-stamp)
260 268(require 'calendar)
269(require 'diary-lib)
261 270
262;; User-configurable variables: 271;; User-configurable variables:
263 272
@@ -267,21 +276,27 @@
267 :version "21.1" 276 :version "21.1"
268 :group 'calendar) 277 :group 'calendar)
269 278
270(defcustom todos-prefix "*/*" 279(defcustom todos-prefix "§" ; "*/*"
271 "TODO mode prefix for entries. 280 "String prefixed to todo items for visual distinction."
281 :type 'string
282 :initialize 'custom-initialize-default
283 :set 'todos-reset-prefix
284 :group 'todos)
285
286;; "TODO mode prefix for entries.
272 287
273This is useful in conjunction with `calendar' and `diary' if you use 288;; This is useful in conjunction with `calendar' and `diary' if you use
274 289
275#include \"~/.todos-do\" 290;; #include \"~/.todos-do\"
276 291
277in your diary file to include your todo list file as part of your 292;; in your diary file to include your todo list file as part of your
278diary. With the default value \"*/*\" the diary displays each entry 293;; diary. With the default value \"*/*\" the diary displays each entry
279every day and it may also be marked on every day of the calendar. 294;; every day and it may also be marked on every day of the calendar.
280Using \"&%%(equal (calendar-current-date) date)\" instead will only 295;; Using \"&%%(equal (calendar-current-date) date)\" instead will only
281show and mark todo entries for today, but may slow down processing of 296;; show and mark todo entries for today, but may slow down processing of
282the diary file somewhat." 297;; the diary file somewhat."
283 :type 'string 298;; :type 'string
284 :group 'todos) 299;; :group 'todos)
285(defcustom todos-file-do (convert-standard-filename "~/.emacs.d/.todos-do") 300(defcustom todos-file-do (convert-standard-filename "~/.emacs.d/.todos-do")
286 "TODO mode list file." 301 "TODO mode list file."
287 :type 'file 302 :type 'file
@@ -352,53 +367,164 @@ Automatically generated when `todos-save-top-priorities' is non-nil."
352 :type 'boolean 367 :type 'boolean
353 :group 'todos) 368 :group 'todos)
354 369
355;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de> 370;; ;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de>
356;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p". 371;; ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p".
357;; 372;; ;;
358(defcustom todos-time-string-format 373;; ;; FIXME: use calendar format instead
359 "%:y-%02m-%02d %02H:%02M" 374;; (defcustom todos-time-string-format
360 "TODO mode time string format for done entries. 375;; "%:y-%02m-%02d %02H:%02M"
361For details see the variable `time-stamp-format'." 376;; "TODO mode time string format for done entries.
362 :type 'string 377;; For details see the variable `time-stamp-format'."
378;; :type 'string
379;; :group 'todos)
380
381;; (defcustom todos-entry-prefix-function 'todos-entry-timestamp-initials
382;; "Function producing text to insert at start of todo entry."
383;; :type 'symbol
384;; :group 'todos)
385;; (defcustom todos-initials (or (getenv "INITIALS") (user-login-name))
386;; "Initials of todo item author."
387;; :type 'string
388;; :group 'todos)
389
390;; (defun todos-entry-timestamp-initials ()
391;; "Prepend timestamp and your initials to the head of a TODO entry."
392;; (let ((time-stamp-format todos-time-string-format))
393;; (concat (time-stamp-string) " " todos-initials ": ")))
394
395;; (defcustom todos-date (calendar-date-string (calendar-current-date) t t)
396;; "Date string inserted in front of a todo item."
397;; :type 'string
398;; :group 'todos)
399
400;; (defcustom todos-time (substring (current-time-string) 11 16)
401;; "Time string inserted in front of a todo item."
402;; :type 'string
403;; :group 'todos)
404
405(defun todos-current-date (&optional time)
406 "Return current date as a string for insertion in front of a todo item.
407With non-nil TIME append the current time."
408 (concat (calendar-date-string (calendar-current-date) t t)
409 (when time
410 (concat " " (substring (current-time-string) 11 16)))))
411
412(defcustom todos-add-time-string t
413 "Add current time to date string inserted in front of new items."
414 :type 'boolean
363 :group 'todos) 415 :group 'todos)
364 416
365(defcustom todos-entry-prefix-function 'todos-entry-timestamp-initials 417;; "Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec")
366 "Function producing text to insert at start of todo entry." 418;; (regexp-opt (list "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31")))
367 :type 'symbol 419(defun todos-date-string ()
368 :group 'todos) 420 "Return a regexp matching a diary date string."
369(defcustom todos-initials (or (getenv "INITIALS") (user-login-name)) 421 (let ((month (regexp-opt (list "Jan" "Feb" "Mar" "Apr" "May" "Jun"
370 "Initials of todo item author." 422 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")))
371 :type 'string 423 (day "[0-3]?[0-9]")
372 :group 'todos) 424 (year "[0-9]\\{4\\}"))
425 (concat month " " day ", " year)))
373 426
374(defun todos-entry-timestamp-initials () 427(defun todos-time-string ()
375 "Prepend timestamp and your initials to the head of a TODO entry." 428 "Return a regexp matching a diary time string."
376 (let ((time-stamp-format todos-time-string-format)) 429 "[0-9]?[0-9][:.][0-9]\\{2\\}")
377 (concat (time-stamp-string) " " todos-initials ": ")))
378 430
379(defface todos-prefix-string 431(defface todos-prefix-string
380 '((t 432 '((t
381 :inherit font-lock-variable-name-face 433 :inherit font-lock-constant-face
382 )) 434 ))
383 "Face for Todos prefix string." 435 "Face for Todos prefix string."
384 :group 'todos) 436 :group 'todos)
385(defvar todos-prefix-face 'todos-prefix-string) 437;; (defvar todos-prefix-face 'todos-prefix-string)
386 438
387(defface todos-item-header 439(defface todos-date
388 '((t 440 '((t
389 :inherit font-lock-function-name-face 441 :inherit diary
390 )) 442 ))
391 "Face for Todos item header string." 443 "Face for Todos prefix string."
392 :group 'todos) 444 :group 'todos)
393(defvar todos-item-header-face 'todos-item-header) 445(defvar todos-date-face 'todos-date)
446
447(defface todos-time
448 '((t
449 :inherit diary-time
450 ))
451 "Face for Todos prefix string."
452 :group 'todos)
453(defvar todos-time-face 'todos-time)
454
455(defun todos-date-string-match (lim)
456 "Find Todos date strings for font-locking."
457 (let ((lim (point-max)))
458 (re-search-forward (concat "^\\[?\\(" (todos-date-string) "\\)") lim t)))
459
460(defun todos-time-string-match (lim)
461 "Find Todos time strings for font-locking."
462 (let ((lim (point-max)))
463 (re-search-forward (concat "^\\[?" (todos-date-string)
464 " \\(" (todos-time-string) "\\)") lim t)))
394 465
395(defvar todos-font-lock-keywords 466(defvar todos-font-lock-keywords
396 (list 467 (list
397 (list (concat "^" (regexp-quote todos-prefix)) 0 'todos-prefix-face t) 468 '(todos-date-string-match 1 todos-date-face t)
398 (list (concat "^" (regexp-quote todos-prefix) "\\(.*[0-9]+ [A-Ba-z0-9]*\\]?:\\)") 469 '(todos-time-string-match 1 todos-time-face t))
399 1 'todos-item-header-face t))
400 "Font-locking for Todos mode.") 470 "Font-locking for Todos mode.")
401 471
472(defcustom todos-include-in-diary nil
473 "Non-nil to allow new Todo items to be included in the diary."
474 :type 'boolean
475 :group 'todos)
476
477(defcustom todos-exclusion-start "["
478 "String prepended to item date to block diary inclusion."
479 :type 'string
480 :group 'todos
481 ;; :initialize 'custom-initialize-default
482 ;; :set ; change in whole Todos file
483 )
484
485(defcustom todos-exclusion-end "]"
486 "String appended to item date to match todos-exclusion-start."
487 :type 'string
488 :group 'todos
489 ;; :initialize 'custom-initialize-default
490 ;; :set ; change in whole Todos file
491 )
492
493(defun todos-toggle-item-diary-inclusion ()
494 "" ;FIXME add docstring
495 (interactive)
496 (save-excursion
497 (let ((beg (goto-char (todos-item-start)))
498 (end (save-excursion
499 (or (todos-time-string-match (todos-item-end))
500 (todos-date-string-match (todos-item-end))))))
501 (if (looking-at "\\[") ; FIXME use todos-exclusion-start
502 (progn
503 (replace-match "")
504 (search-forward "]" (1+ end) t) ; FIXME use todos-exclusion-end
505 (replace-match ""))
506 (when end
507 (insert "[") ; FIXME use todos-exclusion-start
508 (goto-char (1+ end))
509 (insert "]")))))) ; FIXME use todos-exclusion-end
510
511(defun todos-toggle-diary-inclusion (arg)
512 "" ;FIXME add docstring
513 (interactive "p")
514 (save-excursion
515 (save-restriction
516 (when (eq arg 2) (widen))
517 (when (or (eq arg 1) (eq arg 2))
518 (goto-char (point-min))
519 (when (eq arg 2)
520 (re-search-forward (concat "^" (regexp-quote todos-category-beg))
521 (point-max) t)
522 (forward-line)
523 (when (looking-at (regexp-quote todos-category-end)) (forward-line)))
524 (while (not (eobp))
525 (todos-toggle-item-diary-inclusion)
526 (todos-forward-item))))))
527
402;; --------------------------------------------------------------------------- 528;; ---------------------------------------------------------------------------
403 529
404;; Set up some helpful context ... 530;; Set up some helpful context ...
@@ -446,24 +572,121 @@ For details see the variable `time-stamp-format'."
446 572
447(defvar todos-tmp-buffer-name " *todo tmp*") 573(defvar todos-tmp-buffer-name " *todo tmp*")
448 574
449(defvar todos-category-sep (make-string 75 ?-) 575;; ;; FIXME: should the following four be defconsts?
450 "Category separator.") 576;; (defvar todos-category-sep (make-string 75 ?-)
577;; "Category separator.")
451 578
452(defvar todos-category-beg " --- " 579(defvar todos-category-beg "--- " ;" --- "
453 "Category start separator to be prepended onto category name.") 580 "Category start separator to be prepended onto category name.")
454 581
455(defvar todos-category-end "--- End" 582;; (defvar todos-category-end "--- End"
456 "Separator after a category.") 583;; "Separator after a category.")
457
458;; (defvar todos-window-configuration nil
459;; "Variable for storing current window configuration in Todos mode.
460 584
461;; Set before leaving Todos mode buffer by todos-display-categories. 585(defvar todos-item-end " :::"
462;; Restored before re-entering Todo mode buffer by todo-kill-buffer 586 "String marking the end of a todo item.
463;; and todo-jump-to-category-noninteractively.") 587In Todos mode it is made invisible with an overlay.")
464 588
465;; --------------------------------------------------------------------------- 589;; ---------------------------------------------------------------------------
466 590
591(defcustom todos-number-prefix nil
592 "Non-nil to show item prefixes as consecutively increasing integers."
593 :type 'boolean
594 :initialize 'custom-initialize-default
595 :set 'todos-reset-prefix
596 :group 'todos)
597
598(defun todos-reset-prefix (symbol value)
599 "Set SYMBOL's value to VALUE, and ." ; FIXME
600 (let ((oldvalue (symbol-value symbol)))
601 (custom-set-default symbol value)
602 (when (not (equal value oldvalue))
603 (save-window-excursion
604 (todos-show)
605 (save-excursion
606 (widen)
607 (goto-char (point-min))
608 (while (not (eobp))
609 (re-search-forward
610 (concat "^" (regexp-quote todos-category-beg)) (point-max) t)
611 (forward-line)
612 (or (eobp)
613 (while (not (looking-at (regexp-quote todos-category-end)))
614 (remove-overlays (1- (point)) (1+ (point)))
615 (forward-line)))))
616 ;; activate the prefix setting (save-restriction does not help)
617 (todos-show)))))
618
619;; FIXME: rename and/or rewrite
620(defun todos-update-numbered-prefix ()
621 "Update consecutive item numbering in the current category."
622 (save-excursion
623 (goto-char (point-min))
624 (while (not (eobp))
625 (remove-overlays (1- (point)) (1+ (point)))
626 (todos-forward-item))
627 (todos-show)))
628
629(defvar todos-item-start-overlays nil "")
630
631(defvar todos-item-end-overlays nil "")
632
633(defun todos-check-overlay (prop)
634 "" ;FIXME add docstring
635 (let ((ovlist (overlays-in (1- (point)) (1+ (point)))))
636 ;; (let ((ovlist (overlays-in (point) (point))))
637 (when ovlist (overlay-get (car ovlist) prop))))
638
639(defun todos-item-overlays ()
640 "" ;FIXME add docstring
641 (let ((prefix (propertize (concat todos-prefix " ") 'face 'todos-prefix-string))
642 (num 1)
643 ;; (paren show-paren-mode)
644 ov-pref ov-end)
645 ;; turn off show-paren-mode to avoid overlay reduplication problem
646 ;; (if paren (show-paren-mode 0))
647 (save-excursion
648 (goto-char (point-min))
649 (while (not (eobp))
650 (if todos-number-prefix
651 (setq prefix (propertize (concat (number-to-string num) " ")
652 'face 'todos-prefix-string)))
653 (unless (todos-check-overlay 'before-string)
654 (or (and (setq ov-pref (pop todos-item-start-overlays))
655 (move-overlay ov-pref (point) (point)))
656 (and (setq ov-pref (make-overlay (point) (point)))
657 (overlay-put ov-pref 'before-string prefix))))
658 (re-search-forward (concat "\\(" (regexp-quote todos-item-end) "\\)\n"))
659 (backward-char)
660 (unless (todos-check-overlay 'invisible)
661 (or (and (setq ov-end (pop
662 todos-item-end-overlays))
663 (move-overlay ov-end (match-beginning 1) (match-end 1)))
664 (and (setq ov-end (make-overlay (match-beginning 1) (match-end 1)))
665 (overlay-put ov-end 'invisible t))))
666 (forward-line)
667 (if todos-number-prefix (setq num (1+ num))))
668 ;; (if paren (show-paren-mode 1))
669 ;; (todos-show-paren-hack)
670 )))
671
672(defun todos-show-paren-hack ()
673 "Purge overlay duplication due to show-paren-mode."
674 (save-excursion
675 (when show-paren-mode
676 (goto-char (point-min))
677 (while (not (eobp))
678 ;; (let ((ovlist (overlays-in (1- (point)) (1+ (point))))
679 (let ((ovlist (overlays-in (point) (point)))
680 ov)
681 (while (> (length ovlist) 1)
682 (setq ov (pop ovlist))
683 (delete-overlay ov)))
684 (forward-line))
685 (if (and (bolp) (eolp))
686 ;; (let ((ovlist (overlays-in (1- (point)) (1+ (point)))))
687 (let ((ovlist (overlays-in (point) (point))))
688 (remove-overlays (1- (point)) (1+ (point))))))))
689
467(defun todos-category-select () 690(defun todos-category-select ()
468 "Make TODO mode display the current category correctly." 691 "Make TODO mode display the current category correctly."
469 (let ((name (nth todos-category-number todos-categories))) 692 (let ((name (nth todos-category-number todos-categories)))
@@ -473,13 +696,17 @@ For details see the variable `time-stamp-format'."
473 (widen) 696 (widen)
474 (goto-char (point-min)) 697 (goto-char (point-min))
475 (search-forward-regexp 698 (search-forward-regexp
476 (concat "^" 699 (concat "\n" ;"^" (regexp-quote todos-category-sep) "\n"
477 (regexp-quote (concat todos-prefix todos-category-beg name)) 700 (regexp-quote (concat todos-category-beg name))
478 "$")) 701 "$"))
479 (let ((begin (1+ (line-end-position)))) 702 (let ((begin (1+ (line-end-position))))
480 (search-forward-regexp (concat "^" todos-category-end)) 703 ;; (search-forward-regexp (concat "^" todos-category-end))
704 (re-search-forward (concat "^" todos-category-beg) (point-max) t)
481 (narrow-to-region begin (line-beginning-position)) 705 (narrow-to-region begin (line-beginning-position))
482 (goto-char (point-min))))) 706 (goto-char (point-min))))
707 (todos-item-overlays)
708 ;; (todos-show-paren-hack)
709 )
483 710
484(defun todos-forward-category () 711(defun todos-forward-category ()
485 "Go forward to TODO list of next category." 712 "Go forward to TODO list of next category."
@@ -495,21 +722,17 @@ For details see the variable `time-stamp-format'."
495 (mod (1- todos-category-number) (length todos-categories))) 722 (mod (1- todos-category-number) (length todos-categories)))
496 (todos-category-select)) 723 (todos-category-select))
497 724
498(defun todos-backward-item () 725(defun todos-backward-item (&optional count)
499 "Select previous entry of TODO list." 726 "Select previous entry of TODO list."
500 (interactive) 727 (interactive "P")
501 (search-backward-regexp (concat "^" (regexp-quote todos-prefix)) nil t) 728 (re-search-backward (concat (regexp-quote todos-item-end) "\n") nil t count)
502 (message "")) 729 (goto-char (todos-item-start)))
503 730
504(defun todos-forward-item (&optional count) 731(defun todos-forward-item (&optional count)
505 "Select COUNT-th next entry of TODO list." 732 "Select COUNT-th next entry of TODO list."
506 (interactive "P") 733 (interactive "P")
507 (if (listp count) (setq count (car count))) 734 (when (todos-check-overlay 'invisible) (goto-char (todos-item-start)))
508 (end-of-line) 735 (re-search-forward (concat (regexp-quote todos-item-end) "\n") nil t count))
509 (search-forward-regexp (concat "^" (regexp-quote todos-prefix))
510 nil 'goto-end count)
511 (beginning-of-line)
512 (message ""))
513 736
514(defun todos-save () 737(defun todos-save ()
515 "Save the TODO list." 738 "Save the TODO list."
@@ -530,20 +753,18 @@ For details see the variable `time-stamp-format'."
530(defun todos-edit-item () 753(defun todos-edit-item ()
531 "Edit current TODO list entry." 754 "Edit current TODO list entry."
532 (interactive) 755 (interactive)
533 (let* ((prefix (concat todos-prefix " " (todos-entry-timestamp-initials))) 756 (let ((item (todos-item-string)))
534 ;; don't allow editing of Todos prefix string
535 ;; FIXME: or should this be automatically updated upon editing?
536 (item (substring (todos-item-string) (length prefix))))
537 ;; FIXME: disable minibuffer-history ??
538 ;; (minibuffer-history))
539 (if (todos-string-multiline-p item) 757 (if (todos-string-multiline-p item)
540 (todos-edit-multiline) 758 (todos-edit-multiline)
541 (let ((new (concat prefix (read-from-minibuffer "Edit: " item)))) 759 (let ((new (read-from-minibuffer "Edit: " item)))
542 (todos-remove-item) 760 (todos-remove-item)
543 (insert new "\n") 761 (insert new todos-item-end "\n")
544 (todos-backward-item) 762 (todos-backward-item)
545 (message ""))))) 763 (if todos-number-prefix
764 (todos-update-numbered-prefix)
765 (todos-item-overlays))))))
546 766
767;; FIXME to work with overlays
547(defun todos-edit-multiline () 768(defun todos-edit-multiline ()
548 "Set up a buffer for editing a multiline TODO list entry." 769 "Set up a buffer for editing a multiline TODO list entry."
549 (interactive) 770 (interactive)
@@ -580,16 +801,9 @@ For details see the variable `time-stamp-format'."
580 (setq todos-categories (cons cat todos-categories)) 801 (setq todos-categories (cons cat todos-categories))
581 (widen) 802 (widen)
582 (goto-char (point-min)) 803 (goto-char (point-min))
583 ;; (if (search-forward "-*- mode: todo; " 17 t) 804 ;; (insert (format "%s\n%s%s\n%s\n" todos-category-sep todos-category-beg cat
584 ;; (kill-line) 805 ;; todos-category-end))
585 ;; (insert "-*- mode: todo; \n") 806 (insert todos-category-beg cat "\n")
586 ;; (forward-char -1))
587 ;; (insert (format "todos-categories: %S; -*-" todos-categories))
588 ;; (forward-char 1)
589 (insert (format "%s%s%s\n%s\n%s %s\n"
590 todos-prefix todos-category-beg cat
591 todos-category-end
592 todos-prefix todos-category-sep))
593 (if (interactive-p) 807 (if (interactive-p)
594 ;; properly display the newly added category 808 ;; properly display the newly added category
595 (progn (setq todos-category-number 0) (todos-show)) 809 (progn (setq todos-category-number 0) (todos-show))
@@ -598,9 +812,10 @@ For details see the variable `time-stamp-format'."
598;;;###autoload 812;;;###autoload
599(defun todos-add-item-non-interactively (new-item category) 813(defun todos-add-item-non-interactively (new-item category)
600 "Insert NEW-ITEM in TODO list as a new entry in CATEGORY." 814 "Insert NEW-ITEM in TODO list as a new entry in CATEGORY."
815 ;; FIXME: really need this? (and in save-excursion?)
601 (save-excursion 816 (save-excursion
602 (todos-show)) 817 (todos-show))
603 (save-excursion 818 ;; (save-excursion
604 (if (string= "" category) 819 (if (string= "" category)
605 (setq category (nth todos-category-number todos-categories))) 820 (setq category (nth todos-category-number todos-categories)))
606 (let ((cat-exists (member category todos-categories))) 821 (let ((cat-exists (member category todos-categories)))
@@ -608,6 +823,7 @@ For details see the variable `time-stamp-format'."
608 (if cat-exists 823 (if cat-exists
609 (- (length todos-categories) (length cat-exists)) 824 (- (length todos-categories) (length cat-exists))
610 (todos-add-category category)))) 825 (todos-add-category category))))
826 ;; FIXME: really need this? (yes for todos-move-item, to show moved to category)
611 (todos-show) 827 (todos-show)
612 (setq todos-previous-line 0) 828 (setq todos-previous-line 0)
613 (let ((top 1) 829 (let ((top 1)
@@ -623,10 +839,9 @@ For details see the variable `time-stamp-format'."
623 ;; goto-line doesn't have the desired behavior in a narrowed buffer. 839 ;; goto-line doesn't have the desired behavior in a narrowed buffer.
624 (goto-char (point-min)) 840 (goto-char (point-min))
625 (forward-line (1- top))) 841 (forward-line (1- top)))
626 (insert new-item "\n") 842 (todos-insert-with-overlays new-item)
627 (todos-backward-item) 843 ;; (todos-show-paren-hack)
628 (todos-save) 844 );)
629 (message "")))
630 845
631(defun todos-rename-category (new) 846(defun todos-rename-category (new)
632 "Rename current Todos category." 847 "Rename current Todos category."
@@ -645,35 +860,46 @@ For details see the variable `time-stamp-format'."
645 (setq todos-categories (append vec nil)) 860 (setq todos-categories (append vec nil))
646 (save-excursion 861 (save-excursion
647 (widen) 862 (widen)
648 (search-backward (concat todos-prefix todos-category-beg)) 863 (re-search-backward (concat ;(regexp-quote todos-category-sep) "\n"
649 (goto-char (match-end 0)) 864 (regexp-quote todos-category-beg) "\\("
650 (when (looking-at (regexp-quote cat)) 865 (regexp-quote cat) "\\)\n") (point-min) t)
651 (replace-match new t)) 866 ;; (goto-char (match-end 0))
867 ;; (when (looking-at (regexp-quote cat))
868 ;; (replace-match new t))
869 (replace-match new t t nil 1)
652 (goto-char (point-min)) 870 (goto-char (point-min))
653 (setq mode-line-buffer-identification 871 (setq mode-line-buffer-identification
654 (concat "Category: " new)))) 872 (concat "Category: " new))))
655;; (concat "Category: " (format "%18s" new))))) 873;; (concat "Category: " (format "%18s" new)))))
656 (todos-category-select)) 874 (todos-category-select))
657 875
658(defun todos-delete-category () 876(defun todos-delete-category (&optional arg)
659 "Delete current Todos category provided it is empty." 877 "Delete current Todos category provided it is empty.
660 (interactive) 878With ARG non-nil delete the category unconditionally,
661 (if (not (eq (point-max) (point-min))) 879i.e. including all existing entries."
880 (interactive "P")
881 (if (and (null arg)
882 (not (eq (point-max) (point-min))))
662 (message "This category is not empty, so it cannot be deleted") 883 (message "This category is not empty, so it cannot be deleted")
663 (let ((cat (nth todos-category-number todos-categories)) beg end) 884 (let ((cat (nth todos-category-number todos-categories)) beg end)
664 (when (y-or-n-p (concat "Permanently remove category '" cat "'? ")) 885 (when (y-or-n-p (concat "Permanently remove category \"" cat
886 "\"" (and arg " and all its entries") "? "))
665 (widen) 887 (widen)
666 (setq beg (re-search-backward 888 (setq beg (re-search-backward
667 (concat "^" (regexp-quote todos-prefix) todos-category-beg cat) 889 (concat "^" ;(regexp-quote todos-category-sep) "\n"
890 (regexp-quote todos-category-beg) cat "\n")
668 (point-min) nil) 891 (point-min) nil)
669 end (1+ (re-search-forward 892 end (progn
670 (concat "^" todos-category-end "\n" 893 (re-search-forward
671 (regexp-quote todos-prefix) " " todos-category-sep) 894 ;; (concat "^" (regexp-quote todos-category-end) "\n")))
672 (point-max) nil))) 895 (concat "\n" (regexp-quote todos-category-beg) ".*\n")
896 (point-max) t)
897 (match-beginning 0)))
898 (remove-overlays beg end)
673 (kill-region beg end) 899 (kill-region beg end)
674 (setq todos-categories (delete cat todos-categories)) 900 (setq todos-categories (delete cat todos-categories))
675 (todos-category-select) 901 (todos-category-select)
676 (message "Deleted category \"%s\"" cat))))) 902 (message "Deleted category %s" cat)))))
677 903
678(defcustom todos-categories-buffer "*TODOS Categories*" 904(defcustom todos-categories-buffer "*TODOS Categories*"
679 "Name of buffer displayed by `todos-display-categories'" 905 "Name of buffer displayed by `todos-display-categories'"
@@ -730,30 +956,36 @@ Click or type RET on a category name to go to it."
730With a prefix argument solicit the category, otherwise use the current 956With a prefix argument solicit the category, otherwise use the current
731category." 957category."
732 (interactive "P") 958 (interactive "P")
733 (save-excursion 959 ;; (save-excursion
734 (if (not (derived-mode-p 'todos-mode)) (todos-show)) 960 (if (not (derived-mode-p 'todos-mode)) (todos-show))
735 (let* ((new-item (concat todos-prefix " " 961 (let* ((new-item (concat (unless todos-include-in-diary "[")
736 (if todos-entry-prefix-function 962 (todos-current-date todos-add-time-string)
737 (funcall todos-entry-prefix-function)) 963 (unless todos-include-in-diary "]") " "
738 (read-from-minibuffer "New TODO entry: "))) 964 (read-from-minibuffer "New TODO entry: ")))
739 (current-category (nth todos-category-number todos-categories)) 965 (current-category (nth todos-category-number todos-categories))
740 (category (if arg (todos-completing-read) current-category))) 966 (category (if arg (todos-completing-read) current-category)))
741 (todos-add-item-non-interactively new-item category)))) 967 (todos-add-item-non-interactively new-item category)));)
742 968
743(defun todos-insert-item-here () 969(defun todos-insert-item-here ()
744 "Insert a new TODO list entry directly above the entry at point. 970 "Insert a new TODO list entry directly above the entry at point.
745If point is on an empty line, insert the entry there." 971If point is on an empty line, insert the entry there."
746 (interactive) 972 (interactive)
747 (if (not (derived-mode-p 'todos-mode)) (todos-show)) 973 (if (not (derived-mode-p 'todos-mode)) (todos-show))
748 (let ((new-item (concat todos-prefix " " 974 (let ((new (concat (unless todos-include-in-diary "[")
749 (if todos-entry-prefix-function 975 (todos-current-date todos-add-time-string)
750 (funcall todos-entry-prefix-function)) 976 (unless todos-include-in-diary "]") " "
751 (read-from-minibuffer "New TODO entry: ")))) 977 (read-from-minibuffer "New TODO entry: "))))
978 (todos-insert-with-overlays new)))
979
980(defun todos-insert-with-overlays (item)
981 "" ;FIXME add docstring
982 (let (ov-start ov-end p1 p2)
752 (unless (and (bolp) (eolp)) (goto-char (todos-item-start))) 983 (unless (and (bolp) (eolp)) (goto-char (todos-item-start)))
753 (insert (concat new-item "\n")) 984 (insert item todos-item-end "\n")
754 (backward-char) 985 (todos-backward-item)
755 ;; put point at start of new entry 986 (if todos-number-prefix
756 (goto-char (todos-item-start)))) 987 (todos-update-numbered-prefix)
988 (todos-item-overlays))))
757 989
758(defun todos-more-important-p (line) 990(defun todos-more-important-p (line)
759 "Ask whether entry is more important than the one at LINE." 991 "Ask whether entry is more important than the one at LINE."
@@ -775,20 +1007,21 @@ If point is on an empty line, insert the entry there."
775 todos-entry "'? ")))) 1007 todos-entry "'? "))))
776 (when todos-answer 1008 (when todos-answer
777 (todos-remove-item) 1009 (todos-remove-item)
778 (todos-backward-item)) 1010 (when (and (bolp) (eolp)) (todos-backward-item))
779 (message "")) 1011 (if todos-number-prefix
1012 (todos-update-numbered-prefix)
1013 (todos-item-overlays))))
780 (error "No TODO list entry to delete"))) 1014 (error "No TODO list entry to delete")))
781 1015
782(defun todos-raise-item () 1016(defun todos-raise-item ()
783 "Raise priority of current entry." 1017 "Raise priority of current entry."
784 (interactive) 1018 (interactive)
785 (if (> (count-lines (point-min) (point)) 0) 1019 (if (and (not (and (bolp) (eolp)))
1020 (> (count-lines (point-min) (point)) 0))
786 (let ((item (todos-item-string))) 1021 (let ((item (todos-item-string)))
787 (todos-remove-item) 1022 (todos-remove-item)
788 (todos-backward-item) 1023 (todos-backward-item)
789 (save-excursion 1024 (todos-insert-with-overlays item))
790 (insert item "\n"))
791 (message ""))
792 (error "No TODO list entry to raise"))) 1025 (error "No TODO list entry to raise")))
793 1026
794(defun todos-lower-item () 1027(defun todos-lower-item ()
@@ -799,9 +1032,7 @@ If point is on an empty line, insert the entry there."
799 (let ((item (todos-item-string))) 1032 (let ((item (todos-item-string)))
800 (todos-remove-item) 1033 (todos-remove-item)
801 (todos-forward-item) 1034 (todos-forward-item)
802 (save-excursion 1035 (todos-insert-with-overlays item))
803 (insert item "\n"))
804 (message ""))
805 (error "No TODO list entry to lower"))) 1036 (error "No TODO list entry to lower")))
806 1037
807(defun todos-move-item () 1038(defun todos-move-item ()
@@ -844,6 +1075,12 @@ it is created and the item becomes the first entry in that category."
844 (todos-backward-item) 1075 (todos-backward-item)
845 (message ""))) 1076 (message "")))
846 1077
1078(defun todos-highlight-item ()
1079 "Highlight the todo item the cursor is on."
1080 (interactive)
1081 (if hl-line-mode ; todos-highlight-item
1082 (hl-line-mode 0)
1083 (hl-line-mode 1)))
847;; --------------------------------------------------------------------------- 1084;; ---------------------------------------------------------------------------
848 1085
849;; Utility functions: 1086;; Utility functions:
@@ -873,34 +1110,36 @@ between each category."
873 (regexp-quote todos-prefix) " " todos-category-sep "\n") 1110 (regexp-quote todos-prefix) " " todos-category-sep "\n")
874 (concat todos-category-end "\n")))) 1111 (concat todos-category-end "\n"))))
875 beg end) 1112 beg end)
876 (todos-show) 1113 (save-excursion ; FIXME: need this?
877 (save-excursion 1114 (todos-show)
878 (save-restriction 1115 (save-restriction
879 (widen) 1116 (save-current-buffer
880 (copy-to-buffer todos-print-buffer-name (point-min) (point-max)) 1117 (widen)
881 (set-buffer todos-print-buffer-name) 1118 (copy-to-buffer todos-print-buffer-name (point-min) (point-max))
882 (goto-char (point-min)) 1119 (set-buffer todos-print-buffer-name)
883 ;; (when (re-search-forward (regexp-quote todos-header) nil t) 1120 (goto-char (point-min))
884 ;; (beginning-of-line 1) 1121 ;; (when (re-search-forward (regexp-quote todos-header) nil t)
885 ;; (delete-region (point) (line-end-position))) 1122 ;; (beginning-of-line 1)
886 (while (re-search-forward ;Find category start 1123 ;; (delete-region (point) (line-end-position)))
887 (regexp-quote (concat todos-prefix todos-category-beg)) 1124 (while (re-search-forward ;Find category start
888 nil t) 1125 (regexp-quote (concat todos-prefix todos-category-beg))
889 (setq beg (+ (line-end-position) 1)) ;Start of first entry. 1126 nil t)
890 (re-search-forward cat-end nil t) 1127 (setq beg (+ (line-end-position) 1)) ;Start of first entry.
891 (setq end (match-beginning 0)) 1128 (re-search-forward cat-end nil t)
892 (replace-match todos-category-break) 1129 (setq end (match-beginning 0))
893 (narrow-to-region beg end) ;In case we have too few entries. 1130 (replace-match todos-category-break)
894 (goto-char (point-min)) 1131 (narrow-to-region beg end) ;In case we have too few entries.
895 (if (zerop nof-priorities) ;Traverse entries. 1132 (goto-char (point-min))
896 (goto-char end) ;All entries 1133 (if (zerop nof-priorities) ;Traverse entries.
897 (todos-forward-item nof-priorities)) 1134 (goto-char end) ;All entries
898 (setq beg (point)) 1135 (todos-forward-item nof-priorities))
899 (delete-region beg end) 1136 (setq beg (point))
900 (widen)) 1137 (delete-region beg end)
901 (and (looking-at " ") (replace-match "")) ;Remove trailing form-feed. 1138 (widen))
902 (goto-char (point-min)) ;Due to display buffer 1139 (and (looking-at " ") (replace-match "")) ;Remove trailing form-feed.
903 )) 1140 (goto-char (point-min)) ;Due to display buffer
1141 ;; FIXME: after todos-edit-multiline widening remains
1142 )))
904 ;; Could have used switch-to-buffer as it has a norecord argument, 1143 ;; Could have used switch-to-buffer as it has a norecord argument,
905 ;; which is nice when we are called from e.g. todos-print. 1144 ;; which is nice when we are called from e.g. todos-print.
906 ;; Else we could have used pop-to-buffer. 1145 ;; Else we could have used pop-to-buffer.
@@ -950,7 +1189,9 @@ Number of entries for each category is given by `todos-print-priorities'."
950 (widen) 1189 (widen)
951 (goto-char (point-max)) 1190 (goto-char (point-max))
952 (while (re-search-backward 1191 (while (re-search-backward
953 (concat "^" (regexp-quote (concat todos-prefix todos-category-beg)) 1192 ;; (concat "^" (regexp-quote (concat todos-prefix todos-category-beg))
1193 (concat "^" ;(regexp-quote todos-category-sep) "\n"
1194 (regexp-quote todos-category-beg)
954 "\\(.*\\)\n") 1195 "\\(.*\\)\n")
955 (point-min) t) 1196 (point-min) t)
956 (push (match-string-no-properties 1) categories))))) 1197 (push (match-string-no-properties 1) categories)))))
@@ -984,23 +1225,44 @@ Number of entries for each category is given by `todos-print-priorities'."
984(defun todos-item-start () 1225(defun todos-item-start ()
985 "Return point at start of current TODO list item." 1226 "Return point at start of current TODO list item."
986 (save-excursion 1227 (save-excursion
987 (beginning-of-line) 1228 (if (re-search-backward (concat (regexp-quote todos-item-end) "\n") nil t)
988 (if (not (looking-at (regexp-quote todos-prefix))) 1229 (forward-line)
989 (search-backward-regexp 1230 (goto-char (point-min)))
990 (concat "^" (regexp-quote todos-prefix)) nil t)) 1231 ;; for widened buffer in todos-toggle-diary-inclusion
1232 ;; (while (looking-at
1233 ;; (concat "^" (regexp-opt (list todos-category-sep todos-category-beg
1234 ;; todos-category-end))))
1235 ;; (forward-line))
991 (point))) 1236 (point)))
992 1237
993(defun todos-item-end () 1238(defun todos-item-end ()
994 "Return point at end of current TODO list item." 1239 "Return point at end of current TODO list item."
995 (save-excursion 1240 (if (todos-check-overlay 'invisible)
996 (end-of-line) 1241 (search-backward todos-item-end)
997 (search-forward-regexp 1242 (when (not (and (bolp) (eobp)))
998 (concat "^" (regexp-quote todos-prefix)) nil 'goto-end) 1243 (save-excursion
999 (1- (line-beginning-position)))) 1244 (re-search-forward (concat "\\(" (regexp-quote todos-item-end) "\\)\n"))
1245 (match-beginning 1)))))
1000 1246
1001(defun todos-remove-item () 1247(defun todos-remove-item ()
1002 "Delete the current entry from the TODO list." 1248 "Delete the current entry from the TODO list."
1003 (delete-region (todos-item-start) (1+ (todos-item-end)))) 1249 (let ((beg (todos-item-start))
1250 (end (save-excursion
1251 (unless (todos-check-overlay 'invisible) (goto-char (todos-item-end)))
1252 (line-end-position)))
1253 ov-start ov-end)
1254 (goto-char (todos-item-start))
1255 ;; (setq ov-start (car (overlays-in (1- (point)) (1+ (point)))))
1256 (setq ov-start (car (overlays-in (point) (point))))
1257 (push ov-start todos-item-start-overlays)
1258 (delete-overlay ov-start)
1259 (goto-char (todos-item-end))
1260 ;; (setq ov-end (car (overlays-in (1- (point)) (1+ (point)))))
1261 ;; FIXME
1262 (setq ov-end (car (overlays-in (point) (point))))
1263 (push ov-end todos-item-end-overlays)
1264 (delete-overlay ov-end)
1265 (delete-region (todos-item-start) (1+ end))))
1004 1266
1005(defun todos-item-string () 1267(defun todos-item-string ()
1006 "Return current TODO list entry as a string." 1268 "Return current TODO list entry as a string."
@@ -1078,25 +1340,28 @@ Number of entries for each category is given by `todos-print-priorities'."
1078 (make-local-variable 'word-wrap) 1340 (make-local-variable 'word-wrap)
1079 (setq word-wrap t) 1341 (setq word-wrap t)
1080 (make-local-variable 'wrap-prefix) 1342 (make-local-variable 'wrap-prefix)
1081 (setq wrap-prefix 1343 (setq wrap-prefix (make-string (+ 5 (length todos-prefix)) 32))
1082 (make-string (length (concat todos-prefix " "
1083 (todos-entry-timestamp-initials))) 32))
1084 (unless (member '(continuation) fringe-indicator-alist) 1344 (unless (member '(continuation) fringe-indicator-alist)
1085 (push '(continuation) fringe-indicator-alist)) 1345 (push '(continuation) fringe-indicator-alist))
1346 (make-local-variable 'hl-line-range-function)
1347 (setq hl-line-range-function
1348 (lambda() (when (todos-item-end)
1349 (cons (todos-item-start) (todos-item-end)))))
1350 ;; (add-hook 'post-command-hook 'todos-show-paren-hack nil t)
1086 (run-mode-hooks 'todos-mode-hook)) 1351 (run-mode-hooks 'todos-mode-hook))
1087 1352
1088(defvar date) 1353;; (defvar date)
1089(defvar entry) 1354;; (defvar entry)
1090 1355
1091;; t-c should be used from diary code, which requires calendar. 1356;; ;; t-c should be used from diary code, which requires calendar.
1092(declare-function calendar-current-date "calendar" nil) 1357;; (declare-function calendar-current-date "calendar" nil)
1093 1358
1094;; Read about this function in the setup instructions above! 1359;; ;; Read about this function in the setup instructions above!
1095;;;###autoload 1360;; ;;;###autoload
1096(defun todos-cp () 1361;; (defun todos-cp ()
1097 "Make a diary entry appear only in the current date's diary." 1362;; "Make a diary entry appear only in the current date's diary."
1098 (if (equal (calendar-current-date) date) 1363;; (if (equal (calendar-current-date) date)
1099 entry)) 1364;; entry))
1100 1365
1101(define-derived-mode todos-edit-mode text-mode "TODO Edit" 1366(define-derived-mode todos-edit-mode text-mode "TODO Edit"
1102 "Major mode for editing items in the TODO list. 1367 "Major mode for editing items in the TODO list.
@@ -1119,7 +1384,10 @@ Number of entries for each category is given by `todos-print-priorities'."
1119 (unless todos-categories 1384 (unless todos-categories
1120 (setq todos-categories (todos-list-categories))) 1385 (setq todos-categories (todos-list-categories)))
1121 ;; (beginning-of-line) 1386 ;; (beginning-of-line)
1122 (todos-category-select)) 1387 (save-excursion
1388 (todos-category-select)
1389 ;; (todos-show-paren-hack)
1390 ))
1123 1391
1124(defun todos-initial-setup () 1392(defun todos-initial-setup ()
1125 "Set up things to work properly in TODO mode." 1393 "Set up things to work properly in TODO mode."