Function: todo-read-category

todo-read-category is a byte-compiled function defined in todo-mode.el.gz.

Signature

(todo-read-category PROMPT &optional MATCH-TYPE FILE)

Documentation

Choose and return a category name, prompting with PROMPT.

Show completions for existing categories with TAB or SPC.

The argument MATCH-TYPE specifies the matching requirements on the category name: with the value todo or archive the name must complete to that of an existing todo or archive category, respectively; with the value add the name must not be that of an existing category; with all other values both existing and new valid category names are accepted.

With non-nil argument FILE prompt for a file and complete only against categories in that file; otherwise complete against all categories from todo-category-completions-files.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/todo-mode.el.gz
(defun todo-read-category (prompt &optional match-type file)
  "Choose and return a category name, prompting with PROMPT.
Show completions for existing categories with TAB or SPC.

The argument MATCH-TYPE specifies the matching requirements on
the category name: with the value `todo' or `archive' the name
must complete to that of an existing todo or archive category,
respectively; with the value `add' the name must not be that of
an existing category; with all other values both existing and new
valid category names are accepted.

With non-nil argument FILE prompt for a file and complete only
against categories in that file; otherwise complete against all
categories from `todo-category-completions-files'."
  ;; Allow SPC to insert spaces, for adding new category names.
  (let ((minibuffer-local-completion-map
         (let ((map (make-sparse-keymap)))
           (set-keymap-parent map minibuffer-local-completion-map)
           (define-key map " " nil)
           map)))
    (let* ((add (eq match-type 'add))
	   (archive (eq match-type 'archive))
	   (file0 (when (and file (> (length todo-files) 1))
		    (todo-read-file-name (concat "Choose a" (if archive
								 "n archive"
							       " todo")
						 " file: ")
                                         archive t)))
	   (completions (unless file0 (todo-category-completions archive)))
	   (categories (cond (file0
			      (with-current-buffer
				  (find-file-noselect file0 'nowarn)
				(unless (derived-mode-p 'todo-mode) (todo-mode))
				(let ((todo-current-todo-file file0))
				  todo-categories)))
			     ((and add (not file))
			      (with-current-buffer
				  (find-file-noselect todo-current-todo-file)
				todo-categories))
			     (t
			      completions)))
	   (completion-ignore-case todo-completion-ignore-case)
	   (cat (completing-read prompt categories nil
				 (eq match-type 'todo) nil nil
				 ;; Unless we're adding a category via
				 ;; todo-add-category, set default
				 ;; for existing categories to the
				 ;; current category of the chosen
				 ;; file or else of the current file.
				 (if (and categories (not add))
				     (with-current-buffer
					 (find-file-noselect
					  (or file0
					      todo-current-todo-file
					      (todo-absolute-file-name
					       todo-default-todo-file)))
				       (todo-current-category))
				   ;; Trigger prompt for initial category.
				   "")))
	   (catfil (cdr (assoc cat completions)))
	   (str "Category \"%s\" from which file (TAB for choices)? "))
      ;; If we do category completion and the chosen category name
      ;; occurs in more than one file, prompt to choose one file.
      (unless (or file0 add (not catfil))
	(setq file0 (file-truename
		     (if (atom catfil)
			 catfil
		       (todo-absolute-file-name
			(let ((files (mapcar #'todo-short-file-name catfil)))
			  (completing-read (format str cat) files)))))))
      ;; When called without arg FILE, use fallback todo file.
      (unless file0 (setq file0 (or todo-current-todo-file
                                    ;; If we're outside of todo-mode
                                    ;; but there is a current todo
                                    ;; file, use it.
                                    todo-global-current-todo-file
                                    ;; Else, use the default todo file.
                                    (todo-absolute-file-name
				     todo-default-todo-file))))
      ;; First validate only a name passed interactively from
      ;; todo-add-category, which must be of a nonexistent category.
      (unless (and (assoc cat categories) (not add))
	;; Validate only against completion categories.
	(let ((todo-categories categories))
	  (setq cat (todo-validate-name cat 'category)))
	;; When user enters a nonexistent category name by jumping or
	;; moving, confirm that it should be added, then validate.
	(unless add
	  (if (todo-y-or-n-p (format "Add new category \"%s\" to file \"%s\"? "
				cat (todo-short-file-name file0)))
	      (progn
		(when (assoc cat categories)
		  (let ((todo-categories categories))
		    (setq cat (todo-validate-name cat 'category))))
		;; Restore point and narrowing after adding new
		;; category, to avoid moving to beginning of file when
		;; moving marked items to a new category
		;; (todo-move-item).
		(save-excursion
		  (save-restriction
		    (todo-add-category file0 cat))))
	    ;; If we decide not to add a category, exit without returning.
	    (keyboard-quit))))
      (cons cat file0))))