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))))))