diff options
| author | Stephen Berman | 2013-01-14 13:51:14 +0100 |
|---|---|---|
| committer | Stephen Berman | 2013-01-14 13:51:14 +0100 |
| commit | 20166aeaa8fb74437ab85a74ff0dca498f5350e7 (patch) | |
| tree | c8bb804e8128d6e6860e475dbfeaf18e423b2ea4 | |
| parent | b58fa72f2ad2f2c268a3e6eb8d884fe0f229dfac (diff) | |
| download | emacs-20166aeaa8fb74437ab85a74ff0dca498f5350e7.tar.gz emacs-20166aeaa8fb74437ab85a74ff0dca498f5350e7.zip | |
* calendar/todos.el: Implement saving top priority items buffers,
improve implementation of item filtering commands and
infrastucture, and fix two bugs.
(todos-prefix-overlays): Use todos-top-priority face only in Todos
mode.
(todos-multiple-filter-files): Get file-truename of Todos file.
(todos-filter-items): Pass a list of files from the caller instead
of building it here, and move handling of cancelled file selection
dialog to callers. Correct omission of file-wide default number
of top priorities.
(todos-filtered-buffer-name): Treat file-list argument only as a list.
(todos-find-item, todos-check-top-priorities)
(todos-top-priorities-filename)
(todos-save-top-priorities-buffer): New functions.
(todos-save): Use todos-save-top-priorities-buffer.
(todos-jump-to-item): Refactor and use todos-find-item.
(todos-top-priorities): Simplify semantics of prefix argument.
Check if top priorities file exists and if so, visit it, reporting
whether it is up to date. Add optional argument and use it to
handle multiple files.
(todos-diary-items, todos-regexp-items): Add optional argument and
use it to handle multiple files.
(todos-top-priorities-multifile, todos-diary-items-multifile)
(todos-regexp-items-multifile): Refactor, using corresponding
non-multifile command.
(auto-mode-alist): Add pattern for top priorities files to visit
these in Todos Filtered Items mode.
| -rw-r--r-- | lisp/ChangeLog | 30 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 395 |
2 files changed, 273 insertions, 152 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c529800e564..43587c6bc46 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,33 @@ | |||
| 1 | 2013-01-14 Stephen Berman <stephen.berman@gmx.net> | ||
| 2 | |||
| 3 | * calendar/todos.el: Implement saving top priority items buffers, | ||
| 4 | improve implementation of item filtering commands and | ||
| 5 | infrastucture, and fix two bugs. | ||
| 6 | (todos-prefix-overlays): Use todos-top-priority face only in Todos | ||
| 7 | mode. | ||
| 8 | (todos-multiple-filter-files): Get file-truename of Todos file. | ||
| 9 | (todos-filter-items): Pass a list of files from the caller instead | ||
| 10 | of building it here, and move handling of cancelled file selection | ||
| 11 | dialog to callers. Correct omission of file-wide default number | ||
| 12 | of top priorities. | ||
| 13 | (todos-filtered-buffer-name): Treat file-list argument only as a list. | ||
| 14 | (todos-find-item, todos-check-top-priorities) | ||
| 15 | (todos-top-priorities-filename) | ||
| 16 | (todos-save-top-priorities-buffer): New functions. | ||
| 17 | (todos-save): Use todos-save-top-priorities-buffer. | ||
| 18 | (todos-jump-to-item): Refactor and use todos-find-item. | ||
| 19 | (todos-top-priorities): Simplify semantics of prefix argument. | ||
| 20 | Check if top priorities file exists and if so, visit it, reporting | ||
| 21 | whether it is up to date. Add optional argument and use it to | ||
| 22 | handle multiple files. | ||
| 23 | (todos-diary-items, todos-regexp-items): Add optional argument and | ||
| 24 | use it to handle multiple files. | ||
| 25 | (todos-top-priorities-multifile, todos-diary-items-multifile) | ||
| 26 | (todos-regexp-items-multifile): Refactor, using corresponding | ||
| 27 | non-multifile command. | ||
| 28 | (auto-mode-alist): Add pattern for top priorities files to visit | ||
| 29 | these in Todos Filtered Items mode. | ||
| 30 | |||
| 1 | 2013-01-08 Stephen Berman <stephen.berman@gmx.net> | 31 | 2013-01-08 Stephen Berman <stephen.berman@gmx.net> |
| 2 | 32 | ||
| 3 | * calendar/todos.el: Fix tabular alignment in Todos Categories mode. | 33 | * calendar/todos.el: Fix tabular alignment in Todos Categories mode. |
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el index c5792338930..157fcbbdc18 100644 --- a/lisp/calendar/todos.el +++ b/lisp/calendar/todos.el | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | :version "24.2" | 40 | :version "24.2" |
| 41 | :group 'calendar) | 41 | :group 'calendar) |
| 42 | 42 | ||
| 43 | ;; FIXME: use file-truename (but in a defcustom) ? | ||
| 43 | (defcustom todos-files-directory (locate-user-emacs-file "todos/") | 44 | (defcustom todos-files-directory (locate-user-emacs-file "todos/") |
| 44 | "Directory where user's Todos files are saved." | 45 | "Directory where user's Todos files are saved." |
| 45 | :type 'directory | 46 | :type 'directory |
| @@ -520,6 +521,11 @@ items in that category, which overrides NUM." | |||
| 520 | :type 'integer | 521 | :type 'integer |
| 521 | :group 'todos-filtered) | 522 | :group 'todos-filtered) |
| 522 | 523 | ||
| 524 | ;; (defcustom todos-save-top-priorities nil ;FIXME: use or delete this | ||
| 525 | ;; "Non-nil to" | ||
| 526 | ;; :type 'boolean | ||
| 527 | ;; :group 'todos-filtered) | ||
| 528 | |||
| 523 | (defcustom todos-filter-files nil | 529 | (defcustom todos-filter-files nil |
| 524 | "List of default files for multifile item filtering." | 530 | "List of default files for multifile item filtering." |
| 525 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | 531 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) |
| @@ -1568,8 +1574,11 @@ of each other." | |||
| 1568 | done t)) | 1574 | done t)) |
| 1569 | (setq prefix (propertize (concat (number-to-string num) " ") | 1575 | (setq prefix (propertize (concat (number-to-string num) " ") |
| 1570 | 'face | 1576 | 'face |
| 1571 | (if (and (not done) (<= num cat-tp)) | 1577 | ;; Numbers of top priorities have |
| 1572 | 'todos-top-priority ; make defface | 1578 | ;; a distinct face in Todos mode. |
| 1579 | (if (and (not done) (<= num cat-tp) | ||
| 1580 | (eq major-mode 'todos-mode)) | ||
| 1581 | 'todos-top-priority | ||
| 1573 | 'todos-prefix-string)))) | 1582 | 'todos-prefix-string)))) |
| 1574 | (let ((ovs (overlays-in (point) (point))) | 1583 | (let ((ovs (overlays-in (point) (point))) |
| 1575 | marked ov-pref) | 1584 | marked ov-pref) |
| @@ -1894,8 +1903,9 @@ the empty string (i.e., no time string)." | |||
| 1894 | :notify (lambda (&rest ignore) | 1903 | :notify (lambda (&rest ignore) |
| 1895 | (setq todos-multiple-filter-files | 1904 | (setq todos-multiple-filter-files |
| 1896 | (mapcar (lambda (f) | 1905 | (mapcar (lambda (f) |
| 1897 | (concat todos-files-directory | 1906 | (file-truename |
| 1898 | f ".todo")) | 1907 | (concat todos-files-directory |
| 1908 | f ".todo"))) | ||
| 1899 | (widget-value | 1909 | (widget-value |
| 1900 | todos-multiple-filter-files-widget))) | 1910 | todos-multiple-filter-files-widget))) |
| 1901 | (quit-window t) | 1911 | (quit-window t) |
| @@ -1906,31 +1916,20 @@ the empty string (i.e., no time string)." | |||
| 1906 | (message "Click \"Apply\" after selecting files.") | 1916 | (message "Click \"Apply\" after selecting files.") |
| 1907 | (recursive-edit)) | 1917 | (recursive-edit)) |
| 1908 | 1918 | ||
| 1909 | (defun todos-filter-items (filter &optional multifile) | 1919 | (defun todos-filter-items (filter file-list) |
| 1910 | "Build and display a list of items from different categories. | 1920 | "Display a list of items from FILE-LIST that satisfy FILTER. |
| 1911 | 1921 | The values of FILE-LIST and FILTER are passed from the calling | |
| 1912 | The items are selected according to the value of FILTER, which | 1922 | commands. The files in FILE-LIST are either the current Todos |
| 1913 | can be `top' for top priority items, `diary' for diary items, | 1923 | file or those listed in `todos-filter-files' or chosen |
| 1914 | `regexp' for items matching a regular expresion entered by the | 1924 | interactively. The values of FILTER can be `top' for top |
| 1915 | user, or a cons cell of one of these symbols and a number set by | 1925 | priority items, a cons of `top' and a number passed by the |
| 1916 | the calling command, which overrides `todos-show-priorities'. | 1926 | caller, `diary' for diary items, or `regexp' for items matching a |
| 1917 | 1927 | regular expresion entered by the user." | |
| 1918 | With non-nil argument MULTIFILE list top priorities of multiple | ||
| 1919 | Todos files, by default those in `todos-filter-files'." | ||
| 1920 | (let ((num (if (consp filter) (cdr filter) todos-show-priorities)) | 1928 | (let ((num (if (consp filter) (cdr filter) todos-show-priorities)) |
| 1921 | (buf (get-buffer-create todos-filtered-items-buffer)) | 1929 | (buf (get-buffer-create todos-filtered-items-buffer)) |
| 1922 | (files (list todos-current-todos-file)) | 1930 | (multifile (> (length file-list) 1)) |
| 1923 | regexp fname bufstr cat beg end done) | 1931 | regexp fname bufstr cat beg end done) |
| 1924 | (when multifile | 1932 | (if (null file-list) |
| 1925 | (setq files (or todos-multiple-filter-files ; Passed from todos-*-multifile. | ||
| 1926 | (if (or (consp filter) | ||
| 1927 | (null todos-filter-files)) | ||
| 1928 | (progn (todos-multiple-filter-files) | ||
| 1929 | todos-multiple-filter-files) | ||
| 1930 | todos-filter-files)) | ||
| 1931 | todos-multiple-filter-files nil)) | ||
| 1932 | (if (eq files 'quit) (keyboard-quit)) | ||
| 1933 | (if (null files) | ||
| 1934 | (error "No files have been chosen for filtering") | 1933 | (error "No files have been chosen for filtering") |
| 1935 | (with-current-buffer buf | 1934 | (with-current-buffer buf |
| 1936 | (erase-buffer) | 1935 | (erase-buffer) |
| @@ -1939,7 +1938,7 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1939 | (when (eq filter 'regexp) | 1938 | (when (eq filter 'regexp) |
| 1940 | (setq regexp (read-string "Enter a regular expression: "))) | 1939 | (setq regexp (read-string "Enter a regular expression: "))) |
| 1941 | (save-current-buffer | 1940 | (save-current-buffer |
| 1942 | (dolist (f files) | 1941 | (dolist (f file-list) |
| 1943 | ;; Before inserting file contents into temp buffer, save a modified | 1942 | ;; Before inserting file contents into temp buffer, save a modified |
| 1944 | ;; buffer visiting it. | 1943 | ;; buffer visiting it. |
| 1945 | (let ((bf (find-buffer-visiting f))) | 1944 | (let ((bf (find-buffer-visiting f))) |
| @@ -1976,21 +1975,23 @@ Todos files, by default those in `todos-filter-files'." | |||
| 1976 | ;; Delete Todos file categories sexp. | 1975 | ;; Delete Todos file categories sexp. |
| 1977 | (delete-region (line-beginning-position) (1+ (line-end-position))) | 1976 | (delete-region (line-beginning-position) (1+ (line-end-position))) |
| 1978 | (let (fnum) | 1977 | (let (fnum) |
| 1979 | ;; Unless the number of items to show was supplied by prefix | 1978 | ;; Unless the number of top priorities to show was |
| 1980 | ;; argument of caller, the file-wide value from | 1979 | ;; passed by the caller, the file-wide value from |
| 1981 | ;; `todos-priorities-rules', if non-nil, overrides | 1980 | ;; `todos-priorities-rules', if non-nil, overrides |
| 1982 | ;; `todos-show-priorities'. | 1981 | ;; `todos-show-priorities'. |
| 1983 | (unless (consp filter) | 1982 | (unless (consp filter) |
| 1984 | (setq fnum (nth 1 (assoc f todos-priorities-rules)))) | 1983 | (setq fnum (or (nth 1 (assoc f todos-priorities-rules)) |
| 1984 | todos-show-priorities))) | ||
| 1985 | (while (re-search-forward | 1985 | (while (re-search-forward |
| 1986 | (concat "^" (regexp-quote todos-category-beg) "\\(.+\\)\n") | 1986 | (concat "^" (regexp-quote todos-category-beg) "\\(.+\\)\n") |
| 1987 | nil t) | 1987 | nil t) |
| 1988 | (setq cat (match-string 1)) | 1988 | (setq cat (match-string 1)) |
| 1989 | (let (cnum) | 1989 | (let (cnum) |
| 1990 | ;; Unless the number of items to show was supplied by prefix | 1990 | ;; Unless the number of top priorities to show was |
| 1991 | ;; argument of caller, the category-wide value from | 1991 | ;; passed by the caller, the category-wide value |
| 1992 | ;; `todos-priorities-rules', if non-nil, overrides a non-nil | 1992 | ;; from `todos-priorities-rules', if non-nil, |
| 1993 | ;; file-wide value from `todos-priorities-rules' as well as | 1993 | ;; overrides a non-nil file-wide value from |
| 1994 | ;; `todos-priorities-rules' as well as | ||
| 1994 | ;; `todos-show-priorities'. | 1995 | ;; `todos-show-priorities'. |
| 1995 | (unless (consp filter) | 1996 | (unless (consp filter) |
| 1996 | (let ((cats (nth 2 (assoc f todos-priorities-rules)))) | 1997 | (let ((cats (nth 2 (assoc f todos-priorities-rules)))) |
| @@ -2125,13 +2126,69 @@ The new name is constructed from the string BUFFER-TYPE, which | |||
| 2125 | refers to one of the top priorities, diary or regexp item | 2126 | refers to one of the top priorities, diary or regexp item |
| 2126 | filters, and the names of the filtered files in FILE-LIST. Used | 2127 | filters, and the names of the filtered files in FILE-LIST. Used |
| 2127 | in Todos Filter Items mode." | 2128 | in Todos Filter Items mode." |
| 2128 | (let* ((flist (if (listp file-list) file-list (list file-list))) | 2129 | (let* ((multi (> (length file-list) 1)) |
| 2129 | (multi (> (length flist) 1)) | ||
| 2130 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) | 2130 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) |
| 2131 | flist ", "))) | 2131 | file-list ", "))) |
| 2132 | (rename-buffer (format (concat "%s for file" (if multi "s" "") | 2132 | (rename-buffer (format (concat "%s for file" (if multi "s" "") |
| 2133 | " \"%s\"") buffer-type fnames)))) | 2133 | " \"%s\"") buffer-type fnames)))) |
| 2134 | 2134 | ||
| 2135 | (defun todos-find-item (str) | ||
| 2136 | "" | ||
| 2137 | (string-match (concat (if todos-filter-done-items | ||
| 2138 | (concat "\\(?:" todos-done-string-start "\\|" | ||
| 2139 | todos-date-string-start "\\)") | ||
| 2140 | todos-date-string-start) | ||
| 2141 | todos-date-pattern "\\(?: " diary-time-regexp "\\)?" | ||
| 2142 | (if todos-filter-done-items | ||
| 2143 | "\\]" | ||
| 2144 | (regexp-quote todos-nondiary-end)) "?" | ||
| 2145 | "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?" | ||
| 2146 | "\\(?1:.*\\)\\]\\).*$") str) | ||
| 2147 | (let ((cat (match-string 1 str)) | ||
| 2148 | (file (match-string 2 str)) | ||
| 2149 | (archive (string= (match-string 3 str) "(archive) ")) | ||
| 2150 | found) | ||
| 2151 | (setq str (replace-match "" nil nil str 4)) | ||
| 2152 | (setq file (if file | ||
| 2153 | (concat todos-files-directory (substring file 0 -1) | ||
| 2154 | (if archive ".toda" ".todo")) | ||
| 2155 | (if archive | ||
| 2156 | (concat (file-name-sans-extension | ||
| 2157 | todos-global-current-todos-file) ".toda") | ||
| 2158 | todos-global-current-todos-file))) | ||
| 2159 | (find-file-noselect file) | ||
| 2160 | (with-current-buffer (find-buffer-visiting file) | ||
| 2161 | (widen) | ||
| 2162 | (goto-char (point-min)) | ||
| 2163 | (re-search-forward | ||
| 2164 | (concat "^" (regexp-quote (concat todos-category-beg cat)) "$") nil t) | ||
| 2165 | (setq found (search-forward str nil t))) | ||
| 2166 | (list found file cat))) | ||
| 2167 | |||
| 2168 | (defun todos-check-top-priorities () | ||
| 2169 | "Return a message saying whether top priorities file is up-to-date." | ||
| 2170 | (while (not (eobp)) | ||
| 2171 | (let ((item (todos-item-string))) | ||
| 2172 | (unless (car (todos-find-item item)) | ||
| 2173 | (error "Top priorities file is not up to date"))) | ||
| 2174 | (todos-forward-item)) | ||
| 2175 | (message "Top priorities file is up to date.")) | ||
| 2176 | |||
| 2177 | (defun todos-top-priorities-filename () ;FIXME: make part of t-s-t-p-b ? | ||
| 2178 | "" | ||
| 2179 | (let ((bufname (buffer-name))) | ||
| 2180 | (string-match "\"\\([^\"]+\\)\"" bufname) | ||
| 2181 | (let* ((filename-str (substring bufname (match-beginning 1) (match-end 1))) | ||
| 2182 | (filename-base (replace-regexp-in-string ", " "-" filename-str))) | ||
| 2183 | (concat todos-files-directory filename-base ".todt")))) | ||
| 2184 | |||
| 2185 | (defun todos-save-top-priorities-buffer () | ||
| 2186 | "" | ||
| 2187 | (let ((filename (todos-top-priorities-filename))) | ||
| 2188 | (if (file-exists-p filename) | ||
| 2189 | (save-buffer) | ||
| 2190 | (write-region nil nil filename nil t nil t)))) | ||
| 2191 | |||
| 2135 | ;; --------------------------------------------------------------------------- | 2192 | ;; --------------------------------------------------------------------------- |
| 2136 | ;;; Sorting and display routines for Todos Categories mode. | 2193 | ;;; Sorting and display routines for Todos Categories mode. |
| 2137 | 2194 | ||
| @@ -3075,11 +3132,14 @@ displayed." | |||
| 3075 | (interactive) | 3132 | (interactive) |
| 3076 | (todos-show-archive t)) | 3133 | (todos-show-archive t)) |
| 3077 | 3134 | ||
| 3078 | ;; FIXME: need this? | ||
| 3079 | (defun todos-save () | 3135 | (defun todos-save () |
| 3080 | "Save the current Todos file." | 3136 | "Save the current Todos file." |
| 3081 | (interactive) | 3137 | (interactive) |
| 3082 | (save-buffer)) | 3138 | (cond ((eq major-mode 'todos-filtered-items-mode) |
| 3139 | (todos-check-top-priorities) | ||
| 3140 | (todos-save-top-priorities-buffer)) | ||
| 3141 | (t | ||
| 3142 | (save-buffer)))) | ||
| 3083 | 3143 | ||
| 3084 | (defun todos-quit () | 3144 | (defun todos-quit () |
| 3085 | "Exit the current Todos-related buffer. | 3145 | "Exit the current Todos-related buffer. |
| @@ -3380,46 +3440,25 @@ CAT; this is used in Todos Categories mode." | |||
| 3380 | (defun todos-jump-to-item () | 3440 | (defun todos-jump-to-item () |
| 3381 | "Jump to the file and category of the filtered item at point." | 3441 | "Jump to the file and category of the filtered item at point." |
| 3382 | (interactive) | 3442 | (interactive) |
| 3383 | (let ((str (todos-item-string)) | 3443 | (let* ((str (todos-item-string)) |
| 3384 | (buf (current-buffer)) | 3444 | (buf (current-buffer)) |
| 3385 | cat file archive beg) | 3445 | (res (todos-find-item str)) |
| 3386 | (string-match (concat (if todos-filter-done-items | 3446 | (file (nth 1 res)) |
| 3387 | (concat "\\(?:" todos-done-string-start "\\|" | 3447 | (cat (nth 2 res)) |
| 3388 | todos-date-string-start "\\)") | 3448 | beg) |
| 3389 | todos-date-string-start) | 3449 | (if (not (car res)) |
| 3390 | todos-date-pattern "\\(?: " diary-time-regexp "\\)?" | 3450 | (message "Item not found") |
| 3391 | (if todos-filter-done-items | 3451 | (setq beg (match-beginning 0)) |
| 3392 | "\\]" | 3452 | (kill-buffer buf) |
| 3393 | (regexp-quote todos-nondiary-end)) "?" | 3453 | (set-window-buffer (selected-window) |
| 3394 | "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?" | 3454 | (set-buffer (find-buffer-visiting file))) |
| 3395 | "\\(?1:.*\\)\\]\\).*$") str) | 3455 | (setq todos-current-todos-file file) |
| 3396 | (setq cat (match-string 1 str)) | 3456 | (setq todos-category-number (todos-category-number cat)) |
| 3397 | (setq file (match-string 2 str)) | 3457 | (let ((todos-show-with-done (if todos-filter-done-items |
| 3398 | (setq archive (string= (match-string 3 str) "(archive) ")) | 3458 | t |
| 3399 | (setq str (replace-match "" nil nil str 4)) | 3459 | todos-show-with-done))) |
| 3400 | (setq file (if file | 3460 | (todos-category-select)) |
| 3401 | (concat todos-files-directory (substring file 0 -1) | 3461 | (goto-char beg)))) |
| 3402 | (if archive ".toda" ".todo")) | ||
| 3403 | (if archive | ||
| 3404 | (concat (file-name-sans-extension | ||
| 3405 | todos-global-current-todos-file) ".toda") | ||
| 3406 | todos-global-current-todos-file))) | ||
| 3407 | (find-file-noselect file) | ||
| 3408 | (with-current-buffer (find-buffer-visiting file) | ||
| 3409 | (widen) | ||
| 3410 | (goto-char (point-min)) | ||
| 3411 | (re-search-forward | ||
| 3412 | (concat "^" (regexp-quote (concat todos-category-beg cat)) "$") nil t) | ||
| 3413 | (search-forward str) | ||
| 3414 | (setq beg (match-beginning 0))) | ||
| 3415 | (kill-buffer buf) | ||
| 3416 | (set-window-buffer (selected-window) (set-buffer (find-buffer-visiting file))) | ||
| 3417 | (setq todos-current-todos-file file) | ||
| 3418 | (setq todos-category-number (todos-category-number cat)) | ||
| 3419 | (let ((todos-show-with-done (if todos-filter-done-items t | ||
| 3420 | todos-show-with-done))) | ||
| 3421 | (todos-category-select)) | ||
| 3422 | (goto-char beg))) | ||
| 3423 | 3462 | ||
| 3424 | (defun todos-forward-item (&optional count) | 3463 | (defun todos-forward-item (&optional count) |
| 3425 | "Move point down to start of item with next lower priority. | 3464 | "Move point down to start of item with next lower priority. |
| @@ -3695,85 +3734,136 @@ See `todos-set-top-priorities' for more details." | |||
| 3695 | (interactive) | 3734 | (interactive) |
| 3696 | (todos-set-top-priorities t)) | 3735 | (todos-set-top-priorities t)) |
| 3697 | 3736 | ||
| 3698 | (defun todos-top-priorities (&optional num) | 3737 | (defun todos-top-priorities (&optional arg multifile) |
| 3699 | "List top priorities of each category in `todos-filter-files'. | 3738 | "Display a list of top priority items from different categories. |
| 3700 | Number of entries for each category is given by NUM, which | 3739 | The categories are either a subset of those in the current Todos |
| 3701 | defaults to `todos-show-priorities'." | 3740 | file, or else, with non-nil argument MULTIFILE, a subset of the |
| 3741 | categories in the files listed in `todos-filter-files', or if | ||
| 3742 | this nil, in the files chosen from a file selection dialog that | ||
| 3743 | pops up in this case. | ||
| 3744 | |||
| 3745 | With numerical prefix ARG show at most ARG top priority items | ||
| 3746 | from each category. With `C-u' as prefix argument show the | ||
| 3747 | numbers of top priority items specified by category in | ||
| 3748 | `todos-priorities-rules', if this has an entry for the file(s); | ||
| 3749 | otherwise show `todos-show-priorities' items per category in the | ||
| 3750 | file(s). With no prefix argument, if a top priorities file for | ||
| 3751 | the current Todos file has previously been saved (see | ||
| 3752 | `todos-save-top-priorities-buffer'), visit this file; if there is | ||
| 3753 | no such file, build the list as with prefix argument `C-u'. | ||
| 3754 | |||
| 3755 | The prefix ARG regulates how many top priorities from | ||
| 3756 | each category to show, as described above." | ||
| 3702 | (interactive "P") | 3757 | (interactive "P") |
| 3703 | (let ((arg (if num (cons 'top num) 'top)) | 3758 | (let* ((flist (if multifile |
| 3704 | (buf todos-top-priorities-buffer) | 3759 | (or todos-filter-files |
| 3705 | (file todos-current-todos-file)) | 3760 | (progn (todos-multiple-filter-files) |
| 3706 | (todos-filter-items arg) | 3761 | todos-multiple-filter-files)) |
| 3707 | (todos-filtered-buffer-name buf file))) | 3762 | (list todos-current-todos-file))) |
| 3763 | (tp-file (if (equal flist 'quit) | ||
| 3764 | ;; Pressed `cancel' in file selection dialog. | ||
| 3765 | (keyboard-quit) | ||
| 3766 | (concat todos-files-directory | ||
| 3767 | (mapconcat 'identity | ||
| 3768 | (mapcar 'todos-short-file-name flist) | ||
| 3769 | "-") | ||
| 3770 | ".todt"))) | ||
| 3771 | (tp-file-exists (file-exists-p tp-file)) | ||
| 3772 | (buf todos-top-priorities-buffer)) | ||
| 3773 | (cond ((and arg (natnump arg)) | ||
| 3774 | (todos-filter-items (cons 'top arg) flist)) | ||
| 3775 | ((and (not arg) tp-file-exists) | ||
| 3776 | (find-file tp-file) | ||
| 3777 | (todos-prefix-overlays) | ||
| 3778 | (todos-check-top-priorities)) | ||
| 3779 | (t | ||
| 3780 | (todos-filter-items 'top flist))) | ||
| 3781 | (unless tp-file-exists | ||
| 3782 | (todos-filtered-buffer-name buf flist)))) | ||
| 3708 | 3783 | ||
| 3709 | (defun todos-top-priorities-multifile (&optional arg) | 3784 | (defun todos-top-priorities-multifile (&optional arg) |
| 3710 | "List top priorities of each category in `todos-filter-files'. | 3785 | "Display a list of top priority items from different categories. |
| 3711 | 3786 | The categories are a subset of the categories in the files listed | |
| 3712 | If the prefix argument ARG is a number, this is the maximum | 3787 | in `todos-filter-files', or if this nil, in the files chosen from |
| 3713 | number of top priorities to list in each category. If the prefix | 3788 | a file selection dialog that pops up in this case. |
| 3714 | argument is `C-u', prompt for which files to filter and use | 3789 | |
| 3715 | `todos-show-priorities' as the number of top priorities to list | 3790 | With numerical prefix ARG show at most ARG top priority items |
| 3716 | in each category. If the prefix argument is `C-uC-u', prompt | 3791 | from each category in each file. With `C-u' as prefix argument |
| 3717 | both for which files to filter and for how many top priorities to | 3792 | show the numbers of top priority items specified in |
| 3718 | list in each category." | 3793 | `todos-priorities-rules', if this is non-nil; otherwise show |
| 3794 | `todos-show-priorities' items per category. With no prefix | ||
| 3795 | argument, if a top priorities file for the chosen Todos files | ||
| 3796 | exists (see `todos-save-top-priorities-buffer'), visit this file; | ||
| 3797 | if there is no such file, do the same as with prefix argument | ||
| 3798 | `C-u'." | ||
| 3719 | (interactive "P") | 3799 | (interactive "P") |
| 3720 | (let* ((buf todos-top-priorities-buffer) | 3800 | (todos-top-priorities arg t)) |
| 3721 | files | 3801 | |
| 3722 | (pref (if (numberp arg) | 3802 | (defun todos-diary-items (&optional multifile) |
| 3723 | (cons 'top arg) | 3803 | "Display a list of todo diary items from different categories. |
| 3724 | (setq files (if (or (consp arg) | 3804 | The categories are either a subset of those in the current Todos |
| 3725 | (null todos-filter-files)) | 3805 | file, or else, with non-nil argument MULTIFILE, a subset of the |
| 3726 | (progn (todos-multiple-filter-files) | 3806 | categories in the files listed in `todos-filter-files', or if |
| 3727 | todos-multiple-filter-files) | 3807 | this nil, in the files chosen from a file selection dialog that |
| 3728 | todos-filter-files)) | 3808 | pops up in this case." |
| 3729 | (if (equal arg '(16)) | ||
| 3730 | (cons 'top (read-number | ||
| 3731 | "Enter number of top priorities to show: " | ||
| 3732 | todos-show-priorities)) | ||
| 3733 | 'top)))) | ||
| 3734 | (todos-filter-items pref t) | ||
| 3735 | (todos-filtered-buffer-name buf files))) | ||
| 3736 | |||
| 3737 | (defun todos-diary-items () | ||
| 3738 | "Display todo items for diary inclusion in this Todos file." | ||
| 3739 | (interactive) | 3809 | (interactive) |
| 3740 | (let ((buf todos-diary-items-buffer) | 3810 | (let ((flist (if multifile |
| 3741 | (file todos-current-todos-file)) | 3811 | (or todos-filter-files |
| 3742 | (todos-filter-items 'diary) | 3812 | (progn (todos-multiple-filter-files) |
| 3743 | (todos-filtered-buffer-name buf file))) | 3813 | todos-multiple-filter-files)) |
| 3744 | 3814 | (list todos-current-todos-file))) | |
| 3745 | (defun todos-diary-items-multifile (&optional arg) | 3815 | (buf todos-diary-items-buffer)) |
| 3746 | "Display todo items for diary inclusion in one or more Todos file. | 3816 | (if (equal flist 'quit) |
| 3747 | The files are those listed in `todos-filter-files'." | 3817 | ;; Pressed `cancel' in file selection dialog. |
| 3748 | (interactive "P") | 3818 | (keyboard-quit) |
| 3749 | (let ((buf todos-diary-items-buffer) | 3819 | (todos-filter-items 'diary flist) |
| 3750 | (files (if (or arg (null todos-filter-files)) | 3820 | (todos-filtered-buffer-name buf flist)))) |
| 3751 | (progn (todos-multiple-filter-files) | 3821 | |
| 3752 | todos-multiple-filter-files) | 3822 | (defun todos-diary-items-multifile () |
| 3753 | todos-filter-files))) | 3823 | "Display a list of todo diary items from one or more Todos files. |
| 3754 | (todos-filter-items 'diary t) | 3824 | The categories are a subset of the categories in the files listed |
| 3755 | (todos-filtered-buffer-name buf files))) | 3825 | in `todos-filter-files', or if this nil, in the files chosen from |
| 3756 | 3826 | a file selection dialog that pops up in this case." | |
| 3757 | (defun todos-regexp-items () | ||
| 3758 | "Display todo items matching a user-entered regular expression. | ||
| 3759 | The items are those in the current Todos file." | ||
| 3760 | (interactive) | 3827 | (interactive) |
| 3761 | (let ((buf todos-regexp-items-buffer) | 3828 | (todos-diary-items t)) |
| 3762 | (file todos-current-todos-file)) | 3829 | |
| 3763 | (todos-filter-items 'regexp) | 3830 | (defun todos-regexp-items (&optional multifile) |
| 3764 | (todos-filtered-buffer-name buf file))) | 3831 | "Prompt for a regular expression and display items that match it. |
| 3765 | 3832 | The matches may be from different categories and with non-nil | |
| 3766 | (defun todos-regexp-items-multifile (&optional arg) | 3833 | option `todos-filter-done-items', can include not only todo items |
| 3767 | "Display todo items matching a user-entered regular expression. | 3834 | but also done items, including those in Archive files. |
| 3768 | The items are those in the files listed in `todos-filter-files'." | 3835 | |
| 3769 | (interactive "P") | 3836 | The categories are either a subset of those in the current Todos |
| 3770 | (let ((buf todos-regexp-items-buffer) | 3837 | file (and possibly in the corresponding Archive file), or else, |
| 3771 | (files (if (or arg (null todos-filter-files)) | 3838 | with non-nil argument MULTIFILE, a subset of the categories in |
| 3772 | (progn (todos-multiple-filter-files) | 3839 | the files listed in `todos-filter-files', or if this nil, in the |
| 3773 | todos-multiple-filter-files) | 3840 | files chosen from a file selection dialog that pops up in this |
| 3774 | todos-filter-files))) | 3841 | case (and possibly in the corresponding Archive files)." |
| 3775 | (todos-filter-items 'regexp t) | 3842 | (interactive) |
| 3776 | (todos-filtered-buffer-name buf files))) | 3843 | (let ((flist (if multifile |
| 3844 | (or todos-filter-files | ||
| 3845 | (progn (todos-multiple-filter-files) | ||
| 3846 | todos-multiple-filter-files)) | ||
| 3847 | (list todos-current-todos-file))) | ||
| 3848 | (buf todos-regexp-items-buffer)) | ||
| 3849 | (if (equal flist 'quit) | ||
| 3850 | ;; Pressed `cancel' in file selection dialog. | ||
| 3851 | (keyboard-quit) | ||
| 3852 | (todos-filter-items 'regexp flist) | ||
| 3853 | (todos-filtered-buffer-name buf flist)))) | ||
| 3854 | |||
| 3855 | (defun todos-regexp-items-multifile () | ||
| 3856 | "Prompt for a regular expression and display items that match it. | ||
| 3857 | The matches may be from different categories and with non-nil | ||
| 3858 | option `todos-filter-done-items', can include not only todo items | ||
| 3859 | but also done items, including those in Archive files. | ||
| 3860 | |||
| 3861 | The categories are a subset of the categories in the files listed | ||
| 3862 | in `todos-filter-files', or if this nil, in the files chosen from | ||
| 3863 | a file selection dialog that pops up in this case (and possibly | ||
| 3864 | in the corresponding Archive files)." | ||
| 3865 | (interactive) | ||
| 3866 | (todos-regexp-items t)) | ||
| 3777 | 3867 | ||
| 3778 | ;; --------------------------------------------------------------------------- | 3868 | ;; --------------------------------------------------------------------------- |
| 3779 | ;;; Editing Commands | 3869 | ;;; Editing Commands |
| @@ -5729,6 +5819,7 @@ archive, the archive file is deleted." | |||
| 5729 | ;; --------------------------------------------------------------------------- | 5819 | ;; --------------------------------------------------------------------------- |
| 5730 | (add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode)) | 5820 | (add-to-list 'auto-mode-alist '("\\.todo\\'" . todos-mode)) |
| 5731 | (add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode)) | 5821 | (add-to-list 'auto-mode-alist '("\\.toda\\'" . todos-archive-mode)) |
| 5822 | (add-to-list 'auto-mode-alist '("\\.todt\\'" . todos-filtered-items-mode)) | ||
| 5732 | 5823 | ||
| 5733 | ;;; Addition to calendar.el | 5824 | ;;; Addition to calendar.el |
| 5734 | ;; FIXME: autoload when key-binding is defined in calendar.el | 5825 | ;; FIXME: autoload when key-binding is defined in calendar.el |