A searching tool for Org-mode, including custom query languages, commands, saved searches and agenda-like views, etc.
Find a file
Adam Porter fe32388d50 Change/Fix: (--format-element) Use marker's buffer
When formatting an element outside the element's buffer (e.g. when
mapping --format-element across the results of org-ql), the current buffer
is not the element's source buffer, so functions like org-get-tags-at
will not return the correct results, because they don't use the
marker's buffer.  So now we set the current buffer to the marker's
buffer.

As this package matures, this might become unnecessary in the future,
but it's probably best to keep it for correctness.
2018-08-01 10:50:27 -05:00
examples.org Docs: Add examples and update readme 2018-07-10 08:38:17 -05:00
notes.org Notes: Add notes 2018-07-10 08:36:24 -05:00
org-agenda-ng.el Change/Fix: (--format-element) Use marker's buffer 2018-08-01 10:50:27 -05:00
org-ql.el Change: Refactor, improve docstrings, argument handling, etc. 2018-07-10 08:27:54 -05:00
README.org Docs: Add examples and update readme 2018-07-10 08:38:17 -05:00
screenshot.png Update screenshot 2018-05-10 16:52:26 -05:00

org-agenda-ng / org-ql

This is rudimentary, experimental, proof-of-concept alternative code for generating Org agendas. It doesn't support nearly as many features as org-agenda.el does, but it might be useful in some way. It uses some existing code from org-agenda.el and tries to be compatible with parts of it, like org-agenda-finalize-entries and org-agenda-finalize.

Here's an example of generating a kind of agenda view for today (note that the grouping is provided by org-super-agenda, not this code:

  (org-agenda-ng "~/src/emacs/org-super-agenda/test/test.org"
    (and (or (date = today)
             (deadline <=)
             (scheduled <= today))
         (not (done))))

/jiri/org-ql/media/commit/fe32388d5089deefa42732b040ab1e92418d0546/screenshot.png

Here are some other examples:

  ;; Show an agenda-like view of items in "~/org/main.org" with TODO and SOMEDAY keywords which are
  ;; tagged "computer" or "Emacs" and in the category "main":
  (org-agenda-ng "~/org/main.org"
    (and (todo "TODO" "SOMEDAY")
         (tags "computer" "Emacs")
         (category "main")))

  ;; Show an agenda-like view of all habits in all agenda files:
  (org-agenda-ng
    (habit))

  ;; Show an agenda-like view similar to a "traditional" Org agenda:
  (org-agenda-ng
    (or (habit)
        (date = today)
        (deadline <=)
        (scheduled <= today)
        (and (todo "DONE" "CANCELLED")
             (closed = today))))

More examples are available in /jiri/org-ql/src/commit/fe32388d5089deefa42732b040ab1e92418d0546/examples.org.

org-ql

Another way to look at it is like a "query language" for Org buffers. For example:

  ;; Return a list of Org entry elements which have the SOMEDAY keyword, are tagged "Emacs", and have
  ;; priority B or higher:
  (org-ql "~/org/main.org"
    (and (todo "SOMEDAY")
         (tags "Emacs")
         (priority >= "B"))) ;; => ((headline (:raw-value "org-board" :begin 1220270 :end 1220403 ...)) ...)

  ;; Find non-done items which contain the term "Emacs" and have priority "B" or higher, and
  ;; return a list of heading positions:
  (org-ql org-agenda-files
    (and (not (done))
         (regexp "Emacs")
         (priority >= "B"))
    :action-fn (lambda (element)
                 (org-element-property :begin element)))  ;; => (44154 46469 56008 63965 100008 ...)

  ;; Or you can use mapcar around it to get the same result (API is WIP):
  (mapcar (lambda (element)
            (org-element-property :begin element))
          (org-ql org-agenda-files
            (and (not (done))
                 (tags "Emacs")
                 (priority >= "B"))))  ;; => (44154 46469 56008 63965 100008 ...)

  ;; If you kept a database of music in an Org file, you might run a query like this to find tracks
  ;; composed by Chopin that do not have their key recorded in the database:
  (org-ql "~/org/music.org"
    (and (property "genre" "classical")
         (property "composer" "Chopin")
         (not (property "key"))))

Instead of opening an agenda-like buffer with matching entries, org-ql can take a function as an argument that is called at each matching entry to return a result, and finally it returns a list of the results. For example, you could return a list of positions within the buffer, or a list of headings, or headings with entry contents, etc. By default, the matching element is returned, which is the result of calling org-element-headline-parser at that entry.

Results may also be sorted by a user-defined sorting function, or by some built-in sorters: date, deadline, scheduled, priority (which assume that the action-fn is the default, org-element-headline-parser). For example:

  ;; Return TODO items sorted by deadline, then priority.  These built-in sorters assume that items
  ;; are Org elements returned by `org-element-headline-parser' (the default action function).
  (org-ql "~/org/main.org"
    (todo)
    :sort (deadline priority))

  ;; Return TODO items sorted by user-defined sorting function.
  (org-ql "~/org/main.org"
    (todo)
    :sort #'custom-sort-fn)