Function: todo-insert-item--basic
todo-insert-item--basic is a byte-compiled function defined in
todo-mode.el.gz.
Signature
(todo-insert-item--basic &optional ARG DIARY-TYPE DATE-TYPE TIME WHERE)
Documentation
Function implementing the core of todo-insert-item.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/todo-mode.el.gz
(defun todo-insert-item--basic (&optional arg diary-type date-type time where)
"Function implementing the core of `todo-insert-item'."
;; If invoked outside of Todo mode and there is not yet any Todo
;; file, initialize one.
(if (null (funcall todo-files-function))
(todo-show)
(let ((copy (eq where 'copy))
(region (eq where 'region))
(here (eq where 'here))
diary-item)
(when (and arg here)
(user-error "Here insertion only valid in current category"))
(when (and (or copy here)
(or (not (eq major-mode 'todo-mode)) (todo-done-item-p)
(when copy (looking-at "^$"))
(save-excursion
(beginning-of-line)
;; Point is on done items separator.
(looking-at todo-category-done))))
(user-error (concat "Item " (if copy "copying" "insertion")
" is not valid here")))
(when copy (setq diary-item (todo-diary-item-p)))
(when region
(let (use-empty-active-region)
(unless (and todo-use-only-highlighted-region (use-region-p))
(user-error "There is no active region"))))
(let* ((obuf (current-buffer))
(ocat (todo-current-category))
(opoint (point))
(cat+file (cond ((equal arg '(4))
(todo-read-category "Insert in category: "))
((equal arg '(16))
(todo-read-category "Insert in category: "
nil 'file))
(t
(cons (todo-current-category)
(or todo-current-todo-file
(and todo-show-current-file
todo-global-current-todo-file)
(todo-absolute-file-name
todo-default-todo-file))))))
(cat (car cat+file))
(file (cdr cat+file))
(new-item (cond (copy (todo-item-string))
(region (buffer-substring-no-properties
(region-beginning) (region-end)))
(t (if (eq major-mode 'todo-archive-mode)
(user-error (concat "Cannot insert a new Todo"
" item in an archive"))
(read-from-minibuffer "Todo item: ")))))
(date-string (cond
((eq date-type 'date)
(todo-read-date))
((eq date-type 'dayname)
(todo-read-dayname))
((eq date-type 'calendar)
(setq todo-date-from-calendar t)
(or (todo-set-date-from-calendar)
;; If user exits Calendar before choosing
;; a date, cancel item insertion.
(keyboard-quit)))
((and (stringp date-type)
(string-match todo-date-pattern date-type))
(setq todo-date-from-calendar date-type)
(todo-set-date-from-calendar))
(t
(calendar-date-string
(calendar-current-date) t t))))
(time-string (or (and time (todo-read-time))
(and todo-always-add-time-string
(format-time-string "%H:%M")))))
(setq todo-date-from-calendar nil)
(find-file-noselect file 'nowarn)
(set-window-buffer (selected-window)
(set-buffer (find-buffer-visiting file)))
;; If FILE is not in Todo mode, set it now, which also sets
;; CAT to the file's first category.
(unless (derived-mode-p 'todo-mode) (todo-mode))
;; But if FILE was already in todo-mode and the item insertion
;; command was invoked outside of a Todo mode buffer, the
;; above calls to todo-current-category returned nil, so we
;; have to explicitly set CAT to the current category.
(unless cat
(setq cat (todo-current-category)))
(setq todo-current-todo-file file)
(unless todo-global-current-todo-file
(setq todo-global-current-todo-file todo-current-todo-file))
(let ((inhibit-read-only t)
done-only item-added)
(unless copy
(setq new-item
;; Add date, time and diary marking as required.
(concat (if (not (and diary-type
(not todo-include-in-diary)))
todo-nondiary-start
(when (and (eq diary-type 'nonmarking)
(not todo-diary-nonmarking))
diary-nonmarking-symbol))
date-string (when (and time-string ; Can be empty.
(not (zerop (length
time-string))))
(concat " " time-string))
(when (not (and diary-type
(not todo-include-in-diary)))
todo-nondiary-end)
" " new-item))
;; Indent newlines inserted by C-q C-j if nonspace char follows.
(setq new-item (replace-regexp-in-string "\\(\n\\)[^[:blank:]]"
"\n\t" new-item nil nil 1)))
(unwind-protect
(progn
;; If we just visited the file, no category is selected yet.
(when (= (- (point-max) (point-min)) (buffer-size))
(todo-category-number cat)
(todo-category-select))
;; If only done items are displayed in category,
;; toggle to todo items before inserting new item.
(when (save-excursion
(goto-char (point-min))
(looking-at todo-done-string-start))
(setq done-only t)
(todo-toggle-view-done-only))
(if here
(progn
;; Ensure item is inserted where command was invoked.
(unless (= (point) opoint)
(todo-category-number ocat)
(todo-category-select)
(goto-char opoint))
(todo-insert-with-overlays new-item))
(todo-set-item-priority new-item cat t))
(setq item-added t))
;; If user cancels before setting priority, restore
;; display.
(unless item-added
(set-window-buffer (selected-window) (set-buffer obuf))
(when ocat
(unless (equal cat ocat)
(todo-category-number ocat)
(todo-category-select))
(and done-only (todo-toggle-view-done-only)))
(goto-char opoint))
;; If the todo items section is not visible when the
;; insertion command is called (either because only done
;; items were shown or because the category was not in the
;; current buffer), then if the item is inserted at the
;; end of the category, point is at eob and eob at
;; window-start, so that higher priority todo items are
;; out of view. So we recenter to make sure the todo
;; items are displayed in the window.
(when item-added (recenter)))
(todo-update-count 'todo 1)
(when (or diary-item diary-type todo-include-in-diary)
(todo-update-count 'diary 1))
(todo-update-categories-sexp))))))