diff options
-rw-r--r-- | commands/commands_test.go | 2 | ||||
-rw-r--r-- | config/templates.go | 2 | ||||
-rw-r--r-- | doc/aerc-templates.7.scd | 19 | ||||
-rw-r--r-- | lib/state/templates.go | 20 | ||||
-rw-r--r-- | lib/templates/functions.go | 30 | ||||
-rw-r--r-- | models/templates.go | 2 |
6 files changed, 75 insertions, 0 deletions
diff --git a/commands/commands_test.go b/commands/commands_test.go index e510ebe1..7c3ec84f 100644 --- a/commands/commands_test.go +++ b/commands/commands_test.go @@ -106,3 +106,5 @@ func (d *dummyData) PendingKeys() string { return "" } func (d *dummyData) Role() string { return "inbox" } func (d *dummyData) Style(string, string) string { return "" } func (d *dummyData) StyleSwitch(string, ...models.Case) string { return "" } + +func (d *dummyData) StyleMap([]string, ...models.Case) []string { return []string{} } diff --git a/config/templates.go b/config/templates.go index 40e7e450..97ba89b8 100644 --- a/config/templates.go +++ b/config/templates.go @@ -108,3 +108,5 @@ func (d *dummyData) Role() string { return "inbox" } func (d *dummyData) Style(string, string) string { return "" } func (d *dummyData) StyleSwitch(string, ...models.Case) string { return "" } + +func (d *dummyData) StyleMap([]string, ...models.Case) []string { return []string{} } diff --git a/doc/aerc-templates.7.scd b/doc/aerc-templates.7.scd index 6919e5dd..394e22b6 100644 --- a/doc/aerc-templates.7.scd +++ b/doc/aerc-templates.7.scd @@ -402,6 +402,16 @@ aerc provides the following additional functions: {{.StyleSwitch (.From | names | join ", ") (case `Tim` "cyan") (case `Robin` "pink-blink") (default "blue")}} ``` +*.StyleMap* + Apply user-defined styles (see *aerc-stylesets*(7)) to elements of + a string list. The logic is the same than *.StyleSwitch* but works on + a list of elements. An additional *exclude* option is available to + remove the matching elements from the list. + + ``` + {{.StyleMap .Labels (exclude .Folder) (exclude `^spam$`) (case `^inbox$` "red") (case `^Archive/.*` "green") (default "blue") | join " "}} + ``` + *version* Returns the version of aerc, which can be useful for things like X-Mailer. @@ -426,6 +436,15 @@ aerc provides the following additional functions: {{switch .Folder (case `^INBOX$` "📥") (case `^Archive/.*` "🗃") (default "📁")}} ``` +*map* + Transform a string list into another one. The logic is the same than + *switch* but works on a list of elements. An additional *exclude* option + is available to remove the matching elements from the list. + + ``` + {{map .Labels (exclude .Folder) (exclude `^spam$`) (case `^inbox$` "📥") (case `^Archive/.*` "🗃") | join " "}} + ``` + *Function chaining* All of the template functions can be chained together if needed. diff --git a/lib/state/templates.go b/lib/state/templates.go index 8c7df3e8..36f7b725 100644 --- a/lib/state/templates.go +++ b/lib/state/templates.go @@ -560,3 +560,23 @@ func (d *templateData) StyleSwitch(content string, cases ...models.Case) string } return content } + +func (d *templateData) StyleMap(elems []string, cases ...models.Case) []string { + mapped := make([]string, 0, len(elems)) +top: + for _, e := range elems { + for _, c := range cases { + if c.Matches(e) { + if c.Skip() { + continue top + } + cfg := config.Ui.ForAccount(d.Account()) + style := cfg.GetUserStyle(c.Value()) + e = parse.ApplyStyle(style, e) + break + } + } + mapped = append(mapped, e) + } + return mapped +} diff --git a/lib/templates/functions.go b/lib/templates/functions.go index b331dc85..9380bc7b 100644 --- a/lib/templates/functions.go +++ b/lib/templates/functions.go @@ -255,12 +255,18 @@ func compactDir(path string) string { type ( Case struct{ expr, value string } Default struct{ value string } + Exclude struct{ expr string } ) func (c *Case) Matches(s string) bool { return parse.MatchCache(s, c.expr) } func (c *Case) Value() string { return c.value } +func (c *Case) Skip() bool { return false } func (d *Default) Matches(s string) bool { return true } func (d *Default) Value() string { return d.value } +func (d *Default) Skip() bool { return false } +func (e *Exclude) Matches(s string) bool { return parse.MatchCache(s, e.expr) } +func (e *Exclude) Value() string { return "" } +func (e *Exclude) Skip() bool { return true } func switch_(value string, cases ...models.Case) string { for _, c := range cases { @@ -279,6 +285,28 @@ func default_(value string) models.Case { return &Default{value: value} } +func exclude(expr string) models.Case { + return &Exclude{expr: expr} +} + +func map_(elements []string, cases ...models.Case) []string { + mapped := make([]string, 0, len(elements)) +top: + for _, e := range elements { + for _, c := range cases { + if c.Matches(e) { + if c.Skip() { + continue top + } + e = c.Value() + break + } + } + mapped = append(mapped, e) + } + return mapped +} + var templateFuncs = template.FuncMap{ "quote": quote, "wrapText": wrapText, @@ -304,4 +332,6 @@ var templateFuncs = template.FuncMap{ "switch": switch_, "case": case_, "default": default_, + "map": map_, + "exclude": exclude, } diff --git a/models/templates.go b/models/templates.go index ae57c3fb..eb696ccc 100644 --- a/models/templates.go +++ b/models/templates.go @@ -51,9 +51,11 @@ type TemplateData interface { PendingKeys() string Style(string, string) string StyleSwitch(string, ...Case) string + StyleMap([]string, ...Case) []string } type Case interface { Matches(string) bool Value() string + Skip() bool } |