Add: Negation in plain queries

This commit is contained in:
Adam Porter 2019-10-09 19:05:11 -05:00
parent 6b2004e678
commit 949a06c3ab
4 changed files with 43 additions and 21 deletions

View file

@ -164,6 +164,7 @@ The command =org-ql-search= also accepts, and the command =helm-org-ql= only acc
| ~(heading "quoted phrase" "word")~ | ~heading:"quoted phrase",word~ |
| ~(and (tags "book" "books") (priority "A"))~ | ~tags:book,books priority:A~ |
| ~(src :lang "elisp" :regexps ("defun"))~ | ~src:defun,lang=elisp~ or ~src:lang=elisp,defun~ |
| ~(and (tags "space") (not (regexp "moon")))~ | ~tags:space !moon~ |
| ~(priority >= B)~ | ~priority:A,B~ |
Note that the =priority= predicate does not support comparators in the non-sexp syntax, so multiple priorities should be passed instead, as seen in the last example.
@ -375,6 +376,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience
** 0.4-pre
*Added*
+ Negation of terms in plain queries using ~!~. For example, ~tags:space !moon~ to exclude entries which contain ~moon~.
+ Predicates =outline-path= (alias =olp=) and =outline-path-segment= (alias =olps=).
+ Info manual.
+ Command ~org-ql-search~ can search files in ~org-directory~; customization options are available in the ~org-ql-search~ group.

View file

@ -1487,10 +1487,15 @@ Builds the PEG expression using predicates defined in
Multiple predicates are combined with BOOLEAN."
(unless (s-blank-str? input)
(let* ((query (peg-parse-string
((query (+ (or (and predicate-with-args `(pred args -- (cons (intern pred) args)))
(and predicate-without-args `(pred -- (list (intern pred))))
(and plain-string `(s -- (list 'regexp s))))
((query (+ term
(opt (+ (syntax-class whitespace) (any)))))
(term (or (and negation (list positive-term)
;; This is a bit confusing, but it seems to work. There's probably a better way.
`(pred -- (list 'not (car pred))))
positive-term))
(positive-term (or (and predicate-with-args `(pred args -- (cons (intern pred) args)))
(and predicate-without-args `(pred -- (list (intern pred))))
(and plain-string `(s -- (list 'regexp s)))))
(plain-string (substring (+ (not (syntax-class whitespace)) (any))))
(predicate-with-args (substring predicate) ":" args)
(predicate-without-args (substring predicate) ":")
@ -1500,6 +1505,7 @@ Multiple predicates are combined with BOOLEAN."
(keyword (substring (+ (not (or separator "=" "\"" (syntax-class whitespace))) (any))))
(quoted-arg "\"" (substring (+ (not (or separator "\"")) (any))) "\"")
(unquoted-arg (substring (+ (not (or separator "\"" (syntax-class whitespace))) (any))))
(negation "!")
(separator "," ))
input 'noerror)))
;; Discard the t that `peg-parse-string' always returns as the first

View file

@ -339,6 +339,7 @@ Sexp syntax Non-sexp syntax
(heading "quoted phrase" "word") heading:"quoted phrase",word
(and (tags "book" "books") (priority "A")) tags:book,books priority:A
(src :lang "elisp" :regexps ("defun")) src:defun,lang=elisp or src:lang=elisp,defun
(and (tags "space") (not (regexp "moon"))) tags:space !moon
(priority >= B) priority:A,B
Note that the priority predicate does not support comparators in the
@ -695,6 +696,8 @@ File: README.info, Node: 04-pre, Next: 031, Up: Changelog
===========
*Added*
• Negation of terms in plain queries using !. For example,
tags:space !moon to exclude entries which contain moon.
• Predicates outline-path (alias olp) and outline-path-segment (alias
olps).
• Info manual.
@ -980,24 +983,24 @@ Node: org-ql-view-recent-items6452
Node: org-ql-sparse-tree6936
Node: Queries7736
Node: Non-sexp query syntax8578
Node: Predicates10198
Node: Date/time predicates15312
Node: Functions / Macros17947
Node: Agenda-like views18134
Node: Listing / acting-on results19539
Node: Changelog24141
Node: 04-pre24663
Node: 03125607
Node: 0325805
Node: 02328778
Node: 02229004
Node: 02129270
Node: 0229467
Node: 0133500
Node: Notes33599
Node: Comparison with Org Agenda searches33761
Node: org-sidebar34632
Node: License34911
Node: Predicates10277
Node: Date/time predicates15391
Node: Functions / Macros18026
Node: Agenda-like views18213
Node: Listing / acting-on results19618
Node: Changelog24220
Node: 04-pre24742
Node: 03125830
Node: 0326028
Node: 02329001
Node: 02229227
Node: 02129493
Node: 0229690
Node: 0133723
Node: Notes33822
Node: Comparison with Org Agenda searches33984
Node: org-sidebar34855
Node: License35134

End Tag Table

View file

@ -231,6 +231,17 @@ RESULTS should be a list of strings as returned by
;; TODO: Other predicates.
(it "Negated terms"
(expect (org-ql--plain-query "todo: !todo:CHECK,SOMEDAY")
:to-equal '(and (todo) (not (todo "CHECK" "SOMEDAY"))))
(expect (org-ql--plain-query "!todo:CHECK,SOMEDAY todo:")
:to-equal '(and (not (todo "CHECK" "SOMEDAY")) (todo)))
(expect (org-ql--plain-query "tags:universe !moon")
:to-equal '(and (tags "universe") (not (regexp "moon"))))
(expect (org-ql--plain-query "!moon tags:universe")
:to-equal '(and (not (regexp "moon")) (tags "universe")))
(expect (org-ql--plain-query "mars !ts:on=today")
:to-equal '(and (regexp "mars") (not (ts :on "today")))))
(it "Regexp predicates"
(expect (org-ql--plain-query "scheduled")
;; No colon after keyword, so not a predicate query.