aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Meyer <kyle@kyleam.com>2021-06-05 17:13:55 -0400
committerKyle Meyer <kyle@kyleam.com>2021-06-07 00:12:06 -0400
commitdf741cd4254c274903dac9390d2b158558e6efa6 (patch)
treeb31fb392a334850e55ed709d5a914133a6aeddb7
parentf8fed3d666fb9b514a7d33bd869b64446cf2f1ed (diff)
downloadpiem-df741cd4254c274903dac9390d2b158558e6efa6.tar.gz
piem-lei-query-thread: Omit main part of subject if shared
In addition to suppressing identical subjects (after stripping "re:"), public-inbox's web interface will compare the current line's subject with the previous line's, and cut off the shared tail: [PATCH] Add basic integration for Rmail ` <suppressed completely> ` [PATCH v2] " <-- here ` <suppressed completely> I think the above is helpful. However, in some cases, I find the presentation more confusing than helpful: [PATCH 0/3] notmuch: Improve handling of attached patches ` [PATCH 1/3] piem-notmuch--with-current-message: Declare debug and indent specs ` [PATCH 2/3] piem-notmuch-am-ready-mbox: Improve handling of attachments ` <suppressed completely> ` [PATCH v2 0/3] notmuch: Improve handling of attached patches ` [PATCH v2 1/3] piem-notmuch--with-current-message: Declare debug and indent specs ` [PATCH v2 2/3] piem-notmuch-am-ready-mbox: Improve handling of attachments ` [PATCH v2 3/3] gnus, notmuch: Absorb now-shared bits into patch attachment helper ` [PATCH " It takes me a second to figure out what the omitted bits in the last line's subject are. I'm not sure, but I think the subject truncation that I find clear is where the omitted text is the main subject after a bracketed tag (i.e. "[tag] main"), not more or less. Teach piem-lei-query-thread to split the subject into a "prefix" (some number of "[tag]" items) and a "main" part (everything else), and elide a line's main part if it matches the previous line's. In the above example, the last line would be ` [PATCH 3/3] … Message-Id: <20210605211402.20304-12-kyle@kyleam.com>
-rw-r--r--piem-lei.el30
-rw-r--r--tests/piem-lei-tests.el42
2 files changed, 71 insertions, 1 deletions
diff --git a/piem-lei.el b/piem-lei.el
index cf19195..f7ccc6e 100644
--- a/piem-lei.el
+++ b/piem-lei.el
@@ -341,6 +341,33 @@ Return a list with a `piem-lei-msg' object for each root."
thread)
(nreverse roots))))
+(defvar piem-lei-query--subject-split-re
+ (rx string-start
+ ;; Prefix.
+ (group (zero-or-more space)
+ (one-or-more "[" (one-or-more (not (any "]" "\n"))) "]"
+ (one-or-more space)))
+ ;; Main subject. A match consists of at least two islands of
+ ;; non-space characters because there's not much point in
+ ;; eliding one word.
+ (group (one-or-more (not space))
+ (one-or-more space)
+ (not space)
+ (one-or-more anychar))))
+
+(defun piem-lei-query--split-subject (s)
+ (if (string-match piem-lei-query--subject-split-re s)
+ (cons (match-string 1 s) (match-string 2 s))
+ (cons nil s)))
+
+(defun piem-lei-query--elide-subject (s1 s2)
+ (pcase-let ((`(,head2 . ,tail2) (piem-lei-query--split-subject s2)))
+ (if (and s1 head2
+ (let ((tail1 (cdr (piem-lei-query--split-subject s1))))
+ (equal tail1 tail2)))
+ (concat head2 (if (char-displayable-p ?…) "…" "..."))
+ s2)))
+
(defun piem-lei-query--format-thread-marker (level)
(if (= level 0)
""
@@ -400,7 +427,8 @@ Return a list with a `piem-lei-msg' object for each root."
(if (equal subject subject-prev)
""
(concat " "
- (propertize subject
+ (propertize (piem-lei-query--elide-subject
+ subject-prev subject)
'font-lock-face
'piem-lei-query-subject))))
(add-text-properties (line-beginning-position)
diff --git a/tests/piem-lei-tests.el b/tests/piem-lei-tests.el
index e20c62f..71dc109 100644
--- a/tests/piem-lei-tests.el
+++ b/tests/piem-lei-tests.el
@@ -70,5 +70,47 @@
(should-not (piem-lei-query--has-descendant m3 m2))
(should-not (piem-lei-query--has-descendant m3 m1))))
+(ert-deftest piem-lei-query--elide-subject:keep-original ()
+ (should (equal "ghi jlk"
+ (piem-lei-query--elide-subject
+ nil
+ "ghi jlk")))
+ (should (equal "ghi jlk"
+ (piem-lei-query--elide-subject
+ "abc def"
+ "ghi jlk")))
+ (should (equal "abc def"
+ (piem-lei-query--elide-subject
+ "[PATCH] abc def"
+ "abc def")))
+ (should (equal "abc def"
+ (piem-lei-query--elide-subject
+ "[bug#00000] [PATCH] abc def"
+ "abc def")))
+ (should (equal "abc def"
+ (piem-lei-query--elide-subject
+ "[PATCH] abc def"
+ "abc def")))
+ (should (equal "[bug#00000] [PATCH v2] abc"
+ (piem-lei-query--elide-subject
+ "[bug#00000] [PATCH] abc"
+ "[bug#00000] [PATCH v2] abc")))
+ (should (equal "[bug#00000] [PATCH v2] ghi jlk mno"
+ (piem-lei-query--elide-subject
+ "[bug#00000] [PATCH] abc def"
+ "[bug#00000] [PATCH v2] ghi jlk mno"))))
+
+(defvar piem-lei-tests-elide-string (if (char-displayable-p ?…) "…" "..."))
+
+(ert-deftest piem-lei-query--elide-subject:elide ()
+ (should (equal (concat "[PATCH v2] " piem-lei-tests-elide-string)
+ (piem-lei-query--elide-subject
+ "[PATCH] abc def"
+ "[PATCH v2] abc def")))
+ (should (equal (concat "[bug#00000] [PATCH v2] " piem-lei-tests-elide-string)
+ (piem-lei-query--elide-subject
+ "[bug#00000] [PATCH] abc def"
+ "[bug#00000] [PATCH v2] abc def"))))
+
(provide 'piem-lei-tests)
;;; piem-lei-tests.el ends here