Function: todo-move-item
todo-move-item is an interactive and byte-compiled function defined in
todo-mode.el.gz.
Signature
(todo-move-item &optional FILE)
Documentation
Move at least one todo or done item to another category.
If there are marked items, move all of these; otherwise, move the item at point.
With prefix argument FILE, prompt for a specific todo file and
choose (with TAB completion) a category in it to move the item or
items to; otherwise, choose and move to any category in either
the current todo file or one of the files in
todo-category-completions-files. If the chosen category is
not an existing categories, then it is created and the item(s)
become(s) the first entry/entries in that category.
With moved todo items, prompt to set the priority in the category moved to (with multiple todo items, the one that had the highest priority in the category moved from gets the new priority and the rest of the moved todo items are inserted in sequence below it). Moved done items are appended to the top of the done items section in the category moved to.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/todo-mode.el.gz
(defun todo-move-item (&optional file)
"Move at least one todo or done item to another category.
If there are marked items, move all of these; otherwise, move
the item at point.
With prefix argument FILE, prompt for a specific todo file and
choose (with TAB completion) a category in it to move the item or
items to; otherwise, choose and move to any category in either
the current todo file or one of the files in
`todo-category-completions-files'. If the chosen category is
not an existing categories, then it is created and the item(s)
become(s) the first entry/entries in that category.
With moved todo items, prompt to set the priority in the category
moved to (with multiple todo items, the one that had the highest
priority in the category moved from gets the new priority and the
rest of the moved todo items are inserted in sequence below it).
Moved done items are appended to the top of the done items
section in the category moved to."
(interactive "P")
(let* ((cat1 (todo-current-category))
(marked (assoc cat1 todo-categories-with-marks)))
(unless
;; Noop if point is not on an item and there are no marked items.
(and (or (looking-at "^$")
;; On done items separator.
(save-excursion (beginning-of-line)
(looking-at todo-category-done)))
(not marked))
(let* ((file1 todo-current-todo-file)
(item (todo-item-string))
(done-item (and (todo-done-item-p) item))
(omark (save-excursion (todo-item-start) (point-marker)))
(todo 0)
(diary 0)
(done 0)
ov cat2 file2 moved nmark todo-items done-items)
(unwind-protect
(progn
(unless marked
(setq ov (make-overlay (save-excursion (todo-item-start))
(save-excursion (todo-item-end))))
(overlay-put ov 'face 'todo-search))
(let* ((num (if (not marked) 1 (cdr marked)))
(cat+file (todo-read-category
(ngettext "Move item to category: "
"Move items to category: " num)
nil file)))
(while (and (equal (car cat+file) cat1)
(equal (cdr cat+file) file1))
(setq cat+file (todo-read-category
"Choose a different category: ")))
(setq cat2 (car cat+file)
file2 (cdr cat+file))))
(if ov (delete-overlay ov)))
(set-buffer (find-buffer-visiting file1))
(if marked
(progn
(goto-char (point-min))
(while (not (eobp))
(when (todo-marked-item-p)
(if (todo-done-item-p)
(progn
(push (todo-item-string) done-items)
(setq done (1+ done)))
(push (todo-item-string) todo-items)
(setq todo (1+ todo))
(when (todo-diary-item-p)
(setq diary (1+ diary)))))
(todo-forward-item))
(setq todo-items (nreverse todo-items))
(setq done-items (nreverse done-items)))
(if (todo-done-item-p)
(progn
(push done-item done-items)
(setq done 1))
(push item todo-items)
(setq todo 1)
(when (todo-diary-item-p) (setq diary 1))))
(set-window-buffer (selected-window)
(set-buffer (find-file-noselect file2 'nowarn)))
(unwind-protect
(let (here)
(when todo-items
(todo-set-item-priority (pop todo-items) cat2 t)
(setq here (point))
(while todo-items
(todo-forward-item)
(let ((inhibit-read-only t))
(todo-insert-with-overlays (pop todo-items)))))
;; Move done items en bloc to top of done items section.
(when done-items
(todo-category-number cat2)
(widen)
(goto-char (point-min))
(re-search-forward
(concat "^" (regexp-quote (concat todo-category-beg cat2)) "$")
nil t)
(re-search-forward
(concat "^" (regexp-quote todo-category-done)) nil t)
(forward-line)
(unless here (setq here (point)))
(while done-items
(let ((inhibit-read-only t))
(todo-insert-with-overlays (pop done-items)))
(todo-item-end)
(forward-line)))
;; If only done items were moved, move point to the top
;; one, otherwise, move point to the top moved todo item.
(goto-char here)
(setq moved t))
(cond
;; Move succeeded, so remove item from starting category,
;; update item counts and display the category containing
;; the moved item.
(moved
(setq nmark (point-marker))
(when todo (todo-update-count 'todo todo))
(when diary (todo-update-count 'diary diary))
(when done (todo-update-count 'done done))
(todo-update-categories-sexp)
(with-current-buffer (find-buffer-visiting file1)
(save-excursion
(save-restriction
(widen)
(goto-char omark)
(if marked
(let (beg end)
(setq item nil)
(re-search-backward
(concat "^" (regexp-quote todo-category-beg)) nil t)
(forward-line)
(setq beg (point))
(setq end (if (re-search-forward
(concat "^"
(regexp-quote todo-category-beg))
nil t)
(progn
(goto-char (match-beginning 0))
(point-marker))
(point-max-marker)))
(goto-char beg)
(while (< (point) end)
(if (todo-marked-item-p)
(let ((inhibit-read-only t))
(todo-remove-item))
(todo-forward-item)))
(setq todo-categories-with-marks
(assq-delete-all cat1 todo-categories-with-marks)))
(if ov (delete-overlay ov))
(let ((inhibit-read-only t))
(todo-remove-item)))))
(when todo (todo-update-count 'todo (- todo) cat1))
(when diary (todo-update-count 'diary (- diary) cat1))
(when done (todo-update-count 'done (- done) cat1))
(todo-update-categories-sexp))
(set-window-buffer (selected-window)
(set-buffer (find-file-noselect file2 'nowarn)))
(setq todo-category-number (todo-category-number cat2))
(let ((todo-show-with-done (> done 0)))
(todo-category-select))
(goto-char nmark)
;; If item is moved to end of (just first?) category, make
;; sure the items above it are displayed in the window.
(recenter))
;; User quit before setting priority of todo item(s), so
;; return to starting category.
(t
(set-window-buffer (selected-window)
(set-buffer (find-file-noselect file1 'nowarn)))
(todo-category-number cat1)
(todo-category-select)
(goto-char omark))))))))