aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2023-02-27 09:18:16 -0600
committerRobin Jarry <robin@jarry.cc>2023-03-02 23:04:35 +0100
commitd9a8edd8e9269aa1189d55c8d13caa05084435f5 (patch)
tree65ee1373e485902a82155f6b52ebee59403b91e7
parent8f8e22dbdd4f9e2ff1604e47e0fc78ff5912d633 (diff)
downloadaerc-d9a8edd8e9269aa1189d55c8d13caa05084435f5.tar.gz
templates: allow inline user styles
Allow custom user-defined styles in a styleset. The styles can take any name, and must be under the [user] ini section. All attributes apply to user defined styles. Example: [user] red.fg=red red.bold=true Add a .Style function which accepts the name of a user-defined style and applies it to the string. {{.Style "red" "foo"}} Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--CHANGELOG.md2
-rw-r--r--config/style.go32
-rw-r--r--config/templates.go1
-rw-r--r--config/ui.go4
-rw-r--r--doc/aerc-stylesets.7.scd12
-rw-r--r--doc/aerc-templates.7.scd7
-rw-r--r--lib/state/templates.go7
-rw-r--r--models/templates.go1
8 files changed, 66 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4fb5021e..42c41de5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Change local domain name for SMTP with `smtp-domain=example.com` in
`aerc.conf`
- New column-based status line format with `status-columns`.
+- Inline user-defined styles can be inserted in UI templates via the
+ `{{.Style "name" string}}` function.
### Changed
diff --git a/config/style.go b/config/style.go
index 65c5a3b1..317c77d0 100644
--- a/config/style.go
+++ b/config/style.go
@@ -254,6 +254,7 @@ func (s Style) composeWith(styles []*Style) Style {
type StyleSet struct {
objects map[StyleObject]*Style
selected map[StyleObject]*Style
+ user map[string]*Style
path string
}
@@ -261,6 +262,7 @@ func NewStyleSet() StyleSet {
ss := StyleSet{
objects: make(map[StyleObject]*Style),
selected: make(map[StyleObject]*Style),
+ user: make(map[string]*Style),
}
for _, so := range StyleNames {
ss.objects[so] = new(Style)
@@ -285,6 +287,10 @@ func (ss StyleSet) Selected(so StyleObject) tcell.Style {
return ss.selected[so].Get()
}
+func (ss StyleSet) UserStyle(name string) tcell.Style {
+ return ss.user[name].Get()
+}
+
func (ss StyleSet) Compose(so StyleObject, sos []StyleObject) tcell.Style {
base := *ss.objects[so]
styles := make([]*Style, len(sos))
@@ -437,6 +443,32 @@ func (ss *StyleSet) ParseStyleSet(file *ini.File) error {
}
}
+ user, err := file.GetSection("user")
+ if err != nil {
+ // This errors if the section doesn't exist, which is ok
+ return nil
+ }
+ for _, key := range user.KeyStrings() {
+ tokens := strings.Split(key, ".")
+ var styleName, attr string
+ switch len(tokens) {
+ case 2:
+ styleName, attr = tokens[0], tokens[1]
+ default:
+ return errors.New("Style parsing error: " + key)
+ }
+ val := user.KeysHash()[key]
+ s, ok := ss.user[styleName]
+ if !ok {
+ // Haven't seen this name before, add it to the map
+ s = &Style{}
+ ss.user[styleName] = s
+ }
+ if err := s.Set(attr, val); err != nil {
+ return err
+ }
+ }
+
return nil
}
diff --git a/config/templates.go b/config/templates.go
index bc05be66..f618d365 100644
--- a/config/templates.go
+++ b/config/templates.go
@@ -111,3 +111,4 @@ func (d *dummyData) ContentInfo() string { return "" }
func (d *dummyData) StatusInfo() string { return "" }
func (d *dummyData) TrayInfo() string { return "" }
func (d *dummyData) PendingKeys() string { return "" }
+func (d *dummyData) Style(string, string) string { return "" }
diff --git a/config/ui.go b/config/ui.go
index b1330ffd..64469643 100644
--- a/config/ui.go
+++ b/config/ui.go
@@ -629,6 +629,10 @@ func (base *UIConfig) mergeContextual(
return base
}
+func (uiConfig *UIConfig) GetUserStyle(name string) tcell.Style {
+ return uiConfig.style.UserStyle(name)
+}
+
func (uiConfig *UIConfig) GetStyle(so StyleObject) tcell.Style {
return uiConfig.style.Get(so)
}
diff --git a/doc/aerc-stylesets.7.scd b/doc/aerc-stylesets.7.scd
index eaedb4cb..c633dcef 100644
--- a/doc/aerc-stylesets.7.scd
+++ b/doc/aerc-stylesets.7.scd
@@ -166,6 +166,18 @@ declared under a *[viewer]* section of the styleset file.
| *quote_x*
: Above fourth level quoted text.
+User defined styles can be used to style arbitrary strings in go-templates (see
+_.Style_ in *aerc-templates*(7)). User styles must be defined in the _[user]_
+ini section. Styles can be referenced by their name (e.g. _red.fg_ is named
+"red").
+
+Example:
+
+```
+[user]
+red.fg=red
+```
+
## FNMATCH STYLE WILDCARD MATCHING
The styleset configuration can be made simpler by using the fnmatch
diff --git a/doc/aerc-templates.7.scd b/doc/aerc-templates.7.scd
index 83b19ac9..f3f2a568 100644
--- a/doc/aerc-templates.7.scd
+++ b/doc/aerc-templates.7.scd
@@ -363,6 +363,13 @@ aerc provides the following additional functions:
{{compactPath .Folder}}
```
+*.Style*
+ Apply a user-defined style (see *aerc-stylesets*(7)) to a string.
+
+ ```
+ {{.Style "red" .Account}}
+ ```
+
*version*
Returns the version of aerc, which can be useful for things like X-Mailer.
diff --git a/lib/state/templates.go b/lib/state/templates.go
index 2d5e39f5..d5631b11 100644
--- a/lib/state/templates.go
+++ b/lib/state/templates.go
@@ -6,6 +6,7 @@ import (
"time"
"git.sr.ht/~rjarry/aerc/config"
+ "git.sr.ht/~rjarry/aerc/lib/parse"
"git.sr.ht/~rjarry/aerc/models"
sortthread "github.com/emersion/go-imap-sortthread"
"github.com/emersion/go-message/mail"
@@ -449,3 +450,9 @@ func (d *TemplateData) TrayInfo() string {
func (d *TemplateData) PendingKeys() string {
return config.FormatKeyStrokes(d.pendingKeys)
}
+
+func (d *TemplateData) Style(name string, content string) string {
+ cfg := config.Ui.ForAccount(d.Account())
+ style := cfg.GetUserStyle(name)
+ return parse.ApplyStyle(style, content)
+}
diff --git a/models/templates.go b/models/templates.go
index 4886b83c..916b3974 100644
--- a/models/templates.go
+++ b/models/templates.go
@@ -40,4 +40,5 @@ type TemplateData interface {
StatusInfo() string
TrayInfo() string
PendingKeys() string
+ Style(string, string) string
}