diff --git a/docs/meli.conf.5 b/docs/meli.conf.5 index f6325c90..8c856ab3 100644 --- a/docs/meli.conf.5 +++ b/docs/meli.conf.5 @@ -446,6 +446,31 @@ Store sent mail after successful submission. This setting is meant to be disabled for non-standard behaviour in gmail, which auto-saves sent mail on its own. .\" default value .Pq Em true +.It Ic attribution_format_string Ar String +.Pq Em optional +The attribution line appears above the quoted reply text. +The format specifiers for the replied address are: +.Bl -bullet -compact +.It +.Li %+f +— the sender's name and email address. +.It +.Li %+n +— the sender's name (or email address, if no name is included). +.It +.Li %+a +— the sender's email address. +.El +The format string is passed to +.Xr strftime 3 +with the replied envelope's date. +.\" default value +.Pq Em "On %a, %0e %b %Y %H:%M, %+f wrote:%n" +.It Ic attribution_use_posix_locale Ar boolean +.Pq Em optional +Whether the strftime call for the attribution string uses the POSIX locale instead of the user's active locale. +.\" default value +.Pq Em true .El .Sh SHORTCUTS Shortcuts can take the following values: diff --git a/src/components/mail/compose.rs b/src/components/mail/compose.rs index 1e3d5672..d344050c 100644 --- a/src/components/mail/compose.rs +++ b/src/components/mail/compose.rs @@ -314,10 +314,21 @@ impl Composer { } } ret.draft.body = { - let mut ret = format!( - "On {} {} wrote:\n", - envelope.date_as_str(), - envelope.from()[0], + let mut ret = attribution_string( + account_settings!( + context[ret.account_hash] + .composing + .attribution_format_string + ) + .as_ref() + .map(|s| s.as_str()), + envelope.from().get(0), + envelope.date(), + *account_settings!( + context[ret.account_hash] + .composing + .attribution_use_posix_locale + ), ); for l in reply_body.lines() { ret.push('>'); @@ -2210,3 +2221,36 @@ pub fn send_draft_async( ret })) } + +/* Sender details + * %+f — the sender's name and email address. + * %+n — the sender's name (or email address, if no name is included). + * %+a — the sender's email address. + */ +fn attribution_string( + fmt: Option<&str>, + sender: Option<&Address>, + date: UnixTimestamp, + posix: bool, +) -> String { + let fmt = fmt.unwrap_or("On %a, %0e %b %Y %H:%M, %+f wrote:%n"); + let fmt = fmt.replace( + "%+f", + &sender + .map(|addr| addr.to_string()) + .unwrap_or_else(|| "\"\"".to_string()), + ); + let fmt = fmt.replace( + "%+n", + &sender + .map(|addr| addr.get_display_name().unwrap_or_else(|| addr.get_email())) + .unwrap_or_else(|| "\"\"".to_string()), + ); + let fmt = fmt.replace( + "%+a", + &sender + .map(|addr| addr.get_email()) + .unwrap_or_else(|| "\"\"".to_string()), + ); + melib::datetime::timestamp_to_string(date, Some(fmt.as_str()), posix) +} diff --git a/src/conf/composing.rs b/src/conf/composing.rs index cb790d3c..b871b47a 100644 --- a/src/conf/composing.rs +++ b/src/conf/composing.rs @@ -58,6 +58,20 @@ pub struct ComposingSettings { /// Default: true #[serde(default = "true_val")] pub store_sent_mail: bool, + /// The attribution line appears above the quoted reply text. + /// The format specifiers for the replied address are: + /// - `%+f` — the sender's name and email address. + /// - `%+n` — the sender's name (or email address, if no name is included). + /// - `%+a` — the sender's email address. + /// The format string is passed to strftime(3) with the replied envelope's date. + /// Default: "On %a, %0e %b %Y %H:%M, %+f wrote:%n" + #[serde(default = "none")] + pub attribution_format_string: Option, + /// Whether the strftime call for the attribution string uses the POSIX locale instead of + /// the user's active locale + /// Default: true + #[serde(default = "true_val")] + pub attribution_use_posix_locale: bool, } impl Default for ComposingSettings { @@ -70,6 +84,8 @@ impl Default for ComposingSettings { insert_user_agent: true, default_header_values: HashMap::default(), store_sent_mail: true, + attribution_format_string: None, + attribution_use_posix_locale: true, } } } diff --git a/src/conf/overrides.rs b/src/conf/overrides.rs index c15930bf..67eea417 100644 --- a/src/conf/overrides.rs +++ b/src/conf/overrides.rs @@ -266,6 +266,20 @@ pub struct ComposingSettingsOverride { #[doc = " Default: true"] #[serde(default)] pub store_sent_mail: Option, + #[doc = " The attribution line appears above the quoted reply text."] + #[doc = " The format specifiers for the replied address are:"] + #[doc = " - `%+f` — the sender's name and email address."] + #[doc = " - `%+n` — the sender's name (or email address, if no name is included)."] + #[doc = " - `%+a` — the sender's email address."] + #[doc = " The format string is passed to strftime(3) with the replied envelope's date."] + #[doc = " Default: \"On %a, %0e %b %Y %H:%M, %+f wrote:%n\""] + #[serde(default)] + pub attribution_format_string: Option>, + #[doc = " Whether the strftime call for the attribution string uses the POSIX locale instead of"] + #[doc = " the user's active locale"] + #[doc = " Default: true"] + #[serde(default)] + pub attribution_use_posix_locale: Option, } impl Default for ComposingSettingsOverride { fn default() -> Self { @@ -277,6 +291,8 @@ impl Default for ComposingSettingsOverride { insert_user_agent: None, default_header_values: None, store_sent_mail: None, + attribution_format_string: None, + attribution_use_posix_locale: None, } } }