aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/calendar/ChangeLog7
-rw-r--r--lisp/calendar/todos.el307
2 files changed, 177 insertions, 137 deletions
diff --git a/lisp/calendar/ChangeLog b/lisp/calendar/ChangeLog
index 63a1ca71295..a1292a6a0fe 100644
--- a/lisp/calendar/ChangeLog
+++ b/lisp/calendar/ChangeLog
@@ -1,3 +1,10 @@
12013-06-19 Stephen Berman <stephen.berman@gmx.net>
2
3 * todos.el (todos-convert-legacy-files): Add code to make it work
4 after the new version is renamed and has the same namespace as the
5 old version. This also requires there to be no live todo buffers
6 when this command is called.
7
12013-06-18 Stephen Berman <stephen.berman@gmx.net> 82013-06-18 Stephen Berman <stephen.berman@gmx.net>
2 9
3 * todos.el: Reinstate current copyright dates and original 10 * todos.el: Reinstate current copyright dates and original
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index f96dc97f4c8..667b69a66f3 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -4479,148 +4479,181 @@ Helper function for `todos-convert-legacy-files'."
4479 4479
4480(defun todos-convert-legacy-files () 4480(defun todos-convert-legacy-files ()
4481 "Convert legacy Todo files to the current Todos format. 4481 "Convert legacy Todo files to the current Todos format.
4482The files `todo-file-do' and `todo-file-done' are converted and 4482The old-style files named by the variables `todo-file-do' and
4483saved (the latter as a Todos Archive file) with a new name in 4483`todo-file-done' from the old package are converted to the new
4484`todos-directory'. See also the documentation string of 4484format and saved (the latter as a Todos Archive file) with a new
4485name in `todos-directory'. See also the documentation string of
4485`todos-legacy-date-time-regexp' for further details." 4486`todos-legacy-date-time-regexp' for further details."
4486 (interactive) 4487 (interactive)
4487 (eval-when-compile (require 'todo-mode)) 4488 (if todos-file-buffers
4488 ;; Convert `todo-file-do'. 4489 (message "Before converting you must kill all todo file buffers")
4489 (if (file-exists-p todo-file-do) 4490 ;; Before loading legacy code we have to void symbols whose names
4490 (let ((default "todo-do-conv") 4491 ;; are the same in the old and new versions, so use placeholders
4491 file archive-sexp) 4492 ;; during conversion and restore them afterwards.
4492 (with-temp-buffer 4493 (let ((todos-categories-tem todos-categories)
4493 (insert-file-contents todo-file-do) 4494 (todos-prefix-tem todos-prefix)
4494 (let ((end (search-forward ")" (line-end-position) t)) 4495 (todos-category-beg-tem todos-category-beg))
4495 (beg (search-backward "(" (line-beginning-position) t))) 4496 (fset 'todos-mode-tem 'todos-mode)
4496 (setq todo-categories 4497 (makunbound 'todos-categories)
4497 (read (buffer-substring-no-properties beg end)))) 4498 (makunbound 'todos-prefix)
4498 (todo-mode) 4499 (makunbound 'todos-category-beg)
4499 (delete-region (line-beginning-position) (1+ (line-end-position))) 4500 (fmakunbound 'todos-mode)
4500 (while (not (eobp)) 4501 (when (eq this-command 'todos-convert-legacy-files)
4501 (cond 4502 ;; We can't use require because the feature provided by the
4502 ((looking-at (regexp-quote (concat todo-prefix todo-category-beg))) 4503 ;; old version is the same as the new version's.
4503 (replace-match todos-category-beg)) 4504 (load "todo-mode"))
4504 ((looking-at (regexp-quote todo-category-end)) 4505 ;; Convert `todo-file-do'.
4505 (replace-match "")) 4506 (if (file-exists-p todo-file-do)
4506 ((looking-at (regexp-quote (concat todo-prefix " " 4507 (let ((default "todo-do-conv")
4507 todo-category-sep))) 4508 file archive-sexp)
4508 (replace-match todos-category-done)) 4509 (with-temp-buffer
4509 ((looking-at (concat (regexp-quote todo-prefix) " " 4510 (insert-file-contents todo-file-do)
4510 todos-legacy-date-time-regexp " " 4511 (let ((end (search-forward ")" (line-end-position) t))
4511 (regexp-quote todo-initials) ":")) 4512 (beg (search-backward "(" (line-beginning-position) t)))
4512 (todos-convert-legacy-date-time))) 4513 (setq todo-categories
4513 (forward-line)) 4514 (read (buffer-substring-no-properties beg end))))
4514 (setq file (concat todos-directory 4515 (todo-mode)
4515 (read-string 4516 (delete-region (line-beginning-position) (1+ (line-end-position)))
4516 (format "Save file as (default \"%s\"): " default)
4517 nil nil default)
4518 ".todo"))
4519 (write-region (point-min) (point-max) file nil 'nomessage nil t))
4520 (with-temp-buffer
4521 (insert-file-contents file)
4522 (let ((todos-categories (todos-make-categories-list t)))
4523 (todos-update-categories-sexp))
4524 (write-region (point-min) (point-max) file nil 'nomessage))
4525 ;; Convert `todo-file-done'.
4526 (when (file-exists-p todo-file-done)
4527 (with-temp-buffer
4528 (insert-file-contents todo-file-done)
4529 (let ((beg (make-marker))
4530 (end (make-marker))
4531 cat cats comment item)
4532 (while (not (eobp)) 4517 (while (not (eobp))
4533 (when (looking-at todos-legacy-date-time-regexp) 4518 (cond
4534 (set-marker beg (point)) 4519 ((looking-at (regexp-quote (concat todo-prefix todo-category-beg)))
4535 (todos-convert-legacy-date-time) 4520 (replace-match todos-category-beg-tem))
4536 (set-marker end (point)) 4521 ((looking-at (regexp-quote todo-category-end))
4537 (goto-char beg)
4538 (insert "[" todos-done-string)
4539 (goto-char end)
4540 (insert "]")
4541 (forward-char)
4542 (when (looking-at todos-legacy-date-time-regexp)
4543 (todos-convert-legacy-date-time))
4544 (when (looking-at (concat " "
4545 (regexp-quote todo-initials) ":"))
4546 (replace-match "")))
4547 (if (re-search-forward
4548 (concat "^" todos-legacy-date-time-regexp) nil t)
4549 (goto-char (match-beginning 0))
4550 (goto-char (point-max)))
4551 (backward-char)
4552 (when (looking-back "\\[\\([^][]+\\)\\]")
4553 (setq cat (match-string 1))
4554 (goto-char (match-beginning 0))
4555 (replace-match "")) 4522 (replace-match ""))
4556 ;; If the item ends with a non-comment parenthesis not 4523 ((looking-at (regexp-quote (concat todo-prefix " "
4557 ;; followed by a period, we lose (but we inherit that problem 4524 todo-category-sep)))
4558 ;; from todo-mode.el). 4525 (replace-match todos-category-done))
4559 (when (looking-back "(\\(.*\\)) ") 4526 ((looking-at (concat (regexp-quote todo-prefix) " "
4560 (setq comment (match-string 1)) 4527 todos-legacy-date-time-regexp " "
4561 (replace-match "") 4528 (regexp-quote todo-initials) ":"))
4562 (insert "[" todos-comment-string ": " comment "]")) 4529 ;; FIXME: Should todo-initials be converted? That
4563 (set-marker end (point)) 4530 ;; would require changes to item insertion and editing.
4564 (if (member cat cats) 4531 (todos-convert-legacy-date-time)))
4565 ;; If item is already in its category, leave it there.
4566 (unless (save-excursion
4567 (re-search-backward
4568 (concat "^" (regexp-quote todos-category-beg)
4569 "\\(.*\\)$") nil t)
4570 (string= (match-string 1) cat))
4571 ;; Else move it to its category.
4572 (setq item (buffer-substring-no-properties beg end))
4573 (delete-region beg (1+ end))
4574 (set-marker beg (point))
4575 (re-search-backward
4576 (concat "^"
4577 (regexp-quote (concat todos-category-beg cat))
4578 "$")
4579 nil t)
4580 (forward-line)
4581 (if (re-search-forward
4582 (concat "^" (regexp-quote todos-category-beg)
4583 "\\(.*\\)$") nil t)
4584 (progn (goto-char (match-beginning 0))
4585 (newline)
4586 (forward-line -1))
4587 (goto-char (point-max)))
4588 (insert item "\n")
4589 (goto-char beg))
4590 (push cat cats)
4591 (goto-char beg)
4592 (insert todos-category-beg cat "\n\n" todos-category-done "\n"))
4593 (forward-line)) 4532 (forward-line))
4594 (set-marker beg nil) 4533 (setq file (concat todos-directory
4595 (set-marker end nil)) 4534 (read-string
4596 (setq file (concat (file-name-sans-extension file) ".toda")) 4535 (format "Save file as (default \"%s\"): " default)
4597 (write-region (point-min) (point-max) file nil 'nomessage nil t)) 4536 nil nil default)
4598 (with-temp-buffer 4537 ".todo"))
4599 (insert-file-contents file) 4538 (write-region (point-min) (point-max) file nil 'nomessage nil t))
4600 (let ((todos-categories (todos-make-categories-list t))) 4539 (with-temp-buffer
4601 (todos-update-categories-sexp)) 4540 (insert-file-contents file)
4602 (write-region (point-min) (point-max) file nil 'nomessage) 4541 (let* ((todos-category-beg todos-category-beg-tem) ; Used by t-m-c-l.
4603 (setq archive-sexp (read (buffer-substring-no-properties 4542 (todos-categories (todos-make-categories-list t)))
4604 (line-beginning-position) 4543 (todos-update-categories-sexp))
4605 (line-end-position))))) 4544 (write-region (point-min) (point-max) file nil 'nomessage))
4606 (setq file (concat (file-name-sans-extension file) ".todo")) 4545 ;; Convert `todo-file-done'.
4607 ;; Update categories sexp of converted Todos file again, adding 4546 (when (file-exists-p todo-file-done)
4608 ;; counts of archived items. 4547 (with-temp-buffer
4609 (with-temp-buffer 4548 (insert-file-contents todo-file-done)
4610 (insert-file-contents file) 4549 (let ((beg (make-marker))
4611 (let ((sexp (read (buffer-substring-no-properties 4550 (end (make-marker))
4612 (line-beginning-position) 4551 cat cats comment item)
4613 (line-end-position))))) 4552 (while (not (eobp))
4614 (dolist (cat sexp) 4553 (when (looking-at todos-legacy-date-time-regexp)
4615 (let ((archive-cat (assoc (car cat) archive-sexp))) 4554 (set-marker beg (point))
4616 (if archive-cat 4555 (todos-convert-legacy-date-time)
4617 (aset (cdr cat) 3 (aref (cdr archive-cat) 2))))) 4556 (set-marker end (point))
4618 (delete-region (line-beginning-position) (line-end-position)) 4557 (goto-char beg)
4619 (prin1 sexp (current-buffer))) 4558 (insert "[" todos-done-string)
4620 (write-region (point-min) (point-max) file nil 'nomessage))) 4559 (goto-char end)
4621 (todos-reevaluate-filelist-defcustoms) 4560 (insert "]")
4622 (message "Format conversion done.")) 4561 (forward-char)
4623 (user-error "No legacy Todo file exists"))) 4562 (when (looking-at todos-legacy-date-time-regexp)
4563 (todos-convert-legacy-date-time))
4564 (when (looking-at (concat " "
4565 (regexp-quote todo-initials) ":"))
4566 ;; FIXME: Should todo-initials be converted?
4567 (replace-match "")))
4568 (if (re-search-forward
4569 (concat "^" todos-legacy-date-time-regexp) nil t)
4570 (goto-char (match-beginning 0))
4571 (goto-char (point-max)))
4572 (backward-char)
4573 (when (looking-back "\\[\\([^][]+\\)\\]")
4574 (setq cat (match-string 1))
4575 (goto-char (match-beginning 0))
4576 (replace-match ""))
4577 ;; If the item ends with a non-comment parenthesis not
4578 ;; followed by a period, we lose (but we inherit that problem
4579 ;; from todo-mode.el).
4580 (when (looking-back "(\\(.*\\)) ")
4581 (setq comment (match-string 1))
4582 (replace-match "")
4583 (insert "[" todos-comment-string ": " comment "]"))
4584 (set-marker end (point))
4585 (if (member cat cats)
4586 ;; If item is already in its category, leave it there.
4587 (unless (save-excursion
4588 (re-search-backward
4589 (concat "^" (regexp-quote todos-category-beg-tem)
4590 "\\(.*\\)$") nil t)
4591 (string= (match-string 1) cat))
4592 ;; Else move it to its category.
4593 (setq item (buffer-substring-no-properties beg end))
4594 (delete-region beg (1+ end))
4595 (set-marker beg (point))
4596 (re-search-backward
4597 (concat "^"
4598 (regexp-quote (concat todos-category-beg-tem cat))
4599 "$")
4600 nil t)
4601 (forward-line)
4602 (if (re-search-forward
4603 (concat "^" (regexp-quote todos-category-beg-tem)
4604 "\\(.*\\)$") nil t)
4605 (progn (goto-char (match-beginning 0))
4606 (newline)
4607 (forward-line -1))
4608 (goto-char (point-max)))
4609 (insert item "\n")
4610 (goto-char beg))
4611 (push cat cats)
4612 (goto-char beg)
4613 (insert todos-category-beg-tem cat "\n\n"
4614 todos-category-done "\n"))
4615 (forward-line))
4616 (set-marker beg nil)
4617 (set-marker end nil))
4618 (setq file (concat (file-name-sans-extension file) ".toda"))
4619 (write-region (point-min) (point-max) file nil 'nomessage nil t))
4620 (with-temp-buffer
4621 (insert-file-contents file)
4622 (let* ((todos-category-beg todos-category-beg-tem) ; Used by t-m-c-l.
4623 (todos-categories (todos-make-categories-list t)))
4624 (todos-update-categories-sexp))
4625 (write-region (point-min) (point-max) file nil 'nomessage)
4626 (setq archive-sexp (read (buffer-substring-no-properties
4627 (line-beginning-position)
4628 (line-end-position)))))
4629 (setq file (concat (file-name-sans-extension file) ".todo"))
4630 ;; Update categories sexp of converted Todos file again, adding
4631 ;; counts of archived items.
4632 (with-temp-buffer
4633 (insert-file-contents file)
4634 (let ((sexp (read (buffer-substring-no-properties
4635 (line-beginning-position)
4636 (line-end-position)))))
4637 (dolist (cat sexp)
4638 (let ((archive-cat (assoc (car cat) archive-sexp)))
4639 (if archive-cat
4640 (aset (cdr cat) 3 (aref (cdr archive-cat) 2)))))
4641 (delete-region (line-beginning-position) (line-end-position))
4642 (prin1 sexp (current-buffer)))
4643 (write-region (point-min) (point-max) file nil 'nomessage)))
4644 (todos-reevaluate-filelist-defcustoms)
4645 (message "Format conversion done."))
4646 (message "No legacy Todo file exists"))
4647 ;; (setq todos-categories todos-categories-tem
4648 ;; todos-prefix todos-prefix-tem
4649 ;; todos-category-beg todos-category-beg-tem)
4650 ;; (fset 'todos-mode 'todos-mode-tem)
4651 ;; (makunbound 'todos-categories-tem)
4652 ;; (makunbound 'todos-prefix-tem)
4653 ;; (makunbound 'todos-category-beg-tem)
4654 ;; (fmakunbound 'todos-mode-tem)
4655 (unload-feature 'todos)
4656 (require 'todos))))
4624 4657
4625;; ----------------------------------------------------------------------------- 4658;; -----------------------------------------------------------------------------
4626;;; Utility functions for Todos files, categories and items 4659;;; Utility functions for Todos files, categories and items