Mercurial > emacs
changeset 101600:10d6e33982c3
(todo-insert-item-here): Prevent insertion
of a new entry inside of an existing entry. Minor code cleanup.
(todo-add-category): Change the interactive spec. Signal an error
if the Todo file is non-empty but contains no category. Reject
category names that could induce bugs and confusion. Call
todo-mode if the Todo file is new and unsaved. Simplify handling
of local variables cookie. Properly display the newly added
category in Todo mode.
(todo-show): Call todo-initial-setup only if there is neither a
Todo file nor a corresponding unsaved buffer.
(todo-category-alist): Delete function.
(todo-completing-read): New function.
(todo-insert-item, todo-jump-to-category): Use it.
(todo-insert-item): Make the use of the prefix argument conform to
the doc string.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Wed, 28 Jan 2009 03:56:18 +0000 |
parents | d8799ea52d74 |
children | 58bce94ff020 |
files | lisp/calendar/todo-mode.el |
diffstat | 1 files changed, 73 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/calendar/todo-mode.el Wed Jan 28 03:56:08 2009 +0000 +++ b/lisp/calendar/todo-mode.el Wed Jan 28 03:56:18 2009 +0000 @@ -527,28 +527,45 @@ (narrow-to-region (todo-item-start) (todo-item-end)))) ;;;###autoload -(defun todo-add-category (cat) +(defun todo-add-category (&optional 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) - (widen) - (goto-char (point-min)) - (let ((posn (search-forward "-*- mode: todo; " 17 t))) - (if posn - (progn - (goto-char posn) - (kill-line)) - (insert "-*- mode: todo; \n") - (forward-char -1))) - (insert (format "todo-categories: %S; -*-" todo-categories)) - (forward-char 1) - (insert (format "%s%s%s\n%s\n%s %s\n" - todo-prefix todo-category-beg cat - todo-category-end - todo-prefix todo-category-sep))) - 0) + (interactive) + (let ((buf (find-file-noselect todo-file-do t)) + (prompt "Category: ")) + (unless (zerop (buffer-size buf)) + (and (null todo-categories) + (null todo-cats) + (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 + ;; reject names that could induce bugs and confusion + (while (and (cond ((string= "" cat) + (setq prompt "Enter a non-empty category name: ")) + ((string-match "\\`\\s-+\\'" cat) + (setq prompt "Enter a category name that is not only white space: ")) + ((member cat todo-categories) + (setq prompt "Enter a non-existing category name: "))) + (setq cat (read-from-minibuffer prompt)))) + ;; initialize a newly created Todo buffer for Todo mode + (unless (file-exists-p todo-file-do) (todo-mode)) + (setq todo-categories (cons cat todo-categories)) + (widen) + (goto-char (point-min)) + (if (search-forward "-*- mode: todo; " 17 t) + (kill-line) + (insert "-*- mode: todo; \n") + (forward-char -1)) + (insert (format "todo-categories: %S; -*-" todo-categories)) + (forward-char 1) + (insert (format "%s%s%s\n%s\n%s %s\n" + todo-prefix todo-category-beg cat + todo-category-end + todo-prefix todo-category-sep)) + (if (interactive-p) + ;; properly display the newly added category + (progn (setq todo-category-number 0) (todo-show)) + 0)))) ;;;###autoload (defun todo-add-item-non-interactively (new-item category) @@ -596,30 +613,27 @@ "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 current-category)))) + (category (if arg (todo-completing-read) current-category))) (todo-add-item-non-interactively new-item category)))) (defalias 'todo-cmd-inst 'todo-insert-item) (defun todo-insert-item-here () - "Insert new TODO list entry under the cursor." - (interactive "") - (save-excursion - (if (not (derived-mode-p 'todo-mode)) (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"))))) + "Insert a new TODO list entry directly above the entry at point. +If point is on an empty line, insert the entry there." + (interactive) + (if (not (derived-mode-p 'todo-mode)) (todo-show)) + (let ((new-item (concat todo-prefix " " + (read-from-minibuffer + "New TODO entry: " + (if todo-entry-prefix-function + (funcall todo-entry-prefix-function)))))) + (unless (and (bolp) (eolp)) (goto-char (todo-item-start))) + (insert (concat new-item "\n")) + (backward-char) + ;; put point at start of new entry + (goto-char (todo-item-start)))) (defun todo-more-important-p (line) "Ask whether entry is more important than the one at LINE." @@ -801,12 +815,7 @@ (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))) - (default (nth todo-category-number todo-categories)) - (category (completing-read - (concat "Category [" default "]: ") - (todo-category-alist) nil nil nil history default))) + (let ((category (todo-completing-read))) (if (string= "" category) (setq category (nth todo-category-number todo-categories))) (setq todo-category-number @@ -861,9 +870,19 @@ "Return non-nil if STRING spans several lines." (> (todo-string-count-lines string) 1)) -(defun todo-category-alist () - "Generate an alist for use in `completing-read' from `todo-categories'." - (mapcar #'list todo-categories)) +(defun todo-completing-read () + "Return a category name, with completion, for use in Todo mode." + ;; make a copy of todo-categories in case history-delete-duplicates is + ;; non-nil, which makes completing-read alter todo-categories + (let* ((categories (copy-sequence todo-categories)) + (history (cons 'todo-categories (1+ todo-category-number))) + (default (nth todo-category-number todo-categories)) + (category (completing-read + (concat "Category [" default "]: ") + todo-categories nil nil nil history default))) + ;; restore the original value of todo-categories + (setq todo-categories categories) + category)) ;; --------------------------------------------------------------------------- @@ -929,7 +948,12 @@ (defun todo-show () "Show TODO list." (interactive) - (if (file-exists-p todo-file-do) + ;; Call todo-initial-setup only if there is neither a Todo file nor + ;; a corresponding unsaved buffer. + (if (or (file-exists-p todo-file-do) + (let* ((buf (get-buffer (file-name-nondirectory todo-file-do))) + (bufname (buffer-file-name buf))) + (equal (expand-file-name todo-file-do) bufname))) (find-file todo-file-do) (todo-initial-setup)) (if (null todo-categories)