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)