diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-05 03:43:25 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-05 03:43:25 -0500 |
| commit | 77eb4f046cc90d535ba30ec8a408f52cb85da63f (patch) | |
| tree | 33d89e4480c996ec9b583c9c97e5e978cfa8797a /org-drill.el | |
| parent | 49459e2d74ca3b7d11917e314cd13c6cd8f3f039 (diff) | |
| download | org-drill-77eb4f046cc90d535ba30ec8a408f52cb85da63f.tar.gz org-drill-77eb4f046cc90d535ba30ec8a408f52cb85da63f.zip | |
fix: include child subtree in entry-empty-p search bound (upstream #13)
kqr (2019-07-22) reported that drill entries whose answer lives inside a child sub-heading were silently skipped. Their example: a question in the heading text and the answer under `** The Answer`. The function returned t (empty) for such entries, so they never got presented during drill sessions.
The cause is `(outline-next-heading)` in `org-drill-entry-empty-p`. That primitive lands on the first heading at any level, including children. So the search range was metadata-end up to the child's heading line, which excluded the child's body. Bodies that lived in child sub-headings never got searched.
I switched the bound to `(org-end-of-subtree t t)`, which covers the whole subtree of the current heading and degrades gracefully at the last heading in the buffer. The reporter suggested `outline-forward-same-level`, but that primitive errors at the last sibling, which would be its own regression. `org-end-of-subtree` is the canonical Emacs idiom for this kind of bound and handles end-of-buffer correctly.
I added `tests/test-org-drill-entry-empty-p.el` with 6 ERT tests across Normal, Boundary (kqr's exact fixture), and edge categories. The two regression tests fail at HEAD before the fix and pass after.
One semantic note worth flagging: any subtree content now counts as non-empty, including bare child headings with no body of their own. The bug report is silent on that case and I expect it to be rare in practice. If anyone reports the new behavior as a regression, the fix would be to filter heading lines out of the graphical-character search.
Diffstat (limited to 'org-drill.el')
| -rw-r--r-- | org-drill.el | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/org-drill.el b/org-drill.el index 07de25d..c3a73eb 100644 --- a/org-drill.el +++ b/org-drill.el @@ -2157,11 +2157,17 @@ Note: does not actually alter the item." ;; This version is about 5x faster than the old version, above. (defun org-drill-entry-empty-p () - "Return non-nil if the current entry is empty." + "Return non-nil if the current entry is empty. + +The search bound covers the whole subtree, so an entry whose answer +lives inside a child sub-heading is correctly reported as non-empty +\(upstream issue #13). `org-end-of-subtree' is used in place of +`outline-next-heading' because the latter lands on the first child +heading, which truncates the search range before the child's body." (save-excursion (org-back-to-heading t) (let ((lim (save-excursion - (outline-next-heading) (point)))) + (org-end-of-subtree t t) (point)))) (if (fboundp 'org-end-of-meta-data-and-drawers) (org-end-of-meta-data-and-drawers) ; function removed Feb 2015 (org-end-of-meta-data t)) |
