aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2013-06-05 15:59:14 +0200
committerStephen Berman2013-06-05 15:59:14 +0200
commitdb5ea4772d9cddd2113105bbe3d9419f4a5b4a39 (patch)
tree9d719f164cd6c3ea7b08d532a2c5f51e7dd2fd77
parentc66f681c4fced52f47e12dc80e47a8b6075e2401 (diff)
downloademacs-db5ea4772d9cddd2113105bbe3d9419f4a5b4a39.tar.gz
emacs-db5ea4772d9cddd2113105bbe3d9419f4a5b4a39.zip
* todos.el: Further code cleanup. Changes to commentary. Remove
autoload cookies. Handle todo items in Fancy Diary display. (todos-done-separator): Reinstate length one less than window-width until bug#2749 is fixed. (todos-diary-goto-entry): New function, extracted from adapted definition of diary-goto-entry, which is removed to be added to diary-lib.el. (todos-powerset): Rename from todos-powerset-iterative and remove defalias by this name. Add doc string and comments. (todos-modes-set-1, todos-modes-set-2, todos-modes-set-3) (todos-mode-external-set): Add doc string.
-rw-r--r--lisp/calendar/ChangeLog14
-rw-r--r--lisp/calendar/todos.el178
2 files changed, 94 insertions, 98 deletions
diff --git a/lisp/calendar/ChangeLog b/lisp/calendar/ChangeLog
index 8462032f222..078d563df35 100644
--- a/lisp/calendar/ChangeLog
+++ b/lisp/calendar/ChangeLog
@@ -1,3 +1,17 @@
12013-06-05 Stephen Berman <stephen.berman@gmx.net>
2
3 * todos.el: Further code cleanup. Changes to commentary. Remove
4 autoload cookies. Handle todo items in Fancy Diary display.
5 (todos-done-separator): Reinstate length one less than
6 window-width until bug#2749 is fixed.
7 (todos-diary-goto-entry): New function, extracted from adapted
8 definition of diary-goto-entry, which is removed to be added to
9 diary-lib.el.
10 (todos-powerset): Rename from todos-powerset-iterative and remove
11 defalias by this name. Add doc string and comments.
12 (todos-modes-set-1, todos-modes-set-2, todos-modes-set-3)
13 (todos-mode-external-set): Add doc string.
14
12013-06-04 Stephen Berman <stephen.berman@gmx.net> 152013-06-04 Stephen Berman <stephen.berman@gmx.net>
2 16
3 * todos.el (todos-add-item-if-new-category): Change default value. 17 * todos.el (todos-add-item-if-new-category): Change default value.
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index 0f0d00ba1d8..d7b7991082c 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -24,30 +24,40 @@
24 24
25;; This package provides facilities for making, displaying, navigating 25;; This package provides facilities for making, displaying, navigating
26;; and editing todo lists, which are prioritized lists of todo items. 26;; and editing todo lists, which are prioritized lists of todo items.
27;; Todo lists are identified with named categories, providing a means 27;; Todo lists are identified with named categories, so you can group
28;; of grouping thematically related todo items. Each category is 28;; together thematically related todo items. Each category is stored
29;; stored in a file, which provides a further level of organization. 29;; in a file, which thus provides a further level of organization.
30 30;; You can create as many todo files, and in each as many categories,
31;; You can navigate among the items of a category, and between 31;; as you want.
32;; categories and files. You can edit items, reprioritize them within 32
33;; their category, move them to another category, delete them, or mark 33;; With Todos you can navigate among the items of a category, and
34;; items as done and store them separately from the not yet done items 34;; between categories in the same and in different todo files. You
35;; in a category. You can add new files and categories, rename 35;; can edit todo items, reprioritize them within their category, move
36;; categories, move them to another file or delete them. You can also 36;; them to another category, delete them, or mark items as done and
37;; build cross-categorial lists of items that satisfy various 37;; store them separately from the not yet done items in a category.
38;; criteria. And you can display summary tables of the categories in 38;; You can add new todo files and categories, rename categories, move
39;; a file and the types of items they contain. 39;; them to another file or delete them. You can also display summary
40;; tables of the categories in a file and the types of items they
41;; contain. And you can build cross-categorial lists of items that
42;; satisfy various criteria.
40 43
41;; To get started, load this package and type `M-x todos-show'. This 44;; To get started, load this package and type `M-x todos-show'. This
42;; will prompt you for the name of the first todo file and its first 45;; will prompt you for the name of the first todo file, its first
43;; category, create these and display the empty category in Todos 46;; category and the category's first item, create these and display
44;; mode. Then type `i i' to add the first todo item to the category 47;; them in Todos mode. Now you can insert further items into the list
45;; (i.e., to the list). To see a list of all Todos mode commands, 48;; (i.e., the category) and assign them priorities by typing `i i'.
46;; which include entry points to several auxiliary modes, type `C-h 49
47;; m'. Consult the document strings of the commands for details of 50;; You will probably find it convenient to give `todos-show' a global
48;; their use. The `todos' customization group and its subgroups list 51;; key binding in your init file, since it is one of the entry points
49;; the options you can set to alter the behavior of many commands and 52;; to Todos mode; a good choice is `C-c t', since `todos-show' is
50;; various aspects of the display. 53;; bound to `t' in Todos mode.
54
55;; To see a list of all Todos mode commands and their key bindings,
56;; including other entry points, type `C-h m' in Todos mode. Consult
57;; the document strings of the commands for details of their use. The
58;; `todos' customization group and its subgroups list the options you
59;; can set to alter the behavior of many commands and various aspects
60;; of the display.
51 61
52;; This package is a new version of Oliver Seidel's todo-mode.el, 62;; This package is a new version of Oliver Seidel's todo-mode.el,
53;; which retains the same basic organization and handling of todo 63;; which retains the same basic organization and handling of todo
@@ -158,7 +168,6 @@ Otherwise, `todos-show' always visits `todos-default-todos-file'."
158;;; Entering and exiting Todos mode 168;;; Entering and exiting Todos mode
159;; ----------------------------------------------------------------------------- 169;; -----------------------------------------------------------------------------
160 170
161;;;###autoload
162(defun todos-show (&optional solicit-file) 171(defun todos-show (&optional solicit-file)
163 "Visit a Todos file and display one of its categories. 172 "Visit a Todos file and display one of its categories.
164 173
@@ -276,8 +285,9 @@ corresponding Todos file, displaying the corresponding category."
276 cat-added t) 285 cat-added t)
277 (if cat-added 286 (if cat-added
278 ;; If the category was added, save the file now, so we 287 ;; If the category was added, save the file now, so we
279 ;; don't end up with an empty file, which would signal 288 ;; don't risk having an empty todo file, which would
280 ;; an error if we tried to visit it later. 289 ;; signal an error if we tried to visit it later,
290 ;; since doing that looks for category boundaries.
281 (save-buffer 0) 291 (save-buffer 0)
282 ;; If user cancels before adding the category, clean up 292 ;; If user cancels before adding the category, clean up
283 ;; and exit, so we have a fresh slate the next time. 293 ;; and exit, so we have a fresh slate the next time.
@@ -322,7 +332,9 @@ buries it and restores state as needed."
322 (kill-buffer) 332 (kill-buffer)
323 (unless (eq major-mode 'todos-mode) (todos-show))) 333 (unless (eq major-mode 'todos-mode) (todos-show)))
324 ((eq major-mode 'todos-archive-mode) 334 ((eq major-mode 'todos-archive-mode)
325 (todos-save) ; Have to write previously nonexistant archives to file. 335 ;; Have to write a newly created archive to file to avoid
336 ;; subsequent errors.
337 (todos-save)
326 (todos-show) 338 (todos-show)
327 (bury-buffer buf)) 339 (bury-buffer buf))
328 ((eq major-mode 'todos-mode) 340 ((eq major-mode 'todos-mode)
@@ -363,7 +375,6 @@ category."
363 (interactive) 375 (interactive)
364 (todos-forward-category t)) 376 (todos-forward-category t))
365 377
366;;;###autoload
367(defun todos-jump-to-category (&optional file where) 378(defun todos-jump-to-category (&optional file where)
368 "Prompt for a category in a Todos file and jump to it. 379 "Prompt for a category in a Todos file and jump to it.
369 380
@@ -1058,7 +1069,6 @@ means prompt user and omit comment only on confirmation."
1058;;; Item editing commands 1069;;; Item editing commands
1059;; ----------------------------------------------------------------------------- 1070;; -----------------------------------------------------------------------------
1060 1071
1061;;;###autoload
1062(defun todos-basic-insert-item (&optional arg diary nonmarking date-type time 1072(defun todos-basic-insert-item (&optional arg diary nonmarking date-type time
1063 region-or-here) 1073 region-or-here)
1064 "Insert a new Todo item into a category. 1074 "Insert a new Todo item into a category.
@@ -4039,11 +4049,11 @@ number as its value."
4039 (let ((sep todos-done-separator-string)) 4049 (let ((sep todos-done-separator-string))
4040 (propertize (if (= 1 (length sep)) 4050 (propertize (if (= 1 (length sep))
4041 ;; Until bug#2749 is fixed, if separator's length 4051 ;; Until bug#2749 is fixed, if separator's length
4042 ;; is window-width, then with non-nil 4052 ;; is window-width and todos-wrap-lines is
4043 ;; todos-wrap-lines an indented empty line appears 4053 ;; non-nil, an indented empty line appears between
4044 ;; between the separator and the first done item. 4054 ;; the separator and the first done item.
4045 ;; (make-string (1- (window-width)) (string-to-char sep)) 4055 ;; (make-string (window-width) (string-to-char sep))
4046 (make-string (window-width) (string-to-char sep)) 4056 (make-string (1- (window-width)) (string-to-char sep))
4047 todos-done-separator-string) 4057 todos-done-separator-string)
4048 'face 'todos-done-sep))) 4058 'face 'todos-done-sep)))
4049 4059
@@ -4386,6 +4396,17 @@ empty line above the done items separator."
4386 (todos-item-start) 4396 (todos-item-start)
4387 (not (looking-at (regexp-quote todos-nondiary-start)))))) 4397 (not (looking-at (regexp-quote todos-nondiary-start))))))
4388 4398
4399(defun todos-diary-goto-entry ()
4400 "Jump to todo item included in Fancy Diary display.
4401Helper function for `diary-goto-entry'."
4402 (when (eq major-mode 'todos-mode)
4403 (setq opoint (point))
4404 (re-search-backward (concat "^" (regexp-quote todos-category-beg)
4405 "\\(.*\\)\n") nil t)
4406 (todos-category-number (match-string 1))
4407 (todos-category-select)
4408 (goto-char opoint)))
4409
4389(defun todos-done-item-p () 4410(defun todos-done-item-p ()
4390 "Return non-nil if item at point is a done item." 4411 "Return non-nil if item at point is a done item."
4391 (save-excursion 4412 (save-excursion
@@ -4495,21 +4516,28 @@ of each other."
4495;;; Generation of item insertion commands and key bindings 4516;;; Generation of item insertion commands and key bindings
4496;; ----------------------------------------------------------------------------- 4517;; -----------------------------------------------------------------------------
4497 4518
4498;; Can either of these be included in Emacs? The originals are GFDL'd. 4519;; These two powerset definitions are adaptations of code published at
4499 4520;; http://rosettacode.org, whose content is licensed under GFDL 1.2.
4500;; Reformulation of http://rosettacode.org/wiki/Power_set#Common_Lisp. 4521;; The recursive definition is a slight reformulation of
4501(defun todos-powerset-recursive (list) 4522;; http://rosettacode.org/wiki/Power_set#Common_Lisp. The iterative
4502 (cond ((null list) 4523;; definition is my Elisp implementation of
4503 (list nil)) 4524;; http://rosettacode.org/wiki/Power_set#C. Can either of these be
4504 (t 4525;; included in Emacs, or is there no need to concerned about copyright
4505 (let ((recur (todos-powerset-recursive (cdr list))) 4526;; here?
4506 pset) 4527
4507 (dolist (elt recur pset) 4528;; (defun todos-powerset (list)
4508 (push (cons (car list) elt) pset)) 4529;; "Return the powerset of LIST."
4509 (append pset recur))))) 4530;; (cond ((null list)
4510 4531;; (list nil))
4511;; Elisp implementation of http://rosettacode.org/wiki/Power_set#C. 4532;; (t
4512(defun todos-powerset-iterative (list) 4533;; (let ((recur (todos-powerset-recursive (cdr list)))
4534;; pset)
4535;; (dolist (elt recur pset)
4536;; (push (cons (car list) elt) pset))
4537;; (append pset recur)))))
4538
4539(defun todos-powerset (list)
4540 "Return the powerset of LIST."
4513 (let ((card (expt 2 (length list))) 4541 (let ((card (expt 2 (length list)))
4514 pset elt) 4542 pset elt)
4515 (dotimes (n card) 4543 (dotimes (n card)
@@ -4524,9 +4552,6 @@ of each other."
4524 (setq elt nil))) 4552 (setq elt nil)))
4525 pset)) 4553 pset))
4526 4554
4527;; (defalias 'todos-powerset 'todos-powerset-recursive)
4528(defalias 'todos-powerset 'todos-powerset-iterative)
4529
4530(defun todos-gen-arglists (arglist) 4555(defun todos-gen-arglists (arglist)
4531 "Return list of lists of non-nil atoms produced from ARGLIST. 4556 "Return list of lists of non-nil atoms produced from ARGLIST.
4532The elements of ARGLIST may be atoms or lists." 4557The elements of ARGLIST may be atoms or lists."
@@ -6242,7 +6267,7 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6242;; ----------------------------------------------------------------------------- 6267;; -----------------------------------------------------------------------------
6243 6268
6244(defun todos-modes-set-1 () 6269(defun todos-modes-set-1 ()
6245 "" 6270 "Make some settings that apply to multiple Todos modes."
6246 (setq-local font-lock-defaults '(todos-font-lock-keywords t)) 6271 (setq-local font-lock-defaults '(todos-font-lock-keywords t))
6247 (setq-local tab-width todos-indent-to-here) 6272 (setq-local tab-width todos-indent-to-here)
6248 (setq-local indent-line-function 'todos-indent) 6273 (setq-local indent-line-function 'todos-indent)
@@ -6251,7 +6276,7 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6251 (setq wrap-prefix (make-string todos-indent-to-here 32)))) 6276 (setq wrap-prefix (make-string todos-indent-to-here 32))))
6252 6277
6253(defun todos-modes-set-2 () 6278(defun todos-modes-set-2 ()
6254 "" 6279 "Make some settings that apply to multiple Todos modes."
6255 (add-to-invisibility-spec 'todos) 6280 (add-to-invisibility-spec 'todos)
6256 (setq buffer-read-only t) 6281 (setq buffer-read-only t)
6257 (setq-local hl-line-range-function (lambda() (save-excursion 6282 (setq-local hl-line-range-function (lambda() (save-excursion
@@ -6260,7 +6285,7 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6260 (todos-item-end))))))) 6285 (todos-item-end)))))))
6261 6286
6262(defun todos-modes-set-3 () 6287(defun todos-modes-set-3 ()
6263 "" 6288 "Make some settings that apply to multiple Todos modes."
6264 (setq-local todos-categories (todos-set-categories)) 6289 (setq-local todos-categories (todos-set-categories))
6265 (setq-local todos-category-number 1) 6290 (setq-local todos-category-number 1)
6266 (add-hook 'find-file-hook 'todos-display-as-todos-file nil t)) 6291 (add-hook 'find-file-hook 'todos-display-as-todos-file nil t))
@@ -6304,7 +6329,7 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6304 (setq-local todos-show-done-only t)) 6329 (setq-local todos-show-done-only t))
6305 6330
6306(defun todos-mode-external-set () 6331(defun todos-mode-external-set ()
6307 "" 6332 "Set `todos-categories' externally to `todos-current-todos-file'."
6308 (setq-local todos-current-todos-file todos-global-current-todos-file) 6333 (setq-local todos-current-todos-file todos-global-current-todos-file)
6309 (let ((cats (with-current-buffer 6334 (let ((cats (with-current-buffer
6310 ;; Can't use find-buffer-visiting when 6335 ;; Can't use find-buffer-visiting when
@@ -6356,46 +6381,3 @@ Added to `window-configuration-change-hook' in `todos-mode'."
6356(provide 'todos) 6381(provide 'todos)
6357 6382
6358;;; todos.el ends here 6383;;; todos.el ends here
6359
6360;;; necessitated adaptations to diary-lib.el
6361
6362(defun diary-goto-entry (button)
6363 "Jump to the diary entry for the BUTTON at point."
6364 (let* ((locator (button-get button 'locator))
6365 (marker (car locator))
6366 markbuf file opoint)
6367 ;; If marker pointing to diary location is valid, use that.
6368 (if (and marker (setq markbuf (marker-buffer marker)))
6369 (progn
6370 (pop-to-buffer markbuf)
6371 (when (eq major-mode 'todos-mode) (widen))
6372 (goto-char (marker-position marker))
6373 (when (eq major-mode 'todos-mode)
6374 (re-search-backward (concat "^" (regexp-quote todos-category-beg)
6375 "\\(.*\\)\n") nil t)
6376 (todos-category-number (match-string 1))
6377 (todos-category-select)
6378 (goto-char (marker-position marker))))
6379 ;; Marker is invalid (eg buffer has been killed).
6380 (or (and (setq file (cadr locator))
6381 (file-exists-p file)
6382 (find-file-other-window file)
6383 (progn
6384 (when (eq major-mode (default-value 'major-mode)) (diary-mode))
6385 (when (eq major-mode 'todos-mode) (widen))
6386 (goto-char (point-min))
6387 (when (re-search-forward (format "%s.*\\(%s\\)"
6388 (regexp-quote (nth 2 locator))
6389 (regexp-quote (nth 3 locator)))
6390 nil t)
6391 (goto-char (match-beginning 1))
6392 (when (eq major-mode 'todos-mode)
6393 (setq opoint (point))
6394 (re-search-backward (concat "^"
6395 (regexp-quote todos-category-beg)
6396 "\\(.*\\)\n")
6397 nil t)
6398 (todos-category-number (match-string 1))
6399 (todos-category-select)
6400 (goto-char opoint)))))
6401 (message "Unable to locate this diary entry")))))