Spelling fixes.
[bpt/emacs.git] / lisp / calendar / todo-mode.el
index b00c508..de232c2 100644 (file)
@@ -1,7 +1,6 @@
 ;;; todo-mode.el --- major mode for editing TODO list files
 
-;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;   2008, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1999, 2001-2011  Free Software Foundation, Inc.
 
 ;; Author: Oliver Seidel <privat@os10000.net>
 ;; Maintainer: Stephen Berman <stephen.berman@gmx.net>
@@ -32,7 +31,7 @@
 ;;     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.
+;;     categorized, 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.
@@ -48,7 +47,7 @@
 ;;
 ;;  Preface, Quickstart Installation
 ;;
-;;      To get this to work, make emacs execute the line
+;;      To get this to work, make Emacs execute the line
 ;;
 ;;          (autoload 'todo-mode "todo-mode"
 ;;                    "Major mode for editing TODO lists." t)
 ;;
 ;;      The TODO list file has a special format and some auxiliary
 ;;      information, which will be added by the todo-show function if
-;;      it attempts to visit an un-initialised file.  Hence it is
+;;      it attempts to visit an un-initialized file.  Hence it is
 ;;      recommended to use the todo-show function for the first time,
-;;      in order to initialise the file, but it is not necessary
+;;      in order to initialize the file, but it is not necessary
 ;;      afterwards.
 ;;
 ;;      As these commands are quite long to type, I would recommend
 ;;      the addition of two bindings to your to your global keymap.  I
-;;      personally have the following in my initialisation file:
+;;      personally have the following in my initialization file:
 ;;
 ;;          (global-set-key "\C-ct" 'todo-show)  ; switch to TODO buffer
 ;;         (global-set-key "\C-ci" 'todo-insert-item) ; insert new item
 ;;     o   GNATS support
 ;;     o   elide multiline (as in bbdb, or, to a lesser degree, in
 ;;          outline mode)
-;;     o   rewrite complete package to store data as lisp objects
+;;     o   rewrite complete package to store data as Lisp objects
 ;;          and have display modes for display, for diary export,
 ;;          etc.  (Richard Stallman pointed out this is a bad idea)
 ;;      o   so base todo-mode.el on generic-mode.el instead
@@ -505,14 +504,16 @@ Use `todo-categories' instead.")
 (defun todo-edit-item ()
   "Edit current TODO list entry."
   (interactive)
-  (let ((item (todo-item-string)))
-    (if (todo-string-multiline-p item)
-        (todo-edit-multiline)
-      (let ((new (read-from-minibuffer "Edit: " item)))
-        (todo-remove-item)
-        (insert new "\n")
-        (todo-backward-item)
-        (message "")))))
+  (if (< (point-min) (point-max))
+      (let ((item (todo-item-string)))
+       (if (todo-string-multiline-p item)
+           (todo-edit-multiline)
+         (let ((new (read-from-minibuffer "Edit: " item)))
+           (todo-remove-item)
+           (insert new "\n")
+           (todo-backward-item)
+           (message ""))))
+    (error "No TODO list entry to edit")))
 (defalias 'todo-cmd-edit 'todo-edit-item)
 
 (defun todo-edit-multiline ()
@@ -535,7 +536,7 @@ Use `todo-categories' instead.")
     (unless (zerop (buffer-size buf))
       (and (null todo-categories)
           (null todo-cats)
-          (error "Error in %s: File is non-empty but contains no category" 
+          (error "Error in %s: File is non-empty but contains no category"
                  todo-file-do)))
     (unless cat (setq cat (read-from-minibuffer prompt)))
     (with-current-buffer buf
@@ -552,7 +553,7 @@ Use `todo-categories' instead.")
       (setq todo-categories (cons cat todo-categories))
       (widen)
       (goto-char (point-min))
-      (if (search-forward "-*- mode: todo; " 17 t)
+      (if (search-forward "-*- mode: todo; " (+ (point-min) 16) t)
          (kill-line)
        (insert "-*- mode: todo; \n")
        (forward-char -1))
@@ -562,7 +563,7 @@ Use `todo-categories' instead.")
                      todo-prefix todo-category-beg cat
                      todo-category-end
                      todo-prefix todo-category-sep))
-      (if (interactive-p)
+      (if (called-interactively-p 'interactive)
          ;; properly display the newly added category
          (progn (setq todo-category-number 0) (todo-show))
        0))))
@@ -603,7 +604,7 @@ Use `todo-categories' instead.")
 ;;;###autoload
 (defun todo-insert-item (arg)
   "Insert new TODO list entry.
-With a prefix argument solicit the category, otherwise use the current
+With a prefix argument ARG solicit the category, otherwise use the current
 category."
   (interactive "P")
   (save-excursion
@@ -629,11 +630,11 @@ If point is on an empty line, insert the entry there."
                           "New TODO entry: "
                           (if todo-entry-prefix-function
                               (funcall todo-entry-prefix-function))))))
-    (unless (and (bolp) (eolp)) (goto-char (todo-item-start)))
+    (unless (and (bolp) (eolp)) (todo-item-start))
     (insert (concat new-item "\n"))
     (backward-char)
     ;; put point at start of new entry
-    (goto-char (todo-item-start))))
+    (todo-item-start)))
 
 (defun todo-more-important-p (line)
   "Ask whether entry is more important than the one at LINE."
@@ -704,15 +705,15 @@ If point is on an empty line, insert the entry there."
        "(" comment ")"))
     (goto-char (todo-item-end))
     (insert " [" (nth todo-category-number todo-categories) "]")
-    (goto-char (todo-item-start))
+    (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))))
+      (append-to-file temp-point (todo-item-end 'include-sep) todo-file-done)
+      (delete-region temp-point (todo-item-end 'include-sep)))
     (todo-backward-item)
     (message "")))
 
@@ -722,16 +723,18 @@ If point is on an empty line, insert the entry there."
 
 
 ;;;###autoload
-(defun todo-top-priorities (&optional nof-priorities category-pr-page)
+(defun todo-top-priorities (&optional nof-priorities category-pr-page
+                                      interactive)
   "List top priorities for each category.
 
 Number of entries for each category is given by NOF-PRIORITIES which
-defaults to \'todo-show-priorities\'.
+defaults to `todo-show-priorities'.
 
 If CATEGORY-PR-PAGE is non-nil, a page separator \'^L\' is inserted
-between each category."
+between each category.
+INTERACTIVE should be non-nil if this function is called interactively."
 
-  (interactive "P")
+  (interactive "P\ni\nP")
   (or nof-priorities (setq nof-priorities todo-show-priorities))
   (if (listp nof-priorities)            ;universal argument
       (setq nof-priorities (car nof-priorities)))
@@ -745,38 +748,36 @@ between each category."
                       (regexp-quote todo-prefix) " " todo-category-sep "\n")
             (concat todo-category-end "\n"))))
         beg end)
-    (todo-show)
     (save-excursion
+      (todo-show)
       (save-restriction
-        (widen)
-        (copy-to-buffer todo-print-buffer-name (point-min) (point-max))
-        (set-buffer todo-print-buffer-name)
-        (goto-char (point-min))
-        (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 (+ (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)
-          (narrow-to-region beg end)    ;In case we have too few entries.
-          (goto-char (point-min))
-          (if (zerop nof-priorities)      ;Traverse entries.
-              (goto-char end)            ;All entries
-            (todo-forward-item nof-priorities))
-          (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.
-    (display-buffer todo-print-buffer-name)
+       (save-current-buffer
+         (widen)
+         (copy-to-buffer todo-print-buffer-name (point-min) (point-max))
+         (set-buffer todo-print-buffer-name)
+         (goto-char (point-min))
+         (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 (+ (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)
+           (narrow-to-region beg end)    ;In case we have too few entries.
+           (goto-char (point-min))
+           (if (zerop nof-priorities)      ;Traverse entries.
+               (goto-char end)            ;All entries
+             (todo-forward-item nof-priorities))
+           (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
+         )))
+    (when interactive (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)))
 
@@ -838,25 +839,27 @@ Number of entries for each category is given by `todo-print-priorities'."
     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)))
-        (search-backward-regexp
-         (concat "^" (regexp-quote todo-prefix)) nil t))
-    (point)))
-
-(defun todo-item-end ()
-  "Return point at end of current TODO list item."
+  "Go to start of current TODO list item and return point."
+  (beginning-of-line)
+  (if (not (looking-at (regexp-quote todo-prefix)))
+      (search-backward-regexp
+       (concat "^" (regexp-quote todo-prefix)) nil t))
+  (point))
+
+(defun todo-item-end (&optional include-sep)
+  "Return point at end of current TODO list item.
+If INCLUDE-SEP is non-nil, return point after the separator."
   (save-excursion
     (end-of-line)
-    (search-forward-regexp
-     (concat "^" (regexp-quote todo-prefix)) nil 'goto-end)
-    (1- (line-beginning-position))))
+    (if (search-forward-regexp
+         (concat "^" (regexp-quote todo-prefix)) nil 'goto-end)
+        (goto-char (match-beginning 0)))
+    (unless include-sep (skip-chars-backward "\n"))
+    (point)))
 
 (defun todo-remove-item ()
   "Delete the current entry from the TODO list."
-  (delete-region (todo-item-start) (1+ (todo-item-end))))
+  (delete-region (todo-item-start) (todo-item-end 'include-sep)))
 
 (defun todo-item-string ()
   "Return current TODO list entry as a string."
@@ -914,17 +917,9 @@ Number of entries for each category is given by `todo-print-priorities'."
 
 ;; As calendar reads .todo-do before todo-mode is loaded.
 ;;;###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-mode-hooks 'todo-mode-hook))
+(define-derived-mode todo-mode nil "TODO"
+  "Major mode for editing TODO lists."
+  (easy-menu-add todo-menu))
 
 (defvar date)
 (defvar entry)
@@ -977,5 +972,4 @@ Number of entries for each category is given by `todo-print-priorities'."
 
 (provide 'todo-mode)
 
-;; arch-tag: 6fd91be5-776e-4464-a109-da4ea0e4e497
 ;;; todo-mode.el ends here