style: add back support for valid header patterns

Since commit 65dc87db62 ("style: allow specifying multiple headers on
dynamic styles") the regex for picking up dynamic header patterns would
split on occurences of '.', thus preventing regexes like shown in the
test case to be used for matching messages.

Introduce `~/<pattern>/` as a way to wrap such expressions.

Fixes: 65dc87db62 ("style: allow specifying multiple headers on dynamic styles")
Signed-off-by: Robert Günzler <r@gnzler.io>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Robert Günzler
2025-01-08 08:49:14 +01:00
committed by Robin Jarry
parent c6e5627fa1
commit d7954c2ba6
3 changed files with 21 additions and 4 deletions
+6 -3
View File
@@ -506,7 +506,7 @@ func (ss *StyleSet) ParseStyleSet(file *ini.File) error {
var (
styleObjRe = regexp.MustCompile(`^([\w\*\?]+)(\.(?:[\w-]+,.+?)+?)?(\.selected)?\.(\w+)$`)
styleHeaderPatternsRe = regexp.MustCompile(`([\w-]+),(.+?)\.`)
styleHeaderPatternsRe = regexp.MustCompile(`([\w-]+),(~/(?:.+?)/|(?:.+?))\.`)
)
func (ss *StyleSet) parseKey(key *ini.Key, selected bool) error {
@@ -577,9 +577,12 @@ func (c *StyleConf) update(headerPatterns map[string]*StyleHeaderPattern, attr,
for _, p := range headerPatterns {
var pattern string
if strings.HasPrefix(p.RawPattern, "~") {
switch {
case strings.HasPrefix(p.RawPattern, "~/"):
pattern = p.RawPattern[2 : len(p.RawPattern)-1]
case strings.HasPrefix(p.RawPattern, "~"):
pattern = p.RawPattern[1:]
} else {
default:
pattern = "^" + regexp.QuoteMeta(p.RawPattern) + "$"
}
+12
View File
@@ -14,6 +14,7 @@ msglist_*.From,~^"Bob Foo".selected.fg = palegreen
msglist_*.Subject,~PATCH.From,~^"Bob Foo".fg = coral
msglist_*.From,~^"Bob Foo".Subject,~PATCH.X-Baz,exact.X-Clacks-Overhead,~Pratchett$.fg = plum
msglist_*.From,~^"Bob Foo".Subject,~PATCH.X-Clacks-Overhead,~Pratchett$.fg = pink
msglist_*.From,~^"Bob Foo".List-ID,~/lists\.sr\.ht/.fg = pink
`
func TestStyleMultiHeaderPattern(t *testing.T) {
@@ -86,4 +87,15 @@ func TestStyleMultiHeaderPattern(t *testing.T) {
t.Errorf("expected:#%x got:#%x", colorNames["pink"], s.Foreground)
}
})
t.Run("handles uris in regular expressions", func(t *testing.T) {
var h mail.Header
h.SetAddressList("From", []*mail.Address{{"Bob Foo", "Bob@foo.org"}})
h.SetText("List-ID", "List-ID: ~rjarry/aerc-discuss <~rjarry/aerc-discuss.lists.sr.ht>")
s := ss.Get(STYLE_MSGLIST_DEFAULT, &h)
if s.Foreground != colorNames["pink"] {
t.Errorf("expected:#%x got:#%x", colorNames["pink"], s.Foreground)
}
})
}
+3 -1
View File
@@ -313,7 +313,8 @@ syntax is as follows:
*msglist_<name>*._<header>_,_<header_value>_.*<attribute>* = _<attr_value>_
If _<header_value>_ starts with a tilde character _~_, it will be interpreted as
a regular expression.
a regular expression. If you are writing regular expressions that try to match
with _._ or _\._ you need to wrap like this _~/<expression>/_.
_<header>,<header_value>_ can be specified multiple times to narrow down matches
to more than one email header value. In that case, all given headers must match
@@ -328,6 +329,7 @@ msglist\*.X-Sourcehut-Patchset-Update,REJECTED.fg = red
"msglist_*.Subject,~^(\\[[\w-]+\]\\s*)?\\[(RFC )?PATCH.fg" = #ffffaf
"msglist_*.Subject,~^(\\[[\w-]+\]\\s*)?\\[(RFC )?PATCH.selected.fg" = #ffffaf
"msglist_*.From,~^Bob.Subject,~^(\\[[\w-]+\]\\s*)?\\[(RFC )?PATCH.selected.fg" = #ffffaf
"msglist_*.List-ID,~/lists\.sr\.ht/selected.fg" = blue
```
When a dynamic style is matched to an email header, it will be used in priority