]> code.delx.au - gnu-emacs/blobdiff - lisp/calendar/todo-mode.el
(calendar-mode-map, calendar-mouse-3-map): Refer to
[gnu-emacs] / lisp / calendar / todo-mode.el
index bf1ff1a4d4bcfa80d8d78c36c3f4a29430e5c045..6f96ec1cdb224385d2b7cebabcb308516bbe6d4e 100644 (file)
@@ -1,11 +1,12 @@
-;; todo-mode.el -- Major mode for editing TODO list files
+;;; todo-mode.el --- major mode for editing TODO list files
 
-;; Copyright (C) 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004, 2005, 2006
+;;   Free Software Foundation, Inc.
 
-;; Author: Oliver.Seidel@cl.cam.ac.uk (was valid on Aug 2, 1997)
+;; Author: Oliver Seidel <os10000@seidel-space.de>
+;;   [Not clear the above works, July 2000]
 ;; Created: 2 Aug 1997
-;; Version: $Id: todo-mode.el,v 1.31 1997/10/28 22:16:24 os10000 Exp os10000 $
-;; Keywords: Categorised TODO list editor, todo-mode
+;; Keywords: calendar, todo
 
 ;; This file is part of GNU Emacs.
 
@@ -21,8 +22,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;; ---------------------------------------------------------------------------
 
 ;;      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.31 1997/10/28 22:16:24 os10000 Exp os10000 $
-;;
 ;;  Pre-Requisites
 ;;
 ;;      This package will require the following packages to be
 ;;      o   The optional COUNT variable of todo-forward-item should be
 ;;          applied to the other functions performing similar tasks
 ;;      o   Modularization could be done for repeaded elements of
-;;          the code, like the completing-read lines of code.  
+;;          the code, like the completing-read lines of code.
 ;;     o   license / version function
 ;;     o   export to diary file
 ;;     o   todo-report-bug
 ;;
 ;;     Oliver Seidel
 ;;     (Lessingstr. 8, 65760 Eschborn, Federal Republic of Germany)
-;;
-
-;; ---------------------------------------------------------------------------
-
-;;; Change Log:
-
-;; $Log: todo-mode.el,v $
-;; 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>:
-;;
-;; - recommend autoloading instead of require
-;; - inserting from different buffer didn't work
-;;   (now fixed -- I pray)
-;; - provided public entry point to insert items
-;;   from normal lisp code
-;;
-;; Revision 1.22  1997/10/24  16:53:20  os10000
-;; Paul Stodghill <stodghil@CS.Cornell.EDU> writes:
-;;
-;; When invoked with a prefix, todo-insert-item
-;; should not prompt for a category.  (He adds:
-;; At least that's what I think.)
-;;
-;; Revision 1.21  1997/10/24  16:51:02  os10000
-;; Rafael Laboissiere <rafael@icp.inpg.fr> writes:
-;;
-;; I was just annoyed with the fact that there is no way
-;; to dynamically control the insertion accuracy.  I mean:
-;; the variable `todo-insert-threshold' does the job, but
-;; it is not very handy if one wants to mix the two
-;; behaviors (bisection and "insert right here under the
-;; cursor").
-;;
-;; Therefore I did a quick hack in the function
-;; `todo-insert-item'.  Now by giving a prefix argument to
-;; the insert command (i.e. by typing "C-u i"), entries
-;; are inserted exactly at the line where the cursor is.
-;; It would be better to give the value of
-;; `todo-insert-threshold' as a numeric argument of
-;; `todo-insert-item' (like "M-8 i"), but it's too late
-;; now for continuing to hack.
-;;
-;; Revision 1.20  1997/10/17  15:41:57  os10000
-;; Thanks to Harald Backer <harald.backer@fou.telenor.no>, we now have
-;; the following facilities available:
-;;
-;; Added todo-print, todo-top-priorities and todo-jump with matching
-;; variables; Parameterized todo-header, todo-category-beg,
-;; todo-category-end and todo-category-sep; Added autoload comments;
-;; todo-category-select: Modified regexp to make category names unique;
-;; todo-forward-item: Added optional COUNT vaiable; todo-insert-item:
-;; Rewrote completing read entry.
-;;
-;; Also, check out the extended list of things left to be done to this
-;; package at the end of the documentation!
-;;
-;; Revision 1.19  1997/10/16  21:21:16  os10000
-;; Jari Aalto <jari.aalto@poboxes.com> writes:
-;;
-;;     I just downloaded your package and after reading the docs I
-;;     decided to do some reformatting.  Hope you don't mind.  Now
-;;     they are in such a format that the html page can be
-;;     automatically generated from the source file.  As an example, I
-;;     generated the attached page using the following command:
-;;     ripdoc.pls < todo-mode.el | t2html.pls -a "Oliver.Seidel" -e \
-;;     Oliver.Seidel@cl.cam.ac.uk -simple -base
-;;
-;; And of course I appreciate it.  Jari's stuff can be found at:
-;; ftp://cs.uta.fi/pub/ssjaaa/, while I'm making the rev 1.18 page
-;; available at http://www.cl.cam.ac.uk/users/os10000/doc/todo-mode.html
-;; (That link will be valid until 10/1998 or slightly longer.)
-;;
-;; Revision 1.18  1997/10/15  17:18:11  os10000
-;; Everything seems to work in Harald Melands Emacs 20.02 and
-;; my Emacs 19.34.  Beware of the spelling in some of the
-;; variable names.  I looked up "threshold" in a dictionary
-;; and here in Britain this appears to be the way to spell it.
-;;
-;; Revision 1.17  1997/10/15  14:30:41  os10000
-;; Attempted to reconcile Harald's changes with mine since 1.15.
-;;
-;; Revision 1.16  1997/10/15  14:00:12  os10000
-;; Fixed 'file-item' and added 20.02 split-string function.
-;;
-;; Revision 1.15  1997/10/14  22:22:35  os10000
-;; Added string-split (which I stole from ediff-util), changed
-;; pop-to-buffer to switch-to-buffer and added message on how
-;; to exit the multi-line-edit mode.
-;;
-;; Revision 1.14  1997/10/09  09:24:50  os10000
-;; Harald Meland <harald.meland@usit.uio.no> asked for
-;; the latest version, got 1.13, and returned this.
-;; He writes:
-;;
-;; Thanks a lot for the new version of todo-mode.el.  As you will see I
-;; have messed it up a bit, hopefully for the better -- I don't like
-;; short, cryptic names for variables and functions, so I renamed most of
-;; them, and `defalias'ed the old function names.  I hope you don't mind
-;; too much, I just kinda couldn't stop myself.
-;;
-;; Additionally, I included some support for multiline entries, cleaned
-;; up (IMHO :) a lot of the code, included completion-support for which
-;; category to install a new entry in, and possibly some other changes I
-;; can't remember :)
-;;
-;; It's getting rather late, and I have just done some preliminary
-;; testing on whether all of this really works, but so far it looks
-;; good.
-;;
-;; Revision 1.13  1997/08/19  14:00:36  seidel
-;; - changed name to todo-mode
-;; - fixed menu descriptions
-;; - fixed "pressing abort while filing"
-;; - attempted Emacs Lisp Manual *Tips* section compliance
-;;
-;; Revision 1.12  1997/08/06  10:56:15  os10000
-;; Fixed header, typos, layout, documentation.
-;;
-;; Revision 1.11  1997/08/06  09:14:25  os10000
-;; Applied patch from Istvan Marko <istvan@cmdmail.amd.com>
-;; to make menus work anywhere.
-;;
-;; Revision 1.10  1997/08/06  08:56:03  os10000
-;; Acted upon suggestion from Shane Holder <holder@rsn.hp.com>:
-;; Cancelling the editing of an entry will not delete it any more.
-;;
-;; Revision 1.9  1997/08/06 08:12:03  os10000
-;; Improved documentation.  Broke some lines to comply with
-;; Richard Stallman's email to please keep in sync with the
-;; rest of the Emacs distribution files.
-;;
-;; Revision 1.8  1997/08/05 22:39:04  os10000
-;; Made todo-mode.el available under GPL.
-;;
-;; Revision 1.7  1997/08/05 22:34:14  os10000
-;; Fixed insertion routine with help from Trey Jackson
-;; <trey@cs.berkeley.edu>; added todo-inst-tresh;
-;; fixed keyboard layout to remove unwanted keys.
-;;
-;; Revision 1.6  1997/08/05 16:47:01  os10000
-;; Incorporated menus for XEmacs from Allan.Cochrane@soton.sc.philips.com,
-;; fixed TYPO, fixed todo-file-cmd, cleaned up rcs history.
-;;
-;; Revision 1.5  1997/08/05  14:43:39  os10000
-;; Added improvements from Ron Gut <rgut@aware.com>.
-;; Added category management.
-;;
-;; Revision 1.4  1997/08/04  16:18:45  os10000
-;; Added Raise/Lower item.
-;;
-;; Revision 1.3  1997/08/03  12:47:26  os10000
-;; Cleaned up variables, prefix and cursor position.
-;;
-;; Revision 1.2  1997/08/03 12:15:28  os10000
-;; It appears to work.
-;;
-;; Revision 1.1  1997/08/03 12:15:13  os10000
-;; Initial revision
-;;
-
-;; ---------------------------------------------------------------------------
 
 ;;; 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))))))
+(require 'time-stamp)
+
 
 ;; User-configurable variables:
 
 (defgroup todo nil
   "Maintain a list of todo items."
+  :link '(emacs-commentary-link "todo-mode")
+  :version "21.1"
   :group 'calendar)
 
 (defcustom todo-prefix     "*/*"
@@ -526,11 +312,12 @@ 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
+amount and will insert the item in the approximate center of that
 window."
   :type 'integer
   :group 'todo)
-(defvar todo-edit-buffer " *TODO Edit*" "TODO Edit buffer name.")
+(defvar todo-edit-buffer " *TODO Edit*"
+  "TODO Edit buffer name.")
 (defcustom todo-file-top "~/.todo-top"
   "*TODO mode top priorities file.
 
@@ -559,8 +346,7 @@ Automatically generated when `todo-save-top-priorities' is non-nil."
   :type 'boolean
   :group 'todo)
 (defcustom todo-save-top-priorities-too t
-  "*Non-nil makes todo-save automatically save top-priorities in
-`todo-file-top'."
+  "*Non-nil makes `todo-save' automatically save top-priorities in `todo-file-top'."
   :type 'boolean
   :group 'todo)
 
@@ -590,41 +376,22 @@ For details see the variable `time-stamp-format'."
 
 ;; ---------------------------------------------------------------------------
 
-;; Get some outside help ...
-
-(require 'time-stamp)
-(require 'easymenu)
-
-;; ---------------------------------------------------------------------------
-
 ;; Set up some helpful context ...
 
-(defvar todo-categories         nil     "TODO categories.")
-(defvar todo-cats               nil
+(defvar todo-categories nil
+  "TODO categories.")
+
+(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-previous-line 0
+  "Previous line asked about.")
 
-(defvar todo-category-sep (make-string 75 ?-)
-  "Category separator.")
-(defvar todo-category-beg " --- "
-  "Category start separator to be prepended onto category name.")
-(defvar todo-category-end "--- End"
-  "Separator after a category.")
-(defvar todo-header "-*- mode: todo; "
-  "Header of todo files.")
+(defvar todo-previous-answer 0
+  "Previous answer got.")
 
-
-
-;; ---------------------------------------------------------------------------
-
-(if todo-mode-map
-    nil
+(defvar todo-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map t)
     (define-key map "+" 'todo-forward-category)
@@ -646,40 +413,63 @@ Use `todo-categories' instead.")
     (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)))
+    map)
+  "TODO mode keymap.")
+
+(defvar todo-category-number 0 "TODO category number.")
+
+(defvar todo-tmp-buffer-name " *todo tmp*")
+
+(defvar todo-category-sep (make-string 75 ?-)
+  "Category separator.")
+
+(defvar todo-category-beg " --- "
+  "Category start separator to be prepended onto category name.")
+
+(defvar todo-category-end "--- End"
+  "Separator after a category.")
+
+(defvar todo-header "-*- mode: todo; "
+  "Header of todo files.")
+
+;; ---------------------------------------------------------------------------
 
 (defun todo-category-select ()
   "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
      (concat "^"
              (regexp-quote (concat todo-prefix todo-category-beg name))
              "$"))
-    (let ((begin (1+ (point-at-eol))))
+    (let ((begin (1+ (line-end-position))))
       (search-forward-regexp (concat "^" todo-category-end))
-      (narrow-to-region begin (point-at-bol))
+      (narrow-to-region begin (line-beginning-position))
       (goto-char (point-min)))))
 (defalias 'todo-cat-slct 'todo-category-select)
 
-(defun todo-forward-category () "Go forward to TODO list of next category."
+(defun todo-forward-category ()
+  "Go forward to TODO list of next category."
   (interactive)
   (setq todo-category-number
         (mod (1+ todo-category-number) (length todo-categories)))
   (todo-category-select))
 (defalias 'todo-cmd-forw 'todo-forward-category)
 
-(defun todo-backward-category () "Go back to TODO list of previous category."
+(defun todo-backward-category ()
+  "Go back to TODO list of previous category."
   (interactive)
   (setq todo-category-number
         (mod (1- todo-category-number) (length todo-categories)))
   (todo-category-select))
 (defalias 'todo-cmd-back 'todo-backward-category)
 
-(defun todo-backward-item () "Select previous entry of TODO list."
+(defun todo-backward-item ()
+  "Select previous entry of TODO list."
   (interactive)
   (search-backward-regexp (concat "^" (regexp-quote todo-prefix)) nil t)
   (message ""))
@@ -696,14 +486,17 @@ Use `todo-categories' instead.")
   (message ""))
 (defalias 'todo-cmd-next 'todo-forward-item)
 
-(defun todo-save () "Save the TODO list."
+(defun todo-save ()
+  "Save the TODO list."
   (interactive)
-  (save-buffer)
-  (if todo-save-top-priorities-too (todo-save-top-priorities))
-  )
+  (save-excursion
+    (save-restriction
+      (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."
+(defun todo-quit ()
+  "Done with TODO list for now."
   (interactive)
   (widen)
   (todo-save)
@@ -711,7 +504,8 @@ Use `todo-categories' instead.")
   (bury-buffer))
 (defalias 'todo-cmd-done 'todo-quit)
 
-(defun todo-edit-item () "Edit current TODO list entry."
+(defun todo-edit-item ()
+  "Edit current TODO list entry."
   (interactive)
   (let ((item (todo-item-string)))
     (if (todo-string-multiline-p item)
@@ -734,8 +528,8 @@ Use `todo-categories' instead.")
     (todo-edit-mode)
     (narrow-to-region (todo-item-start) (todo-item-end))))
 
-;;;### autoload
-(defun todo-add-category (cat) 
+;;;###autoload
+(defun todo-add-category (cat)
   "Add new category CAT to the TODO list."
   (interactive "sCategory: ")
   (save-window-excursion
@@ -754,11 +548,11 @@ Use `todo-categories' instead.")
     (forward-char 1)
     (insert (format "%s%s%s\n%s\n%s %s\n"
                     todo-prefix todo-category-beg cat
-                    todo-category-end 
+                    todo-category-end
                     todo-prefix todo-category-sep)))
   0)
 
-;;;### autoload
+;;;###autoload
 (defun todo-add-item-non-interactively (new-item category)
   "Insert NEW-ITEM in TODO list as a new entry in CATEGORY."
   (save-excursion
@@ -791,8 +585,8 @@ Use `todo-categories' instead.")
     (todo-save)
     (message "")))
 
-;;;### autoload
-(defun todo-insert-item (ARG)
+;;;###autoload
+(defun todo-insert-item (arg)
   "Insert new TODO list entry.
 With a prefix argument solicit the category, otherwise use the current
 category."
@@ -807,18 +601,16 @@ category."
           (categories todo-categories)
           (history (cons 'categories (1+ todo-category-number)))
           (current-category (nth todo-category-number todo-categories))
-          (category 
-           (if ARG
+          (category
+           (if arg
                current-category
-             (completing-read 
-              (concat "Category ["
-                      current-category "]: ")
-              (todo-category-alist) nil nil nil history))))
+             (completing-read (concat "Category [" current-category "]: ")
+                              (todo-category-alist) nil nil nil
+                              history current-category))))
       (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 "")
@@ -844,7 +636,8 @@ category."
   todo-previous-answer)
 (defalias 'todo-ask-p 'todo-more-important-p)
 
-(defun todo-delete-item () "Delete current TODO list entry."
+(defun todo-delete-item ()
+  "Delete current TODO list entry."
   (interactive)
   (if (> (count-lines (point-min) (point-max)) 0)
       (let* ((todo-entry (todo-item-string-start))
@@ -858,7 +651,8 @@ category."
     (error "No TODO list entry to delete")))
 (defalias 'todo-cmd-kill 'todo-delete-item)
 
-(defun todo-raise-item () "Raise priority of current entry."
+(defun todo-raise-item ()
+  "Raise priority of current entry."
   (interactive)
   (if (> (count-lines (point-min) (point)) 0)
       (let ((item (todo-item-string)))
@@ -870,7 +664,8 @@ category."
     (error "No TODO list entry to raise")))
 (defalias 'todo-cmd-rais 'todo-raise-item)
 
-(defun todo-lower-item () "Lower priority of current entry."
+(defun todo-lower-item ()
+  "Lower priority of current entry."
   (interactive)
   (if (> (count-lines (point) (point-max)) 1)
       ;; Assume there is a final newline
@@ -883,33 +678,34 @@ category."
     (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 ")")))
-        (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 ""))
-    (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 "")))
 
 ;; ---------------------------------------------------------------------------
 
@@ -930,7 +726,7 @@ between each category."
   (or nof-priorities (setq nof-priorities todo-show-priorities))
   (if (listp nof-priorities)            ;universal argument
       (setq nof-priorities (car nof-priorities)))
-  (let ((todo-print-buffer-name "*Tmp*")
+  (let ((todo-print-buffer-name todo-tmp-buffer-name)
         ;;(todo-print-category-number 0)
         (todo-category-break (if category-pr-page "\f" ""))
         (cat-end
@@ -947,14 +743,13 @@ between each category."
         (copy-to-buffer todo-print-buffer-name (point-min) (point-max))
         (set-buffer todo-print-buffer-name)
         (goto-char (point-min))
-        (if (re-search-forward (regexp-quote todo-header) nil t)
-            (progn
-              (beginning-of-line 1)
-              (kill-line)))             ;Remove mode line
+        (when (re-search-forward (regexp-quote todo-header) nil t)
+         (beginning-of-line 1)
+         (delete-region (point) (line-end-position)))
         (while (re-search-forward       ;Find category start
                 (regexp-quote (concat todo-prefix todo-category-beg))
                 nil t)
-          (setq beg (+ (point-at-eol) 1)) ;Start of first entry.
+          (setq beg (+ (line-end-position) 1)) ;Start of first entry.
           (re-search-forward cat-end nil t)
           (setq end (match-beginning 0))
           (replace-match todo-category-break)
@@ -974,10 +769,8 @@ between each category."
     ;; Else we could have used pop-to-buffer.
     (display-buffer todo-print-buffer-name)
     (message "Type C-x 1 to remove %s window.  M-C-v to scroll the help."
-             todo-print-buffer-name)
-    ))
+             todo-print-buffer-name)))
 
-;;;###autoload
 (defun todo-save-top-priorities (&optional nof-priorities)
   "Save top priorities for each category in `todo-file-top'.
 
@@ -990,42 +783,35 @@ defaults to `todo-show-priorities'."
         (todo-top-priorities nof-priorities)
         (set-buffer todo-tmp-buffer-name)
         (write-file todo-file-top)
-        (kill-this-buffer)
-        ))))
+        (kill-this-buffer)))))
 
 ;;;###autoload
 (defun todo-print (&optional category-pr-page)
-  "Print todo summary using \\\[todo-print-function].
-If CATEGORY-PR-PAGE is non-nil, a page separator \'^L\' is inserted
+  "Print todo summary using `todo-print-function'.
+If CATEGORY-PR-PAGE is non-nil, a page separator `^L' is inserted
 between each category.
 
-Number of entries for each category is given by
-\'todo-print-priorities\'."
+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)
-              (set-buffer todo-tmp-buffer-name)
-              (and (funcall todo-print-function)
-                   (kill-this-buffer))
-            (message "Todo printing done."))
-            )))
-    (message "todo-print-function undefinded")
-    ))
+    (save-excursion
+      (save-restriction
+       (todo-top-priorities todo-print-priorities
+                            category-pr-page)
+       (set-buffer todo-tmp-buffer-name)
+       (and (funcall todo-print-function)
+            (kill-this-buffer))
+       (message "Todo printing done.")))))
 
 (defun todo-jump-to-category ()
   "Jump to a category.  Default is previous category."
   (interactive)
   (let* ((categories todo-categories)
          (history (cons 'categories (1+ todo-category-number)))
-        (category (completing-read 
-                    (concat "Category ["
-                            (nth todo-category-number todo-categories) "]: ")
-                    (todo-category-alist) nil nil nil history)))
+        (default (nth todo-category-number todo-categories))
+        (category (completing-read
+                    (concat "Category [" default "]: ")
+                    (todo-category-alist) nil nil nil history default)))
     (if (string= "" category)
         (setq category (nth todo-category-number todo-categories)))
     (setq todo-category-number
@@ -1035,8 +821,9 @@ Number of entries for each category is given by
             (todo-add-category category)))
     (todo-show)))
 
-(defun todo-line-string () "Return current line in buffer as a string."
-  (buffer-substring (point-at-bol) (point-at-eol)))
+(defun todo-line-string ()
+  "Return current line in buffer as a string."
+  (buffer-substring (line-beginning-position) (line-end-position)))
 
 (defun todo-item-string-start ()
   "Return the start of this TODO list entry as a string."
@@ -1046,7 +833,8 @@ Number of entries for each category is given by
         (setq item (concat (substring item 0 56) "...")))
     item))
 
-(defun todo-item-start () "Return point at start of current TODO list item."
+(defun todo-item-start ()
+  "Return point at start of current TODO list item."
   (save-excursion
     (beginning-of-line)
     (if (not (looking-at (regexp-quote todo-prefix)))
@@ -1054,17 +842,20 @@ Number of entries for each category is given by
          (concat "^" (regexp-quote todo-prefix)) nil t))
     (point)))
 
-(defun todo-item-end () "Return point at end of current TODO list item."
+(defun todo-item-end ()
+  "Return point at end of current TODO list item."
   (save-excursion
     (end-of-line)
     (search-forward-regexp
      (concat "^" (regexp-quote todo-prefix)) nil 'goto-end)
-    (1- (point-at-bol))))
+    (1- (line-beginning-position))))
 
-(defun todo-remove-item () "Delete the current entry from the TODO list."
+(defun todo-remove-item ()
+  "Delete the current entry from the TODO list."
   (delete-region (todo-item-start) (1+ (todo-item-end))))
 
-(defun todo-item-string () "Return current TODO list entry as a string."
+(defun todo-item-string ()
+  "Return current TODO list entry as a string."
   (buffer-substring (todo-item-start) (todo-item-end)))
 
 (defun todo-string-count-lines (string)
@@ -1077,45 +868,7 @@ Number of entries for each category is given by
 
 (defun todo-category-alist ()
   "Generate an alist for use in `completing-read' from `todo-categories'."
-  (mapcar (lambda (cat) (cons cat nil))
-          todo-categories))
-
-;; utility functions:  These are available in XEmacs, but not in Emacs 19.34
-
-(if (not (fboundp 'point-at-bol))
-    (defun point-at-bol () "Return value of point at beginning of line."
-      (save-excursion
-        (beginning-of-line)
-        (point))))
-
-(if (not (fboundp 'point-at-eol))
-    (defun point-at-eol () "Return value of point at end of line."
-      (save-excursion
-        (end-of-line)
-        (point))))
-
-;; splits at a white space, returns a list
-(if (not (fboundp 'split-string))
-    (defun split-string (string &optional separators)
-      "Splits STRING into substrings where there are matches for SEPARATORS.
-Each match for SEPARATORS is a splitting point.
-The substrings between the splitting points are made into a list
-which is returned.
-If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
-      (let ((rexp (or separators "[ \f\t\n\r\v]+"))
-            (start 0)
-            (list nil))
-        (while (string-match rexp string start)
-          (or (eq (match-beginning 0) 0)
-              (setq list
-                    (cons (substring string start (match-beginning 0))
-                          list)))
-          (setq start (match-end 0)))
-        (or (eq start (length string))
-            (setq list
-                  (cons (substring string start)
-                        list)))
-        (nreverse list))))
+  (mapcar #'list todo-categories))
 
 ;; ---------------------------------------------------------------------------
 
@@ -1146,32 +899,38 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
                     ))
 
 ;; As calendar reads .todo-do before todo-mode is loaded.
-;;;### autoload
-(defun todo-mode () "Major mode for editing TODO lists.\n\n\\{todo-mode-map}"
+;;;###autoload
+(defun todo-mode ()
+  "Major mode for editing TODO lists.
+
+\\{todo-mode-map}"
   (interactive)
+  (kill-all-local-variables)
   (setq major-mode 'todo-mode)
   (setq mode-name "TODO")
   (use-local-map todo-mode-map)
   (easy-menu-add todo-menu)
-  (run-hooks 'todo-mode-hook))
+  (run-mode-hooks 'todo-mode-hook))
+
+(eval-when-compile
+  (defvar date)
+  (defvar entry))
 
 ;; Read about this function in the setup instructions above!
-;;;### autoload
+;;;###autoload
 (defun todo-cp ()
-  "Make a diary entry appear only in the current date's diary"
+  "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)
-  (setq major-mode 'todo-edit-mode)
-  (setq mode-name "TODO Edit")
-  (run-hooks 'todo-edit-mode-hook))
-
-;;;### autoload
-(defun todo-show () "Show TODO list."
+      entry))
+
+(define-derived-mode todo-edit-mode text-mode "TODO Edit"
+  "Major mode for editing items in the TODO list.
+
+\\{todo-edit-mode-map}")
+
+;;;###autoload
+(defun todo-show ()
+  "Show TODO list."
   (interactive)
   (if (file-exists-p todo-file-do)
       (find-file todo-file-do)
@@ -1188,7 +947,8 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
   (beginning-of-line)
   (todo-category-select))
 
-(defun todo-initial-setup () "Set up things to work properly in TODO mode."
+(defun todo-initial-setup ()
+  "Set up things to work properly in TODO mode."
   (find-file todo-file-do)
   (erase-buffer)
   (todo-mode)
@@ -1196,6 +956,5 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
 
 (provide 'todo-mode)
 
-;; ---------------------------------------------------------------------------
+;;; arch-tag: 6fd91be5-776e-4464-a109-da4ea0e4e497
 ;;; todo-mode.el ends here
-;; ---------------------------------------------------------------------------