aboutsummaryrefslogtreecommitdiffstats
path: root/config/ui.go
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2022-09-06 07:33:21 +0200
committerRobin Jarry <robin@jarry.cc>2023-01-06 22:56:47 +0100
commit535300cfdbfc6e72fe9717c409fa64f072a1c581 (patch)
treedadcb1c1d88406134e532ab0f6cd87e54ff659d7 /config/ui.go
parent012be0192c88f4fcfd5ed559edff4ca7366eb351 (diff)
downloadaerc-535300cfdbfc6e72fe9717c409fa64f072a1c581.tar.gz
config: add columns based index format
The index-format option comes from mutt and is neither user friendly, nor intuitive. Introduce a new way of configuring the message list contents. Replace index-format with multiple settings to make everything more intuitive. Reuse the table widget added in the previous commit. index-columns Comma-separated list of column names followed by optional alignment and width specifiers. column-separator String separator between columns. column-$name One setting for every name defined in index-columns. This supports golang text/template syntax and allows access to the same message information than before and much more. When index-format is still defined in aerc.conf (which will most likely happen when users will update after this patch), convert it to the new index-columns + column-$name and column-separator system and a warning is displayed on startup so that users are aware that they need to update their config. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
Diffstat (limited to 'config/ui.go')
-rw-r--r--config/ui.go178
1 files changed, 176 insertions, 2 deletions
diff --git a/config/ui.go b/config/ui.go
index 18724af2..98b9f629 100644
--- a/config/ui.go
+++ b/config/ui.go
@@ -4,9 +4,11 @@ import (
"fmt"
"path"
"regexp"
+ "strconv"
"strings"
"time"
+ "git.sr.ht/~rjarry/aerc/lib/templates"
"git.sr.ht/~rjarry/aerc/log"
"github.com/gdamore/tcell/v2"
"github.com/go-ini/ini"
@@ -14,8 +16,12 @@ import (
)
type UIConfig struct {
+ IndexColumns []*ColumnDef `ini:"-"`
+ ColumnSeparator string `ini:"column-separator"`
+ // deprecated
+ IndexFormat string `ini:"index-format"`
+
AutoMarkRead bool `ini:"auto-mark-read"`
- IndexFormat string `ini:"index-format"`
TimestampFormat string `ini:"timestamp-format"`
ThisDayTimeFormat string `ini:"this-day-time-format"`
ThisWeekTimeFormat string `ini:"this-week-time-format"`
@@ -92,9 +98,39 @@ type uiContextKey struct {
}
func defaultUiConfig() *UIConfig {
+ date, _ := templates.ParseTemplate("column-date", "{{.DateAutoFormat .Date.Local}}")
+ name, _ := templates.ParseTemplate("column-name", "{{index (.From | names) 0}}")
+ flags, _ := templates.ParseTemplate("column-flags", `{{.Flags | join ""}}`)
+ subject, _ := templates.ParseTemplate("column-subject", "{{.Subject}}")
return &UIConfig{
+ IndexFormat: "", // deprecated
+ IndexColumns: []*ColumnDef{
+ {
+ Name: "date",
+ Width: 20,
+ Flags: ALIGN_LEFT | WIDTH_EXACT,
+ Template: date,
+ },
+ {
+ Name: "name",
+ Width: 17,
+ Flags: ALIGN_LEFT | WIDTH_EXACT,
+ Template: name,
+ },
+ {
+ Name: "flags",
+ Width: 4,
+ Flags: ALIGN_RIGHT | WIDTH_EXACT,
+ Template: flags,
+ },
+ {
+ Name: "subject",
+ Flags: ALIGN_LEFT | WIDTH_AUTO,
+ Template: subject,
+ },
+ },
+ ColumnSeparator: " ",
AutoMarkRead: true,
- IndexFormat: "%-20.20D %-17.17n %Z %s",
TimestampFormat: "2006-01-02 03:04 PM",
ThisDayTimeFormat: "",
ThisWeekTimeFormat: "",
@@ -283,9 +319,147 @@ func (config *UIConfig) parse(section *ini.Section) error {
config.MessageViewThisDayTimeFormat = config.TimestampFormat
}
+ if config.IndexFormat != "" {
+ log.Warnf("%s %s",
+ "The index-format setting has been replaced by index-columns.",
+ "index-format will be removed in aerc 0.17.")
+ }
+ if key, err := section.GetKey("index-columns"); err == nil {
+ columns, err := ParseColumnDefs(key, section)
+ if err != nil {
+ return err
+ }
+ config.IndexColumns = columns
+ config.IndexFormat = "" // to silence popup at startup
+ } else if config.IndexFormat != "" {
+ columns, err := convertIndexFormat(config.IndexFormat)
+ if err != nil {
+ return err
+ }
+ config.IndexColumns = columns
+ }
+
return nil
}
+var indexFmtRegexp = regexp.MustCompile(`%(-?\d+)?(\.\d+)?([A-Za-z%])`)
+
+func convertIndexFormat(indexFormat string) ([]*ColumnDef, error) {
+ matches := indexFmtRegexp.FindAllStringSubmatch(indexFormat, -1)
+ if matches == nil {
+ return nil, fmt.Errorf("invalid index-format")
+ }
+
+ var columns []*ColumnDef
+
+ for _, m := range matches {
+ alignWidth := m[1]
+ verb := m[3]
+
+ var f string
+ var width float64 = 0
+ var flags ColumnFlags = ALIGN_LEFT
+ name := ""
+
+ switch verb {
+ case "%":
+ f = verb
+ case "a":
+ f = `{{(index .From 0).Address}}`
+ name = "sender"
+ case "A":
+ f = `{{if eq (len .ReplyTo) 0}}{{(index .From 0).Address}}{{else}}{{(index .ReplyTo 0).Address}}{{end}}`
+ name = "reply-to"
+ case "C":
+ f = "{{.Number}}"
+ name = "num"
+ case "d", "D":
+ f = "{{.DateAutoFormat .Date.Local}}"
+ name = "date"
+ case "f":
+ f = `{{index (.From | persons) 0}}`
+ name = "from"
+ case "F":
+ f = `{{.Peer | names | join ", "}}`
+ name = "peers"
+ case "g":
+ f = `{{.Labels | join ", "}}`
+ name = "labels"
+ case "i":
+ f = "{{.MessageId}}"
+ name = "msg-id"
+ case "n":
+ f = `{{index (.From | names) 0}}`
+ name = "name"
+ case "r":
+ f = `{{.To | persons | join ", "}}`
+ name = "to"
+ case "R":
+ f = `{{.Cc | persons | join ", "}}`
+ name = "cc"
+ case "s":
+ f = "{{.Subject}}"
+ name = "subject"
+ case "t":
+ f = "{{(index .To 0).Address}}"
+ name = "to0"
+ case "T":
+ f = "{{.Account}}"
+ name = "account"
+ case "u":
+ f = "{{index (.From | mboxes) 0}}"
+ name = "mboxes"
+ case "v":
+ f = "{{index (.From | names) 0}}"
+ name = "name"
+ case "Z":
+ f = `{{.Flags | join ""}}`
+ name = "flags"
+ width = 4
+ flags = ALIGN_RIGHT
+ case "l":
+ f = "{{.Size}}"
+ name = "size"
+ default:
+ f = "%" + verb
+ }
+ if name == "" {
+ name = "wtf"
+ }
+
+ t, err := templates.ParseTemplate(fmt.Sprintf("column-%s", name), f)
+ if err != nil {
+ return nil, err
+ }
+
+ if alignWidth != "" {
+ width, err = strconv.ParseFloat(alignWidth, 64)
+ if err != nil {
+ return nil, err
+ }
+ if width < 0 {
+ width = -width
+ } else {
+ flags = ALIGN_RIGHT
+ }
+ }
+ if width == 0 {
+ flags |= WIDTH_AUTO
+ } else {
+ flags |= WIDTH_EXACT
+ }
+
+ columns = append(columns, &ColumnDef{
+ Name: name,
+ Width: width,
+ Flags: flags,
+ Template: t,
+ })
+ }
+
+ return columns, nil
+}
+
func (ui *UIConfig) loadStyleSet(styleSetDirs []string) error {
ui.style = NewStyleSet()
err := ui.style.LoadStyleSet(ui.StyleSetName, styleSetDirs)