Gnus development mailing list
 help / color / mirror / Atom feed
From: Kevin Greiner <kgreiner@xpediantsolutions.com>
Subject: Re: two agent nits
Date: Tue, 02 Dec 2003 00:01:42 -0600	[thread overview]
Message-ID: <uznebsqpl.fsf@xpediantsolutions.com> (raw)
In-Reply-To: <uzneca1jd.fsf@xpediantsolutions.com>

[-- Attachment #1: Type: text/plain, Size: 3961 bytes --]

Kevin Greiner <kgreiner@xpediantsolutions.com> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
>> Kevin Greiner <kgreiner@xpediantsolutions.com> writes:
>>
>>> Simon Josefsson <jas@extundo.com> writes:
>>>
>>>> Kevin Greiner <kgreiner@xpediantsolutions.com> writes:
>>>>
>>>>> Simon Josefsson <jas@extundo.com> writes:
>>>>>
>>>>>> * I can't seem to get the agent to fetch read articles.
>>>>>>   gnus-agent-consider-all-articles's value is t
>>>>>>   The default agent category predicate is 'true'.
>>>>>>   `J s' and `J u' just download unread or ticked articles.
>>>>>
>>>>> Have to tried setting gnus-agent-consider-all-articles to nil?  That
>>>>> seems to work for me.
>>>>
>>>> I tried, but still the same.  Pressing `J u' on groups just say it is
>>>> finished, but only the unread/ticked articles are in my local cache.
>>>>
>>>> Hm.  The manual and the docstring for the variable doesn't seem to be
>>>> in sync.  I thought the variable did what the docstring said, but the
>>>> manual just discuss missing headers.  Which one is correct?
>>>
>>> The variable gnus-agent-consider-all-articles appears in
>>> gnus-agent-fetch-headers but NOT gnus-agent-fetch-articles.  However,
>>> gnus-agent-fetch-group-1 calls gnus-agent-fetch-headers to get the
>>> list of new articles so gnus-agent-consider-all-articles may, by
>>> modifying the return value of gnus-agent-fetch-headers, effect the
>>> list of articles being fetched by gnus-agent-fetch-articles.
>>
>> Thanks for the pointers, I think I isolated the problem, from g-a-f-a:
>>
>>   (let* ((fetch-all (and gnus-agent-consider-all-articles
>>                          ;; Do not fetch all headers if the predicate
>>                          ;; implies that we only consider unread articles.
>>                          (not (gnus-predicate-implies-unread
>>                                (gnus-agent-find-parameter group
>>                                                           'agent-predicate)))))
>>
>> Fetch-all evaluate to nil for me, causing the function to only return
>> a list of unread articles.  Since g-a-c-a-a is t, the reason fetch-al
>> is nil is because of the second statement.
>>
>> (gnus-predicate-implies-unread 'true)
>>  => ignore
>>
>> (not (gnus-predicate-implies-unread 'true))
>>  => nil
>>
>> Reading the docstring:
>>
>> (gnus-predicate-implies-unread PREDICATE)
>>   Say whether PREDICATE implies unread articles only.
>>   It is okay to miss some cases, but there must be no false positives.
>>   That is, if this function returns true, then indeed the predicate must
>>   return only unread articles.
>>
>> The 'ignore return value is not documented, and because it is non-nil
>> it is treated as true by the caller in this case.
>>
>> If I apply this change, everything works, but I can't tell if it is
>> the right thing.
>
> Thanks for isolating the problem.  I'm also not certain that this is
> the right thing to do.  It is certainly the correct answer if the
> function is gnus-agent-true but what if the function is a compiled
> function returned by gnus-category-make-function?
>
>> --- gnus-agent.el.~6.180.~	2003-12-01 12:35:54.000000000 +0100
>> +++ gnus-agent.el	2003-12-01 17:39:06.000000000 +0100
>> @@ -2455,7 +2455,7 @@
>>          ((not function)
>>           nil)
>>          ((functionp function)
>> -         'ignore)
>> +	 nil)
>>          ((memq (car function) '(or and not))
>>           (apply (car function)
>>                  (mapcar 'gnus-function-implies-unread-1 (cdr function))))
>
>

Simon,

I finally realized what bothered me with this patch.  If you look
closely, the resulting code has a cond statement with four cases.  In
three cases, the result is simply nil.  In the fourth case, the
function recurses.  Taken together that means that the function simply
degenerates into nil.

So here's my version of the patch.  It is unfortunately a good deal
more complex.  I'd appreciate some feedback before I check it in.


[-- Attachment #2: Patch to fetch read articles. --]
[-- Type: text/plain, Size: 3597 bytes --]

--- lisp.cvs_ref/gnus-agent.el	Mon Dec  1 23:05:10 2003
+++ lisp/gnus-agent.el	Tue Dec  2 00:00:26 2003
@@ -2445,22 +2445,58 @@
 (defun gnus-predicate-implies-unread (predicate)
   "Say whether PREDICATE implies unread articles only.
 It is okay to miss some cases, but there must be no false positives.
-That is, if this function returns true, then indeed the predicate must
+That is, if this predicate returns true, then indeed the predicate must
 return only unread articles."
-  (gnus-function-implies-unread-1 (gnus-category-make-function predicate)))
+  (eq t (gnus-function-implies-unread-1 
+         (gnus-category-make-function-1 predicate))))
 
 (defun gnus-function-implies-unread-1 (function)
-  (cond ((eq function (symbol-function 'gnus-agent-read-p))
-         nil)
-        ((not function)
-         nil)
-        ((functionp function)
-         'ignore)
-        ((memq (car function) '(or and not))
-         (apply (car function)
-                (mapcar 'gnus-function-implies-unread-1 (cdr function))))
-        (t
-         (error "Unknown function: %s" function))))
+  "Recursively evaluate a predicate function to determine whether it can select
+any read articles.  Returns t if the function is known to never
+return read articles, nil when it is known to always return read
+articles, and t_nil when the function may return both read and unread
+articles."
+  (let ((func (car function))
+        (args (mapcar 'gnus-function-implies-unread-1 (cdr function))))
+    (cond ((eq func 'and)
+           (cond ((memq t args) ; if any argument returns only unread articles
+                  ;; then that argument constrains the result to only unread articles.
+                  t)
+                 ((memq 't_nil args) ; if any argument is indeterminate
+                  ;; then the result is indeterminate
+                  't_nil)))
+          ((eq func 'or)
+           (cond ((memq nil args) ; if any argument returns read articles
+                  ;; then that argument ensures that the results includes read articles.
+                  nil)
+                 ((memq 't_nil args) ; if any argument is indeterminate
+                  ;; then that argument ensures that the results are indeterminate
+                  't_nil)
+                 (t ; if all arguments return only unread articles
+                  ;; then the result returns only unread articles
+                  t)))
+          ((eq func 'not)
+           (cond ((eq (car args) 't_nil) ; if the argument is indeterminate
+                  ; then the result is indeterminate
+                  (car args))
+                 (t ; otherwise
+                  ; toggle the result to be the opposite of the argument
+                  (not (car args)))))
+          ((eq func 'gnus-agent-read-p)
+           nil) ; The read predicate NEVER returns unread articles
+          ((eq func 'gnus-agent-false)
+           t) ; The false predicate returns t as the empty set excludes all read articles
+          ((eq func 'gnus-agent-true)
+           nil) ; The true predicate ALWAYS returns read articles
+          ((catch 'found-match
+             (let ((alist gnus-category-predicate-alist))
+               (while alist
+                 (if (eq func (cdar alist))
+                     (throw 'found-match t)
+                   (setq alist (cdr alist))))))
+           't_nil) ; All other predicates return read and unread articles
+          (t
+           (error "Unknown predicate function: %s" function)))))
 
 (defun gnus-group-category (group)
   "Return the category GROUP belongs to."

[-- Attachment #3: Type: text/plain, Size: 7 bytes --]


Kevin

  parent reply	other threads:[~2003-12-02  6:01 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-30 16:53 Simon Josefsson
2003-11-30 19:53 ` Harry Putnam
2003-11-30 20:18   ` Simon Josefsson
2003-12-01  3:13     ` Harry Putnam
2003-12-01  4:47 ` Kevin Greiner
2003-12-01 11:39   ` Simon Josefsson
2003-12-01 15:56     ` Kevin Greiner
2003-12-01 16:46       ` Simon Josefsson
2003-12-01 17:30         ` Kevin Greiner
2003-12-01 19:45           ` Simon Josefsson
2003-12-01 20:35             ` Harry Putnam
2003-12-02  3:02               ` Wes Hardaker
2003-12-02  6:01           ` Kevin Greiner [this message]
2003-12-02 17:40             ` Simon Josefsson
2003-12-03 21:47             ` Harry Putnam
2003-12-03 22:14               ` Simon Josefsson
2003-12-04  1:50                 ` Harry Putnam
2003-12-04  2:29                   ` Simon Josefsson
2003-12-04  5:54                     ` Harry Putnam
2003-12-05  2:57                       ` Harry Putnam
2003-12-05  3:25                         ` Simon Josefsson
2003-12-05  3:54                           ` Harry Putnam
2003-12-05  4:13                             ` Simon Josefsson
2003-12-05 13:33                               ` Harry Putnam
2003-12-02 20:35     ` Simon Josefsson
2003-12-02 22:28       ` Kevin Greiner
2003-12-01 12:30   ` Harry Putnam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=uznebsqpl.fsf@xpediantsolutions.com \
    --to=kgreiner@xpediantsolutions.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).