summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-01-20 10:41:47 +0100
committerAnton Khirnov <anton@khirnov.net>2021-01-20 11:39:27 +0100
commit3b78137e97565f90a48aad92dc471c47e63747eb (patch)
treeca0780c013888b126e0a315279f02377e58e0b16
parent720e92a4a54b80a0ab8432e8e2defcdfe6b0c49f (diff)
widgets/thread: option for smarter subject in message summary
In the smart mode, display subject only if it's different from parent (modulo leading re:'s). Since the subject should not change most of the time, this reduces visual clutter.
-rw-r--r--alot/defaults/alot.rc.spec10
-rw-r--r--alot/widgets/thread.py43
2 files changed, 46 insertions, 7 deletions
diff --git a/alot/defaults/alot.rc.spec b/alot/defaults/alot.rc.spec
index d2b7866c..00e527b5 100644
--- a/alot/defaults/alot.rc.spec
+++ b/alot/defaults/alot.rc.spec
@@ -74,6 +74,16 @@ thread_authors_me = string(default='Me')
# the thread subject
thread_subject = option('oldest', 'notmuch', default='notmuch')
+# Whether/how to display the subject in the message summary line in thread
+# view. Valid values are:
+#
+# * 'yes' always display the subject
+# * 'no' never display the subject
+# * 'smart' use heuristics to decide whether the subject should be shown.
+# Currently that means the subject is displayed if it is different
+# from parent message's, or if the message in question has no parent.
+thread_message_summary_subject = option('yes', 'no', 'smart', default = 'smart')
+
# When constructing the unique list of thread authors, order by date of
# author's first or latest message in thread
thread_authors_order_by = option('first_message', 'latest_message', default='first_message')
diff --git a/alot/widgets/thread.py b/alot/widgets/thread.py
index b0276eb0..cc7fbbf2 100644
--- a/alot/widgets/thread.py
+++ b/alot/widgets/thread.py
@@ -29,15 +29,13 @@ class MessageSummaryWidget(urwid.WidgetWrap):
:param message: a message
:type message: alot.db.Message
"""
+ author, address = message.get_author()
+ text = author if author else address
- try:
- subj = message.headers['Subject']
- except KeyError:
- subj = ''
- subj = re.sub(r'\n\s+', r' ', ','.join(subj))
+ subj = self._extract_subj(message)
+ if subj:
+ text += ': ' + subj
- author, address = message.get_author()
- text = '%s: %s' % (author if author != '' else address, subj)
date = message.get_datestring()
if date is not None:
text += " (%s)" % date
@@ -60,6 +58,37 @@ class MessageSummaryWidget(urwid.WidgetWrap):
attr, attr_focus)
super().__init__(line)
+ def _extract_subj(self, msg):
+ subj_style = settings.get('thread_message_summary_subject')
+
+ if subj_style == 'no':
+ return ''
+
+ try:
+ subj = ','.join(msg.headers['Subject'])
+ except KeyError:
+ return ''
+
+ # for "smart" display style, check if normalized subject
+ # is the same as parent's
+ if subj_style == 'smart' and msg.parent is not None:
+ try:
+ parent_subj = ','.join(msg.parent.headers['Subject'])
+ except KeyError:
+ pass
+ else:
+ def normalize_subj(subj):
+ # normalize subject for comparison - replace all
+ # whitespace sequences with a single space and strip
+ # leading re:'s
+ subj = re.sub(r'\s+', ' ', subj)
+ return re.sub(r'(re:? *)*', '', subj, flags = re.IGNORECASE)
+
+ if normalize_subj(subj) == normalize_subj(parent_subj):
+ return ''
+
+ return re.sub(r'\n\s+', r' ', subj)
+
class _MIMEPartWidget(urwid.WidgetWrap):
# when not None, a list of child _MIMEPartWidget subclasses