Add property matcher

This commit is contained in:
Adam Porter 2018-05-10 18:58:21 -05:00
parent 58b2cca65f
commit 39a8c36b92
3 changed files with 30 additions and 0 deletions

View file

@ -66,6 +66,13 @@ Another way to look at it is like a "query language" for Org buffers. For examp
(and (not (done)) (and (not (done))
(tags "Emacs") (tags "Emacs")
(priority >= "B")))) ;; => (44154 46469 56008 63965 100008 ...) (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"))))
#+END_SRC #+END_SRC
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. 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.

View file

@ -186,6 +186,16 @@ Doesn't seem to make any difference.
(regexp "over")) (regexp "over"))
#+END_SRC #+END_SRC
** Property matching
#+BEGIN_SRC elisp
(org-agenda-ng "~/src/emacs/org-super-agenda/test/test.org"
(property "agenda-group"))
(org-agenda-ng "~/src/emacs/org-super-agenda/test/test.org"
(property "agenda-group" "plans"))
#+END_SRC
** Screenshot code ** Screenshot code
#+BEGIN_SRC elisp #+BEGIN_SRC elisp

View file

@ -128,6 +128,7 @@ NONE-PREDS."
(todo #'org-agenda-ng--todo-p) (todo #'org-agenda-ng--todo-p)
(done #'org-agenda-ng--done-p) (done #'org-agenda-ng--done-p)
(tags #'org-agenda-ng--tags-p) (tags #'org-agenda-ng--tags-p)
(property #'org-ql--property-p)
(regexp #'org-ql--regexp-p) (regexp #'org-ql--regexp-p)
(org-back-to-heading #'outline-back-to-heading)) (org-back-to-heading #'outline-back-to-heading))
(org-with-wide-buffer (org-with-wide-buffer
@ -474,3 +475,15 @@ comparator, PRIORITY should be a priority string."
(save-excursion (save-excursion
(goto-char (line-beginning-position)) (goto-char (line-beginning-position))
(re-search-forward regexp end t)))) (re-search-forward regexp end t))))
(defun org-ql--property-p (property &optional value)
"Return non-nil if current entry has PROPERTY, and optionally VALUE."
(pcase property
('nil (user-error "Property matcher requires a PROPERTY argument."))
(_ (pcase value
('nil
;; Check that PROPERTY exists
(org-entry-get (point) property))
(_
;; Check that PROPERTY has VALUE
(string-equal value (org-entry-get (point) property 'selective)))))))