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