I'm trying to use org-drill with cards made up of one-line headings, which the documentation considers an "empty card" (that is, one without a body).

The recommended way to make them show up in drill sessions is to add an empty comment to the body, like a line with only #. It works, but I'm trying to fix this in a way cleaner than mass-editing my org file.

I found the variable org-drill-card-type-alist, whose default value is

      '((nil org-drill-present-simple-card)
        ("simple" org-drill-present-simple-card)
        ("twosided" org-drill-present-two-sided-card nil t)

The t at the end of the twosided sexp means drill-empty-p, which means:

When supplied, DRILL-EMPTY-P is a boolean value, default nil. When non-nil, cards of this type will be presented during tests even if their bodies are empty.

This seems to be exactly what I want, so I set the nil (default) and simple (for good measure) card types like this, using customize-set-variable:

      '((nil org-drill-present-simple-card nil t)
        ("simple" org-drill-present-simple-card nil t)
        ("twosided" org-drill-present-two-sided-card nil t)

I eval the sexp / restart org-mode / restart Emacs, and still M-x org-drill ignores the empty cards.

Am I doing something wrong? Is this a bug? Are there any workarounds?


The DRILL-EMPTY-P parameter in entries of org-drill-card-type-alist is only considered for cards with an explicit DRILL_CARD_TYPE in function org-drill-entry-status.

As a workaround treat drill-cards with nil card type as non-empty if the DRILL-EMPTY-P parameter of that type is set:

(defun org-drill-entry-status-workaround (oldfun &rest args)
  "Call adviced `org-drill-entry-status' as OLDFUN with ARGS.
Temporarily let `org-entry-empty-p' return nil for empty drill cards
with DRILL_CARD_TYPE nil."
  (let ((oldfun-entry-empty-p (symbol-function 'org-entry-empty-p)))
    (cl-letf (((symbol-function 'org-entry-empty-p)
               (lambda ()
                 (and (funcall oldfun-entry-empty-p) ;; in principle the old fun
                      ;; with the exception:
                      (null (and
                             (null (org-entry-get (point) "DRILL_CARD_TYPE"))
                             (nth 3 (assoc nil org-drill-card-type-alist)))))))) ;; DRILL-EMPTY-P
      (apply oldfun args))))

(advice-add 'org-drill-entry-status :around #'org-drill-entry-status-workaround)

With this workaround org-drill works as you expect it in the following test org buffer with emacs-version 25.3.1 and org-drill 2.6.1.

* first                                                               :drill:
  :ID:       97a78aeb-8e62-4243-b49b-faccb12dd31c
* second                                                              :drill:
  :ID:       c0acc9c5-bdca-4414-96bb-61ea2aeb85e1

* Local Variables                                                     :noexport:
# Local Variables:
# org-drill-card-type-alist: ((nil org-drill-present-simple-card nil t))
# end:
| improve this answer | |

I've just installed org-drill and this behavior seems a bit unsafe to me. It's documented, but I still spent quite a bit of time figuring out why the verb card from the spanish.org example never shows up. Turns out it's empty.

I'm paranoid that I would occasionally make such mistakes and lose cards forever if it ignores empty ones. So I just redefined the org-drill-entry-empty-p function to always say it's non-empty.

(use-package org-drill
  (defun org-drill-entry-empty-p () nil)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.