Subject: bug#73581: 29.4; Gnus: Error doing a search on nnmaildir with gnus-search-find-grep

From: Visuwesh <[email-masked]>
Date: Sat, 12 Apr 2025 17:37:19 +0530

[சனி ஏப்ரல் 12, 2025] Daniel Cerqueira wrote:

>>> The patch did not work.  I haven't recorded the message error, but it
>>> was something to do with the something-generate-artlist having the wrong
>>> number of arguments.
>>>
>>> You don't need to fix it, if you don't want to, have too much work, or
>>> don't have time.
>>
>> I can give a shot at debugging, when I have time, if you provide the
>> backtrace.  Getting the find-grep backend to work was a goal for me, you
>> gave me a good excuse to procrastinate from working on my thesis.  ;-)
>
> Ahaha!  Now it is giving no error.  But it is also not resulting a
> result (from a search query that I know it has matches).
>
> The message that I get is:
>
> Group nnselect:nnselect-87tt6taade.fsf contains no messages
>
> I also have changed this variable:
>
> (set 'gnus-search-default-engines
>       '((nnimap . gnus-search-imap)
>         (nnmaildir . gnus-search-find-grep)
>         (nnselect . gnus-search-nnselect)
>         ;; (nnselect . gnus-search-find-grep)
>         ))
>
> Maybe this variable is incorrect?  What I want is for the nnmaildir
> back-end to use find-grep.

I modify that exact variable to make nnmaildir use
gnus-search-find-grep.  I forgot to pass the mandatory argument to
forward-whitespace.  Please try the patch below instead,

diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index 41915a0e3c0..d6450bbbaff 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -2110,20 +2140,31 @@ gnus-search-prepare-query
 	val)
     (when (stringp query)
       ;; Look for these meta keys:
-      (while (string-match
-	      "\\(thread\\|grep\\|limit\\|raw\\):\\([^ ]+\\)"
-	      query)
-	(setq val (match-string 2 query))
-	(setf (alist-get (intern (match-string 1 query)) query-spec)
-	      ;; This is stupid.
-	      (cond
-	       ((equal val "t"))
-	       ((null (zerop (string-to-number val)))
-		(string-to-number val))
-	       (t val)))
-	(setq query
-	      (string-trim (replace-match "" t t query 0)))
-	(setf (alist-get 'query query-spec) query)))
+      (with-temp-buffer
+        (insert query)
+        (goto-char (point-min))
+        (while (re-search-forward "\\(thread\\|grep\\|limit\\|raw\\):" nil t)
+          (setq val (cons
+                     (match-string 1)
+                     (buffer-substring (point)
+                                       (if (eq (char-after) ?\")
+                                           (progn (forward-sexp) (point))
+                                         (progn (forward-whitespace 1)
+                                                (if (eobp)
+                                                    (point)
+                                                  (1- (point))))))))
+          (setf (alist-get (intern (car val)) query-spec)
+                ;; This is stupid.
+                (cond
+	         ((equal (cdr val) "t"))
+	         ((null (zerop (string-to-number (cdr val))))
+		  (string-to-number (cdr val)))
+	         (t (string-trim (cdr val) "\"" "\""))))
+          (setq query (string-trim (string-replace
+                                    (concat (car val) ":" (cdr val))
+                                    ""
+                                    query)))
+          (setf (alist-get 'query query-spec) query))))
     (when (and gnus-search-use-parsed-queries
 	       (null (alist-get 'raw query-spec)))
       (setf (alist-get 'parsed-query query-spec)

>>> Okay.  Regarding subject, I understand grep not doing it; but regarding
>>> time, something can be done with find (it is find-grep after all).  No
>>> need or no pressure in doing it, though.
>>
>> I don't think we can exploit the various time statistics attached with a
>> file to achieve what you want.  A message from 2019 reports:
>>
>>     % stat ~/mail/XXX/inbox/cur/1641645812.328064_1.astatine,U=1:2,S
>>       File: ~/mail/XXX/inbox/cur/1641645812.328064_1.astatine,U=1:2,S
>>       Size: 8420      	Blocks: 24         IO Block: 4096   regular file
>>     Device: 8,4	Inode: 5774494     Links: 1
>>     Access: (0600/-rw-------)  Uid: ( 1000/     viz)   Gid: ( 1000/     viz)
>>     Access: 2025-04-12 13:46:05.575388637 +0530
>>     Modify: 2022-01-08 18:13:32.297967005 +0530
>>     Change: 2022-06-05 07:44:16.919565297 +0530
>>      Birth: 2022-01-08 18:13:32.297967005 +0530
>>    % grep ^Date: ~/mail/XXX/inbox/cur/1641645812.328064_1.astatine,U=1:2,S
>>    Date: Mon, 21 Jan 2019 02:14:48 -0800
>
> What I was thinking is using the arguments of the executable find, such
> as atime, ctime, mtime (which one fits best?), when using a query for
> time, such as since:3d (I believe the keyword for other queries is
> "since:", but I am not sure of this).

The problem is mtime, ctime and atime are clearly not reliable as shown
in the example above.  So we cannot rely on them to indirectly query the
Date header.