diff options
| author | Stephen Berman | 2012-06-01 00:41:02 +0100 |
|---|---|---|
| committer | Stephen Berman | 2012-06-01 00:41:02 +0100 |
| commit | 6be041629978b30cd2033d21b05e54aa6f2da120 (patch) | |
| tree | 9dab60b3843fa3d6cfded9f01a5573c807f87f76 | |
| parent | 0833689ae72c676f868f07cb8c11c92118b9d9b4 (diff) | |
| download | emacs-6be041629978b30cd2033d21b05e54aa6f2da120.tar.gz emacs-6be041629978b30cd2033d21b05e54aa6f2da120.zip | |
* calendar/todos.el: Further code rearrangement and comment
revision.
(todos-add-to-buffer-list, todos-update-buffer-list): New functions.
(todos-file-buffers): New variable.
(todos-reset-global-current-todos-file): Use it to simplify
implementation of this function.
(todos-filtered): New defgroup.
(todos-filter-buffer, todos-top-priorities-buffer)
(todos-diary-items-buffer, todos-regexp-items-buffer)
(todos-priorities-rules, todos-show-priorities)
(todos-filter-files, todos-filter-done-items): Use it.
(todos-skip-archived-categories): Rename from
todos-ignore-archived-categories and adjust users.
(todos-display-as-todos-file): Rename from todos-after-find-file
and adjust callers.
(todos-reset-highlight-item, todos-mode-external-set)
(todos-jump-to-category, todos-jump-to-item)
(todos-raise-category-priority, todos-insert-item)
(todos-move-item): Use find-file-visiting.
(todos-make-categories-list): Use file-truename.
(todos-display-categories-1): Adjust title text for archive files;
use done label for item counts in archive files.
(todos-modes-set-3): Add todos-display-as-todos-file to
find-file-hook.
(todos-mode): Add todos-add-to-buffer-list to find-file-hook and
todos-update-buffer-list post-command-hook.
(todos-unload-hook): And remove them.
(todos-show): Only when interactively invoked from an archive,
switch to corresponding Todos file.
(todos-archive-done-item): Remove obsolete code; fix handling of
marked items; fix search for existing category; check whether
archive exists and write to file if not; improve display handling.
| -rw-r--r-- | lisp/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 449 |
2 files changed, 279 insertions, 205 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5ba432496e1..bfa2a03c5a2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,38 @@ | |||
| 1 | 2012-09-22 Stephen Berman <stephen.berman@gmx.net> | ||
| 2 | |||
| 3 | * calendar/todos.el: Further code rearrangement and comment | ||
| 4 | revision. | ||
| 5 | (todos-add-to-buffer-list, todos-update-buffer-list): New functions. | ||
| 6 | (todos-file-buffers): New variable. | ||
| 7 | (todos-reset-global-current-todos-file): Use it to simplify | ||
| 8 | implementation of this function. | ||
| 9 | (todos-filtered): New defgroup. | ||
| 10 | (todos-filter-buffer, todos-top-priorities-buffer) | ||
| 11 | (todos-diary-items-buffer, todos-regexp-items-buffer) | ||
| 12 | (todos-priorities-rules, todos-show-priorities) | ||
| 13 | (todos-filter-files, todos-filter-done-items): Use it. | ||
| 14 | (todos-skip-archived-categories): Rename from | ||
| 15 | todos-ignore-archived-categories and adjust users. | ||
| 16 | (todos-display-as-todos-file): Rename from todos-after-find-file | ||
| 17 | and adjust callers. | ||
| 18 | (todos-reset-highlight-item, todos-mode-external-set) | ||
| 19 | (todos-jump-to-category, todos-jump-to-item) | ||
| 20 | (todos-raise-category-priority, todos-insert-item) | ||
| 21 | (todos-move-item): Use find-file-visiting. | ||
| 22 | (todos-make-categories-list): Use file-truename. | ||
| 23 | (todos-display-categories-1): Adjust title text for archive files; | ||
| 24 | use done label for item counts in archive files. | ||
| 25 | (todos-modes-set-3): Add todos-display-as-todos-file to | ||
| 26 | find-file-hook. | ||
| 27 | (todos-mode): Add todos-add-to-buffer-list to find-file-hook and | ||
| 28 | todos-update-buffer-list post-command-hook. | ||
| 29 | (todos-unload-hook): And remove them. | ||
| 30 | (todos-show): Only when interactively invoked from an archive, | ||
| 31 | switch to corresponding Todos file. | ||
| 32 | (todos-archive-done-item): Remove obsolete code; fix handling of | ||
| 33 | marked items; fix search for existing category; check whether | ||
| 34 | archive exists and write to file if not; improve display handling. | ||
| 35 | |||
| 1 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> | 36 | 2012-09-21 Stephen Berman <stephen.berman@gmx.net> |
| 2 | 37 | ||
| 3 | * calendar/todos.el: Further comment revision. | 38 | * calendar/todos.el: Further comment revision. |
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el index 76658cff06f..b5193f22f28 100644 --- a/lisp/calendar/todos.el +++ b/lisp/calendar/todos.el | |||
| @@ -28,8 +28,7 @@ | |||
| 28 | ;;; Code: | 28 | ;;; Code: |
| 29 | 29 | ||
| 30 | (require 'diary-lib) | 30 | (require 'diary-lib) |
| 31 | ;; For remove-if-not and find-if-not in todos-reset-global-current-todos-file | 31 | ;; For remove-duplicates in todos-insertion-commands-args. |
| 32 | ;; and for remove-duplicates in todos-insertion-commands-args. | ||
| 33 | (eval-when-compile (require 'cl)) | 32 | (eval-when-compile (require 'cl)) |
| 34 | 33 | ||
| 35 | ;; --------------------------------------------------------------------------- | 34 | ;; --------------------------------------------------------------------------- |
| @@ -106,7 +105,7 @@ Otherwise, `todos-show' always visits `todos-default-todos-file'." | |||
| 106 | (remove-hook 'pre-command-hook 'todos-show-current-file t))) | 105 | (remove-hook 'pre-command-hook 'todos-show-current-file t))) |
| 107 | 106 | ||
| 108 | (defcustom todos-visit-files-commands (list 'find-file 'dired-find-file) | 107 | (defcustom todos-visit-files-commands (list 'find-file 'dired-find-file) |
| 109 | "List of commands to visit files for `todos-after-find-file'. | 108 | "List of file finding commands for `todos-display-as-todos-file'. |
| 110 | Invoking these commands to visit a Todos or Todos Archive file | 109 | Invoking these commands to visit a Todos or Todos Archive file |
| 111 | calls `todos-show' or `todos-show-archive', so that the file is | 110 | calls `todos-show' or `todos-show-archive', so that the file is |
| 112 | displayed correctly." | 111 | displayed correctly." |
| @@ -263,91 +262,16 @@ Todos category. The resulting control becomes the local value of | |||
| 263 | :type 'function | 262 | :type 'function |
| 264 | :group 'todos) | 263 | :group 'todos) |
| 265 | 264 | ||
| 266 | (defun todos-special-buffer-name (buffer-type file-list) | 265 | (defcustom todos-skip-archived-categories nil |
| 267 | "Rename Todos special buffer using BUFFER-TYPE and FILE-LIST. | ||
| 268 | |||
| 269 | The new name is constructed from the string BUFFER-TYPE, which | ||
| 270 | refers to one of the top priorities, diary or regexp item | ||
| 271 | filters, and the names of the filtered files in FILE-LIST. Used | ||
| 272 | in Todos Filter Items mode." | ||
| 273 | (let* ((flist (if (listp file-list) file-list (list file-list))) | ||
| 274 | (multi (> (length flist) 1)) | ||
| 275 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) | ||
| 276 | flist ", "))) | ||
| 277 | (rename-buffer (format (concat "%s for file" (if multi "s" "") | ||
| 278 | " \"%s\"") buffer-type fnames)))) | ||
| 279 | |||
| 280 | (defcustom todos-filter-buffer "Todos filtered items" | ||
| 281 | "Initial name of buffer in Todos Filter Items mode." | ||
| 282 | :type 'string | ||
| 283 | :group 'todos) | ||
| 284 | |||
| 285 | (defcustom todos-top-priorities-buffer "Todos top priorities" | ||
| 286 | "Buffer type string for `todos-special-buffer-name'." | ||
| 287 | :type 'string | ||
| 288 | :group 'todos) | ||
| 289 | |||
| 290 | (defcustom todos-diary-items-buffer "Todos diary items" | ||
| 291 | "Buffer type string for `todos-special-buffer-name'." | ||
| 292 | :type 'string | ||
| 293 | :group 'todos) | ||
| 294 | |||
| 295 | (defcustom todos-regexp-items-buffer "Todos regexp items" | ||
| 296 | "Buffer type string for `todos-special-buffer-name'." | ||
| 297 | :type 'string | ||
| 298 | :group 'todos) | ||
| 299 | |||
| 300 | (defcustom todos-priorities-rules nil | ||
| 301 | "List of rules giving how many items `todos-top-priorities' shows. | ||
| 302 | This variable should be set interactively by | ||
| 303 | `\\[todos-set-top-priorities-in-file]' or | ||
| 304 | `\\[todos-set-top-priorities-in-category]'. | ||
| 305 | |||
| 306 | Each rule is a list of the form (FILE NUM ALIST), where FILE is a | ||
| 307 | member of `todos-files', NUM is a number specifying the default | ||
| 308 | number of top priority items for each category in that file, and | ||
| 309 | ALIST, when non-nil, consists of conses of a category name in | ||
| 310 | FILE and a number specifying the default number of top priority | ||
| 311 | items in that category, which overrides NUM." | ||
| 312 | :type 'list | ||
| 313 | :group 'todos) | ||
| 314 | |||
| 315 | (defcustom todos-show-priorities 1 | ||
| 316 | "Default number of top priorities shown by `todos-top-priorities'." | ||
| 317 | :type 'integer | ||
| 318 | :group 'todos) | ||
| 319 | |||
| 320 | (defcustom todos-filter-files nil | ||
| 321 | "List of default files for multifile item filtering." | ||
| 322 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | ||
| 323 | (mapcar 'todos-short-file-name | ||
| 324 | (funcall todos-files-function)))) | ||
| 325 | :group 'todos) | ||
| 326 | |||
| 327 | ;; FIXME: is there a better alternative to this? | ||
| 328 | (defun todos-reevaluate-filter-files-defcustom () | ||
| 329 | "Reevaluate defcustom of `todos-filter-files'. | ||
| 330 | Called after adding or deleting a Todos file." | ||
| 331 | (eval (defcustom todos-filter-files nil | ||
| 332 | "List of files for multifile item filtering." | ||
| 333 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | ||
| 334 | (mapcar 'todos-short-file-name | ||
| 335 | (funcall todos-files-function)))) | ||
| 336 | :group 'todos))) | ||
| 337 | |||
| 338 | (defcustom todos-filter-done-items nil | ||
| 339 | "Non-nil to include done items when processing regexp filters. | ||
| 340 | Done items from corresponding archive files are also included." | ||
| 341 | :type 'boolean | ||
| 342 | :group 'todos) | ||
| 343 | |||
| 344 | (defcustom todos-ignore-archived-categories nil | ||
| 345 | "Non-nil to skip categories with only archived items when browsing. | 266 | "Non-nil to skip categories with only archived items when browsing. |
| 346 | 267 | ||
| 347 | \\[todos-display-categories], which displays all categories; but | 268 | Moving by category todos or archive file (with |
| 348 | those with only archived items are shown in `todos-archived-only' | 269 | \\[todos-forward-category] and \\[todos-backward-category]) skips |
| 349 | face and clicking them in Todos Categories mode visits the | 270 | categories that contain only archived items. Other commands |
| 350 | archived categories." ;FIXME | 271 | still recognize these categories. In Todos Categories |
| 272 | mode (reached with \\[todos-display-categories]) these categories | ||
| 273 | shown in `todos-archived-only' face and clicking them in Todos | ||
| 274 | Categories mode visits the archived categories." | ||
| 351 | :type 'boolean | 275 | :type 'boolean |
| 352 | :group 'todos) | 276 | :group 'todos) |
| 353 | 277 | ||
| @@ -411,9 +335,13 @@ the diary date." | |||
| 411 | (forward-line))) | 335 | (forward-line))) |
| 412 | (todos-category-select))))))) | 336 | (todos-category-select))))))) |
| 413 | 337 | ||
| 414 | (defcustom todos-print-function 'ps-print-buffer-with-faces | 338 | (defcustom todos-always-add-time-string nil |
| 415 | "Function called to print buffer content; see `todos-print'." | 339 | "Non-nil adds current time to a new item's date header by default. |
| 416 | :type 'symbol | 340 | When the Todos insertion commands have a non-nil \"maybe-notime\" |
| 341 | argument, this reverses the effect of | ||
| 342 | `todos-always-add-time-string': if t, these commands omit the | ||
| 343 | current time, if nil, they include it." | ||
| 344 | :type 'boolean | ||
| 417 | :group 'todos) | 345 | :group 'todos) |
| 418 | 346 | ||
| 419 | (defcustom todos-completion-ignore-case nil | 347 | (defcustom todos-completion-ignore-case nil |
| @@ -435,7 +363,7 @@ the diary date." | |||
| 435 | (custom-set-default symbol value) | 363 | (custom-set-default symbol value) |
| 436 | (when (not (equal value oldvalue)) | 364 | (when (not (equal value oldvalue)) |
| 437 | (dolist (f files) | 365 | (dolist (f files) |
| 438 | (let ((buf (get-file-buffer f))) | 366 | (let ((buf (find-buffer-visiting f))) |
| 439 | (when buf | 367 | (when buf |
| 440 | (with-current-buffer buf | 368 | (with-current-buffer buf |
| 441 | (require 'hl-line) | 369 | (require 'hl-line) |
| @@ -443,15 +371,6 @@ the diary date." | |||
| 443 | (hl-line-mode 1) | 371 | (hl-line-mode 1) |
| 444 | (hl-line-mode -1))))))))) | 372 | (hl-line-mode -1))))))))) |
| 445 | 373 | ||
| 446 | (defcustom todos-always-add-time-string nil | ||
| 447 | "Non-nil adds current time to a new item's date header by default. | ||
| 448 | When the Todos insertion commands have a non-nil \"maybe-notime\" | ||
| 449 | argument, this reverses the effect of | ||
| 450 | `todos-always-add-time-string': if t, these commands omit the | ||
| 451 | current time, if nil, they include it." | ||
| 452 | :type 'boolean | ||
| 453 | :group 'todos) | ||
| 454 | |||
| 455 | (defcustom todos-wrap-lines t | 374 | (defcustom todos-wrap-lines t |
| 456 | "Non-nil to wrap long lines via `todos-line-wrapping-function'." | 375 | "Non-nil to wrap long lines via `todos-line-wrapping-function'." |
| 457 | :group 'todos | 376 | :group 'todos |
| @@ -502,8 +421,82 @@ todo-mode.el." | |||
| 502 | :type 'regexp | 421 | :type 'regexp |
| 503 | :group 'todos) | 422 | :group 'todos) |
| 504 | 423 | ||
| 424 | (defcustom todos-print-function 'ps-print-buffer-with-faces | ||
| 425 | "Function called to print buffer content; see `todos-print'." | ||
| 426 | :type 'symbol | ||
| 427 | :group 'todos) | ||
| 428 | |||
| 429 | (defgroup todos-filtered nil | ||
| 430 | "User options for Todos Filter Items mode." | ||
| 431 | :version "24.2" | ||
| 432 | :group 'todos) | ||
| 433 | |||
| 434 | (defcustom todos-filter-buffer "Todos filtered items" | ||
| 435 | "Initial name of buffer in Todos Filter Items mode." | ||
| 436 | :type 'string | ||
| 437 | :group 'todos-filtered) | ||
| 438 | |||
| 439 | (defcustom todos-top-priorities-buffer "Todos top priorities" | ||
| 440 | "Buffer type string for `todos-special-buffer-name'." | ||
| 441 | :type 'string | ||
| 442 | :group 'todos-filtered) | ||
| 443 | |||
| 444 | (defcustom todos-diary-items-buffer "Todos diary items" | ||
| 445 | "Buffer type string for `todos-special-buffer-name'." | ||
| 446 | :type 'string | ||
| 447 | :group 'todos-filtered) | ||
| 448 | |||
| 449 | (defcustom todos-regexp-items-buffer "Todos regexp items" | ||
| 450 | "Buffer type string for `todos-special-buffer-name'." | ||
| 451 | :type 'string | ||
| 452 | :group 'todos-filtered) | ||
| 453 | |||
| 454 | (defcustom todos-priorities-rules nil | ||
| 455 | "List of rules giving how many items `todos-top-priorities' shows. | ||
| 456 | This variable should be set interactively by | ||
| 457 | `\\[todos-set-top-priorities-in-file]' or | ||
| 458 | `\\[todos-set-top-priorities-in-category]'. | ||
| 459 | |||
| 460 | Each rule is a list of the form (FILE NUM ALIST), where FILE is a | ||
| 461 | member of `todos-files', NUM is a number specifying the default | ||
| 462 | number of top priority items for each category in that file, and | ||
| 463 | ALIST, when non-nil, consists of conses of a category name in | ||
| 464 | FILE and a number specifying the default number of top priority | ||
| 465 | items in that category, which overrides NUM." | ||
| 466 | :type 'list | ||
| 467 | :group 'todos-filtered) | ||
| 468 | |||
| 469 | (defcustom todos-show-priorities 1 | ||
| 470 | "Default number of top priorities shown by `todos-top-priorities'." | ||
| 471 | :type 'integer | ||
| 472 | :group 'todos-filtered) | ||
| 473 | |||
| 474 | (defcustom todos-filter-files nil | ||
| 475 | "List of default files for multifile item filtering." | ||
| 476 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | ||
| 477 | (mapcar 'todos-short-file-name | ||
| 478 | (funcall todos-files-function)))) | ||
| 479 | :group 'todos-filtered) | ||
| 480 | |||
| 481 | ;; FIXME: is there a better alternative to this? | ||
| 482 | (defun todos-reevaluate-filter-files-defcustom () | ||
| 483 | "Reevaluate defcustom of `todos-filter-files'. | ||
| 484 | Called after adding or deleting a Todos file." | ||
| 485 | (eval (defcustom todos-filter-files nil | ||
| 486 | "List of files for multifile item filtering." | ||
| 487 | :type `(set ,@(mapcar (lambda (f) (list 'const f)) | ||
| 488 | (mapcar 'todos-short-file-name | ||
| 489 | (funcall todos-files-function)))) | ||
| 490 | :group 'todos))) | ||
| 491 | |||
| 492 | (defcustom todos-filter-done-items nil | ||
| 493 | "Non-nil to include done items when processing regexp filters. | ||
| 494 | Done items from corresponding archive files are also included." | ||
| 495 | :type 'boolean | ||
| 496 | :group 'todos-filtered) | ||
| 497 | |||
| 505 | (defgroup todos-categories nil | 498 | (defgroup todos-categories nil |
| 506 | "Faces for Todos Categories mode." | 499 | "User options for Todos Categories mode." |
| 507 | :version "24.2" | 500 | :version "24.2" |
| 508 | :group 'todos) | 501 | :group 'todos) |
| 509 | 502 | ||
| @@ -797,7 +790,7 @@ categories display according to priority." | |||
| 797 | diary-time-regexp "\\)?") lim t) | 790 | diary-time-regexp "\\)?") lim t) |
| 798 | (let* ((date (match-string-no-properties 1)) | 791 | (let* ((date (match-string-no-properties 1)) |
| 799 | (time (match-string-no-properties 2)) | 792 | (time (match-string-no-properties 2)) |
| 800 | ;; days-between needs a non-empty time string. | 793 | ;; Function days-between requires a non-empty time string. |
| 801 | (date-time (concat date " " (or time "00:00")))) | 794 | (date-time (concat date " " (or time "00:00")))) |
| 802 | (or (and (not (string-match ".+day\\|\\*" date)) | 795 | (or (and (not (string-match ".+day\\|\\*" date)) |
| 803 | (< (days-between date-time (current-time-string)) 0)) | 796 | (< (days-between date-time (current-time-string)) 0)) |
| @@ -870,12 +863,6 @@ mode following todo (not done) items." | |||
| 870 | ;; --------------------------------------------------------------------------- | 863 | ;; --------------------------------------------------------------------------- |
| 871 | ;;; Todos mode local variables and hook functions | 864 | ;;; Todos mode local variables and hook functions |
| 872 | 865 | ||
| 873 | (defvar todos-files (funcall todos-files-function) | ||
| 874 | "List of truenames of user's Todos files.") | ||
| 875 | |||
| 876 | (defvar todos-archives (funcall todos-files-function t) | ||
| 877 | "List of truenames of user's Todos archives.") | ||
| 878 | |||
| 879 | (defvar todos-current-todos-file nil | 866 | (defvar todos-current-todos-file nil |
| 880 | "Variable holding the name of the currently active Todos file.") | 867 | "Variable holding the name of the currently active Todos file.") |
| 881 | 868 | ||
| @@ -885,30 +872,37 @@ This function is added to `pre-command-hook' when user option | |||
| 885 | `todos-show-current-file' is set to non-nil." | 872 | `todos-show-current-file' is set to non-nil." |
| 886 | (setq todos-global-current-todos-file todos-current-todos-file)) | 873 | (setq todos-global-current-todos-file todos-current-todos-file)) |
| 887 | 874 | ||
| 888 | (defun todos-after-find-file () | 875 | (defun todos-display-as-todos-file () |
| 889 | "Show Todos files correctly when visited from outside of Todos mode." | 876 | "Show Todos files correctly when visited from outside of Todos mode." |
| 890 | (and (member this-command todos-visit-files-commands) | 877 | (and (member this-command todos-visit-files-commands) |
| 891 | (= (- (point-max) (point-min)) (buffer-size)) | 878 | (= (- (point-max) (point-min)) (buffer-size)) |
| 892 | (member major-mode '(todos-mode todos-archive-mode)) | 879 | (member major-mode '(todos-mode todos-archive-mode)) |
| 893 | (todos-category-select))) | 880 | (todos-category-select))) |
| 894 | 881 | ||
| 895 | ;; FIXME: this slows down killing Todos buffer noticeably | 882 | (defun todos-add-to-buffer-list () |
| 883 | "Add name of just visited Todos file to `todos-file-buffers'. | ||
| 884 | This function is added to `find-file-hook' in Todos mode." | ||
| 885 | (let ((filename (file-truename (buffer-file-name)))) | ||
| 886 | (when (member filename todos-files) | ||
| 887 | (add-to-list 'todos-file-buffers filename)))) | ||
| 888 | |||
| 889 | (defun todos-update-buffer-list () | ||
| 890 | "Make current Todos mode buffer file car of `todos-file-buffers'. | ||
| 891 | This function is added to `post-command-hook' in Todos mode." | ||
| 892 | (let ((filename (file-truename (buffer-file-name)))) | ||
| 893 | (unless (eq (car todos-file-buffers) filename) | ||
| 894 | (setq todos-file-buffers | ||
| 895 | (cons filename (delete filename todos-file-buffers)))))) | ||
| 896 | |||
| 896 | (defun todos-reset-global-current-todos-file () | 897 | (defun todos-reset-global-current-todos-file () |
| 897 | "Update the value of `todos-global-current-todos-file'. | 898 | "Update the value of `todos-global-current-todos-file'. |
| 898 | This becomes the latest existing Todos file or, if there is none, | 899 | This becomes the latest existing Todos file or, if there is none, |
| 899 | the value of `todos-default-todos-file'. | 900 | the value of `todos-default-todos-file'. |
| 900 | This function is added to `kill-buffer-hook' in Todos mode." | 901 | This function is added to `kill-buffer-hook' in Todos mode." |
| 901 | (let ((todos-buffer-list (nreverse | 902 | (let ((filename (file-truename (buffer-file-name)))) |
| 902 | (remove-if-not | 903 | (setq todos-file-buffers (delete filename todos-file-buffers)) |
| 903 | (lambda (f) | 904 | (setq todos-global-current-todos-file (or (car todos-file-buffers) |
| 904 | (member f (mapcar | 905 | todos-default-todos-file)))) |
| 905 | 'file-name-nondirectory | ||
| 906 | (funcall todos-files-function)))) | ||
| 907 | (mapcar 'buffer-name (buffer-list))))) | ||
| 908 | latest) | ||
| 909 | (setq latest (find-if-not (lambda (f) (string= f (buffer-name))) | ||
| 910 | todos-buffer-list)) | ||
| 911 | (setq todos-global-current-todos-file (or latest todos-default-todos-file)))) | ||
| 912 | 906 | ||
| 913 | (defvar todos-categories nil | 907 | (defvar todos-categories nil |
| 914 | "Alist of categories in the current Todos file. | 908 | "Alist of categories in the current Todos file. |
| @@ -936,6 +930,15 @@ Set by the command `todos-show-done-only' and used by | |||
| 936 | ;; --------------------------------------------------------------------------- | 930 | ;; --------------------------------------------------------------------------- |
| 937 | ;;; Global variables and helper functions | 931 | ;;; Global variables and helper functions |
| 938 | 932 | ||
| 933 | (defvar todos-files (funcall todos-files-function) | ||
| 934 | "List of truenames of user's Todos files.") | ||
| 935 | |||
| 936 | (defvar todos-archives (funcall todos-files-function t) | ||
| 937 | "List of truenames of user's Todos archives.") | ||
| 938 | |||
| 939 | (defvar todos-file-buffers nil | ||
| 940 | "List of file names of live Todos mode buffers.") | ||
| 941 | |||
| 939 | (defvar todos-global-current-todos-file nil | 942 | (defvar todos-global-current-todos-file nil |
| 940 | "Variable holding name of current Todos file. | 943 | "Variable holding name of current Todos file. |
| 941 | Used by functions called from outside of Todos mode to visit the | 944 | Used by functions called from outside of Todos mode to visit the |
| @@ -1131,9 +1134,15 @@ the file." | |||
| 1131 | (widen) | 1134 | (widen) |
| 1132 | (goto-char (point-min)) | 1135 | (goto-char (point-min)) |
| 1133 | (let (counts cat archive) | 1136 | (let (counts cat archive) |
| 1134 | (when buffer-file-name ; Don't check with `todos-convert-legacy-files'. | 1137 | ;; If the file is a todo file and has archived items, identify the |
| 1138 | ;; archive, in order to count its items. But skip this with | ||
| 1139 | ;; `todos-convert-legacy-files', since that converts filed items to | ||
| 1140 | ;; archived items. | ||
| 1141 | (when buffer-file-name ; During conversion there is no file yet. | ||
| 1142 | ;; If the file is an archive, it doesn't have an archive. | ||
| 1135 | ;; FIXME: can todos-archives be too old here? | 1143 | ;; FIXME: can todos-archives be too old here? |
| 1136 | (unless (member buffer-file-name (funcall todos-files-function t)) | 1144 | (unless (member (file-truename buffer-file-name) |
| 1145 | (funcall todos-files-function t)) | ||
| 1137 | (setq archive (concat (file-name-sans-extension | 1146 | (setq archive (concat (file-name-sans-extension |
| 1138 | todos-current-todos-file) ".toda")))) | 1147 | todos-current-todos-file) ".toda")))) |
| 1139 | (while (not (eobp)) | 1148 | (while (not (eobp)) |
| @@ -1144,8 +1153,9 @@ the file." | |||
| 1144 | (setq counts (make-vector 4 0)) | 1153 | (setq counts (make-vector 4 0)) |
| 1145 | (setq todos-categories | 1154 | (setq todos-categories |
| 1146 | (append todos-categories (list (cons cat counts)))) | 1155 | (append todos-categories (list (cons cat counts)))) |
| 1147 | ;; todos-archives may be too old here (e.g. during | 1156 | ;; Add archived item count to the todo file item counts. |
| 1148 | ;; todos-move-category). | 1157 | ;; Make sure to include newly created archives, e.g. due to |
| 1158 | ;; todos-move-category. | ||
| 1149 | (when (member archive (funcall todos-files-function t)) | 1159 | (when (member archive (funcall todos-files-function t)) |
| 1150 | (let ((archive-count 0)) | 1160 | (let ((archive-count 0)) |
| 1151 | (with-current-buffer (find-file-noselect archive) | 1161 | (with-current-buffer (find-file-noselect archive) |
| @@ -1226,10 +1236,11 @@ editing or a bug in todos.el." | |||
| 1226 | 1236 | ||
| 1227 | (defun todos-item-start () | 1237 | (defun todos-item-start () |
| 1228 | "Move to start of current Todos item and return its position." | 1238 | "Move to start of current Todos item and return its position." |
| 1229 | (unless (or | 1239 | (unless (or ;FIXME: bad comment |
| 1230 | ;; Point is either on last item in this category or on the empty | 1240 | ;; Point is either on last item in this category or on the empty |
| 1231 | ;; line between done and not done items. | 1241 | ;; line between done and not done items. |
| 1232 | (looking-at "^$") | 1242 | (looking-at "^$") |
| 1243 | ;; FIXME: bad comment, why this sexp? | ||
| 1233 | ;; There are no done items in this category yet. | 1244 | ;; There are no done items in this category yet. |
| 1234 | (looking-at (regexp-quote todos-category-beg))) | 1245 | (looking-at (regexp-quote todos-category-beg))) |
| 1235 | (goto-char (line-beginning-position)) | 1246 | (goto-char (line-beginning-position)) |
| @@ -1805,6 +1816,19 @@ set the user customizable option `todos-priorities-rules'." | |||
| 1805 | (delete frule rules))) | 1816 | (delete frule rules))) |
| 1806 | (customize-save-variable 'todos-priorities-rules rules))) | 1817 | (customize-save-variable 'todos-priorities-rules rules))) |
| 1807 | 1818 | ||
| 1819 | (defun todos-special-buffer-name (buffer-type file-list) ;FIXME: rename to `filtered' | ||
| 1820 | "Rename Todos special buffer using BUFFER-TYPE and FILE-LIST. | ||
| 1821 | |||
| 1822 | The new name is constructed from the string BUFFER-TYPE, which | ||
| 1823 | refers to one of the top priorities, diary or regexp item | ||
| 1824 | filters, and the names of the filtered files in FILE-LIST. Used | ||
| 1825 | in Todos Filter Items mode." | ||
| 1826 | (let* ((flist (if (listp file-list) file-list (list file-list))) | ||
| 1827 | (multi (> (length flist) 1)) | ||
| 1828 | (fnames (mapconcat (lambda (f) (todos-short-file-name f)) | ||
| 1829 | flist ", "))) | ||
| 1830 | (rename-buffer (format (concat "%s for file" (if multi "s" "") | ||
| 1831 | " \"%s\"") buffer-type fnames)))) | ||
| 1808 | 1832 | ||
| 1809 | ;; --------------------------------------------------------------------------- | 1833 | ;; --------------------------------------------------------------------------- |
| 1810 | ;;; Sorting and display routines for Todos Categories mode. | 1834 | ;;; Sorting and display routines for Todos Categories mode. |
| @@ -1947,7 +1971,7 @@ which is the value of the user option | |||
| 1947 | (cons todos-categories-archived-label | 1971 | (cons todos-categories-archived-label |
| 1948 | 'archived))) | 1972 | 'archived))) |
| 1949 | "")) | 1973 | "")) |
| 1950 | 'face (if (and todos-ignore-archived-categories | 1974 | 'face (if (and todos-skip-archived-categories |
| 1951 | (zerop (todos-get-count 'todo cat)) | 1975 | (zerop (todos-get-count 'todo cat)) |
| 1952 | (zerop (todos-get-count 'done cat)) | 1976 | (zerop (todos-get-count 'done cat)) |
| 1953 | (not (zerop (todos-get-count 'archived cat)))) | 1977 | (not (zerop (todos-get-count 'archived cat)))) |
| @@ -1988,10 +2012,13 @@ which is the value of the user option | |||
| 1988 | (set-buffer (get-buffer-create todos-categories-buffer))) | 2012 | (set-buffer (get-buffer-create todos-categories-buffer))) |
| 1989 | (kill-all-local-variables) | 2013 | (kill-all-local-variables) |
| 1990 | (todos-categories-mode) | 2014 | (todos-categories-mode) |
| 1991 | (let (buffer-read-only) | 2015 | (let ((archive (member todos-current-todos-file todos-archives)) |
| 2016 | buffer-read-only) | ||
| 1992 | (erase-buffer) | 2017 | (erase-buffer) |
| 1993 | ;; FIXME: add usage tips? | 2018 | ;; FIXME: add usage tips? |
| 1994 | (insert (format "Category counts for Todos file \"%s\"." | 2019 | (insert (format (concat "Category counts for Todos " |
| 2020 | (if archive "archive" "file") | ||
| 2021 | " \"%s\".") | ||
| 1995 | (todos-short-file-name todos-current-todos-file))) | 2022 | (todos-short-file-name todos-current-todos-file))) |
| 1996 | (newline 2) | 2023 | (newline 2) |
| 1997 | ;; Make space for the column of category numbers. | 2024 | ;; Make space for the column of category numbers. |
| @@ -1999,9 +2026,10 @@ which is the value of the user option | |||
| 1999 | ;; Add the category and item count buttons (if this is the list of | 2026 | ;; Add the category and item count buttons (if this is the list of |
| 2000 | ;; categories in an archive, show only done item counts). | 2027 | ;; categories in an archive, show only done item counts). |
| 2001 | (todos-insert-sort-button todos-categories-category-label) | 2028 | (todos-insert-sort-button todos-categories-category-label) |
| 2002 | (if (member todos-current-todos-file todos-archives) | 2029 | (if archive |
| 2003 | (insert (concat (make-string 6 32) | 2030 | (progn |
| 2004 | (format "%s" todos-categories-archived-label))) | 2031 | (insert (make-string 3 32)) |
| 2032 | (todos-insert-sort-button todos-categories-done-label)) | ||
| 2005 | (insert (make-string 3 32)) | 2033 | (insert (make-string 3 32)) |
| 2006 | (todos-insert-sort-button todos-categories-todo-label) | 2034 | (todos-insert-sort-button todos-categories-todo-label) |
| 2007 | (insert (make-string 2 32)) | 2035 | (insert (make-string 2 32)) |
| @@ -2056,7 +2084,7 @@ which is the value of the user option | |||
| 2056 | (setq buffer-read-only t))) | 2084 | (setq buffer-read-only t))) |
| 2057 | 2085 | ||
| 2058 | ;; --------------------------------------------------------------------------- | 2086 | ;; --------------------------------------------------------------------------- |
| 2059 | ;;; Todos insertion commands, key bindings and keymap | 2087 | ;;; Routines for generating Todos insertion commands and key bindings |
| 2060 | 2088 | ||
| 2061 | ;; Can either of these be included in Emacs? The originals are GFDL'd. | 2089 | ;; Can either of these be included in Emacs? The originals are GFDL'd. |
| 2062 | 2090 | ||
| @@ -2209,6 +2237,8 @@ which is the value of the user option | |||
| 2209 | map) | 2237 | map) |
| 2210 | "Keymap for Todos mode insertion commands.") | 2238 | "Keymap for Todos mode insertion commands.") |
| 2211 | 2239 | ||
| 2240 | ;;; Key maps and menus | ||
| 2241 | |||
| 2212 | ;; ??FIXME: use easy-mmode-define-keymap and easy-mmode-defmap | 2242 | ;; ??FIXME: use easy-mmode-define-keymap and easy-mmode-defmap |
| 2213 | (defvar todos-key-bindings | 2243 | (defvar todos-key-bindings |
| 2214 | `( | 2244 | `( |
| @@ -2436,6 +2466,8 @@ which is the value of the user option | |||
| 2436 | map) | 2466 | map) |
| 2437 | "Todos Top Priorities mode keymap.") | 2467 | "Todos Top Priorities mode keymap.") |
| 2438 | 2468 | ||
| 2469 | ;;; Mode definitions | ||
| 2470 | |||
| 2439 | (defun todos-modes-set-1 () | 2471 | (defun todos-modes-set-1 () |
| 2440 | "" | 2472 | "" |
| 2441 | (set (make-local-variable 'font-lock-defaults) '(todos-font-lock-keywords t)) | 2473 | (set (make-local-variable 'font-lock-defaults) '(todos-font-lock-keywords t)) |
| @@ -2455,7 +2487,7 @@ which is the value of the user option | |||
| 2455 | (set (make-local-variable 'todos-categories) (todos-set-categories)) | 2487 | (set (make-local-variable 'todos-categories) (todos-set-categories)) |
| 2456 | (set (make-local-variable 'todos-category-number) 1) | 2488 | (set (make-local-variable 'todos-category-number) 1) |
| 2457 | (set (make-local-variable 'todos-first-visit) t) | 2489 | (set (make-local-variable 'todos-first-visit) t) |
| 2458 | (add-hook 'post-command-hook 'todos-after-find-file nil t)) | 2490 | (add-hook 'find-file-hook 'todos-display-as-todos-file nil t)) |
| 2459 | 2491 | ||
| 2460 | (put 'todos-mode 'mode-class 'special) | 2492 | (put 'todos-mode 'mode-class 'special) |
| 2461 | 2493 | ||
| @@ -2478,6 +2510,8 @@ which is the value of the user option | |||
| 2478 | (set (make-local-variable 'todos-first-visit) t) | 2510 | (set (make-local-variable 'todos-first-visit) t) |
| 2479 | (set (make-local-variable 'todos-show-done-only) nil) | 2511 | (set (make-local-variable 'todos-show-done-only) nil) |
| 2480 | (set (make-local-variable 'todos-categories-with-marks) nil) | 2512 | (set (make-local-variable 'todos-categories-with-marks) nil) |
| 2513 | (add-hook 'find-file-hook 'todos-add-to-buffer-list nil t) | ||
| 2514 | (add-hook 'post-command-hook 'todos-update-buffer-list nil t) | ||
| 2481 | (when todos-show-current-file | 2515 | (when todos-show-current-file |
| 2482 | (add-hook 'pre-command-hook 'todos-show-current-file nil t)) | 2516 | (add-hook 'pre-command-hook 'todos-show-current-file nil t)) |
| 2483 | ;; FIXME: works more or less, but should be tied to the defcustom | 2517 | ;; FIXME: works more or less, but should be tied to the defcustom |
| @@ -2491,7 +2525,9 @@ which is the value of the user option | |||
| 2491 | (defun todos-unload-hook () | 2525 | (defun todos-unload-hook () |
| 2492 | "" | 2526 | "" |
| 2493 | (remove-hook 'pre-command-hook 'todos-show-current-file t) | 2527 | (remove-hook 'pre-command-hook 'todos-show-current-file t) |
| 2494 | (remove-hook 'post-command-hook 'todos-after-find-file t) | 2528 | (remove-hook 'post-command-hook 'todos-update-buffer-list t) |
| 2529 | (remove-hook 'find-file-hook 'todos-display-as-todos-file t) | ||
| 2530 | (remove-hook 'find-file-hook 'todos-add-to-buffer-list t) | ||
| 2495 | (remove-hook 'window-configuration-change-hook | 2531 | (remove-hook 'window-configuration-change-hook |
| 2496 | (lambda () | 2532 | (lambda () |
| 2497 | (setq todos-done-separator | 2533 | (setq todos-done-separator |
| @@ -2515,7 +2551,7 @@ which is the value of the user option | |||
| 2515 | "" | 2551 | "" |
| 2516 | (set (make-local-variable 'todos-current-todos-file) | 2552 | (set (make-local-variable 'todos-current-todos-file) |
| 2517 | todos-global-current-todos-file) | 2553 | todos-global-current-todos-file) |
| 2518 | (let ((cats (with-current-buffer (get-file-buffer todos-current-todos-file) | 2554 | (let ((cats (with-current-buffer (find-buffer-visiting todos-current-todos-file) |
| 2519 | ;; FIXME: or just todos-categories? | 2555 | ;; FIXME: or just todos-categories? |
| 2520 | (todos-set-categories)))) | 2556 | (todos-set-categories)))) |
| 2521 | (set (make-local-variable 'todos-categories) cats))) | 2557 | (set (make-local-variable 'todos-categories) cats))) |
| @@ -2560,6 +2596,8 @@ buries it and restores state as needed." | |||
| 2560 | (cond ((eq major-mode 'todos-categories-mode) | 2596 | (cond ((eq major-mode 'todos-categories-mode) |
| 2561 | (kill-buffer) | 2597 | (kill-buffer) |
| 2562 | (setq todos-descending-counts nil) | 2598 | (setq todos-descending-counts nil) |
| 2599 | ;; FIXME: this jumps to todo file even when todos-display-categories | ||
| 2600 | ;; was called from archive | ||
| 2563 | (todos-show)) | 2601 | (todos-show)) |
| 2564 | ((eq major-mode 'todos-filter-items-mode) | 2602 | ((eq major-mode 'todos-filter-items-mode) |
| 2565 | (kill-buffer) | 2603 | (kill-buffer) |
| @@ -2607,7 +2645,10 @@ corresponding Todos file, displaying the corresponding category." | |||
| 2607 | (todos-read-file-name "Choose a Todos file to visit: " | 2645 | (todos-read-file-name "Choose a Todos file to visit: " |
| 2608 | nil t) | 2646 | nil t) |
| 2609 | (error "There are no Todos files"))) | 2647 | (error "There are no Todos files"))) |
| 2610 | ((eq major-mode 'todos-archive-mode) | 2648 | ((and (eq major-mode 'todos-archive-mode) |
| 2649 | ;; Called noninteractively via todos-quit from | ||
| 2650 | ;; Todos Categories mode to return to archive file. | ||
| 2651 | (called-interactively-p 'any)) | ||
| 2611 | (setq cat (todos-current-category)) | 2652 | (setq cat (todos-current-category)) |
| 2612 | (concat (file-name-sans-extension todos-current-todos-file) | 2653 | (concat (file-name-sans-extension todos-current-todos-file) |
| 2613 | ".todo")) | 2654 | ".todo")) |
| @@ -2659,7 +2700,7 @@ In addition, the lines with the category names and item counts | |||
| 2659 | are buttonized, and pressing one of these button jumps to the | 2700 | are buttonized, and pressing one of these button jumps to the |
| 2660 | category in Todos mode (or Todos Archive mode, for categories | 2701 | category in Todos mode (or Todos Archive mode, for categories |
| 2661 | containing only archived items, provided user option | 2702 | containing only archived items, provided user option |
| 2662 | `todos-ignore-archived-categories' is non-nil. These categories | 2703 | `todos-skip-archived-categories' is non-nil. These categories |
| 2663 | are shown in `todos-archived-only' face." | 2704 | are shown in `todos-archived-only' face." |
| 2664 | (interactive) | 2705 | (interactive) |
| 2665 | (todos-display-categories-1) | 2706 | (todos-display-categories-1) |
| @@ -2693,28 +2734,6 @@ are shown in `todos-archived-only' face." | |||
| 2693 | ;; (interactive) | 2734 | ;; (interactive) |
| 2694 | ;; (todos-display-sorted 'archived)) | 2735 | ;; (todos-display-sorted 'archived)) |
| 2695 | 2736 | ||
| 2696 | (defun todos-hide-show-item-numbering () | ||
| 2697 | "" | ||
| 2698 | (interactive) | ||
| 2699 | (todos-reset-prefix 'todos-number-priorities (not todos-number-priorities))) | ||
| 2700 | |||
| 2701 | (defun todos-hide-show-done-items () | ||
| 2702 | "Show hidden or hide visible done items in current category." | ||
| 2703 | (interactive) | ||
| 2704 | (if (zerop (todos-get-count 'done (todos-current-category))) | ||
| 2705 | (message "There are no done items in this category.") | ||
| 2706 | (save-excursion | ||
| 2707 | (goto-char (point-min)) | ||
| 2708 | (let ((todos-show-with-done (not (re-search-forward | ||
| 2709 | todos-done-string-start nil t)))) | ||
| 2710 | (todos-category-select))))) | ||
| 2711 | |||
| 2712 | (defun todos-show-done-only () | ||
| 2713 | "Switch between displaying only done or only todo items." | ||
| 2714 | (interactive) | ||
| 2715 | (setq todos-show-done-only (not todos-show-done-only)) | ||
| 2716 | (todos-category-select)) | ||
| 2717 | |||
| 2718 | (defun todos-show-archive (&optional ask) | 2737 | (defun todos-show-archive (&optional ask) |
| 2719 | "Visit the archive of the current Todos category, if it exists. | 2738 | "Visit the archive of the current Todos category, if it exists. |
| 2720 | If the category has no archived items, prompt to visit the | 2739 | If the category has no archived items, prompt to visit the |
| @@ -2757,6 +2776,28 @@ last category displayed." ;FIXME | |||
| 2757 | (interactive) | 2776 | (interactive) |
| 2758 | (todos-show-archive t)) | 2777 | (todos-show-archive t)) |
| 2759 | 2778 | ||
| 2779 | (defun todos-hide-show-item-numbering () | ||
| 2780 | "" | ||
| 2781 | (interactive) | ||
| 2782 | (todos-reset-prefix 'todos-number-priorities (not todos-number-priorities))) | ||
| 2783 | |||
| 2784 | (defun todos-hide-show-done-items () | ||
| 2785 | "Show hidden or hide visible done items in current category." | ||
| 2786 | (interactive) | ||
| 2787 | (if (zerop (todos-get-count 'done (todos-current-category))) | ||
| 2788 | (message "There are no done items in this category.") | ||
| 2789 | (save-excursion | ||
| 2790 | (goto-char (point-min)) | ||
| 2791 | (let ((todos-show-with-done (not (re-search-forward | ||
| 2792 | todos-done-string-start nil t)))) | ||
| 2793 | (todos-category-select))))) | ||
| 2794 | |||
| 2795 | (defun todos-show-done-only () | ||
| 2796 | "Switch between displaying only done or only todo items." | ||
| 2797 | (interactive) | ||
| 2798 | (setq todos-show-done-only (not todos-show-done-only)) | ||
| 2799 | (todos-category-select)) | ||
| 2800 | |||
| 2760 | (defun todos-highlight-item () | 2801 | (defun todos-highlight-item () |
| 2761 | "Toggle highlighting the todo item the cursor is on." | 2802 | "Toggle highlighting the todo item the cursor is on." |
| 2762 | (interactive) | 2803 | (interactive) |
| @@ -3150,7 +3191,7 @@ category is the first)." | |||
| 3150 | (setq todos-category-number | 3191 | (setq todos-category-number |
| 3151 | (1+ (mod (- todos-category-number (if back 2 0)) | 3192 | (1+ (mod (- todos-category-number (if back 2 0)) |
| 3152 | (length todos-categories)))) | 3193 | (length todos-categories)))) |
| 3153 | (when todos-ignore-archived-categories | 3194 | (when todos-skip-archived-categories |
| 3154 | (while (and (zerop (todos-get-count 'todo)) | 3195 | (while (and (zerop (todos-get-count 'todo)) |
| 3155 | (zerop (todos-get-count 'done)) | 3196 | (zerop (todos-get-count 'done)) |
| 3156 | (not (zerop (todos-get-count 'archive)))) | 3197 | (not (zerop (todos-get-count 'archive)))) |
| @@ -3182,7 +3223,7 @@ file, otherwise jump within the current Todos file." | |||
| 3182 | ;; Jump to archived-only Categories from Todos Categories | 3223 | ;; Jump to archived-only Categories from Todos Categories |
| 3183 | ;; mode. | 3224 | ;; mode. |
| 3184 | (and cat | 3225 | (and cat |
| 3185 | todos-ignore-archived-categories | 3226 | todos-skip-archived-categories |
| 3186 | (zerop (todos-get-count 'todo cat)) | 3227 | (zerop (todos-get-count 'todo cat)) |
| 3187 | (zerop (todos-get-count 'done cat)) | 3228 | (zerop (todos-get-count 'done cat)) |
| 3188 | (not (zerop (todos-get-count 'archived cat))) | 3229 | (not (zerop (todos-get-count 'archived cat))) |
| @@ -3201,7 +3242,7 @@ file, otherwise jump within the current Todos file." | |||
| 3201 | (kill-buffer)) | 3242 | (kill-buffer)) |
| 3202 | (if (or cat other-file) | 3243 | (if (or cat other-file) |
| 3203 | (set-window-buffer (selected-window) | 3244 | (set-window-buffer (selected-window) |
| 3204 | (set-buffer (get-file-buffer file)))) | 3245 | (set-buffer (find-buffer-visiting file)))) |
| 3205 | (unless todos-global-current-todos-file | 3246 | (unless todos-global-current-todos-file |
| 3206 | (setq todos-global-current-todos-file todos-current-todos-file)) | 3247 | (setq todos-global-current-todos-file todos-current-todos-file)) |
| 3207 | (todos-category-number category) ; (1+ (length t-c)) if new category. | 3248 | (todos-category-number category) ; (1+ (length t-c)) if new category. |
| @@ -3244,7 +3285,7 @@ The category is chosen by prompt, with TAB completion." | |||
| 3244 | todos-global-current-todos-file) ".toda") | 3285 | todos-global-current-todos-file) ".toda") |
| 3245 | todos-global-current-todos-file))) | 3286 | todos-global-current-todos-file))) |
| 3246 | (find-file-noselect file) | 3287 | (find-file-noselect file) |
| 3247 | (with-current-buffer (get-file-buffer file) | 3288 | (with-current-buffer (find-buffer-visiting file) |
| 3248 | (widen) | 3289 | (widen) |
| 3249 | (goto-char (point-min)) | 3290 | (goto-char (point-min)) |
| 3250 | (re-search-forward | 3291 | (re-search-forward |
| @@ -3252,7 +3293,7 @@ The category is chosen by prompt, with TAB completion." | |||
| 3252 | (search-forward str) | 3293 | (search-forward str) |
| 3253 | (setq beg (match-beginning 0))) | 3294 | (setq beg (match-beginning 0))) |
| 3254 | (kill-buffer buf) | 3295 | (kill-buffer buf) |
| 3255 | (set-window-buffer (selected-window) (set-buffer (get-file-buffer file))) | 3296 | (set-window-buffer (selected-window) (set-buffer (find-buffer-visiting file))) |
| 3256 | (setq todos-current-todos-file file) | 3297 | (setq todos-current-todos-file file) |
| 3257 | (setq todos-category-number (todos-category-number cat)) | 3298 | (setq todos-category-number (todos-category-number cat)) |
| 3258 | (let ((todos-show-with-done (if todos-filter-done-items t | 3299 | (let ((todos-show-with-done (if todos-filter-done-items t |
| @@ -3484,7 +3525,7 @@ i.e. including all existing todo and done items." | |||
| 3484 | "the archived category will remain\n" | 3525 | "the archived category will remain\n" |
| 3485 | "after deleting the todo category. " | 3526 | "after deleting the todo category. " |
| 3486 | "Do you still want to delete it\n" | 3527 | "Do you still want to delete it\n" |
| 3487 | "(see 'todos-ignore-archived-categories' " | 3528 | "(see 'todos-skip-archived-categories' " |
| 3488 | "for another option)? "))) | 3529 | "for another option)? "))) |
| 3489 | (t | 3530 | (t |
| 3490 | (y-or-n-p (concat "Permanently remove category \"" cat | 3531 | (y-or-n-p (concat "Permanently remove category \"" cat |
| @@ -3561,7 +3602,7 @@ With non-nil argument LOWER, lower the category's priority." | |||
| 3561 | (aset catvec num1 (cons cat1 (cdr cat1-list))) | 3602 | (aset catvec num1 (cons cat1 (cdr cat1-list))) |
| 3562 | (setq todos-categories (append catvec nil)) | 3603 | (setq todos-categories (append catvec nil)) |
| 3563 | (setq newcats todos-categories) | 3604 | (setq newcats todos-categories) |
| 3564 | (with-current-buffer (get-file-buffer todos-current-todos-file) | 3605 | (with-current-buffer (find-buffer-visiting todos-current-todos-file) |
| 3565 | (setq todos-categories newcats) | 3606 | (setq todos-categories newcats) |
| 3566 | (todos-update-categories-sexp)) | 3607 | (todos-update-categories-sexp)) |
| 3567 | (forward-line (if lower -1 -2)) | 3608 | (forward-line (if lower -1 -2)) |
| @@ -3873,12 +3914,12 @@ the priority is not given by HERE but by prompting." | |||
| 3873 | (todos-jump-to-category nil t) | 3914 | (todos-jump-to-category nil t) |
| 3874 | (set-window-buffer | 3915 | (set-window-buffer |
| 3875 | (selected-window) | 3916 | (selected-window) |
| 3876 | (set-buffer (get-file-buffer todos-global-current-todos-file)))) | 3917 | (set-buffer (find-buffer-visiting todos-global-current-todos-file)))) |
| 3877 | ((equal arg '(4)) ; FIXME: just arg? | 3918 | ((equal arg '(4)) ; FIXME: just arg? |
| 3878 | (todos-jump-to-category) | 3919 | (todos-jump-to-category) |
| 3879 | (set-window-buffer | 3920 | (set-window-buffer |
| 3880 | (selected-window) | 3921 | (selected-window) |
| 3881 | (set-buffer (get-file-buffer todos-global-current-todos-file)))) | 3922 | (set-buffer (find-buffer-visiting todos-global-current-todos-file)))) |
| 3882 | (t | 3923 | (t |
| 3883 | (when (not (derived-mode-p 'todos-mode)) (todos-show)))) | 3924 | (when (not (derived-mode-p 'todos-mode)) (todos-show)))) |
| 3884 | (let (buffer-read-only) | 3925 | (let (buffer-read-only) |
| @@ -4453,7 +4494,7 @@ entry/entries in that category." | |||
| 4453 | (while (equal name cat1) | 4494 | (while (equal name cat1) |
| 4454 | (setq name (todos-read-category prompt))) | 4495 | (setq name (todos-read-category prompt))) |
| 4455 | name)) | 4496 | name)) |
| 4456 | (set-buffer (get-file-buffer file1)) | 4497 | (set-buffer (find-buffer-visiting file1)) |
| 4457 | (if marked | 4498 | (if marked |
| 4458 | (progn | 4499 | (progn |
| 4459 | (setq item nil) | 4500 | (setq item nil) |
| @@ -4477,7 +4518,7 @@ entry/entries in that category." | |||
| 4477 | (todos-update-count 'todo count) | 4518 | (todos-update-count 'todo count) |
| 4478 | (todos-update-count 'diary count-diary) | 4519 | (todos-update-count 'diary count-diary) |
| 4479 | (todos-update-categories-sexp) | 4520 | (todos-update-categories-sexp) |
| 4480 | (with-current-buffer (get-file-buffer file1) | 4521 | (with-current-buffer (find-buffer-visiting file1) |
| 4481 | (save-excursion | 4522 | (save-excursion |
| 4482 | (save-restriction | 4523 | (save-restriction |
| 4483 | (widen) | 4524 | (widen) |
| @@ -4655,7 +4696,6 @@ done item at point. | |||
| 4655 | If the archive of this file does not exist, it is created. If | 4696 | If the archive of this file does not exist, it is created. If |
| 4656 | this category does not exist in the archive, it is created." | 4697 | this category does not exist in the archive, it is created." |
| 4657 | (interactive) | 4698 | (interactive) |
| 4658 | ;; (when (not (member (buffer-file-name) (funcall todos-files-function t))) | ||
| 4659 | (when (eq major-mode 'todos-mode) | 4699 | (when (eq major-mode 'todos-mode) |
| 4660 | (if (and all (zerop (todos-get-count 'done))) | 4700 | (if (and all (zerop (todos-get-count 'done))) |
| 4661 | (message "No done items in this category") | 4701 | (message "No done items in this category") |
| @@ -4667,16 +4707,7 @@ this category does not exist in the archive, it is created." | |||
| 4667 | todos-current-todos-file) ".toda")) | 4707 | todos-current-todos-file) ".toda")) |
| 4668 | (archive (if (file-exists-p afile) | 4708 | (archive (if (file-exists-p afile) |
| 4669 | (find-file-noselect afile t) | 4709 | (find-file-noselect afile t) |
| 4670 | (progn | 4710 | (get-buffer-create afile))) |
| 4671 | ;; todos-add-category requires an exisiting file... | ||
| 4672 | (with-current-buffer (get-buffer-create afile) | ||
| 4673 | (erase-buffer) | ||
| 4674 | (write-region (point-min) (point-max) afile | ||
| 4675 | nil 'nomessage nil t))) | ||
| 4676 | ;; ...but the file still lacks a categories sexp, so | ||
| 4677 | ;; visiting the file would barf on todos-set-categories, | ||
| 4678 | ;; hence we just return the buffer. | ||
| 4679 | (get-buffer afile))) | ||
| 4680 | (item (and (todos-done-item-p) (concat (todos-item-string) "\n"))) | 4711 | (item (and (todos-done-item-p) (concat (todos-item-string) "\n"))) |
| 4681 | (count 0) | 4712 | (count 0) |
| 4682 | marked-items beg end all-done | 4713 | marked-items beg end all-done |
| @@ -4686,12 +4717,13 @@ this category does not exist in the archive, it is created." | |||
| 4686 | (save-excursion | 4717 | (save-excursion |
| 4687 | (goto-char (point-min)) | 4718 | (goto-char (point-min)) |
| 4688 | (while (not (eobp)) | 4719 | (while (not (eobp)) |
| 4689 | (if (todos-marked-item-p) | 4720 | (when (todos-marked-item-p) |
| 4690 | (if (not (todos-done-item-p)) | 4721 | (if (not (todos-done-item-p)) |
| 4691 | (throw 'end (message "Only done items can be archived")) | 4722 | (throw 'end (message "Only done items can be archived")) |
| 4692 | (concat marked-items (todos-item-string) "\n") | 4723 | (setq marked-items |
| 4693 | (setq count (1+ count))) | 4724 | (concat marked-items (todos-item-string) "\n")) |
| 4694 | (todos-forward-item))))) | 4725 | (setq count (1+ count)))) |
| 4726 | (todos-forward-item)))) | ||
| 4695 | (all | 4727 | (all |
| 4696 | (if (y-or-n-p "Archive all done items in this category? ") | 4728 | (if (y-or-n-p "Archive all done items in this category? ") |
| 4697 | (save-excursion | 4729 | (save-excursion |
| @@ -4711,28 +4743,32 @@ this category does not exist in the archive, it is created." | |||
| 4711 | (throw 'end nil)))) | 4743 | (throw 'end nil)))) |
| 4712 | (when (or marked all item) | 4744 | (when (or marked all item) |
| 4713 | (with-current-buffer archive | 4745 | (with-current-buffer archive |
| 4746 | (unless buffer-file-name (erase-buffer)) | ||
| 4714 | (let ((current todos-global-current-todos-file) | 4747 | (let ((current todos-global-current-todos-file) |
| 4715 | (buffer-read-only)) | 4748 | (buffer-read-only)) |
| 4716 | (widen) | 4749 | (widen) |
| 4717 | (goto-char (point-min)) | 4750 | (goto-char (point-min)) |
| 4718 | (if (progn | 4751 | (if (and (re-search-forward (concat "^" |
| 4719 | (re-search-forward | 4752 | (regexp-quote |
| 4720 | (concat "^" (regexp-quote (concat todos-category-beg cat))) | 4753 | (concat todos-category-beg |
| 4721 | nil t) | 4754 | cat))) |
| 4722 | (re-search-forward (regexp-quote todos-category-done) nil t)) | 4755 | nil t) |
| 4723 | (forward-char) | 4756 | (re-search-forward (regexp-quote todos-category-done) |
| 4724 | ;; todos-add-category uses t-c-t-f, so temporarily set it. | 4757 | nil t)) |
| 4725 | (setq todos-current-todos-file afile) | 4758 | (forward-char) ; Start of done items section. |
| 4726 | (todos-add-category cat) | 4759 | (todos-add-category cat) |
| 4727 | (goto-char (point-max))) | 4760 | (goto-char (point-max))) ; Start of done items section. |
| 4728 | (insert (cond (marked marked-items) | 4761 | (insert (cond (marked marked-items) |
| 4729 | (all all-done) | 4762 | (all all-done) |
| 4730 | (item))) | 4763 | (item))) |
| 4731 | (todos-update-count 'done (if (or marked all) count 1)) | 4764 | (todos-update-count 'done (if (or marked all) count 1)) |
| 4732 | (todos-update-categories-sexp) | 4765 | (todos-update-categories-sexp) |
| 4733 | ;; Save to file now (using write-region in order not to visit | 4766 | ;; Save to file now (using write-region in order not to get |
| 4734 | ;; afile) so we can visit it later with todos-show-archive. | 4767 | ;; prompted for file to save to), to let auto-mode-alist take |
| 4735 | (write-region nil nil afile) | 4768 | ;; effect below. |
| 4769 | (unless buffer-file-name | ||
| 4770 | (write-region nil nil afile) | ||
| 4771 | (kill-buffer)) | ||
| 4736 | (setq todos-current-todos-file current))) | 4772 | (setq todos-current-todos-file current))) |
| 4737 | (with-current-buffer tbuf | 4773 | (with-current-buffer tbuf |
| 4738 | (cond ((or marked item) | 4774 | (cond ((or marked item) |
| @@ -4764,12 +4800,15 @@ this category does not exist in the archive, it is created." | |||
| 4764 | (todos-update-categories-sexp) | 4800 | (todos-update-categories-sexp) |
| 4765 | (todos-prefix-overlays) | 4801 | (todos-prefix-overlays) |
| 4766 | ;; FIXME: Heisenbug: item displays mark -- but not when edebugging | 4802 | ;; FIXME: Heisenbug: item displays mark -- but not when edebugging |
| 4767 | (remove-overlays (point-min) (point-max) | 4803 | ;; (remove-overlays (point-min) (point-max) |
| 4768 | 'before-string todos-item-mark))) | 4804 | ;; 'before-string todos-item-mark) |
| 4769 | (display-buffer (find-file-noselect afile) t) | 4805 | )) |
| 4770 | ;; FIXME: how to avoid switch-to-buffer and still get tbuf above | 4806 | (find-file afile) |
| 4771 | ;; afile? What about pop-to-buffer-same-window in recent trunk? | 4807 | (todos-category-number cat) |
| 4772 | (switch-to-buffer tbuf)))))) | 4808 | (todos-category-select) |
| 4809 | ;; FIXME: what if window is already split? | ||
| 4810 | (split-window-below) | ||
| 4811 | (set-window-buffer (selected-window) tbuf)))))) | ||
| 4773 | 4812 | ||
| 4774 | (defun todos-archive-category-done-items () | 4813 | (defun todos-archive-category-done-items () |
| 4775 | "Move all done items in this category to its archive." | 4814 | "Move all done items in this category to its archive." |