about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--config/config.go9
-rw-r--r--config/style.go50
-rw-r--r--doc/aerc-stylesets.7.scd21
-rw-r--r--widgets/msglist.go27
4 files changed, 90 insertions, 17 deletions
diff --git a/config/config.go b/config/config.go
index 3ae26c1..bb83579 100644
--- a/config/config.go
+++ b/config/config.go
@@ -699,3 +699,12 @@ func (uiConfig UIConfig) GetStyle(so StyleObject) tcell.Style {
 func (uiConfig UIConfig) GetStyleSelected(so StyleObject) tcell.Style {
 	return uiConfig.style.Selected(so)
 }
+
+func (uiConfig UIConfig) GetComposedStyle(base StyleObject,
+	styles []StyleObject) tcell.Style {
+	return uiConfig.style.Compose(base, styles)
+}
+
+func (uiConfig UIConfig) GetComposedStyleSelected(base StyleObject, styles []StyleObject) tcell.Style {
+	return uiConfig.style.ComposeSelected(base, styles)
+}
diff --git a/config/style.go b/config/style.go
index caf9e4f..af7241d 100644
--- a/config/style.go
+++ b/config/style.go
@@ -31,9 +31,9 @@ const (
 	STYLE_MSGLIST_DEFAULT
 	STYLE_MSGLIST_UNREAD
 	STYLE_MSGLIST_READ
+	STYLE_MSGLIST_FLAGGED
 	STYLE_MSGLIST_DELETED
 	STYLE_MSGLIST_MARKED
-	STYLE_MSGLIST_FLAGGED
 
 	STYLE_DIRLIST_DEFAULT
 
@@ -67,9 +67,9 @@ var StyleNames = map[string]StyleObject{
 	"msglist_default": STYLE_MSGLIST_DEFAULT,
 	"msglist_unread":  STYLE_MSGLIST_UNREAD,
 	"msglist_read":    STYLE_MSGLIST_READ,
+	"msglist_flagged": STYLE_MSGLIST_FLAGGED,
 	"msglist_deleted": STYLE_MSGLIST_DELETED,
 	"msglist_marked":  STYLE_MSGLIST_MARKED,
-	"msglist_flagged": STYLE_MSGLIST_FLAGGED,
 
 	"dirlist_default": STYLE_DIRLIST_DEFAULT,
 
@@ -180,6 +180,31 @@ func (s *Style) Set(attr, val string) error {
 	return nil
 }
 
+func (s Style) composeWith(styles []*Style) Style {
+	newStyle := s
+	for _, st := range styles {
+		if st.Fg != s.Fg {
+			newStyle.Fg = st.Fg
+		}
+		if st.Bg != s.Bg {
+			newStyle.Bg = st.Bg
+		}
+		if st.Bold != s.Bold {
+			newStyle.Bold = st.Bold
+		}
+		if st.Blink != s.Blink {
+			newStyle.Blink = st.Blink
+		}
+		if st.Underline != s.Underline {
+			newStyle.Underline = st.Underline
+		}
+		if st.Reverse != s.Reverse {
+			newStyle.Reverse = st.Reverse
+		}
+	}
+	return newStyle
+}
+
 type StyleSet struct {
 	objects  map[StyleObject]*Style
 	selected map[StyleObject]*Style
@@ -213,6 +238,27 @@ func (ss StyleSet) Selected(so StyleObject) tcell.Style {
 	return ss.selected[so].Get()
 }
 
+func (ss StyleSet) Compose(so StyleObject, sos []StyleObject) tcell.Style {
+	base := *ss.objects[so]
+	styles := make([]*Style, len(sos))
+	for i, so := range sos {
+		styles[i] = ss.objects[so]
+	}
+
+	return base.composeWith(styles).Get()
+}
+
+func (ss StyleSet) ComposeSelected(so StyleObject,
+	sos []StyleObject) tcell.Style {
+	base := *ss.selected[so]
+	styles := make([]*Style, len(sos))
+	for i, so := range sos {
+		styles[i] = ss.selected[so]
+	}
+
+	return base.composeWith(styles).Get()
+}
+
 func findStyleSet(stylesetName string, stylesetsDir []string) (string, error) {
 	for _, dir := range stylesetsDir {
 		stylesetPath, err := homedir.Expand(path.Join(dir, stylesetName))
diff --git a/doc/aerc-stylesets.7.scd b/doc/aerc-stylesets.7.scd
index e3e7b1f..818bf69 100644
--- a/doc/aerc-stylesets.7.scd
+++ b/doc/aerc-stylesets.7.scd
@@ -107,12 +107,12 @@ styling.
 :  Unread messages in a message list.
 |  msglist_read
 :  Read messages in a message list.
+|  msglist_flagged
+:  The messages with the flagged flag.
 |  msglist_deleted
 :  The messages marked as deleted.
 |  msglist_marked
 :  The messages with the marked flag.
-|  msglist_flagged
-:  The messages with the flagged flag.
 |  dirlist_default
 :  The default style for directories in the directory list.
 |  completion_default
@@ -175,6 +175,23 @@ If we specify the global style selected modifer using fnmatch as below:
 
 This toggles the reverse switch for selected version of all the style objects.
 
+## Layered styles
+Some styles, (currently only the `msglist\*` ones) are applied in layers. If
+a style differs from the base (in this case `msglist_default`) then that style
+applies, unless overridden by a higher layer. The order that `msglist` styles
+are applied in is, from first to last:
+
+```
+msglist_default
+msglist_unread
+msglist_read
+msglist_flagged
+msglist_deleted
+msglist_marked
+```
+
+So, the marked style will override all other msglist styles.
+
 ## Colors
 The color values are set using the values accepted by the tcell library.
 The values can be one of the following.
diff --git a/widgets/msglist.go b/widgets/msglist.go
index b7c10d7..61738a8 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -108,12 +108,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
 			config.UI_CONTEXT_SUBJECT: msg.Envelope.Subject,
 		})
 
-		so := config.STYLE_MSGLIST_DEFAULT
-
-		// deleted message
-		if _, ok := store.Deleted[msg.Uid]; ok {
-			so = config.STYLE_MSGLIST_DELETED
-		}
+		msg_styles := []config.StyleObject{}
 		// unread message
 		seen := false
 		flagged := false
@@ -127,25 +122,31 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
 		}
 
 		if seen {
-			so = config.STYLE_MSGLIST_READ
+			msg_styles = append(msg_styles, config.STYLE_MSGLIST_READ)
 		} else {
-			so = config.STYLE_MSGLIST_UNREAD
+			msg_styles = append(msg_styles, config.STYLE_MSGLIST_UNREAD)
 		}
 
 		if flagged {
-			so = config.STYLE_MSGLIST_FLAGGED
+			msg_styles = append(msg_styles, config.STYLE_MSGLIST_FLAGGED)
+		}
+
+		// deleted message
+		if _, ok := store.Deleted[msg.Uid]; ok {
+			msg_styles = append(msg_styles, config.STYLE_MSGLIST_DELETED)
 		}
 
 		// marked message
 		if store.IsMarked(msg.Uid) {
-			so = config.STYLE_MSGLIST_MARKED
+			msg_styles = append(msg_styles, config.STYLE_MSGLIST_MARKED)
 		}
 
-		style := uiConfig.GetStyle(so)
-
+		var style tcell.Style
 		// current row
 		if row == ml.store.SelectedIndex()-ml.scroll {
-			style = uiConfig.GetStyleSelected(so)
+			style = uiConfig.GetComposedStyleSelected(config.STYLE_MSGLIST_DEFAULT, msg_styles)
+		} else {
+			style = uiConfig.GetComposedStyle(config.STYLE_MSGLIST_DEFAULT, msg_styles)
 		}
 
 		ctx.Fill(0, row, ctx.Width(), 1, ' ', style)