mutt:“index_format”中的条件日期格式

Mar*_*ter 15 mutt date

index_format在 mutt 中设置了以下值:

"%Z %{%Y %b %e  %H:%M} %?X?(%X)&   ? %-22.22F  %.100s %> %5c "
Run Code Online (Sandbox Code Playgroud)

它以格式显示日期为

2013 Dec 5
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以根据电子邮件的年龄使用不同的日期格式。我的意思是:

for less than 7 days:  today, yesterday, tuesday, monday
this year:             Dec 5
older than this year:  2013 Dec 5
Run Code Online (Sandbox Code Playgroud)

我想我已经在 Thunderbird 中看到了这个功能。把它放在笨蛋里会很好

小智 16

如果您使用的是 mutt (v1.5+) 的“开发”版本 - 你绝对应该 - 有可能使用手册中描述的外部过滤器。

首先,您需要一个可以根据消息的年龄输出不同内容的脚本。这是 Python 中的一个示例:

#!/usr/bin/env python
"""mutt format date

Prints different index_format strings for mutt according to a
messages age.

The single command line argument should be a unix timestamp
giving the message's date (%{}, etc. in Mutt).
"""

import sys
from datetime import datetime

INDEX_FORMAT = "%Z {} %?X?(%X)&   ? %-22.22F  %.100s %> %5c%"

def age_fmt(msg_date, now):
    # use iso date for messages of the previous year and before
    if msg_date.date().year < now.date().year:
        return '%[%Y-%m-%d]'

    # use "Month Day" for messages of this year
    if msg_date.date() < now.date():
        return '%10[%b %e]'

    # if a message appears to come from the future
    if msg_date > now:
        return '  b0rken'

    # use only the time for messages that arrived today
    return '%10[%H:%m]'

if __name__ == '__main__':
    msg_date = datetime.fromtimestamp(int(sys.argv[1]))
    now = datetime.now()
    print INDEX_FORMAT.format(age_fmt(msg_date, now))
Run Code Online (Sandbox Code Playgroud)

将其保存为mutt-fmt-datePATH 中的某个位置。

这里有两件事很重要:

  • 格式字符串必须包含其中一次被 Python{}的返回值替换age_fmt()
  • 格式字符串必须以 a 结尾,%这样 Mutt 才能解释它。

然后你可以在你.muttrc的如下使用它:

set index_format="mutt-fmt-date %[%s] |"
Run Code Online (Sandbox Code Playgroud)

然后穆特会

  1. %[%s]根据格式字符串的规则进行解释。
  2. 调用mutt-fmt-date与1作为参数(因为结果|在最后)。
  3. 再次将它从脚本中返回的内容解释为格式字符串(因为%末尾的 )。

警告:脚本将针对每条将要显示的消息执行。滚动邮箱时,由此产生的延迟可能非常明显。

这是一个 C 版本,它的表现有些充分:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define DAY (time_t)86400
#define YEAR (time_t)31556926

int main(int argc, const char *argv[]) {
    time_t current_time;
    time_t message_time;

    const char *old, *recent, *today;
    const char *format;

    current_time = time(NULL);

    if (argc!=6) {
        printf("Usage: %s old recent today format timestamp\n", argv[0]);
        return 2;
    }

    old = argv[1];
    recent = argv[2];
    today = argv[3];

    format = argv[4];

    message_time = atoi(argv[5]);

    if ((message_time/YEAR) < (current_time/YEAR)) {
        printf(format, old);
    } else if ((message_time/DAY) < (current_time/DAY)) {
        printf(format, recent);
    } else {
        printf(format, today);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这与 muttrc 行一起使用:

set index_format='mfdate "%[%d.%m.%y]" "%8[%e. %b]" "%8[%H:%m]" "%Z %%s %-20.20L %?y?[%-5.5y]&       ? %?M?+& ?%s%%" "%[%s]" |'
Run Code Online (Sandbox Code Playgroud)


use*_*ser 7

不幸的是,对于当前版本的 Mutt这似乎是不可能的。

$index_format支持一组特定的格式说明符,从各种消息元数据中提取。它在 Mutt 手册中有描述(或者这里是相同的“稳定”版本的文档),正如您从表中看到的,只有少数格式说明符是有条件的。那些是%M,%y%Y; %M是隐藏的消息的数量,如果该线程处于折叠状态,和%y和%Y是X标签标头如果存在。

消息日期和时间的实际格式化由 完成strftime(3),它根本不支持条件格式化。

也许可以做一个丑陋通过不断改写消息文件解决办法Date:头,但我不想这样做,至少。但是,这是我能想到的最不坏的可能性。

我能想到的唯一真正的解决方案是在 Mutt 中实现这种支持(几乎可以肯定 Thunderbird 就是这样做的),或者编写一个strftime支持条件格式的替代品,并使用 LD_PRELOAD 或类似机制注入它。然而,后者将影响Mutt 中通过 strftime 的所有日期和时间显示,而不仅仅是与消息索引有关。

  • 如果您使用的是 1.5+ 版本(您绝对应该使用),则有一种方法。建议重写日期标题很有趣,不过…… (2认同)