#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