~sircmpwn/aerc

index: allow dynamic formatting of message dates v1 PROPOSED

Robin Jarry
Robin Jarry: 1
 index: allow dynamic formatting of message dates

 6 files changed, 53 insertions(+), 7 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/26011/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] index: allow dynamic formatting of message dates Export this patch

Robin Jarry
When a message has been sent today (or this year) allow formatting the
date differently.

For example, with:

 [ui]
 index-format=%-25.25n   %-25.25D   %s
 timestamp-format=2006 Jan 02, 15:04 GMT-0700
 this-day-time-format=Today at 15:04
 this-year-time-format=Jan 02

The message list would look like this (spaces collapsed):

 Robin Jarry        Today at 16:30             [PATCH 1/2] bindings: prepare for more modifers
 bugzilla@dpdk.org  Oct 26                     [dpdk-dev] [Bug 839] pdump: any subsequent runs of pdump_autotest fail
 Holger Levsen      2020 Mar 15, 13:44 GMT+01  +1 (Re: FTP Team -- call for volunteers)

Signed-off-by: Robin Jarry <robin@jarry.cc>
---
 config/aerc.conf.in   | 14 ++++++++++++++
 config/config.go      |  8 ++++++--
 config/triggers.go    |  2 ++
 doc/aerc-config.5.scd | 12 ++++++++++++
 lib/format/format.go  | 23 ++++++++++++++++++-----
 widgets/msglist.go    |  1 +
 6 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/config/aerc.conf.in b/config/aerc.conf.in
index b9381a8bde7b..0421901a8bf3 100644
--- a/config/aerc.conf.in
+++ b/config/aerc.conf.in
@@ -15,6 +15,20 @@ index-format=%D %-17.17n %Z %s
# Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time)
timestamp-format=2006-01-02 03:04 PM

#
# Index-only time format for messages that were received/sent today.
# If this is not specified, timestamp-format is used instead.
#
# Default: ""
today-time-format=

#
# Index-only time format for messages that were received/sent this year.
# If this is not specified, timestamp-format is used instead.
#
# Default: ""
this-year-time-format=

#
# Width of the sidebar, including the border.
#
diff --git a/config/config.go b/config/config.go
index af9c63b27a61..dfcbd4dde716 100644
--- a/config/config.go
+++ b/config/config.go
@@ -29,6 +29,8 @@ type GeneralConfig struct {
type UIConfig struct {
	IndexFormat         string        `ini:"index-format"`
	TimestampFormat     string        `ini:"timestamp-format"`
	ThisDayTimeFormat   string        `ini:"this-day-time-format"`
	ThisYearTimeFormat  string        `ini:"this-year-time-format"`
	ShowHeaders         []string      `delim:","`
	RenderAccountTabs   string        `ini:"render-account-tabs"`
	PinnedTabMarker     string        `ini:"pinned-tab-marker"`
@@ -491,8 +493,10 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
		Ini: file,

		Ui: UIConfig{
			IndexFormat:     "%D %-17.17n %s",
			TimestampFormat: "2006-01-02 03:04 PM",
			IndexFormat:        "%D %-17.17n %s",
			TimestampFormat:    "2006-01-02 03:04 PM",
			ThisDayTimeFormat:  "",
			ThisYearTimeFormat: "",
			ShowHeaders: []string{
				"From", "To", "Cc", "Bcc", "Subject", "Date",
			},
diff --git a/config/triggers.go b/config/triggers.go
index 847a10f3770e..4777371b1cfa 100644
--- a/config/triggers.go
+++ b/config/triggers.go
@@ -38,6 +38,8 @@ func (trig *TriggersConfig) ExecNewEmail(account *AccountConfig,
		func(part string) (string, error) {
			formatstr, args, err := format.ParseMessageFormat(
				part, conf.Ui.TimestampFormat,
				conf.Ui.ThisDayTimeFormat,
				conf.Ui.ThisYearTimeFormat,
				format.Ctx{
					FromAddress: account.From,
					AccountName: account.Name,
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index 46c441667c47..d781164ef481 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -87,6 +87,18 @@ These options are configured in the *[ui]* section of aerc.conf.

	Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time)

*today-time-format*
	Index-only time format for messages that were received/sent today.
	If this is not specified, *timestamp-format* is used instead.

	Default: ""

*this-year-time-format*
	Index-only time format for messages that were received/sent this year.
	If this is not specified, *timestamp-format* is used instead.

	Default: ""

*sidebar-width*
	Width of the sidebar, including the border. Set to zero to disable the
	sidebar.
diff --git a/lib/format/format.go b/lib/format/format.go
index 30e8be7f698f..16398865c8d6 100644
--- a/lib/format/format.go
+++ b/lib/format/format.go
@@ -47,8 +47,8 @@ type Ctx struct {
	MsgIsMarked bool
}

func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
	[]interface{}, error) {
func ParseMessageFormat(format string, timeFmt string, thisDayTimeFmt string,
	thisYearTimeFmt string, ctx Ctx) (string, []interface{}, error) {
	retval := make([]byte, 0, len(format))
	var args []interface{}

@@ -144,7 +144,8 @@ func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
			}
			retval = append(retval, 's')
			args = append(args,
				dummyIfZeroDate(date.Local(), timeFmt))
				dummyIfZeroDate(date.Local(),
					timeFmt, thisDayTimeFmt, thisYearTimeFmt))
		case 'D':
			date := envelope.Date
			if date.IsZero() {
@@ -152,7 +153,8 @@ func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
			}
			retval = append(retval, 's')
			args = append(args,
				dummyIfZeroDate(date.Local(), timeFmt))
				dummyIfZeroDate(date.Local(),
					timeFmt, thisDayTimeFmt, thisYearTimeFmt))
		case 'f':
			if envelope == nil {
				return "", nil,
@@ -374,9 +376,20 @@ handle_end_error:
		errors.New("reached end of string while parsing message format")
}

func dummyIfZeroDate(date time.Time, format string) string {
func dummyIfZeroDate(date time.Time, format string, todayFormat string,
	thisYearFormat string) string {
	if date.IsZero() {
		return strings.Repeat("?", len(format))
	}
	year, month, day := date.Date()
	thisYear, thisMonth, thisDay := time.Now().Date()
	if year == thisYear {
		if month == thisMonth && day == thisDay && todayFormat != "" {
			return date.Format(todayFormat)
		}
		if thisYearFormat != "" {
			return date.Format(thisYearFormat)
		}
	}
	return date.Format(format)
}
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 8f5a06e09d9e..6055da37e750 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -155,6 +155,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
		ctx.Fill(0, row, ctx.Width(), 1, ' ', style)
		fmtStr, args, err := format.ParseMessageFormat(
			uiConfig.IndexFormat, uiConfig.TimestampFormat,
			uiConfig.ThisDayTimeFormat, uiConfig.ThisYearTimeFormat,
			format.Ctx{
				FromAddress: ml.aerc.SelectedAccount().acct.From,
				AccountName: ml.aerc.SelectedAccount().Name(),
-- 
2.30.2