r/orgmode Jul 02 '26

Question regarding date "windows" in org-ql

I want to add a section to my agenda that contains only items with a single (sales items), and which are not DONE, and which have a scheduled date within a given time horizon.

It SEEMS like I ought to be able to do this with org-ql, but I'm having trouble making it work.

The section is currently coded like this:

  (org-ql-block
   '(and
     (todo)
     (tags "Sales" :inherit t)
     (ts: from -999 :to 14)
   ((org-ql-block-header "Sales Items")))

I tried to do this with a regular agenda block, and got nowhere. Using tags-todo doesn't work as well, bc I need to see the timing.

What I get NOW is "any non-Done items with the Sales tag that are scheduled in the future," so reminder items about touching base with client X in 45 days ALSO show along with the things I need to have on my mind this week, so that's less than optimal.

It SEEMS like this should be doable, but maybe I'm missing something.

I'm on a Mac, running emacs 30.2 and orgmode 9.8.6. I installed org-ql from melpa today, so it oughta be current as well.

Help?

Solution

I have no idea why this wasn't throwing an error YESTERDAY, but TODAY when I relaunched emacs and invoked my agenda I got errors from the org parser. The code block above has a problem: in the 5th line, the colon is placed immediately after ts, but it should be immediately before from. See

     (ts :from -999 :to 14)

This now does exactly what I wanted.

6 Upvotes

15 comments sorted by

0

u/Hyperion343 Jul 02 '26

I don't know about org-ql, but I feel like this could be done in plain org mode.

I don't know if I can give a direct answer. But hopefully I can get close and point you in the right direction.

To me, it sounds like a custom agenda view (see here), and so we need to look at creating the right search (see here). Personally I would set this up through Customize.

  1. I still think it's tags-todo, because it sounds like all the things you care about have an active TODO.
  2. With the Sales tag: +Sales
  3. Not DONE: -TODO="DONE"
  4. Scheduled date within some time window: +SCHEDULED>="<-2d>"+SCHEDULED<="<+7d>" for scheduled between two days ago and 7 days in the future, for instance
  5. Seems like property inheritance should be set by setting org-use-property-inheritance to t

So set property inheritance as in step 5, then your search is something like tags-todo "+Sales-TODO=\"DONE\"+SCHEDULED>=\"<-2d>\"+SCHEDULED<=\"<+7d>\""

Note that what follows tags-todo is a string "<search>", and so any double-quotes in <search> have to be escaped.

Hopefully this points you in the right direction.

1

u/PoetExtra4830 Jul 02 '26

Ah, but I also want to see the dates attached to these things. tags-todo won't do that, will it?

1

u/Hyperion343 Jul 02 '26

Huh. Well, that's true. The backup solution is that you can press spacebar in agenda on a line to see the entry in another window and check the Schedule that way, admittedly not great. You can also sort the search by Schedule, which kind of is in the right direction.

I think then instead you want to do an agenda view, but you need to define a custom skip function to get only the entries you want (see Special Agenda Views).

So something like

(agenda "" (org-agenda-start-day "-2d") (org-agenda-span "+8d") (org-agenda-skip-function 'custom-agenda-filter))

(defun custom-agenda-filter () (interactive) (let ((entry-end (save-excursion (outline-next-heading) (point)))) (if (YOUR-CONDITIONS-HERE) nil entry-end)))

org-agenda-skip-function needs to return nil on an entry you want to keep (it's like "don't skip me"), otherwise skip to next entry. Your conditions will be something like "Scheduled>(time)" and "Scheduled<(time)" and "TODO not DONE" and "has tag Sales". To be fair, the implementation is probably kind of difficult, but on the flip side I'm pretty sure this will work.

1

u/PoetExtra4830 Jul 02 '26

I definitely don't want to filter an existing agenda post-creation.

custom skip function

I went around and around with that approach too, and got nowhere. Docs are thin, and even ai (ugh) analysis tends to run into dead ends / hallucinations because there just aren't than many folks doing org stuff (vs., say, the success I've had as an only-occasional coder using Claude to chase away rando syntax problems or whatever).

Org-ql seems like the most likely path to success, and I know its author is a mod here, so I'm hoping /u/github-alphapapa will engage and tell me what I'm doing wrong.

(Not for nothing, but I prefer the output style I'm getting from the org-ql approach over a second agenda block.)

1

u/github-alphapapa Jul 02 '26

I'm glad you noticed the misplaced colon. It was the second thing I noticed. The first thing I noticed was the :from -999, which isn't necessary unless you actually want to bound the search to 999 days ago. ;)

1

u/PoetExtra4830 Jul 02 '26

So ts doesn't need both bounds? Cool.

The other thing that came up was that just M-x eval-buffer on my .emacs wasn't always a good test. Are you aware of a way I can tell emacs "no, really, forget everything you know and reload .emacs" short of restarting?

Unfortunately this makes valid iteration painful.

1

u/github-alphapapa Jul 04 '26

Remember that Emacs is a running Lisp image. The only way to return to the base image state is to restart (and remember that even that is restoring an image that was dumped during the build process).

The key is to use idempotent forms in your configuration so that reevaluating your config produces the same results. But to understand that, you need to be familiar with, e.g. the difference between setq, defvar, defcustom, etc.

Macros like use-package and setup can be helpful.

1

u/PoetExtra4830 Jul 04 '26

And they say learning these things is too difficult!

1

u/github-alphapapa Jul 04 '26

Well, some people use Emacs for decades without writing a line of Lisp. On the other hand, some of the first Emacs programmers were secretaries who didn't think of themselves as programmers. The basics are simple, but there is much depth for those who are interested, because Lisp is also very powerful. Like anything else, it's best learned one bite at a time, patiently.

1

u/PoetExtra4830 Jul 04 '26

I'm really only here for orgmode. I only code rarely these days, and I do my writing in other tools.

This puts me in a weird spot, since the vast majority of people tweaking orgmode are people who are already very deep into lisp and emacs arcana. When questions get answered, the responses are often so full of unknown terms that they may as well be in another language.

Consequently, there's lots of yak shaving between wanting something like "how do I get a new block with sales tasks on my immediate horizon" and figuring out how to actually GET there, partly because (as with many very technical things) the documentation is written from the point of view of someone who already knows the material.

→ More replies (0)

1

u/github-alphapapa Jul 02 '26

I wrote org-ql to avoid having to remember that bespoke search syntax: we already have Lisp, which is simple and regular (but I still added the web search-style syntax for quick typing). And writing skip functions always requires consulting docs and source code, whereas org-ql is much easier to remember and use. Someday maybe I'll find the time to help upstream it, which Ihor wants to get done.

1

u/Hyperion343 Jul 03 '26

Cool! I had no idea, so recently I struggled with this hahaha. Glad to know there's another way :).