config: allow custom separators in author lists

Allow distinguishing between commas separating authors and separating
first and last names.

Amended by db: reformat NEWS entry and commit message. Tweaked
whitespace in lib/thread.cc.
This commit is contained in:
Lars Kotthoff 2023-12-22 14:06:34 -07:00 committed by David Bremner
parent 199e2de224
commit d34720e7b3
9 changed files with 90 additions and 5 deletions

11
NEWS
View file

@ -1,3 +1,14 @@
Notmuch 0.39 (UNRELEASED)
=========================
General
-------
Allow to customize the separator between individual and matched and
non-matched authors when showing threads. See
`search.authors_separator` and `search.authors_matched_separator` in
notmuch-config(1).
Notmuch 0.38.3 (2024-03-09) Notmuch 0.38.3 (2024-03-09)
=========================== ===========================

View file

@ -273,6 +273,19 @@ paths are presumed relative to `$HOME` for items in section
Default: empty list. Note that :any:`notmuch-setup(1)` puts Default: empty list. Note that :any:`notmuch-setup(1)` puts
``deleted;spam`` here when creating new configuration file. ``deleted;spam`` here when creating new configuration file.
.. nmconfig:: search.authors_separator
The string to separate authors when showing a thread.
Default: ,
.. nmconfig:: search.authors_matched_separator
The string to separate matched from non-matched authors when showing a
thread.
Default: |
.. nmconfig:: show.extra_headers .. nmconfig:: show.extra_headers
By default :any:`notmuch-show(1)` includes the following headers By default :any:`notmuch-show(1)` includes the following headers

View file

@ -608,6 +608,10 @@ _notmuch_config_key_to_string (notmuch_config_key_t key)
return "database.autocommit"; return "database.autocommit";
case NOTMUCH_CONFIG_EXTRA_HEADERS: case NOTMUCH_CONFIG_EXTRA_HEADERS:
return "show.extra_headers"; return "show.extra_headers";
case NOTMUCH_CONFIG_AUTHORS_SEPARATOR:
return "search.authors_separator";
case NOTMUCH_CONFIG_AUTHORS_MATCHED_SEPARATOR:
return "search.authors_matched_separator";
case NOTMUCH_CONFIG_INDEX_AS_TEXT: case NOTMUCH_CONFIG_INDEX_AS_TEXT:
return "index.as_text"; return "index.as_text";
default: default:
@ -658,6 +662,10 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
return ""; return "";
case NOTMUCH_CONFIG_AUTOCOMMIT: case NOTMUCH_CONFIG_AUTOCOMMIT:
return "8000"; return "8000";
case NOTMUCH_CONFIG_AUTHORS_SEPARATOR:
return ", ";
case NOTMUCH_CONFIG_AUTHORS_MATCHED_SEPARATOR:
return "| ";
case NOTMUCH_CONFIG_EXTRA_HEADERS: case NOTMUCH_CONFIG_EXTRA_HEADERS:
case NOTMUCH_CONFIG_HOOK_DIR: case NOTMUCH_CONFIG_HOOK_DIR:
case NOTMUCH_CONFIG_BACKUP_DIR: case NOTMUCH_CONFIG_BACKUP_DIR:

View file

@ -2565,6 +2565,8 @@ typedef enum {
NOTMUCH_CONFIG_AUTOCOMMIT, NOTMUCH_CONFIG_AUTOCOMMIT,
NOTMUCH_CONFIG_EXTRA_HEADERS, NOTMUCH_CONFIG_EXTRA_HEADERS,
NOTMUCH_CONFIG_INDEX_AS_TEXT, NOTMUCH_CONFIG_INDEX_AS_TEXT,
NOTMUCH_CONFIG_AUTHORS_SEPARATOR,
NOTMUCH_CONFIG_AUTHORS_MATCHED_SEPARATOR,
NOTMUCH_CONFIG_LAST NOTMUCH_CONFIG_LAST
} notmuch_config_key_t; } notmuch_config_key_t;

View file

@ -122,21 +122,28 @@ _thread_add_matched_author (notmuch_thread_t *thread,
/* Construct an authors string from matched_authors_array and /* Construct an authors string from matched_authors_array and
* authors_array. The string contains matched authors first, then * authors_array. The string contains matched authors first, then
* non-matched authors (with the two groups separated by '|'). Within * non-matched authors (with the two groups separated by '|' or the custom
* each group, authors are listed in date order. */ * separator defined in the configuration). Within each group, authors are
* listed in date order and separated by ',' or the custom separator defined in
* the configuration. */
static void static void
_resolve_thread_authors_string (notmuch_thread_t *thread) _resolve_thread_authors_string (notmuch_thread_t *thread)
{ {
unsigned int i; unsigned int i;
char *author; char *author;
int first_non_matched_author = 1; int first_non_matched_author = 1;
const char *authors_sep = notmuch_config_get (thread->notmuch,
NOTMUCH_CONFIG_AUTHORS_SEPARATOR);
const char *authors_matched_sep = notmuch_config_get (thread->notmuch,
NOTMUCH_CONFIG_AUTHORS_MATCHED_SEPARATOR);
/* First, list all matched authors in date order. */ /* First, list all matched authors in date order. */
for (i = 0; i < thread->matched_authors_array->len; i++) { for (i = 0; i < thread->matched_authors_array->len; i++) {
author = (char *) g_ptr_array_index (thread->matched_authors_array, i); author = (char *) g_ptr_array_index (thread->matched_authors_array, i);
if (thread->authors) if (thread->authors)
thread->authors = talloc_asprintf (thread, "%s, %s", thread->authors = talloc_asprintf (thread, "%s%s%s",
thread->authors, thread->authors,
authors_sep,
author); author);
else else
thread->authors = author; thread->authors = author;
@ -149,12 +156,14 @@ _resolve_thread_authors_string (notmuch_thread_t *thread)
author, NULL, NULL)) author, NULL, NULL))
continue; continue;
if (first_non_matched_author) { if (first_non_matched_author) {
thread->authors = talloc_asprintf (thread, "%s| %s", thread->authors = talloc_asprintf (thread, "%s%s%s",
thread->authors, thread->authors,
authors_matched_sep,
author); author);
} else { } else {
thread->authors = talloc_asprintf (thread, "%s, %s", thread->authors = talloc_asprintf (thread, "%s%s%s",
thread->authors, thread->authors,
authors_sep,
author); author);
} }

View file

@ -63,6 +63,8 @@ index.as_text=
maildir.synchronize_flags=true maildir.synchronize_flags=true
new.ignore= new.ignore=
new.tags=unread;inbox new.tags=unread;inbox
search.authors_matched_separator=|
search.authors_separator=,
search.exclude_tags= search.exclude_tags=
user.name=Notmuch Test Suite user.name=Notmuch Test Suite
user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org

View file

@ -303,6 +303,8 @@ index.as_text=
maildir.synchronize_flags=true maildir.synchronize_flags=true
new.ignore= new.ignore=
new.tags=unread;inbox new.tags=unread;inbox
search.authors_matched_separator=|
search.authors_separator=,
search.exclude_tags= search.exclude_tags=
user.name=Notmuch Test Suite user.name=Notmuch Test Suite
user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
@ -325,6 +327,8 @@ database.mail_root
database.path database.path
maildir.synchronize_flags maildir.synchronize_flags
new.tags new.tags
search.authors_matched_separator
search.authors_separator
user.name user.name
user.other_email user.other_email
user.primary_email user.primary_email

26
test/T206-author-separator.sh Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
test_description="custom separator for authors"
. $(dirname "$0")/test-lib.sh || exit 1
test_begin_subtest "Adding parent message"
generate_message [body]=findme [id]=new-parent-id [subject]=author-reorder-threadtest '[from]="User <user@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "Added 1 new message to the database."
test_begin_subtest "Adding initial child message"
generate_message [body]=findme "[in-reply-to]=\<new-parent-id\>" [subject]=author-reorder-threadtest '[from]="last name, first name <user1@example.com>"' '[date]="Sat, 01 Jan 2000 12:01:00 -0000"'
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "Added 1 new message to the database."
test_begin_subtest "Adding second child message"
generate_message [body]=findme "[in-reply-to]=\<new-parent-id\>" [subject]=author-reorder-threadtest '[from]="first last <user2@example.com>"' '[date]="Sat, 01 Jan 2000 12:02:00 -0000"'
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "Added 1 new message to the database."
test_begin_subtest "Custom separarator is used"
notmuch config set search.authors_matched_separator "#"
notmuch config set search.authors_separator ";"
output=$(notmuch search from:user | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2000-01-01 [1/3] User#last name, first name;first last; author-reorder-threadtest (inbox unread)"
test_done

View file

@ -441,6 +441,8 @@ cat <<'EOF' >EXPECTED
11: '8000' 11: '8000'
12: 'NULL' 12: 'NULL'
13: '' 13: ''
14: ', '
15: '| '
== stderr == == stderr ==
EOF EOF
unset MAILDIR unset MAILDIR
@ -725,6 +727,8 @@ test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "list by keys (ndlc)" test_begin_subtest "list by keys (ndlc)"
notmuch config set search.exclude_tags "foo;bar;fub" notmuch config set search.exclude_tags "foo;bar;fub"
notmuch config set search.authors_matched_separator "| "
notmuch config set search.authors_separator ", "
notmuch config set new.ignore "sekrit_junk" notmuch config set new.ignore "sekrit_junk"
notmuch config set index.as_text "text/" notmuch config set index.as_text "text/"
cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL% cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
@ -754,6 +758,8 @@ cat <<'EOF' >EXPECTED
11: '8000' 11: '8000'
12: 'NULL' 12: 'NULL'
13: 'text/' 13: 'text/'
14: ', '
15: '| '
== stderr == == stderr ==
EOF EOF
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT
@ -789,6 +795,8 @@ cat <<'EOF' >EXPECTED
11: '8000' 11: '8000'
12: 'NULL' 12: 'NULL'
13: '' 13: ''
14: ', '
15: '| '
== stderr == == stderr ==
EOF EOF
test_expect_equal_file EXPECTED OUTPUT.clean test_expect_equal_file EXPECTED OUTPUT.clean
@ -865,6 +873,8 @@ key with spaces value, with, spaces!
maildir.synchronize_flags true maildir.synchronize_flags true
new.ignore sekrit_junk new.ignore sekrit_junk
new.tags unread;inbox new.tags unread;inbox
search.authors_matched_separator |
search.authors_separator ,
search.exclude_tags foo;bar;fub search.exclude_tags foo;bar;fub
show.extra_headers (null) show.extra_headers (null)
test.key1 testvalue1 test.key1 testvalue1