aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2012-05-27 23:40:56 +0100
committerStephen Berman2012-05-27 23:40:56 +0100
commit459c6e9331e8128b32ad966137115f1bf1d88423 (patch)
treeea3d5bf95ccc374c1e7fe89da163312672a9e1c2
parent2a9e69d6098c9454a1c022f0d11ddae0751f1c05 (diff)
downloademacs-459c6e9331e8128b32ad966137115f1bf1d88423.tar.gz
emacs-459c6e9331e8128b32ad966137115f1bf1d88423.zip
* calendar/todos.el: Further comment revision.
(todos-reset-global-current-todos-file): Try to make this not slow down kill-buffer. (todos-update-categories-sexp): Handle the case where there is no categories sexp yet, i.e. after inserting the first item in the file, so todos-display-categories works. (todos-read-file-name): Improve implementation. (todos-validate-name): Use variable todos-files. (todos-category-number): New variable. (todos-insert-category-line, todos-update-categories-display) (todos-raise-category-priority): Use it. (todos-add-file): Remove unused remnant code.
-rw-r--r--lisp/ChangeLog15
-rw-r--r--lisp/calendar/todos.el266
2 files changed, 141 insertions, 140 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c595306bcc5..576afa3c4eb 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,6 +1,21 @@
12012-09-21 Stephen Berman <stephen.berman@gmx.net> 12012-09-21 Stephen Berman <stephen.berman@gmx.net>
2 2
3 * calendar/todos.el: Further comment revision. 3 * calendar/todos.el: Further comment revision.
4 (todos-reset-global-current-todos-file):
5 Try to make this not slow down kill-buffer.
6 (todos-update-categories-sexp): Handle the case where there is no
7 categories sexp yet, i.e. after inserting the first item in the
8 file, so todos-display-categories works.
9 (todos-read-file-name): Improve implementation.
10 (todos-validate-name): Use variable todos-files.
11 (todos-category-number): New variable.
12 (todos-insert-category-line, todos-update-categories-display)
13 (todos-raise-category-priority): Use it.
14 (todos-add-file): Remove unused remnant code.
15
162012-09-21 Stephen Berman <stephen.berman@gmx.net>
17
18 * calendar/todos.el: Further comment revision.
4 (todos-set-item-top-priority): New command. 19 (todos-set-item-top-priority): New command.
5 (todos-reset-global-current-todos-file): 20 (todos-reset-global-current-todos-file):
6 Use todos-files-function instead of todos-files. 21 Use todos-files-function instead of todos-files.
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index 82c8f03210c..89bfeabb919 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -28,7 +28,8 @@
28;;; Code: 28;;; Code:
29 29
30(require 'diary-lib) 30(require 'diary-lib)
31;; For remove-duplicates in todos-insertion-commands-args. 31;; For remove-if-not and find-if-not in todos-reset-global-current-todos-file
32;; and for remove-duplicates in todos-insertion-commands-args.
32(eval-when-compile (require 'cl)) 33(eval-when-compile (require 'cl))
33 34
34;; --------------------------------------------------------------------------- 35;; ---------------------------------------------------------------------------
@@ -913,19 +914,35 @@ This function is added to `pre-command-hook' when user option
913This becomes the latest existing Todos file or, if there is none, 914This becomes the latest existing Todos file or, if there is none,
914the value of `todos-default-todos-file'. 915the value of `todos-default-todos-file'.
915This function is added to `kill-buffer-hook' in Todos mode." 916This function is added to `kill-buffer-hook' in Todos mode."
916 (let ((buflist (copy-sequence (buffer-list))) 917 ;; (let ((buflist (copy-sequence (buffer-list)))
917 (cur todos-global-current-todos-file)) 918 ;; (cur todos-global-current-todos-file))
918 (catch 'done 919 ;; (catch 'done
919 (while buflist 920 ;; (while buflist
920 (let* ((buf (pop buflist)) 921 ;; (let* ((buf (pop buflist))
921 (bufname (buffer-file-name buf))) 922 ;; (bufname (buffer-file-name buf)))
922 (when bufname (setq bufname (file-truename bufname))) 923 ;; (when bufname (setq bufname (file-truename bufname)))
923 (when (and (member bufname (funcall todos-files-function)) 924 ;; (when (and (member bufname (funcall todos-files-function))
924 (not (eq buf (current-buffer)))) 925 ;; (not (eq buf (current-buffer))))
925 (setq todos-global-current-todos-file bufname) 926 ;; (setq todos-global-current-todos-file bufname)
926 (throw 'done nil))))) 927 ;; (throw 'done nil)))))
927 (if (equal cur todos-global-current-todos-file) 928 ;; (if (equal cur todos-global-current-todos-file)
928 (setq todos-global-current-todos-file todos-default-todos-file)))) 929 ;; (setq todos-global-current-todos-file todos-default-todos-file))))
930 (let ((todos-buffer-list (nreverse
931 (remove-if-not
932 (lambda (f)
933 (member f (mapcar
934 'file-name-nondirectory
935 (funcall todos-files-function))))
936 (mapcar 'buffer-name (buffer-list)))))
937 latest)
938 ;; (while todos-buffer-list
939 ;; (let ((todos-bufname (pop todos-buffer-list)))
940 ;; (unless (string= todos-bufname (buffer-name))
941 ;; (setq latest todos-bufname
942 ;; todos-buffer-list nil))))
943 (setq latest (find-if-not (lambda (f) (string= f (buffer-name)))
944 todos-buffer-list))
945 (setq todos-global-current-todos-file (or latest todos-default-todos-file))))
929 946
930(defvar todos-categories nil 947(defvar todos-categories nil
931 "Alist of categories in the current Todos file. 948 "Alist of categories in the current Todos file.
@@ -1109,7 +1126,7 @@ With nil or omitted CATEGORY, default to the current category."
1109 ((eq type 'archived) 3)))) 1126 ((eq type 'archived) 3))))
1110 (aset counts idx (+ increment (aref counts idx))))) 1127 (aset counts idx (+ increment (aref counts idx)))))
1111 1128
1112(defun todos-set-categories () 1129(defun todos-set-categories () ;FIXME
1113 "Set `todos-categories' from the sexp at the top of the file." 1130 "Set `todos-categories' from the sexp at the top of the file."
1114 ;; New archive files created by `todos-move-category' are empty, which would 1131 ;; New archive files created by `todos-move-category' are empty, which would
1115 ;; make the sexp test fail and raise an error, so in this case we skip it. 1132 ;; make the sexp test fail and raise an error, so in this case we skip it.
@@ -1139,7 +1156,15 @@ With nil or omitted CATEGORY, default to the current category."
1139 (widen) 1156 (widen)
1140 (goto-char (point-min)) 1157 (goto-char (point-min))
1141 (if (looking-at (concat "^" (regexp-quote todos-category-beg))) 1158 (if (looking-at (concat "^" (regexp-quote todos-category-beg)))
1142 (progn (newline) (goto-char (point-min))) 1159 (progn (newline) (goto-char (point-min)) ; Make space for sexp.
1160 ;; No categories sexp means the first item was just added
1161 ;; to this file, so have to initialize Todos file and
1162 ;; categories variables in order e.g. to enable categories
1163 ;; display.
1164 (setq todos-default-todos-file (buffer-file-name))
1165 (setq todos-categories (todos-make-categories-list t))
1166 (when todos-ignore-archived-categories
1167 (setq todos-categories-full todos-categories)))
1143 ;; With empty buffer (e.g. with new archive in 1168 ;; With empty buffer (e.g. with new archive in
1144 ;; `todos-move-category') `kill-line' signals end of buffer. 1169 ;; `todos-move-category') `kill-line' signals end of buffer.
1145 (kill-region (line-beginning-position) (line-end-position))) 1170 (kill-region (line-beginning-position) (line-end-position)))
@@ -1398,22 +1423,19 @@ form but the absolute truename is returned. With non-nil ARCHIVE
1398return the absolute truename of a Todos archive file. With non-nil 1423return the absolute truename of a Todos archive file. With non-nil
1399MUSTMATCH the name of an existing file must be chosen; 1424MUSTMATCH the name of an existing file must be chosen;
1400otherwise, a new file name is allowed." 1425otherwise, a new file name is allowed."
1401 (unless (file-exists-p todos-files-directory) 1426 (let* ((completion-ignore-case todos-completion-ignore-case)
1402 (make-directory todos-files-directory)) 1427 (files (mapcar 'todos-short-file-name
1403 (let ((completion-ignore-case todos-completion-ignore-case) 1428 (if archive todos-archives todos-files)))
1404 (files (mapcar 'file-name-sans-extension 1429 (file (completing-read prompt files nil mustmatch nil nil
1405 (directory-files todos-files-directory nil 1430 (unless files
1406 (if archive "\.toda$" "\.todo$")))) 1431 ;; Trigger prompt for initial file.
1407 (file "")) 1432 ""))))
1408 (while (string= "" file) 1433 (unless (file-exists-p todos-files-directory)
1409 (setq file (completing-read prompt files nil mustmatch)) 1434 (make-directory todos-files-directory))
1410 (setq prompt "Enter a non-empty name (TAB for list of current files): "))
1411 (setq file (concat todos-files-directory file
1412 (if archive ".toda" ".todo")))
1413 (unless mustmatch 1435 (unless mustmatch
1414 (when (not (member file todos-files)) 1436 (setq file (todos-validate-name file 'file)))
1415 (todos-validate-name file 'file))) 1437 (setq file (file-truename (concat todos-files-directory file
1416 (file-truename file))) 1438 (if archive ".toda" ".todo"))))))
1417 1439
1418(defun todos-read-category (prompt &optional mustmatch added) 1440(defun todos-read-category (prompt &optional mustmatch added)
1419 "Choose and return a category name, prompting with PROMPT. 1441 "Choose and return a category name, prompting with PROMPT.
@@ -1436,11 +1458,10 @@ ask whether to add the category."
1436 ;; current category. 1458 ;; current category.
1437 (if todos-categories 1459 (if todos-categories
1438 (todos-current-category) 1460 (todos-current-category)
1439 ;; Trigger prompt for initial category 1461 ;; Trigger prompt for initial category.
1440 ""))) 1462 "")))
1441 new) 1463 new)
1442 (unless mustmatch 1464 (unless mustmatch
1443 ;; (when (not (assoc cat categories))
1444 (todos-validate-name cat 'category) 1465 (todos-validate-name cat 'category)
1445 (unless added 1466 (unless added
1446 (if (y-or-n-p (format (concat "There is no category \"%s\" in " 1467 (if (y-or-n-p (format (concat "There is no category \"%s\" in "
@@ -1463,7 +1484,7 @@ TYPE can be either a file or a category"
1463 (setq prompt 1484 (setq prompt
1464 (cond ((eq type 'file) 1485 (cond ((eq type 'file)
1465 ;; FIXME: just todos-files ? 1486 ;; FIXME: just todos-files ?
1466 (if (funcall (todos-files)) 1487 (if todos-files
1467 "Enter a non-empty file name: " 1488 "Enter a non-empty file name: "
1468 ;; Empty string passed by todos-show to 1489 ;; Empty string passed by todos-show to
1469 ;; prompt for initial Todos file. 1490 ;; prompt for initial Todos file.
@@ -1942,18 +1963,20 @@ LABEL determines which type of count is sorted."
1942 (mapcar 'cdr todos-categories)))) 1963 (mapcar 'cdr todos-categories))))
1943 (list 0 1 2 3))) 1964 (list 0 1 2 3)))
1944 1965
1966(defvar todos-category-number nil)
1967
1945(defun todos-insert-category-line (cat &optional nonum) 1968(defun todos-insert-category-line (cat &optional nonum)
1946 "Insert button displaying category CAT's name and item counts. 1969 "Insert button with category CAT's name and item counts.
1947With non-nil argument NONUM show only these; otherwise, insert a 1970With non-nil argument NONUM show only these; otherwise, insert a
1948number in front of the button indicating the category's priority. 1971number in front of the button indicating the category's priority.
1949The number and the category name are separated by the string 1972The number and the category name are separated by the string
1950which is the value of the user option 1973which is the value of the user option
1951`todos-categories-number-separator'." 1974`todos-categories-number-separator'."
1952 (let* ((archive (member todos-current-todos-file todos-archives)) 1975 (let ((archive (member todos-current-todos-file todos-archives))
1976 (num todos-category-number)
1953 (str (todos-padded-string cat)) 1977 (str (todos-padded-string cat))
1954 (opoint (point))) 1978 (opoint (point)))
1955 ;; num is declared in caller. 1979 (setq num (1+ num) todos-category-number num)
1956 (setq num (1+ num))
1957 (insert-button 1980 (insert-button
1958 (concat (if nonum 1981 (concat (if nonum
1959 (make-string (+ 4 (length todos-categories-number-separator)) 1982 (make-string (+ 4 (length todos-categories-number-separator))
@@ -2043,49 +2066,49 @@ which is the value of the user option
2043(defun todos-update-categories-display (sortkey) 2066(defun todos-update-categories-display (sortkey)
2044 "" 2067 ""
2045 (let* ((cats0 (if (and todos-ignore-archived-categories 2068 (let* ((cats0 (if (and todos-ignore-archived-categories
2046 (not (eq major-mode 'todos-categories-mode))) 2069 ;; FIXME: is this every true?
2047 todos-categories-full 2070 (not (eq major-mode 'todos-categories-mode)))
2048 todos-categories)) 2071 todos-categories-full
2049 (cats (todos-sort cats0 sortkey)) 2072 todos-categories))
2050 (archive (member todos-current-todos-file todos-archives)) 2073 (cats (todos-sort cats0 sortkey))
2051 ;; `num' is used by todos-insert-category-line. 2074 (archive (member todos-current-todos-file todos-archives))
2052 (num 0) 2075 (todos-category-number 0)
2053 ;; Find start of Category button if we just entered Todos Categories 2076 ;; Find start of Category button if we just entered Todos Categories
2054 ;; mode. 2077 ;; mode.
2055 (pt (if (eq (point) (point-max)) 2078 (pt (if (eq (point) (point-max))
2056 (save-excursion 2079 (save-excursion
2057 (forward-line -2) 2080 (forward-line -2)
2058 (goto-char (next-single-char-property-change 2081 (goto-char (next-single-char-property-change
2059 (point) 'face nil (line-end-position)))))) 2082 (point) 'face nil (line-end-position))))))
2060 (buffer-read-only)) 2083 (buffer-read-only))
2061 (forward-line 2) 2084 (forward-line 2)
2062 (delete-region (point) (point-max)) 2085 (delete-region (point) (point-max))
2063 ;; Fill in the table with buttonized lines, each showing a category and 2086 ;; Fill in the table with buttonized lines, each showing a category and
2064 ;; its item counts. 2087 ;; its item counts.
2065 (mapc (lambda (cat) (todos-insert-category-line cat sortkey)) 2088 (mapc (lambda (cat) (todos-insert-category-line cat sortkey))
2066 (mapcar 'car cats)) 2089 (mapcar 'car cats))
2067 (newline) 2090 (newline)
2068 ;; Add a line showing item count totals. 2091 ;; Add a line showing item count totals.
2069 (insert (make-string (+ 4 (length todos-categories-number-separator)) 32) 2092 (insert (make-string (+ 4 (length todos-categories-number-separator)) 32)
2070 (todos-padded-string todos-categories-totals-label) 2093 (todos-padded-string todos-categories-totals-label)
2071 (mapconcat 2094 (mapconcat
2072 (lambda (elt) 2095 (lambda (elt)
2073 (concat 2096 (concat
2074 (make-string (1+ (/ (length (car elt)) 2)) 32) 2097 (make-string (1+ (/ (length (car elt)) 2)) 32)
2075 (format "%3d" (nth (cdr elt) (todos-total-item-counts))) 2098 (format "%3d" (nth (cdr elt) (todos-total-item-counts)))
2076 ;; Add an extra space if label length is odd (using 2099 ;; Add an extra space if label length is odd (using
2077 ;; definition of oddp from cl.el). 2100 ;; definition of oddp from cl.el).
2078 (if (eq (logand (length (car elt)) 1) 1) " "))) 2101 (if (eq (logand (length (car elt)) 1) 1) " ")))
2079 (if archive 2102 (if archive
2080 (list (cons todos-categories-done-label 2)) 2103 (list (cons todos-categories-done-label 2))
2081 (list (cons todos-categories-todo-label 0) 2104 (list (cons todos-categories-todo-label 0)
2082 (cons todos-categories-diary-label 1) 2105 (cons todos-categories-diary-label 1)
2083 (cons todos-categories-done-label 2) 2106 (cons todos-categories-done-label 2)
2084 (cons todos-categories-archived-label 3))) 2107 (cons todos-categories-archived-label 3)))
2085 "")) 2108 ""))
2086 ;; Put cursor on Category button initially. 2109 ;; Put cursor on Category button initially.
2087 (if pt (goto-char pt)) 2110 (if pt (goto-char pt))
2088 (setq buffer-read-only t))) 2111 (setq buffer-read-only t)))
2089 2112
2090;; --------------------------------------------------------------------------- 2113;; ---------------------------------------------------------------------------
2091;;; Todos insertion commands, key bindings and keymap 2114;;; Todos insertion commands, key bindings and keymap
@@ -2552,6 +2575,7 @@ which is the value of the user option
2552 todos-global-current-todos-file) 2575 todos-global-current-todos-file)
2553 (let ((cats (with-current-buffer (get-file-buffer todos-current-todos-file) 2576 (let ((cats (with-current-buffer (get-file-buffer todos-current-todos-file)
2554 (if todos-ignore-archived-categories 2577 (if todos-ignore-archived-categories
2578 ;; FIXME: how will this be set?
2555 todos-categories-full 2579 todos-categories-full
2556 (todos-set-categories))))) 2580 (todos-set-categories)))))
2557 (set (make-local-variable 'todos-categories) cats))) 2581 (set (make-local-variable 'todos-categories) cats)))
@@ -2639,24 +2663,24 @@ corresponding Todos file, displaying the corresponding category."
2639 (interactive "P") 2663 (interactive "P")
2640 (let* ((cat) 2664 (let* ((cat)
2641 (file (cond (solicit-file 2665 (file (cond (solicit-file
2642 (if (funcall todos-files-function) 2666 (if (funcall todos-files-function)
2643 (todos-read-file-name "Choose a Todos file to visit: " 2667 (todos-read-file-name "Choose a Todos file to visit: "
2644 nil t) 2668 nil t)
2645 (error "There are no Todos files"))) 2669 (error "There are no Todos files")))
2646 ((eq major-mode 'todos-archive-mode) 2670 ((eq major-mode 'todos-archive-mode)
2647 (setq cat (todos-current-category)) 2671 (setq cat (todos-current-category))
2648 (concat (file-name-sans-extension todos-current-todos-file) 2672 (concat (file-name-sans-extension todos-current-todos-file)
2649 ".todo")) 2673 ".todo"))
2650 (t 2674 (t
2651 ;; FIXME: If an archive is value of 2675 ;; FIXME: If an archive is value of
2652 ;; todos-current-todos-file, todos-show will revisit 2676 ;; todos-current-todos-file, todos-show will revisit
2653 ;; rather than the corresponding todo file -- ok or make 2677 ;; rather than the corresponding todo file -- ok or make
2654 ;; it customizable? 2678 ;; it customizable?
2655 (or todos-current-todos-file 2679 (or todos-current-todos-file
2656 (and todos-show-current-file 2680 (and todos-show-current-file
2657 todos-global-current-todos-file) 2681 todos-global-current-todos-file)
2658 todos-default-todos-file 2682 todos-default-todos-file
2659 (todos-add-file)))))) 2683 (todos-add-file))))))
2660 (if (and todos-first-visit todos-display-categories-first) 2684 (if (and todos-first-visit todos-display-categories-first)
2661 (todos-display-categories) 2685 (todos-display-categories)
2662 (set-window-buffer (selected-window) 2686 (set-window-buffer (selected-window)
@@ -3407,9 +3431,8 @@ Noninteractively, return the name of the new file."
3407 (interactive) 3431 (interactive)
3408 (let ((prompt (concat "Enter name of new Todos file " 3432 (let ((prompt (concat "Enter name of new Todos file "
3409 "(TAB or SPC to see current names): ")) 3433 "(TAB or SPC to see current names): "))
3410 file shortname) 3434 file)
3411 (setq file (todos-read-file-name prompt));)) 3435 (setq file (todos-read-file-name prompt))
3412 (setq shortname (todos-short-file-name file))
3413 (with-current-buffer (get-buffer-create file) 3436 (with-current-buffer (get-buffer-create file)
3414 (erase-buffer) 3437 (erase-buffer)
3415 (write-region (point-min) (point-max) file nil 'nomessage nil t) 3438 (write-region (point-min) (point-max) file nil 'nomessage nil t)
@@ -3423,43 +3446,6 @@ Noninteractively, return the name of the new file."
3423 (todos-show)) 3446 (todos-show))
3424 file))) 3447 file)))
3425 3448
3426;; FIXME: return value is not used by most callers
3427;; (defun todos-add-category (&optional cat)
3428;; "Add a new category to the current Todos file.
3429;; Called interactively, prompts for category name, then visits the
3430;; category in Todos mode. Non-interactively, argument CAT provides
3431;; the category name and the return value is the category number."
3432;; (interactive)
3433;; (let* ((buffer-read-only)
3434;; ;; FIXME: check against todos-archive-done-item with empty file
3435;; (buf (find-file-noselect todos-current-todos-file t))
3436;; ;; (buf (get-file-buffer todos-current-todos-file))
3437;; (num (1+ (length todos-categories)))
3438;; (counts (make-vector 4 0))) ; [todo diary done archived]
3439;; (unless (zerop (buffer-size buf))
3440;; (and (null todos-categories)
3441;; (error "Error in %s: File is non-empty but contains no category"
3442;; todos-current-todos-file)))
3443;; (unless cat (setq cat (read-from-minibuffer "Enter new category name: ")))
3444;; (with-current-buffer buf
3445;; (setq cat (todos-validate-name cat 'category))
3446;; (setq todos-categories (append todos-categories (list (cons cat counts))))
3447;; (if todos-categories-full
3448;; (setq todos-categories-full (append todos-categories-full
3449;; (list (cons cat counts)))))
3450;; (widen)
3451;; (goto-char (point-max))
3452;; (save-excursion ; Save point for todos-category-select.
3453;; (insert todos-category-beg cat "\n\n" todos-category-done "\n"))
3454;; (todos-update-categories-sexp)
3455;; ;; If called by command, display the newly added category, else return
3456;; ;; the category number to the caller.
3457;; (if (called-interactively-p 'any) ; FIXME?
3458;; (progn
3459;; (setq todos-category-number num)
3460;; (todos-category-select))
3461;; num))))
3462
3463(defun todos-add-category (&optional cat) 3449(defun todos-add-category (&optional cat)
3464 "Add a new category to the current Todos file. 3450 "Add a new category to the current Todos file.
3465Called interactively, prompts for category name, then visits the 3451Called interactively, prompts for category name, then visits the
@@ -3588,7 +3574,7 @@ i.e. including all existing todo and done items."
3588 "Raise priority of category point is on in Todos Categories buffer. 3574 "Raise priority of category point is on in Todos Categories buffer.
3589With non-nil argument LOWER, lower the category's priority." 3575With non-nil argument LOWER, lower the category's priority."
3590 (interactive) 3576 (interactive)
3591 (let (num) 3577 (let ((num todos-category-number))
3592 (save-excursion 3578 (save-excursion
3593 (forward-line 0) 3579 (forward-line 0)
3594 (skip-chars-forward " ") 3580 (skip-chars-forward " ")