]> code.delx.au - gnu-emacs/blobdiff - lisp/calendar/todo-mode.el
Minor fix to earlier changes today.
[gnu-emacs] / lisp / calendar / todo-mode.el
index 21293466d948d31a682b6bb21e99fd714b2c6eb0..fc167b45b250f74bd743eeda78f0311546c923c2 100644 (file)
@@ -4,7 +4,7 @@
 
 ;; Author: Oliver.Seidel@cl.cam.ac.uk (was valid on Aug 2, 1997)
 ;; Created: 2 Aug 1997
-;; Version: $Id: todo-mode.el,v 1.23 1997/10/24 17:30:54 os10000 Exp os10000 $
+;; Version: $Id: todo-mode.el,v 1.33 1997/12/04 17:45:22 os10000 Exp os10000 $
 ;; Keywords: Categorised TODO list editor, todo-mode
 
 ;; This file is part of GNU Emacs.
 
 ;;; Commentary:
 
+;;  Mode Description
+;;
+;;     TODO is a major mode for EMACS which offers functionality to
+;;     treat most lines in one buffer as a list of items one has to
+;;     do.  There are facilities to add new items, which are
+;;     categorised, to edit or even delete items from the buffer.
+;;     The buffer contents are currently compatible with the diary,
+;;     so that the list of todo-items will show up in the FANCY diary
+;;     mode.
+;;
+;;     Notice: Besides the major mode, this file also exports the
+;;     function `todo-show' which will change to the one specific
+;;     TODO file that has been specified in the todo-file-do
+;;     variable.  If this file does not conform to the TODO mode
+;;     conventions, the todo-show function will add the appropriate
+;;     header and footer.  I don't anticipate this to cause much
+;;     grief, but be warned, in case you attempt to read a plain text
+;;     file.
+;;
 ;;  Preface, Quickstart Installation
 ;;
 ;;      To get this to work, make emacs execute the line
 ;;      entered by visiting the TODO file, and later by switching to
 ;;      its buffer).
 ;;
+;;      If you are an advanced user of this package, please consult
+;;      the whole source code for autoloads, because there are several
+;;      extensions that are not explicitly listed in the above quick
+;;      installation.
+;;
 ;;  Version
 ;;
 ;;      Which version of todo-mode.el does this documentation refer to?
 ;;
-;;      $Id: todo-mode.el,v 1.23 1997/10/24 17:30:54 os10000 Exp os10000 $
+;;      $Id: todo-mode.el,v 1.33 1997/12/04 17:45:22 os10000 Exp os10000 $
 ;;
 ;;  Pre-Requisites
 ;;
 ;;          time-stamp
 ;;          easymenu
 ;;
-;;  Mode Description
-;;
-;;     TODO is a major mode for EMACS which offers functionality to
-;;     treat most lines in one buffer as a list of items one has to
-;;     do.  There are facilities to add new items, which are
-;;     categorised, to edit or even delete items from the buffer.
-;;     The buffer contents are currently compatible with the diary,
-;;     so that the list of todo-items will show up in the FANCY diary
-;;     mode.
-;;
-;;     Notice: Besides the major mode, this file also exports the
-;;     function "todo-show" which will change to the one specific
-;;     TODO file that has been specified in the todo-file-do
-;;     variable.  If this file does not conform to the TODO mode
-;;     conventions, the todo-show function will add the appropriate
-;;     header and footer.  I don't anticipate this to cause much
-;;     grief, but be warned, in case you attempt to read a plain text
-;;     file.
-;;
 ;;  Operation
 ;;
 ;;     You will have the following facilities available:
 ;;          d  to file the current entry, including a
 ;;                                 comment and timestamp
 ;;          e  to edit the current entry
+;;          E  to edit a multi-line entry
 ;;          f  to file the current entry, including a
 ;;                                 comment and timestamp
-;;          i  to insert a new entry
+;;          i  to insert a new entry, with prefix, omit category
+;;          I  to insert a new entry at current cursor position
 ;;         j  jump to category
 ;;          k  to kill the current entry
 ;;          l  to lower the current entry's priority
 ;;          q  to save the list and exit the buffer
 ;;          r  to raise the current entry's priority
 ;;          s  to save the list
+;;          S  to save the list of top priorities
 ;;         t  show top priority items for each category
 ;;
 ;;     When you add a new entry, you are asked for the text and then
 ;;     as the value of `todo-prefix'.  Please note that this may slow
 ;;     down the processing of your diary file some.
 ;;
+;;      Carsten Dominik <dominik@strw.LeidenUniv.nl> suggested that
+;;
+;;          "&%%(todo-cp)"
+;;
+;;      might be nicer and to that effect a function has been declared
+;;      further down in the code.  You may wish to auto-load this.
+;;
+;;      Carsten also writes that that *changing* the prefix after the
+;;      todo list is already established is not as simple as changing
+;;      the variable - the todo files have to be changed by hand.
+;;
 ;;  Variable todo-file-do
 ;;
 ;;     This variable is fairly self-explanatory.  You have to store
 ;;     even blend in with the EMACS diary package.  So anyway, this
 ;;     variable holds the name of the file for the filed todo-items.
 ;;
+;;  Variable todo-file-top
+;;
+;;      File storing the top priorities of your TODO list when
+;;      todo-save-top-priorities is non-nil.  Nice to include in your
+;;      diary instead of the complete TODO list.
+;;
 ;;  Variable todo-mode-hook
 ;;
 ;;     Just like other modes, too, this mode offers to call your
 ;;             is the window size at which it will stop.  If you set the
 ;;             threshhold to zero, the upper and lower bound will coincide at
 ;;             the end of the loop and you will insert your item just before
-;;             that point.  If you set the threshhold to i.e. 8, it will stop
+;;             that point.  If you set the threshhold to, e.g. 8, it will stop
 ;;             as soon as the window size drops below that amount and will
 ;;             insert the item in the approximate centre of that window.  I
 ;;             got the idea for this feature after reading a very helpful
 ;;      These originally were my ideas, but now also include all the
 ;;      suggestions that I included before forgetting them:
 ;;
-;;      o   Automatic save of top-priorities to file, for inclusion in
-;;          .diary, at save of .todo-do, ref. automatic save of .bbdb
-;;          in gnus
 ;;      o   Fancy fonts for todo/top-priority buffer
 ;;      o   Remove todo-prefix option in todo-top-priorities
 ;;      o   Rename category
 ;;; Change Log:
 
 ;; $Log: todo-mode.el,v $
+;; Revision 1.33  1997/12/04 17:45:22  os10000
+;; Another patch by Michael Cook to fix annotation.
+;;
+;; Revision 1.32  1997/12/03  12:18:20  os10000
+;; Added category patch by Michael R Cook <mcook@cognex.com>.
+;;
+;; Revision 1.31  1997/10/28  22:16:24  os10000
+;; Three insertion options:
+;; i without prefix: ask for category, do binary insertion
+;; i with prefix: do binary insertion in current category
+;; uppercase I: insert directly under cursor
+;;
+;; Revision 1.30  1997/10/28 21:59:48  os10000
+;; Improved documentation, fixed insertion with prefix.
+;;
+;; Revision 1.29  1997/10/28 21:47:12  os10000
+;; Implemented "insert-under-cursor" as suggested by
+;; Kai Grossjohann <grossjohann@ls6.cs.uni-dortmund.de>.
+;;
+;; Revision 1.28  1997/10/28 21:37:05  os10000
+;; Incorporated simplifying suggestions from
+;; Carsten Dominik <dominik@strw.LeidenUniv.nl>.
+;;
+;; Revision 1.27  1997/10/28 21:26:55  os10000
+;; Patch from Paul Stodghill <stodghil@CS.Cornell.EDU>:
+;; The patch below fixes todo-insert-item so that it will
+;; insert the item in place, instead of at the top of the
+;; buffer, when invoked with a prefix argument.
+;;
+;; Revision 1.26  1997/10/28 21:14:51  os10000
+;; Improvements sent in by Dave Love <d.love@dl.ac.uk>:
+;; todo-mode.el: Doc fixes.  Customization.
+;; (todo-add-item-non-interactively): New arg -- don't dynamically bind ARG.
+;; (todo-insert-item): Use it.
+;;
+;; Revision 1.25  1997/10/28 20:03:27  os10000
+;; Harald Backer <harald.backer@fou.telenor.no> sent the following:
+;; Added `todo-save-top-priorities' and option to automatically save top
+;; priorities file when saving todo-file.  Changed some default values.
+;; Bug fixes.
+;;
+;; Revision 1.24  1997/10/28 19:41:53  os10000
+;; Added fix from Frank Ridderbusch <ridderbusch.pad@sni.de>,
+;; an apostrophe was missing.
+;;
 ;; Revision 1.23  1997/10/24  17:30:54  os10000
 ;; Added three suggestions from Carsten
 ;; Dominik <dominik@strw.LeidenUniv.nl>:
 
 ;;; Code:
 
+(eval-and-compile                       ; Removable for installation in
+                                        ; Emacs 20.
+  (condition-case ()
+      (require 'custom)
+    (error nil))
+  (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
+      nil ;; We've got what we needed
+    ;; We have the old custom-library, hack around it!
+    (defmacro defgroup (&rest args)
+      nil)
+    (defmacro defcustom (var value doc &rest args) 
+      (` (defvar (, var) (, value) (, doc))))))
+
 ;; User-configurable variables:
 
-(defvar todo-prefix     "*/*"           "*TODO mode prefix for entries.")
-(defvar todo-file-do    "~/.todo-do"    "*TODO mode list file.")
-(defvar todo-file-done  "~/.todo-done"  "*TODO mode archive file.")
-(defvar todo-mode-hook  nil             "*TODO mode hooks.")
-(defvar todo-edit-mode-hook nil         "*TODO Edit mode hooks.")
-(defvar todo-insert-threshold 0         "*TODO mode insertion accuracy.")
+(defgroup todo nil
+  "Maintain a list of todo items."
+  :group 'calendar)
+
+(defcustom todo-prefix     "*/*"
+  "*TODO mode prefix for entries.
+
+This is useful in conjunction with `calendar' and `diary' if you use
+
+#include \"~/.todo-do\"
+
+in your diary file to include your todo list file as part of your
+diary.  With the default value \"*/*\" the diary displays each entry
+every day and it may also be marked on every day of the calendar.
+Using \"&%%(equal (calendar-current-date) date)\" instead will only
+show and mark todo entreis for today, but may slow down processing of
+the diary file somewhat."
+  :type 'string
+  :group 'todo)
+(defcustom todo-file-do    "~/.todo-do"
+  "*TODO mode list file."
+  :type 'file
+  :group 'todo)
+(defcustom todo-file-done  "~/.todo-done"
+  "*TODO mode archive file."
+  :type 'file
+  :group 'todo)
+(defcustom todo-mode-hook  nil
+  "*TODO mode hooks."
+  :type 'hook
+  :group 'todo)
+(defcustom todo-edit-mode-hook nil
+  "*TODO Edit mode hooks."
+  :type 'hook
+  :group 'todo)
+(defcustom todo-insert-threshold 0
+  "*TODO mode insertion accuracy.
+
+If you have 8 items in your TODO list, then you may get asked 4
+questions by the binary insertion algorithm.  However, you may not
+really have a need for such accurate priorities amongst your TODO
+items.  If you now think about the binary insertion halfing the size
+of the window each time, then the threshhold is the window size at
+which it will stop.  If you set the threshhold to zero, the upper and
+lower bound will coincide at the end of the loop and you will insert
+your item just before that point.  If you set the threshhold to,
+e.g. 8, it will stop as soon as the window size drops below that
+amount and will insert the item in the approximate centre of that
+window."
+  :type 'integer
+  :group 'todo)
 (defvar todo-edit-buffer " *TODO Edit*" "TODO Edit buffer name.")
-
-(defvar todo-print-function 'ps-print-buffer-with-faces
-  "*Function to print the current buffer.")
-(defvar todo-show-priorities 1
-  "*Default number of priorities to show by
-  \\[todo-top-priorities].  0 means show all entries.")
-(defvar todo-print-priorities 0
-  "*Default number of priorities to print by
-  \\[todo-print].  0 means print all entries.")
-(defvar todo-remove-separator t
-  "*Non-nil removes category separators in
- \\[todo-top-priorities] and \\[todo-print].")
-
+(defcustom todo-file-top "~/.todo-top"
+  "*TODO mode top priorities file.
+
+Not in TODO format, but diary compatible.
+Automatically generated when `todo-save-top-priorities' is non-nil."
+  :type 'string
+  :group 'todo)
+
+(defcustom todo-print-function 'ps-print-buffer-with-faces
+  "*Function to print the current buffer."
+  :type 'symbol
+  :group 'todo)
+(defcustom todo-show-priorities 1
+  "*Default number of priorities to show by \\[todo-top-priorities].
+0 means show all entries."
+  :type 'integer
+  :group 'todo)
+(defcustom todo-print-priorities 0
+  "*Default number of priorities to print by \\[todo-print].
+0 means print all entries."
+  :type 'integer
+  :group 'todo)
+(defcustom todo-remove-separator t
+  "*Non-nil to remove category separators in\
+\\[todo-top-priorities] and \\[todo-print]."
+  :type 'boolean
+  :group 'todo)
+(defcustom todo-save-top-priorities-too t
+  "*Non-nil makes todo-save automatically save top-priorities in
+`todo-file-top'."
+  :type 'boolean
+  :group 'todo)
 
 ;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de>
 ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p".
 ;;
-(defvar todo-time-string-format
+(defcustom todo-time-string-format
   "%:y-%02m-%02d %02H:%02M"
-  "TODO mode time string format for done entries.
-For details see the variable `time-stamp-format'.")
-
-(defvar todo-entry-prefix-function 'todo-entry-timestamp-initials
-  "*Function producing text to insert at start of todo entry.")
-(defvar todo-initials (or (getenv "INITIALS") (user-login-name))
-  "*Initials of todo item author.")
+  "*TODO mode time string format for done entries.
+For details see the variable `time-stamp-format'."
+  :type 'string
+  :group 'todo)
+
+(defcustom todo-entry-prefix-function 'todo-entry-timestamp-initials
+  "*Function producing text to insert at start of todo entry."
+  :type 'symbol
+  :group 'todo)
+(defcustom todo-initials (or (getenv "INITIALS") (user-login-name))
+  "*Initials of todo item author."
+  :type 'string
+  :group 'todo)
 
 (defun todo-entry-timestamp-initials ()
+  "Prepend timestamp and your initials to the head of a TODO entry."
   (let ((time-stamp-format todo-time-string-format))
     (concat (time-stamp-string) " " todo-initials ": ")))
 
@@ -455,13 +606,15 @@ For details see the variable `time-stamp-format'.")
 ;; Set up some helpful context ...
 
 (defvar todo-categories         nil     "TODO categories.")
-(defvar todo-cats               nil     "Old variable for holding the
-TODO categories. Use `todo-categories' instead.")
+(defvar todo-cats               nil
+  "Old variable for holding the TODO categories.
+Use `todo-categories' instead.")
 (defvar todo-previous-line      0       "Previous line that I asked about.")
 (defvar todo-previous-answer    0       "Previous answer that I got.")
 (defvar todo-mode-map           nil     "TODO mode keymap.")
 (defvar todo-category-number    0       "TODO category number.")
 
+(defvar todo-tmp-buffer-name "*Tmp*")
 
 (defvar todo-category-sep (make-string 75 ?-)
   "Category separator.")
@@ -482,11 +635,12 @@ TODO categories. Use `todo-categories' instead.")
     (suppress-keymap map t)
     (define-key map "+" 'todo-forward-category)
     (define-key map "-" 'todo-backward-category)
+    (define-key map "d" 'todo-file-item) ;done/delete
     (define-key map "e" 'todo-edit-item)
     (define-key map "E" 'todo-edit-multiline)
-    (define-key map "d" 'todo-file-item) ;done/delete
     (define-key map "f" 'todo-file-item)
     (define-key map "i" 'todo-insert-item)
+    (define-key map "I" 'todo-insert-item-here)
     (define-key map "j" 'todo-jump-to-category)
     (define-key map "k" 'todo-delete-item)
     (define-key map "l" 'todo-lower-item)
@@ -496,6 +650,7 @@ TODO categories. Use `todo-categories' instead.")
     (define-key map "q" 'todo-quit)
     (define-key map "r" 'todo-raise-item)
     (define-key map "s" 'todo-save)
+    (define-key map "S" 'todo-save-top-priorities)
     (define-key map "t" 'todo-top-priorities)
     (setq todo-mode-map map)))
 
@@ -503,7 +658,8 @@ TODO categories. Use `todo-categories' instead.")
   "Make TODO mode display the current category correctly."
   (let ((name (nth todo-category-number todo-categories)))
     (setq mode-line-buffer-identification
-          (concat "Category: " name))
+;;          (concat "Category: " name))
+          (concat "Category: " (format "%18s" name)))
     (widen)
     (goto-char (point-min))
     (search-forward-regexp
@@ -537,7 +693,7 @@ TODO categories. Use `todo-categories' instead.")
 (defalias 'todo-cmd-prev 'todo-backward-item)
 
 (defun todo-forward-item (&optional count)
-  "Select Nth next entry of TODO list."
+  "Select COUNT-th next entry of TODO list."
   (interactive "P")
   (if (listp count) (setq count (car count)))
   (end-of-line)
@@ -549,13 +705,15 @@ TODO categories. Use `todo-categories' instead.")
 
 (defun todo-save () "Save the TODO list."
   (interactive)
-  (save-buffer))
+  (save-buffer)
+  (if todo-save-top-priorities-too (todo-save-top-priorities))
+  )
 (defalias 'todo-cmd-save 'todo-save)
 
 (defun todo-quit () "Done with TODO list for now."
   (interactive)
   (widen)
-  (save-buffer)
+  (todo-save)
   (message "")
   (bury-buffer))
 (defalias 'todo-cmd-done 'todo-quit)
@@ -584,8 +742,9 @@ TODO categories. Use `todo-categories' instead.")
     (narrow-to-region (todo-item-start) (todo-item-end))))
 
 ;;;### autoload
-(defun todo-add-category (cat) "Add a new category to the TODO list."
-  (interactive)
+(defun todo-add-category (cat) 
+  "Add new category CAT to the TODO list."
+  (interactive "sCategory: ")
   (save-window-excursion
     (setq todo-categories (cons cat todo-categories))
     (find-file todo-file-do)
@@ -608,9 +767,10 @@ TODO categories. Use `todo-categories' instead.")
 
 ;;;### autoload
 (defun todo-add-item-non-interactively (new-item category)
-  "Insert new TODO list entry."
+  "Insert NEW-ITEM in TODO list as a new entry in CATEGORY."
+  (save-excursion
+    (todo-show))
   (save-excursion
-    (todo-show)
     (if (string= "" category)
         (setq category (nth todo-category-number todo-categories)))
     (let ((cat-exists (member category todo-categories)))
@@ -618,53 +778,66 @@ TODO categories. Use `todo-categories' instead.")
             (if cat-exists
                 (- (length todo-categories) (length cat-exists))
               (todo-add-category category))))
-    (if (not ARG)
-       (progn
-         (todo-show)
-         (setq todo-previous-line 0)
-         (let ((top 1)
-               (bottom (1+ (count-lines (point-min) (point-max)))))
-           (while (> (- bottom top) todo-insert-threshold)
-             (let* ((current (/ (+ top bottom) 2))
-                    (answer (if (< current bottom)
-                                (todo-more-important-p current) nil)))
-               (if answer
-                   (setq bottom current)
-                 (setq top (1+ current)))))
-           (setq top (/ (+ top bottom) 2))
-           ;; goto-line doesn't have the desired behavior in a narrowed buffer
-           (goto-char (point-min))
-           (forward-line (1- top))))
-      (beginning-of-line))
+    (todo-show)
+    (setq todo-previous-line 0)
+    (let ((top 1)
+         (bottom (1+ (count-lines (point-min) (point-max)))))
+      (while (> (- bottom top) todo-insert-threshold)
+       (let* ((current (/ (+ top bottom) 2))
+              (answer (if (< current bottom)
+                          (todo-more-important-p current) nil)))
+         (if answer
+             (setq bottom current)
+           (setq top (1+ current)))))
+      (setq top (/ (+ top bottom) 2))
+      ;; goto-line doesn't have the desired behavior in a narrowed buffer
+      (goto-char (point-min))
+      (forward-line (1- top)))
     (insert new-item "\n")
     (todo-backward-item)
-    (save-buffer)
+    (todo-save)
     (message "")))
 
 ;;;### autoload
 (defun todo-insert-item (ARG)
-  "Insert new TODO list entry."
+  "Insert new TODO list entry.
+With a prefix argument solicit the category, otherwise use the current
+category."
   (interactive "P")
-  (todo-show)
-  (let* ((new-item (concat todo-prefix " "
-                          (read-from-minibuffer
-                            "New TODO entry: "
-                                 (if todo-entry-prefix-function
-                                     (funcall todo-entry-prefix-function)))))
-         (categories todo-categories)
-         (history (cons 'categories (1+ todo-category-number)))
-        (current-category (nth todo-category-number todo-categories))
-        (category 
-         (if ARG
-             current-category
+  (save-excursion
+    (if (not (string-equal mode-name "TODO")) (todo-show))
+    (let* ((new-item (concat todo-prefix " "
+                            (read-from-minibuffer
+                             "New TODO entry: "
+                             (if todo-entry-prefix-function
+                                 (funcall todo-entry-prefix-function)))))
+          (categories todo-categories)
+          (history (cons 'categories (1+ todo-category-number)))
+          (current-category (nth todo-category-number todo-categories))
+          (category 
+           (if ARG
+               current-category
              (completing-read 
-                    (concat "Category ["
-                            current-category "]: ")
-                    (todo-category-alist) nil nil nil history))))
-    (todo-add-item-non-interactively new-item category)))
+              (concat "Category ["
+                      current-category "]: ")
+              (todo-category-alist) nil nil nil history))))
+      (todo-add-item-non-interactively new-item category))))
 
 (defalias 'todo-cmd-inst 'todo-insert-item)
 
+;;;### autoload
+(defun todo-insert-item-here ()
+  "Insert new TODO list entry under the cursor."
+  (interactive "")
+  (save-excursion
+    (if (not (string-equal mode-name "TODO")) (todo-show))
+    (let* ((new-item (concat todo-prefix " "
+                            (read-from-minibuffer
+                             "New TODO entry: "
+                             (if todo-entry-prefix-function
+                                 (funcall todo-entry-prefix-function))))))
+      (insert (concat new-item "\n")))))
+
 (defun todo-more-important-p (line)
   "Ask whether entry is more important than the one at LINE."
   (if (not (equal todo-previous-line line))
@@ -717,33 +890,35 @@ TODO categories. Use `todo-categories' instead.")
     (error "No TODO list entry to lower")))
 (defalias 'todo-cmd-lowr 'todo-lower-item)
 
-(defun todo-file-item () "File the current TODO list entry away."
-  (interactive)
-  (if (> (count-lines (point-min) (point-max)) 0)
-      (let ((comment (read-from-minibuffer "Comment: "))
-            (time-stamp-format todo-time-string-format))
-        (if (> (length comment) 0)
-            (progn
-              (goto-char (todo-item-end))
-              (insert
-              (if (save-excursion (beginning-of-line)
-                                  (looking-at (regexp-quote todo-prefix)))
-                  " "
-                "\n\t")
-              "(" (nth todo-category-number todo-categories) ": "
-              comment ")\n")))
-        (goto-char (todo-item-start))
-        (let ((temp-point (point)))
-          (if (looking-at (regexp-quote todo-prefix))
-              (replace-match (time-stamp-string))
-           ;; Standard prefix -> timestamp
-            ;; Else prefix non-standard item start with timestamp
-            (insert (time-stamp-string)))
-          (append-to-file temp-point (todo-item-end) todo-file-done)
-          (delete-region temp-point (1+ (todo-item-end))))
-        (todo-backward-item)
-        (message ""))
-    (error "No TODO list entry to file away")))
+(defun todo-file-item (&optional comment)
+  "File the current TODO list entry away,
+annotated with an optional COMMENT."
+  (interactive "sComment: ")
+  (or (> (count-lines (point-min) (point-max)) 0)
+      (error "No TODO list entry to file away"))
+  (let ((time-stamp-format todo-time-string-format))
+    (if (and comment (> (length comment) 0))
+       (progn
+         (goto-char (todo-item-end))
+         (insert
+          (if (save-excursion (beginning-of-line)
+                              (looking-at (regexp-quote todo-prefix)))
+              " "
+            "\n\t")
+          "(" comment ")")))
+    (goto-char (todo-item-end))
+    (insert " [" (nth todo-category-number todo-categories) "]")
+    (goto-char (todo-item-start))
+    (let ((temp-point (point)))
+      (if (looking-at (regexp-quote todo-prefix))
+         (replace-match (time-stamp-string))
+       ;; Standard prefix -> timestamp
+       ;; Else prefix non-standard item start with timestamp
+       (insert (time-stamp-string)))
+      (append-to-file temp-point (1+ (todo-item-end)) todo-file-done)
+      (delete-region temp-point (1+ (todo-item-end))))
+    (todo-backward-item)
+    (message "")))
 
 ;; ---------------------------------------------------------------------------
 
@@ -800,17 +975,33 @@ between each category."
           (setq beg (point))
           (delete-region beg end)
           (widen))
+        (and (looking-at "\f") (replace-match "")) ;Remove trailing form-feed.
         (goto-char (point-min))         ;Due to display buffer
         ))
     ;; Could have used switch-to-buffer as it has a norecord argument,
     ;; which is nice when we are called from e.g. todo-print.
-    ;; Else we could have used pop-to-buffer should be used.
+    ;; Else we could have used pop-to-buffer.
     (display-buffer todo-print-buffer-name)
-    ;;(switch-to-buffer todo-print-buffer-name t)
     (message "Type C-x 1 to remove %s window.  M-C-v to scroll the help."
              todo-print-buffer-name)
     ))
 
+;;;###autoload
+(defun todo-save-top-priorities (&optional nof-priorities)
+  "Save top priorities for each category in `todo-file-top'.
+
+Number of entries for each category is given by NOF-PRIORITIES which
+defaults to `todo-show-priorities'."
+  (interactive "P")
+  (save-window-excursion
+    (save-excursion
+      (save-restriction
+        (todo-top-priorities nof-priorities)
+        (set-buffer todo-tmp-buffer-name)
+        (write-file todo-file-top)
+        (kill-this-buffer)
+        ))))
+
 ;;;###autoload
 (defun todo-print (&optional category-pr-page)
   "Print todo summary using \\\[todo-print-function].
@@ -820,18 +1011,20 @@ between each category.
 Number of entries for each category is given by
 \'todo-print-priorities\'."
   (interactive "P")
+  (if todo-print-function
+      (progn
   (save-window-excursion
   (save-excursion
     (save-restriction
       (todo-top-priorities todo-print-priorities
                                     category-pr-page)
-      (if todo-print-function
-          (progn
-            (funcall todo-print-function)
+              (set-buffer todo-tmp-buffer-name)
+              (and (funcall todo-print-function)
+                   (kill-this-buffer))
             (message "Todo printing done."))
-            (message "")                ; To get rid of message from
-                                        ; todo-top-priorities.
-            )))))
+            )))
+    (message "todo-print-function undefinded")
+    ))
 
 (defun todo-jump-to-category ()
   "Jump to a category.  Default is previous category."
@@ -888,11 +1081,11 @@ Number of entries for each category is given by
   (length (split-string string "\n")))
 
 (defun todo-string-multiline-p (string)
-  "Returns non-nil if STRING spans several lines"
+  "Return non-nil if STRING spans several lines."
   (> (todo-string-count-lines string) 1))
 
 (defun todo-category-alist ()
-  "Generate an alist fro use in `completing-read' from `todo-categories'"
+  "Generate an alist for use in `completing-read' from `todo-categories'."
   (mapcar (lambda (cat) (cons cat nil))
           todo-categories))
 
@@ -946,6 +1139,7 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
                     ["Edit item"            todo-edit-item t]
                     ["File item"            todo-file-item t]
                     ["Insert new item"      todo-insert-item t]
+                    ["Insert item here"     todo-insert-item-here t]
                     ["Kill item"            todo-delete-item t]
                     "---"
                     ["Lower item priority"  todo-lower-item t]
@@ -955,6 +1149,7 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
                     ["Previous item"        todo-backward-item t]
                     "---"
                     ["Save"                 todo-save t]
+                    ["Save Top Priorities"  todo-save-top-priorities t]
                     "---"
                     ["Quit"                 todo-quit t]
                     ))
@@ -969,6 +1164,14 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
   (easy-menu-add todo-menu)
   (run-hooks 'todo-mode-hook))
 
+;; Read about this function in the setup instructions above!
+;;;### autoload
+(defun todo-cp ()
+  "Make a diary entry appear only in the current date's diary"
+  (if (equal (calendar-current-date) date)
+      entry
+    nil))
+
 (defun todo-edit-mode ()
   "Major mode for editing items in the TODO list\n\n\\{todo-edit-mode-map}"
   (text-mode)