Re: [PATCH v2] emacs: add notmuch-expr, sexp-style queries
Tom Fitzhenry writes: > +(require 'ert) > +(require 'notmuch-expr) Any ideas (from anyone) how we can run these tests in the notmuch test suite? I guess some kind of shim might be needed, but perhaps it can just be wrapped in one or more test_emacs calls. > + > +(defmacro notmuch-expr (query) > + "Compile an sexp QUERY into a textual notmuch query." > + `(notmuch-expr--eval ,query)) Does this need to be a macro? If so I'd appreciate a brief comment as to why. At this point optimizing performace seems pretty premature, but maybe there are other good reasons. > index 165aaa43..8c5843e5 100644 > --- a/emacs/notmuch.el > +++ b/emacs/notmuch.el > @@ -79,6 +79,7 @@ > (require 'notmuch-maildir-fcc) > (require 'notmuch-message) > (require 'notmuch-parser) > +(require 'notmuch-expr) > I know we have just been requiring things historically, but I really wonder if it's the right thing to do, especially since it seems the library is not (yet) used for anything. Perhaps an autoload cookie on the appropriate functions would be best. By the way, I'd eventually like the CLI to parse S-expr queries (and/or perhaps JSON queries) to avoid passing via strings (and all the problems that entails). I'm not sure when I'll get around to it. There are also some design details to be worked out, but hopefully it would bne a mostly-compatible syntax with what is provided here. ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
Re: [PATCH v2] emacs: add notmuch-expr, sexp-style queries
Tom Fitzhenry writes: > From: Tom Fitzhenry > > notmuch-expr allows you to write notmuch search queries in sexp style like: > > (notmuch-expr > '(and > (to "emacs-devel") > "info manual" > (or > (not (is "spam")) > (is "important" > > which will generate the textual query: > > "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" > --- > emacs/Makefile.local | 1 + > emacs/notmuch-expr-test.el | 96 > emacs/notmuch-expr.el | 124 + > emacs/notmuch.el | 1 + > 4 files changed, 222 insertions(+) > create mode 100644 emacs/notmuch-expr-test.el > create mode 100644 emacs/notmuch-expr.el > > diff --git a/emacs/Makefile.local b/emacs/Makefile.local > index d1b320c3..f68e6e31 100644 > --- a/emacs/Makefile.local > +++ b/emacs/Makefile.local > @@ -22,6 +22,7 @@ emacs_sources := \ > $(dir)/notmuch-version.el \ > $(dir)/notmuch-jump.el \ > $(dir)/notmuch-company.el \ > + $(dir)/notmuch-expr.el \ > $(dir)/notmuch-draft.el > > elpa_sources := ${emacs_sources} $(dir)/notmuch-pkg.el > diff --git a/emacs/notmuch-expr-test.el b/emacs/notmuch-expr-test.el > new file mode 100644 > index ..92029fec > --- /dev/null > +++ b/emacs/notmuch-expr-test.el > @@ -0,0 +1,96 @@ > +(require 'ert) > +(require 'notmuch-expr) > + > +(ert-deftest and () > + (should > +(equal > + "(\"valued\" AND is:unread AND from:s...@example.com)" > + (notmuch-expr > + '(and > + "valued" > + (is "unread") > + (from "s...@example.com")) > + > +(ert-deftest body () > + (should > + (equal > +"(body:wallace AND from:gromit)" > +(notmuch-expr > + '(and > + (body "wallace") > + (from "gromit")) > + > +(ert-deftest regex () > + (should > + (equal > +"(subject:\"/Ca+sh/\" AND NOT is:important)" > +(notmuch-expr > + '(and > + (subject "/Ca+sh/") > + (not (is "important"))) > + > +(ert-deftest precedence () > + (should > + (equal > +"(to:emacs-devel AND (NOT is:spam OR is:important))" > +(notmuch-expr > + '(and > + (to "emacs-devel") > + (or > + (not (is "spam")) > + (is "important"))) > + > +(ert-deftest xor () > + (should > + (equal > +"is:inbox XOR is:sent" > +(notmuch-expr > + '(xor > + (is "inbox") > + (is "sent")) > + > +(ert-deftest literal () > + (should > + (equal > +"(is:inbox OR from:foo)" > +(notmuch-expr > + '(or > + (is "inbox") > + (literal "from:foo")) > + > +(ert-deftest string () > + (should > + (equal > +"(is:inbox OR \"from:foo\")" > +(notmuch-expr > + '(or > + (is "inbox") > + "from:foo") > + > +(ert-deftest tag-with-spaces () > + (should > + (equal > +"is:\"a tag\"" > +(notmuch-expr > + '(tag "a tag") > + > +(ert-deftest quoted-spaces () > + (should > + (equal > +"subject:\"Hello there\"" > +(notmuch-expr > + '(subject "Hello there") > + > +(ert-deftest quoted-backslash () > + (should > + (equal > +"subject:\"A celebration! \\o/ Woo.\"" > +(notmuch-expr > + '(subject "A celebration! \\o/ Woo.") > + > +(ert-deftest quoted-quote () > + (should > + (equal > +"subject:\"Gandalf: \\\"Use the force!\\\" 2001\"" > +(notmuch-expr > + '(subject "Gandalf: \"Use the force!\" 2001") > diff --git a/emacs/notmuch-expr.el b/emacs/notmuch-expr.el > new file mode 100644 > index ..f5a3429f > --- /dev/null > +++ b/emacs/notmuch-expr.el > @@ -0,0 +1,124 @@ > +;;; notmuch-expr.el --- An S-exp library for building notmuch search queries > -*- lexical-binding: t; -*- > + > +;; Author: Tom Fitzhenry > +;; Package-Requires: ((emacs "24.1")) > +;; URL: https://notmuchmail.org I recently improved consistency of the library headers. They don't confirm to the Emacs conventions but its close enough, and I think internal consistency would be nice to maintain here. Don't specify "URL". "Homepage" would be better, but since this is not an entry point library its better to omit this. I think "notmuch.el" is the only library that specifies this currently. Likewise because "notmuch-expr" is not a standalone _package_ "Package-Requires" should not be specified. By the way, notmuch now requires emacs 25.1, so specifying a lower version would not make sense here anyway. Cheers, Jonas > + > +;;; Commentary: > + > +;; This package provides a way to build notmuch search queries via > s-expressions. > +;; > +;; For example, rather than write: > + > +;; "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" > +;; > +;; this package allows you to generate the same query via s-expressions: > +;; > +;; (notmuch-expr > +;; '(and > +;;(to "emacs-devel") > +;;"info manual" > +;;(or > +;; (not (is "spam")) > +;; (is "impor
Re: [PATCH v2] emacs: add notmuch-expr, sexp-style queries
On Friday, 2020-11-13 at 23:01:22 +11, Tom Fitzhenry wrote: > From: Tom Fitzhenry > > notmuch-expr allows you to write notmuch search queries in sexp style like: > > (notmuch-expr > '(and > (to "emacs-devel") > "info manual" > (or > (not (is "spam")) > (is "important" > > which will generate the textual query: > > "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" Reviewed-by: David Edmondson > --- > emacs/Makefile.local | 1 + > emacs/notmuch-expr-test.el | 96 > emacs/notmuch-expr.el | 124 + > emacs/notmuch.el | 1 + > 4 files changed, 222 insertions(+) > create mode 100644 emacs/notmuch-expr-test.el > create mode 100644 emacs/notmuch-expr.el > > diff --git a/emacs/Makefile.local b/emacs/Makefile.local > index d1b320c3..f68e6e31 100644 > --- a/emacs/Makefile.local > +++ b/emacs/Makefile.local > @@ -22,6 +22,7 @@ emacs_sources := \ > $(dir)/notmuch-version.el \ > $(dir)/notmuch-jump.el \ > $(dir)/notmuch-company.el \ > + $(dir)/notmuch-expr.el \ > $(dir)/notmuch-draft.el > > elpa_sources := ${emacs_sources} $(dir)/notmuch-pkg.el > diff --git a/emacs/notmuch-expr-test.el b/emacs/notmuch-expr-test.el > new file mode 100644 > index ..92029fec > --- /dev/null > +++ b/emacs/notmuch-expr-test.el > @@ -0,0 +1,96 @@ > +(require 'ert) > +(require 'notmuch-expr) > + > +(ert-deftest and () > + (should > +(equal > + "(\"valued\" AND is:unread AND from:s...@example.com)" > + (notmuch-expr > + '(and > + "valued" > + (is "unread") > + (from "s...@example.com")) > + > +(ert-deftest body () > + (should > + (equal > +"(body:wallace AND from:gromit)" > +(notmuch-expr > + '(and > + (body "wallace") > + (from "gromit")) > + > +(ert-deftest regex () > + (should > + (equal > +"(subject:\"/Ca+sh/\" AND NOT is:important)" > +(notmuch-expr > + '(and > + (subject "/Ca+sh/") > + (not (is "important"))) > + > +(ert-deftest precedence () > + (should > + (equal > +"(to:emacs-devel AND (NOT is:spam OR is:important))" > +(notmuch-expr > + '(and > + (to "emacs-devel") > + (or > + (not (is "spam")) > + (is "important"))) > + > +(ert-deftest xor () > + (should > + (equal > +"is:inbox XOR is:sent" > +(notmuch-expr > + '(xor > + (is "inbox") > + (is "sent")) > + > +(ert-deftest literal () > + (should > + (equal > +"(is:inbox OR from:foo)" > +(notmuch-expr > + '(or > + (is "inbox") > + (literal "from:foo")) > + > +(ert-deftest string () > + (should > + (equal > +"(is:inbox OR \"from:foo\")" > +(notmuch-expr > + '(or > + (is "inbox") > + "from:foo") > + > +(ert-deftest tag-with-spaces () > + (should > + (equal > +"is:\"a tag\"" > +(notmuch-expr > + '(tag "a tag") > + > +(ert-deftest quoted-spaces () > + (should > + (equal > +"subject:\"Hello there\"" > +(notmuch-expr > + '(subject "Hello there") > + > +(ert-deftest quoted-backslash () > + (should > + (equal > +"subject:\"A celebration! \\o/ Woo.\"" > +(notmuch-expr > + '(subject "A celebration! \\o/ Woo.") > + > +(ert-deftest quoted-quote () > + (should > + (equal > +"subject:\"Gandalf: \\\"Use the force!\\\" 2001\"" > +(notmuch-expr > + '(subject "Gandalf: \"Use the force!\" 2001") > diff --git a/emacs/notmuch-expr.el b/emacs/notmuch-expr.el > new file mode 100644 > index ..f5a3429f > --- /dev/null > +++ b/emacs/notmuch-expr.el > @@ -0,0 +1,124 @@ > +;;; notmuch-expr.el --- An S-exp library for building notmuch search queries > -*- lexical-binding: t; -*- > + > +;; Author: Tom Fitzhenry > +;; Package-Requires: ((emacs "24.1")) > +;; URL: https://notmuchmail.org > + > +;;; Commentary: > + > +;; This package provides a way to build notmuch search queries via > s-expressions. > +;; > +;; For example, rather than write: > + > +;; "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" > +;; > +;; this package allows you to generate the same query via s-expressions: > +;; > +;; (notmuch-expr > +;; '(and > +;;(to "emacs-devel") > +;;"info manual" > +;;(or > +;; (not (is "spam")) > +;; (is "important" > +;; > +;; See notmuch-expr-test.el for more examples. > +;; > +;; Some search terms are unsupported. To use those, use the `literal' atom. > +;; For example: (literal "path:spam") > +;; > +;; man page: notmuch-search-terms(7). > +;; The generated search query may change across different versions. > + > +;;; Code: > + > +(defmacro notmuch-expr (query) > + "Compile an sexp QUERY into a textual notmuch query." > + `(notmuch-expr--eval ,query)) > + > +(defun notmuch-expr--eval (expr) > + (pcase expr > +(`(tag ,s) (notmuch-expr--is s
[PATCH v2] emacs: add notmuch-expr, sexp-style queries
From: Tom Fitzhenry notmuch-expr allows you to write notmuch search queries in sexp style like: (notmuch-expr '(and (to "emacs-devel") "info manual" (or (not (is "spam")) (is "important" which will generate the textual query: "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" --- emacs/Makefile.local | 1 + emacs/notmuch-expr-test.el | 96 emacs/notmuch-expr.el | 124 + emacs/notmuch.el | 1 + 4 files changed, 222 insertions(+) create mode 100644 emacs/notmuch-expr-test.el create mode 100644 emacs/notmuch-expr.el diff --git a/emacs/Makefile.local b/emacs/Makefile.local index d1b320c3..f68e6e31 100644 --- a/emacs/Makefile.local +++ b/emacs/Makefile.local @@ -22,6 +22,7 @@ emacs_sources := \ $(dir)/notmuch-version.el \ $(dir)/notmuch-jump.el \ $(dir)/notmuch-company.el \ + $(dir)/notmuch-expr.el \ $(dir)/notmuch-draft.el elpa_sources := ${emacs_sources} $(dir)/notmuch-pkg.el diff --git a/emacs/notmuch-expr-test.el b/emacs/notmuch-expr-test.el new file mode 100644 index ..92029fec --- /dev/null +++ b/emacs/notmuch-expr-test.el @@ -0,0 +1,96 @@ +(require 'ert) +(require 'notmuch-expr) + +(ert-deftest and () + (should +(equal + "(\"valued\" AND is:unread AND from:s...@example.com)" + (notmuch-expr + '(and + "valued" + (is "unread") + (from "s...@example.com")) + +(ert-deftest body () + (should + (equal +"(body:wallace AND from:gromit)" +(notmuch-expr + '(and + (body "wallace") + (from "gromit")) + +(ert-deftest regex () + (should + (equal +"(subject:\"/Ca+sh/\" AND NOT is:important)" +(notmuch-expr + '(and + (subject "/Ca+sh/") + (not (is "important"))) + +(ert-deftest precedence () + (should + (equal +"(to:emacs-devel AND (NOT is:spam OR is:important))" +(notmuch-expr + '(and + (to "emacs-devel") + (or + (not (is "spam")) + (is "important"))) + +(ert-deftest xor () + (should + (equal +"is:inbox XOR is:sent" +(notmuch-expr + '(xor + (is "inbox") + (is "sent")) + +(ert-deftest literal () + (should + (equal +"(is:inbox OR from:foo)" +(notmuch-expr + '(or + (is "inbox") + (literal "from:foo")) + +(ert-deftest string () + (should + (equal +"(is:inbox OR \"from:foo\")" +(notmuch-expr + '(or + (is "inbox") + "from:foo") + +(ert-deftest tag-with-spaces () + (should + (equal +"is:\"a tag\"" +(notmuch-expr + '(tag "a tag") + +(ert-deftest quoted-spaces () + (should + (equal +"subject:\"Hello there\"" +(notmuch-expr + '(subject "Hello there") + +(ert-deftest quoted-backslash () + (should + (equal +"subject:\"A celebration! \\o/ Woo.\"" +(notmuch-expr + '(subject "A celebration! \\o/ Woo.") + +(ert-deftest quoted-quote () + (should + (equal +"subject:\"Gandalf: \\\"Use the force!\\\" 2001\"" +(notmuch-expr + '(subject "Gandalf: \"Use the force!\" 2001") diff --git a/emacs/notmuch-expr.el b/emacs/notmuch-expr.el new file mode 100644 index ..f5a3429f --- /dev/null +++ b/emacs/notmuch-expr.el @@ -0,0 +1,124 @@ +;;; notmuch-expr.el --- An S-exp library for building notmuch search queries -*- lexical-binding: t; -*- + +;; Author: Tom Fitzhenry +;; Package-Requires: ((emacs "24.1")) +;; URL: https://notmuchmail.org + +;;; Commentary: + +;; This package provides a way to build notmuch search queries via s-expressions. +;; +;; For example, rather than write: + +;; "to:emacs-devel AND (NOT is:spam OR is:important) AND \"info manual\"" +;; +;; this package allows you to generate the same query via s-expressions: +;; +;; (notmuch-expr +;; '(and +;;(to "emacs-devel") +;;"info manual" +;;(or +;; (not (is "spam")) +;; (is "important" +;; +;; See notmuch-expr-test.el for more examples. +;; +;; Some search terms are unsupported. To use those, use the `literal' atom. +;; For example: (literal "path:spam") +;; +;; man page: notmuch-search-terms(7). +;; The generated search query may change across different versions. + +;;; Code: + +(defmacro notmuch-expr (query) + "Compile an sexp QUERY into a textual notmuch query." + `(notmuch-expr--eval ,query)) + +(defun notmuch-expr--eval (expr) + (pcase expr +(`(tag ,s) (notmuch-expr--is s)) +(`(is ,s) (notmuch-expr--is s)) +(`(from ,s)(notmuch-expr--from s)) +(`(to ,s) (notmuch-expr--to s)) +(`(body ,s)(notmuch-expr--body s)) +(`(subject ,s) (notmuch-expr--subject s)) + +;; Boolean operators. +(`(and . ,clauses) (notmuch-expr--and clauses)) +(`(or . ,clauses) (notmuch-expr--or clauses)) +(`(not ,clause)(notmuch-expr--not clause)) +(`(xor ,c1 ,c2)(notmuch-expr--xor c