reddit / emacs

mu4e-query: S-expression query builder for mu4e

mickeyp 路 2022-11-18 12:35
mickeyp 路 2022-11-18 12:38
I got fed up dealing with strings in mu4e as it's cumbersome to concat and format and quote and escape and... So I wrote this little thing. It takes s-exp forms and generates valid mu4e query strings. It works quite well for me, but I'm sure there are bugs. I'm keen on adding more helper forms to remove the tedium of writing complex queries. I'm thinking about something to help generate contextual maildir queries as that is a common thing to need. Love to hear what people think.
twleo 路 2022-11-18 19:56
Good stuff! I just wrote similar things by myself few weeks ago, which only support `and` and `or`. 馃槀 I use `:and`/`:or` instead of pure `and`/`or` though to have a similar syntax like `org-super-agenda` (and built-in highlight of emacs synteax)
nv-elisp 路 2022-11-18 20:56
It would be nice if there was a minor mode which allowed one to use this in mu4e's search prompt directly.
[deleted] 路 2022-11-18 21:48
[deleted]
github-alphapapa 路 2022-11-18 21:50
Cool, reminds me of something similar I did in org-ql using the `peg` library: https://github.com/alphapapa/org-ql/blob/master/org-ql.el#L909 > I'm keen on adding more helper forms to remove the tedium of writing complex queries. I'm thinking about something to help generate contextual maildir queries as that is a common thing to need. You might want to look at how I implemented the `org-ql-defpred` macro. It integrates with the PEG-based sexp query parsing, automatically adding to the DSL that the parser uses. See also: https://github.com/alphapapa/org-ql/blob/master/examples/defpred.org
mickeyp 路 2022-11-19 08:17
Shouldn't be hard to write
Aminumbra 路 2022-11-19 13:07
I wrote this a few months ago: ``` (defun lps/--mu4e-read-date (&optional prompt) (let ((time (decode-time (org-read-date nil t)))) (format "%04d%02d%02d" (decoded-time-year time) (decoded-time-month time) (decoded-time-day time)))) (defun lps/--mu4e-read-date-range (&optional prompt) (concat (lps/--mu4e-read-date "Mail ranging from ...") ".." (lps/--mu4e-read-date "... to ..."))) (defun lps/--mu4e-read-mime-type (&optional prompt) (require 'mailcap) (mailcap-parse-mimetypes) (completing-read (or prompt "Mime type: ") (mailcap-mime-types))) (defvar lps/--mu4e-build-query-alist '((?q "quit" "quit") (?\ "" "" read-string) (?f "from" "from:" read-string) (?t "to" "to:" read-string) (?d "date" "date:" ((?d "date" "" lps/--mu4e-read-date) (?r "range" "" lps/--mu4e-read-date-range))) (?F "Flag" "flag:" ((?u "unread" "unread") (?d "draft" "draft") (?f "flagged" "flagged") (?n "new" "new") (?p "passed" "passed") (?r "replied" "replied") (?s "seen" "seen") (?t "trashed" "trashed") (?a "attach" "attach") (?e "encrypted" "encrypted") (?S "Signed" "signed"))) (?s "subject" "subject:" read-string) (?m "mime" "mime:" lps/--mu4e-read-mime-type))) (defun lps/--mu4e-parse-query (choices) (let* ((choice (read-multiple-choice "Test: " choices)) (rest (cddr choice)) (str (car rest)) (read-fun-or-continue (cadr rest))) (cond ((char-equal (car choice) ?q) :quit) ((functionp read-fun-or-continue) (concat str (funcall read-fun-or-continue (concat str " ")))) ((consp read-fun-or-continue) (concat str (lps/--mu4e-parse-query read-fun-or-continue))) (t str)))) (defun lps/mu4e-build-query (&optional start-query) "Provides a simpler interface to build mu4e search queries. A caveat is that it does not insert logical separators (NOT, AND, OR ...) between expressions, so the expression has to be modified by hand if needed" (interactive "P") (let ((choices lps/--mu4e-build-query-alist) (query-list (if start-query (list (completing-read "Search for: " mu4e--search-hist nil nil nil 'mu4e--search-hist)) nil)) (choice nil)) (while (not (eq (setq choice (lps/--mu4e-parse-query choices)) :quit)) (push choice query-list)) (let ((query (mapconcat 'identity (reverse query-list) " "))) (mu4e-search query "Search for: " t))))) ``` It is very limited and requires `org-read-date` to work, but it can be the start of something a bit better if you really want. Main reason I wrote this was because I had trouble remebering the correct date format for queries, but it was not hard to add the other filters.
mickeyp 路 2022-11-19 17:35
Huh. I didn't know about `peg` or even `org-ql`! Both look neat. I will have to play around with them.
github-alphapapa 路 2022-11-20 15:26
Cool. Please let me know if you have any feedback.