Sparse trees and the match syntax
Table of Contents
- 1. How to use this file
- 2. Playground
- 3. Your first sparse tree: open TODO entries
- 4. Getting back: moving, unfolding and clearing
- 5. Specific TODO keywords (T)
- 6. Regexp sparse trees (/ or r)
- 7. Tags and property matches (m, M and C-c \)
- 8. Match syntax: tags
- 9. Match syntax: the TODO part
- 10. Match syntax: properties
- 11. Match syntax: dates
- 12. Property value (p)
- 13. Deadlines (d)
- 14. Dates before, after and between (b, a, D)
- 15. More ways to get a sparse tree
- 16. Common mistakes
- 17. Differences from Emacs
- 18. Further reading
1. How to use this file
A sparse tree folds the buffer so that only the entries you are looking for stay visible, together with the headlines above them (their "context"). The matches are highlighted and collected in the window's location list, so you can jump from one to the next. Nothing in the file changes: a sparse tree is only a way of looking at it.
This file has two halves:
- the Playground, a small task list (an office move, a household, side projects) that every exercise searches, and
- one heading per kind of sparse tree and per part of the match syntax, each with examples, exercises (Try:) and the exact result (Expect:).
Working through it:
- The file starts folded (
#+STARTUP: overview). Put the cursor on a heading and press<Tab>to open it;<S-Tab>cycles the whole buffer. <prefix>means<leader>o(the default prefix), so<prefix>/is<leader>o/. Withexamples/minimal_init.luathe leader is<Space>.- Press
g?at any time to list every keymap of the buffer. - Sparse trees don't edit anything, but if you do change the Playground,
uundoes andgit checkout examples/10-sparse-trees.orgrestores it. The expected results below assume the Playground is unchanged. - Coming from Emacs?
C-c /andC-c \work too (:h org-emacs-keys).
Start Neovim from the root of the repository with the bundled config:
nvim -u examples/minimal_init.lua examples/10-sparse-trees.org
examples/minimal_init.lua loads org.nvim from this checkout, sets
<Space> as the leader, points the agenda at examples/*.org and sends
captures to a scratch directory. Sparse trees only look at the current
buffer, so none of that matters here except the leader key.
Every sparse tree prints a message like 4 matches for +urgent. That
number is the easiest thing to check, so each Expect: gives it.
Today is Mon 2026-09-28 in these examples. Only the deadline tree (d) and
the relative dates (<today>, <+1w>) depend on the real date; their
Expect: lines say so.
1.1. Keys in this file
| Key | Action |
|---|---|
<prefix>/ |
sparse tree menu (Emacs C-c /) |
<C-c>/ |
the same menu, Emacs key |
<C-c>\ |
tags / property match tree, straight away |
]l [l |
next / previous match (:lnext :lprev) |
:lopen |
list every match in the location list |
<C-c><C-c> |
remove the highlights (first press) |
<prefix>/ then c |
remove the highlights |
<S-Tab>, :Org show_all |
unfold again |
<C-c><C-x>q |
turn tag groups on / off in matches |
In the menu of <prefix>/:
/orr- lines matching a (Vim) regexp
t- open TODO entries (not done)
T- entries with the TODO keyword(s) you type (
NEXT|WAITING) m- entries selected by a tags / property match
M- the same, open TODO entries only
p- entries with a property value (
ASSIGNEE=Bob) d- deadlines past due or inside their warning period
b- entries with a date before a date
a- entries with a date after a date
D- entries with a date between two dates
c- clear the highlights
2. Playground
This is the data the exercises search. Open it once with <Tab> (and
<Tab> again for everything) to see what is there. Notice:
- the TODO keywords (
#+TODO: TODO NEXT WAITING | DONE CANCELLED), - the tags, some of them inherited from a parent headline,
- the
Effort,COSTandASSIGNEEproperties, - the
CATEGORYof each group, and - the SCHEDULED / DEADLINE / CLOSED lines and plain timestamps.
All the level-3 headlines of this file are here, so LEVEL=3 finds
exactly the tasks of the Playground.
2.1. Office move  work
All tasks of the office move inherit the work tag from this headline.
2.1.1. TODO Sign the new lease  urgent
The landlord sends the Invoice for the deposit after the signature.
2.1.2. NEXT Book the movers  phone
Ask for an invoice with the VAT number on it.
2.1.3. WAITING Quote from the cleaning company  email
2.1.4. TODO Pack the archive room
2.1.5. DONE Choose the new office
2.1.6. Team meeting about the move  meeting
2.2. Home  home
2.2.1. TODO Fix the leaking tap  urgent
2.2.2. TODO Paint the fence
2.2.3. TODO Buy groceries  errand
2.2.4. NEXT Call the plumber back  phone urgent
Pay the plumber's invoice in cash.
2.2.5. CANCELLED Repaint the garage
2.2.6. DONE Renew the car insurance  errand
2.3. Side projects
2.3.1. TODO Write a blog post about sparse trees  writing
2.3.2. TODO Submit the conference talk  writing urgent
2.3.3. Idea: a garden planner app  idea
Noted while weeding the garden.
3. Your first sparse tree: open TODO entries
<prefix>/ opens a small menu; each key builds a different sparse tree.
The simplest one is t: every headline with a TODO keyword that is not
done (TODO, NEXT and WAITING here; DONE and CANCELLED are done
states because they come after the | in #+TODO:).
What happens:
- the whole buffer is folded to its top-level headlines (OVERVIEW),
- each matching headline is shown with all its ancestors,
- the matching headlines are highlighted (the
Searchcolour), and - the location list of the window is filled with the matches, and the cursor goes to the first one.
Try: press <prefix>/ then t.
Expect: the message 11 matches for TODO entries. Under "Playground"
you see the three groups and, under them, these headlines highlighted:
- Office move: Sign the new lease, Book the movers, Quote from the cleaning company, Pack the archive room
- Home: Fix the leaking tap, Paint the fence, Buy groceries, Call the plumber back
- Side projects: Write a blog post…, Submit the conference talk, Library book reservation
"Choose the new office" (DONE), "Repaint the garage" (CANCELLED), "Team meeting about the move" and "Idea: a garden planner app" (no keyword) are hidden. The other top-level headings of this file stay folded.
4. Getting back: moving, unfolding and clearing
4.1. Jumping from match to match
The matches are in the location list of the window, so the usual Vim commands move between them:
]l/[l(Neovim 0.11+ default mappings) or:lnext/:lprev,:lfirst/:llast,:lopenshows the list (its title isSparse tree: ...);<CR>on a line jumps there,:lclosecloses it.
Try: after the TODO tree above, press ]l three times, then [l once.
Expect: the cursor goes Sign the new lease → Book the movers → Quote from
the cleaning company → Pack the archive room, then back to Quote from the
cleaning company. :lopen lists 11 lines.
4.2. Showing everything again
A sparse tree only changes the folds. Any visibility command undoes it:
<S-Tab>cycles the whole buffer (OVERVIEW → CONTENTS → SHOW ALL),:Org show_allshows everything,:Org overviewfolds everything,<Tab>on a folded headline opens just that one.
4.3. Removing the highlights
The highlights stay until one of these:
- the first
<C-c><C-c>in the buffer only removes them (like Emacs, it does nothing else that time), <prefix>/thencremoves them and empties the location list,- any change to the buffer removes them.
Try: build the TODO tree again (<prefix>/ t), then press <C-c><C-c>.
Expect: the highlights disappear at once; the folds stay as they are.
Press <prefix>/ t again and then <prefix>/ c: same result, and
:lopen now shows an empty list.
5. Specific TODO keywords (T)
T asks for one or more keywords, with completion on the keywords of the
buffer. Separate several keywords with | (or spaces). Done keywords are
allowed here, unlike with t.
NEXT- 2 matches: Book the movers, Call the plumber back
NEXT|WAITING- 4 matches: the two above, Quote from the cleaning company, Library book reservation
DONE CANCELLED- 3 matches: Choose the new office, Repaint the garage, Renew the car insurance
Try: <prefix>/ T, type NEXT|WAITING and press <CR>.
Expect: 4 matches for NEXT|WAITING: Book the movers, Quote from the
cleaning company, Call the plumber back and Library book reservation.
Try: <prefix>/ T and type DONE.
Expect: 2 matches for DONE: Choose the new office and Renew the car
insurance. The keyword is compared exactly: done finds nothing.
6. Regexp sparse trees (/ or r)
/ (or r) asks for a regular expression and highlights every line that
matches, anywhere in the buffer: headlines, body text, drawers and these
explanations too. Each match shows the lines of its entry and the
headlines above it. Only the matching part of the line is highlighted.
In the <prefix>/ menu the regexp is a Vim regexp (:h pattern), and
it is case-sensitive: add \c to ignore case. (Emacs uses an Emacs regexp
and ignores case; see Differences from Emacs.)
| Pattern | Matches |
|---|---|
[i]nvoice |
2 lines: Book the movers, Call the plumber back |
\c[i]nvoice |
3 lines: the two above and Sign the new lease |
[I]nvoice |
1 line: the body of Sign the new lease |
^\*\+ [N]EXT |
2 headlines in the NEXT state |
:[A]SSIGNEE: *Bob |
2 property lines: Book the movers, Pack … |
SCHEDULED: <2026-1[0] |
3 planning lines: scheduled in October |
Try: <prefix>/ /, type [i]nvoice and press <CR>.
Expect: 2 matches for /[i]nvoice/. The body lines of "Book the movers"
and "Call the plumber back" are visible under their headlines, with the
word highlighted. The capitalised word in the body of "Sign the new lease"
is not a match, because the pattern is case-sensitive.
Try: the same with \c[i]nvoice.
Expect: 3 matches for /\c[i]nvoice/: the two lines above plus the body
line of "Sign the new lease".
Try: <prefix>/ r and type SCHEDULED: <2026-1[0].
Expect: 3 matches: the SCHEDULED lines of Pack the archive room,
Paint the fence and Library book reservation. Press ]l to walk through
them; :lopen lists the three lines.
7. Tags and property matches (m, M and C-c \)
m asks for a match string (a tags / property / TODO query, the same
syntax as the agenda's m view and clock tables) and shows every headline
that it selects. M does the same but keeps only open TODO entries.
<C-c>\ skips the menu and asks for the match directly (Emacs
org-match-sparse-tree). To keep only open TODO entries there, end the
match with /! (see the TODO part).
Headlines are matched, not lines: the whole headline is highlighted.
| Keys | Match | Result |
|---|---|---|
<prefix>/ m |
+urgent |
4 matches |
<prefix>/ M |
+work |
4 matches (only the open TODO ones) |
<C-c>\ |
+work |
7 matches (Office move and its 6 tasks) |
<C-c>\ |
+work/! |
4 matches, like M |
Try: <prefix>/ m, type +urgent and press <CR>.
Expect: 4 matches for +urgent: Sign the new lease, Fix the leaking
tap, Call the plumber back and Submit the conference talk.
Try: <C-c>\ and type +work, then <C-c>\ again with +work/!.
Expect: first 7 matches for +work (Office move and every task under
it, because tags are inherited), then 4 matches: Sign the new lease,
Book the movers, Quote from the cleaning company and Pack the archive
room. The DONE task and the meeting (no keyword) are left out.
The next sections go through the match syntax piece by piece. Use
<C-c>\ (or <prefix>/ m) for every example.
8. Match syntax: tags
A match string is a list of terms. For tags:
work- tagged
work(the+is optional) +work- tagged
work -work- not tagged
work +a+b- tagged
aANDb a:banda&b- the same:
:and&also mean AND a|b- tagged
aORb {regexp}- a tag matching an (Emacs) regexp
Rules worth remembering:
- AND binds tighter than OR:
a+b|cis "(a and b) or c". There are no parentheses. - Tags are inherited: a child has the tags of its parents (and of
#+FILETAGS:).tags_exclude_from_inheritanceanduse_tag_inheritancechange that. - Tag names are compared exactly:
Workdoes not findwork. Regexps in{...}ignore case. - A term cannot contain spaces. Text that does not start a new term ends
the match silently, as in Emacs:
work -urgentis the same aswork.
8.1. Simple tags, AND, NOT
+home- 7: Home and its 6 tasks
+urgent+home- 2: Fix the leaking tap, Call the plumber back
home:urgent- 2: the same
home&urgent- 2: the same
+work-urgent- 6: Office move and its tasks, except the lease
+urgent-work- 3: Fix the leaking tap, Call the plumber back, Submit the conference talk
+phone- 2: Book the movers, Call the plumber back
Try: <C-c>\ with +work-urgent.
Expect: 6 matches for +work-urgent: Office move, Book the movers, Quote
from the cleaning company, Pack the archive room, Choose the new office
and Team meeting about the move. "Sign the new lease" is hidden.
8.2. OR, and how it mixes with AND
work|home- 14: both groups and all their tasks
phone|email- 3: Book the movers, Quote from the cleaning company, Call the plumber back
home+urgent|writing- 4: Fix the leaking tap, Call the plumber back, the blog post, the conference talk
+work+urgent|+home+errand- 3: Sign the new lease, Buy groceries, Renew the car insurance
Try: <C-c>\ with home+urgent|writing.
Expect: 4 matches. Read it as "(home AND urgent) OR writing": Fix the
leaking tap and Call the plumber back (home and urgent), Write a blog post
about sparse trees and Submit the conference talk (writing).
8.3. Inheritance
"Pick up the book at the front desk" has no tags of its own, but its
parent "Library book reservation" is tagged errand.
+errand- 4: Buy groceries, Renew the car insurance, Library book reservation, Pick up the book at the front desk
+work- 7: Office move and its 6 tasks, none of which has its own tag
Try: <C-c>\ with +errand.
Expect: 4 matches, the level-4 "Pick up the book at the front desk"
among them.
8.4. Tag regexps
{...} holds an Emacs regexp that is compared with each tag (ignoring
case). It can be negated with - like a tag.
| Match | Count | Headlines |
|---|---|---|
{^w} |
9 | tags starting with w: work (7) and writing (2) |
{ing$} |
3 | writing (2) and meeting: both end in "ing" |
{^e} |
5 | errand (4) and email (1) |
+home-{^e} |
5 | Home, Fix…, Paint…, Call…, Repaint… |
Try: <C-c>\ with {^w}.
Expect: 9 matches: Office move and its six tasks, plus Write a blog post
about sparse trees and Submit the conference talk.
8.5. Tag groups
The second #+TAGS: line of this file defines a group tag:
[ Office : meeting email ]. With group_tags on (the default), the
match Office finds entries tagged Office, meeting or email, and
-Office excludes all three. <C-c><C-x>q turns groups off and on.
| Match | Count | Headlines |
|---|---|---|
Office |
2 | Quote…, Team meeting about the move |
+work-Office |
5 | Office move, Sign…, Book…, Pack…, Choose… |
Try: <C-c>\ with Office. Then press <C-c><C-x>q and run the same
match again. Press <C-c><C-x>q once more to turn groups back on.
Expect: 2 matches with groups on; 0 matches for Office with groups
off (no headline has the tag Office itself).
8.6. Gotcha: spaces end the match
Try: <C-c>\ with work -urgent (with a space).
Expect: 7 matches, exactly like work: the space ends the match and
-urgent is ignored without an error. Type work-urgent instead.
9. Match syntax: the TODO part
Everything after the last / is matched against the TODO keyword.
/NEXT- keyword is NEXT
/NEXT|WAITING- NEXT or WAITING
/-DONE- keyword is not DONE (entries without a keyword match too)
/!- only open TODO entries (a not-done keyword)
/!-WAITING- open TODO entries, except WAITING
/{^W}- a keyword matching an Emacs regexp
TAGS/TODO-PART- both parts must match
Examples (the number is the match count):
/NEXT- 2: Book the movers, Call the plumber back
/NEXT|WAITING- 4: the two above, Quote…, Library book reservation
/DONE|CANCELLED- 3: Choose…, Repaint…, Renew…
/!- 11: the same as
<prefix>/t /!-WAITING- 9: the 11 open entries minus the 2 WAITING ones
/{^W}- 2: Quote…, Library book reservation
+home/!- 4: Fix…, Paint…, Buy groceries, Call…
+work/-DONE- 6: the Office move group, minus Choose the new office
+urgent/TODO- 3: Sign…, Fix…, Submit the conference talk
-home/!- 7: the open entries outside Home
Try: <C-c>\ with +home/!.
Expect: 4 matches for +home/!: Fix the leaking tap, Paint the fence,
Buy groceries and Call the plumber back. The DONE and CANCELLED tasks and
the Home headline itself (no keyword) are not shown.
Try: <C-c>\ with +work/-DONE.
Expect: 6 matches: Office move, Sign the new lease, Book the movers,
Quote from the cleaning company, Pack the archive room and Team meeting
about the move. -DONE keeps headlines without any keyword; use /! when
you only want open tasks.
10. Match syntax: properties
A term can also compare a property: NAME OPERATOR VALUE.
Operators: = (or ==), <> (or != or /=), <, <=, >, >=.
The value decides the kind of comparison:
"text"in double quotes: a string comparison,- a number (
100,2.5): a numeric comparison, {regexp}: an Emacs regexp, ignoring case (<>means "does not match"),"[2026-10-01 Thu]","<today>"…: a date comparison (next section).
A missing property counts as the empty string "" in string comparisons
and as 0 in numeric ones. Add * after the operator (<*, >=*,
<>*, …) to match only entries that have the property.
Properties are not inherited in matches unless use_property_inheritance
says so (it is false by default). CATEGORY is special: it always comes
from the nearest :CATEGORY: above, or from #+CATEGORY:.
10.1. Strings
| Match | Count | Headlines |
|---|---|---|
ASSIGNEE"Bob"= |
2 | Book the movers, Pack the archive room |
ASSIGNEE"bob"= |
0 | strings are compared exactly |
ASSIGNEE<>*"Bob" |
3 | Sign…, Quote…, Paint the fence |
Effort"1:00"= |
1 | Sign the new lease |
+home+ASSIGNEE"Alice"= |
1 | Paint the fence |
Try: <C-c>\ with ASSIGNEE"Bob", then with =ASSIGNEE<>*"Bob".
Expect: 2 matches, then 3 matches: Sign the new lease (Alice), Quote
from the cleaning company (Carol) and Paint the fence (Alice). Without the
star (ASSIGNEE<>"Bob") every headline without an ASSIGNEE would match
too, the headings of this tutorial included.
10.2. Numbers
Numbers are read like Emacs's string-to-number: the leading number of
the value, so "1:30" is 1 and "0:45" is 0. Use them for plain
numbers such as COST; for efforts, see the strings above or compare
whole hours.
| Match | Count | Headlines |
|---|---|---|
COST>100 |
4 | Sign (1200), Book (450), Paint (150), Renew (640) |
COST>=*500 |
2 | Sign the new lease, Renew the car insurance |
COST<=*100 |
1 | Fix the leaking tap (80) |
COST>100+home |
2 | Paint the fence, Renew the car insurance |
Effort>=*2 |
3 | Pack… (4:00), Paint… (5:00), Write a blog… (2:00) |
Effort<*1 |
3 | Book… (0:30), Quote… (0:15), Fix… (0:45) |
Try: <C-c>\ with COST>=*500.
Expect: 2 matches: Sign the new lease and Renew the car insurance.
Try: <C-c>\ with COST<=100 (no star).
Expect: many more matches than you might think: Fix the leaking tap, and
every headline without a COST (it counts as 0), the headings of this
tutorial included. Now try COST<=*100: 1 match.
10.3. Regexps on property values
| Match | Count | Headlines |
|---|---|---|
ASSIGNEE={^[ab]} |
4 | Alice (2) and Bob (2): regexps ignore case |
ASSIGNEE={o} |
3 | Bob (2) and Carol |
ASSIGNEE<>{^b}+Effort>=*1 |
3 | Sign…, Paint…, Write a blog… (no ASSIGNEE) |
Try: <C-c>\ with ASSIGNEE={^[ab]}.
Expect: 4 matches: Sign the new lease, Book the movers, Pack the
archive room and Paint the fence.
10.4. Special properties
Some property names are computed from the headline:
| Name | Value |
|---|---|
LEVEL |
the number of stars |
TODO |
the TODO keyword |
PRIORITY |
the priority letter; B when there is no cookie |
CATEGORY |
the category (inherited, see above) |
ITEM |
the headline text, without stars, keyword and tags |
TAGS ALLTAGS |
own tags / all tags, as :a:b: |
SCHEDULED DEADLINE CLOSED |
the planning dates |
TIMESTAMP TIMESTAMP_IA |
the first active / inactive timestamp |
LEVEL=3- 16: every task of the Playground
LEVEL>3- 1: Pick up the book at the front desk
LEVEL=2+work- 1: Office move
TODO"NEXT"=- 2: Book the movers, Call the plumber back
PRIORITY"A"=- 1: Sign the new lease
PRIORITY<"C"+LEVEL=3- 15: every task but Paint the fence (
[#C]): a task without a cookie has priority B CATEGORY"household"=- 7: Home and its 6 tasks
CATEGORY"hobby"/!=- 3: the blog post, the conference talk, the library book
ITEM={lease\|plumber}- 2: Sign the new lease, Call the plumber back
(
\|is "or" in an Emacs regexp) ALLTAGS={:phone:}- 2: Book the movers, Call the plumber back
Try: <C-c>\ with PRIORITY"A", then =LEVEL>3, then
CATEGORY"hobby"/!=.
Expect: 1 match (Sign the new lease), 1 match (Pick up the book at
the front desk), 3 matches (Write a blog post about sparse trees, Submit
the conference talk, Library book reservation).
11. Match syntax: dates
Put a date in double quotes, inside angle or square brackets, and the
property is compared as a date. Works with SCHEDULED, DEADLINE,
CLOSED, TIMESTAMP (the first active timestamp of the entry),
TIMESTAMP_IA (the first inactive one) and any property holding a
timestamp. An entry without the date never matches.
Angle brackets work as well as square ones (the Emacs manual uses angle
brackets, like "<today>" below). The examples use square
brackets: written in this file, an angle-bracket date would itself be an
active timestamp of the explanation headings, and date searches would find
them.
| Date value | Means |
|---|---|
"[2026-10-01 Thu]" |
that day at 00:00 |
"[2026-10-01 Thu 14:00]" |
that day at 14:00 |
"<today>" |
today at 00:00 |
"<tomorrow>" |
tomorrow; "<yesterday>" also works |
"<now>" |
now, with the time |
"<+2d>" "<-1w>" |
today plus / minus days, weeks, months (m), years (y) |
11.1. Absolute dates (always the same result)
| Match | Count | Headlines |
|---|---|---|
SCHEDULED<"[2026-10-01 Thu]" |
2 | Book the movers, Buy groceries |
SCHEDULED>""= |
3 | Pack…, Paint…, Library book reservation |
DEADLINE<""= |
4 | Sign…, Choose…, Fix…, Renew… |
DEADLINE<""/!= |
2 | Sign the new lease, Fix the leaking tap |
CLOSED>""= |
2 | Choose the new office, Renew the car insurance |
TIMESTAMP>""= |
1 | Team meeting about the move |
TIMESTAMP_IA<"[2026-10-01 Thu]" |
1 | Idea: a garden planner app |
Try: <C-c>\ with DEADLINE<""/!=.
Expect: 2 matches: Sign the new lease (due Oct 2) and Fix the leaking
tap (due Sep 25). The DONE entries with an early deadline are left out by
/!.
Try: <C-c>\ with CLOSED>"", then with
=TIMESTAMP>""=.
Expect: 2 matches (Choose the new office, Renew the car insurance),
then 1 match (Team meeting about the move: its plain timestamp is its
TIMESTAMP; SCHEDULED and DEADLINE dates don't count as TIMESTAMP).
11.2. Relative dates
These depend on the day you run them. On Mon 2026-09-28:
| Match | Count | Headlines |
|---|---|---|
SCHEDULED<"<today>"= |
1 | Buy groceries |
SCHEDULED<"<tomorrow>"= |
2 | Buy groceries, Book the movers |
DEADLINE<"<+1w>"/! |
2 | Sign the new lease, Fix the leaking tap |
SCHEDULED>"<+2w>" |
1 | Paint the fence (Oct 17) |
Try: <C-c>\ with SCHEDULED<"<tomorrow>"=.
Expect: on 2026-09-28, 2 matches. On a later day, every entry
scheduled up to tomorrow matches, so the count only grows.
12. Property value (p)
p is a shortcut for a single property: type NAME=value and it builds
the match NAME"value"= for you (quotes are added when missing).
Try: <prefix>/ p and type ASSIGNEE=Bob.
Expect: 2 matches for ASSIGNEE"Bob"=: Book the movers and Pack the
archive room.
Try: <prefix>/ p and type COST=450.
Expect: 1 match: Book the movers. (The comparison is a string one, so
COST=450.0 finds nothing.)
13. Deadlines (d)
d shows the open entries whose deadline is past or inside its warning
period: deadline_warning_days (14 by default) before the date, or the
entry's own -Nd cookie (the -40d in the DEADLINE of "Submit the
conference talk" warns 40 days ahead). Done entries are never shown.
Try: <prefix>/ d.
Expect: on Mon 2026-09-28, 3 matches for deadlines:
- Sign the new lease (due in 4 days),
- Fix the leaking tap (3 days overdue),
- Submit the conference talk (due in 32 days, but the
-40dcookie warns 40 days ahead).
Not shown: Write a blog post (Nov 20 is 53 days away), Choose the new office and Renew the car insurance (done). On a later date more entries fall inside their warning period.
14. Dates before, after and between (b, a, D)
b, a and D open the calendar to pick a date (D asks twice: from,
to). In the calendar, h l j k move by day / week, < > by
month, . goes to today, i lets you type a date (like 2026-10-01,
+3d or fri), and <CR> selects.
An entry matches when its SCHEDULED, DEADLINE or one of its active timestamps is:
b: strictly before the date,a: strictly after the date,D: between the two dates, both included.
CLOSED dates and inactive timestamps (like the one under the Idea) are not used.
Try: <prefix>/ b; in the calendar press i, type 2026-10-01 and
press <CR> (the typed date is taken at once).
Expect: 6 matches for before 2026-10-01: Book the movers (Sep 29),
Choose the new office (deadline Sep 20), Team meeting about the move
(Sep 30), Fix the leaking tap (Sep 25), Buy groceries (Sep 28) and Renew
the car insurance (deadline Sep 30).
Try: <prefix>/ a, then i, 2026-10-15, <CR>.
Expect: 3 matches for after 2026-10-15: Paint the fence (Oct 17),
Write a blog post (Nov 20) and Submit the conference talk (Oct 30).
Try: <prefix>/ D, then i, 2026-10-01, <CR> (the first
calendar) and i, 2026-10-12, <CR> (the second one).
Expect: 3 matches for between 2026-10-01 and 2026-10-12: Sign the new
lease (Oct 2), Pack the archive room (Oct 12, the last day is included)
and Library book reservation (Oct 5).
15. More ways to get a sparse tree
15.1. From a link
A link to a file with ::/regexp/ after the name opens the file as a
regexp sparse tree. Here the regexp is an Emacs regexp.
Try: put the cursor on the link above and press <CR> (or gx).
Expect: 2 matches: the ASSIGNEE lines in the property drawers of Sign
the new lease and Paint the fence, highlighted. Unlike the / menu entry,
this regexp ignores case, like Emacs.
15.2. From an agenda custom command
The agenda's custom_commands can build a sparse tree of the current
buffer instead of an agenda: tags_tree (a match string), todo_tree (a
TODO keyword) and occur_tree (an Emacs regexp). They can't be blocks of a
composite command. For example, in your config:
require("org").setup({
agenda = {
custom_commands = {
-- <prefix>a then U: the urgent open tasks of the current buffer
U = { description = "Urgent tree", type = "tags_tree",
match = "+urgent/!" },
-- <prefix>a then N: every NEXT entry of the current buffer
N = { description = "NEXT tree", type = "todo_tree", match = "NEXT" },
-- <prefix>a then I: the lines about bills (an Emacs regexp)
I = { description = "Bills", type = "occur_tree", match = "[i]nvoice" },
},
},
})
examples/minimal_init.lua does not define these, so this one is only to
read. With them, <prefix>a U in this file shows 3 matches (Sign the
new lease, Fix the leaking tap, Submit the conference talk).
15.3. Speed key
With use_speed_commands = true, pressing / with the cursor on the
first star of a headline opens the sparse tree menu (like <prefix>/).
16. Common mistakes
work -urgent- same as
work: the space ends the match. Writework-urgent. Work- 0 matches: tags are compared exactly. Write
work(or{^work$}, which ignores case). (a|b)+c- parentheses are not part of the syntax. Write
a+c|b+c. COST<100- entries without a COST match too (a missing number is
0). Write
COST<*100. Effort<"1:00"- entries without an Effort match too (
"" < "1:00"). WriteEffort<*"1:00". Effort<1:30- read as
Effort<1AND a tag named30: 0 matches. WriteEffort<*"1:30". ASSIGNEE=Bob- without quotes it is not a comparison: a search for
the tag
ASSIGNEEthat stops at=, so 0 matches. WriteASSIGNEE"Bob"=. [i]nvoicein the/menu- a case-sensitive Vim regexp. Write
\c[i]nvoiceto ignore case.
Try: <C-c>\ with Effort<*"1:00".
Expect: 3 matches: Book the movers ("0:30"), Quote from the cleaning
company ("0:15") and Fix the leaking tap ("0:45").
17. Differences from Emacs
- In the
<prefix>/menu,/andrtake a Vim regexp and are case-sensitive (Emacs: an Emacs regexp, ignoring case).\cmakes it ignore case. Links with::/regexp/andoccur_treecommands take an Emacs regexp. cin the menu clears the highlights. In Emacsccycles the kind of date used byb,aandD(scheduled/deadline, all timestamps, only deadlines, …). Hereb,aandDalways look at SCHEDULED, DEADLINE and the active timestamps of each entry, and match whole headlines.pasks forNAME=valuein one prompt (Emacs asks for the property, then the value).
18. Further reading
:h org-sparse-tree— the menu and<C-c>\:h org-match-syntax— the whole match syntax:h org-tag-groups— group tags in matches:h org-agenda-custom-commands—tags_tree,todo_tree,occur_tree:h org-hidden-lines— how the folds of a sparse tree are made:h org-read-date— what you can type in the calendar withi- 05-tags.org and 06-properties-columns.org: tags and properties themselves
- 09-agenda.org: the same match syntax in the agenda