#3144: Parent and child match pattern modifier
--------------------------+----------------------
Reporter: jlh | Owner: mutt-dev
Type: enhancement | Status: new
Priority: minor | Milestone:
Component: mutt | Version:
Resolution: | Keywords:
--------------------------+----------------------
Comment (by kevin8t8):
Sorry but I am not willing to apply this in its current form.
The behavior of "not" (!) is unclear and even contradictory in the patch.
Should it apply to the pattern or to the parent/child operator? Should
there be a difference between
{{{
!>~f foo.com
!>(~f foo.com)
!(>~f foo.com)
>!~f foo.com
>(!~f foo.com)
}}}
Right now it looks like it's always applied to the pattern.
Related is the behavior when a message doesn't have a parent or child. It
looks like the code is trying to use the "pattern not" to make this
decision, but I'm not convinced that's always appropriate.
In the childsmatch logic in mutt_pattern_exec():
{{{
+ for (; t; t = t->next) {
+ if (!t->message)
+ continue;
+ if (pattern_exec (pat, flags, ctx, t->message, cache))
+ return !pat->not;
+ }
+ return pat->not;
}}}
The not is already evaluated in pattern_exec() but then it's returning
!pat->not. If the pattern were ">!~f bar", this will return false if one
of the children is not from bar (i.e. matches the pattern). After the
loop it's returning pat->not. With the same pattern ">!~f bar", it will
return true if _all_ of the children messages were from bar (i.e. none of
the children match the pattern).
The problem is the conflation of trying to apply "not" to the operator
logic and the pattern at the same time.
Other notes:
* Does it make sense for a parent/child operator to be applied to ~()
operator? Right now the code is, but this seems a bad idea.
* At an implementation level, I'm not happy with how the patch is
structured. It's not aligned with the rest of the pattern code. Creating
a new outer mutt_pattern_exec() that just deals with this pseudo-operator
is ugly.
* Vincent: an important correction to your version of the patch. Note
that the pattern_cache_t applies to a single header: it doesn't deal with
threads. So inside the mutt_pattern_exec(), the first two calls to
pattern_exec() should pass NULL for the cache because they are looking at
parent/children. Only the third call should actually pass the cache
through.
--
Ticket URL: <https://dev.mutt.org/trac/ticket/3144#comment:11>
Mutt <http://www.mutt.org/>
The Mutt mail user agent