Re: [PATCH v5] Emacs: Ensure left-to-right display for message headers

2020-08-08 Thread David Bremner
Teemu Likonen  writes:

> In notmuch-show buffer insert invisible U+200E LEFT-TO-RIGHT MARK
> character at the beginning of message header paragraph if the From
> header contains a right-to-left character. This ensures that the
> header paragraph is always rendered in left-to-right mode.
>
> See Emacs Lisp reference manual section "(elisp) Bidirectional
> Display" for more info.

v5 applied to master.

d
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH v2] configure: check for pytest with python -m pytest

2020-08-08 Thread David Bremner
Tomi Ollila  writes:

> On Mon, Aug 03 2020, Đoàn Trần Công Danh wrote:
>
>> On different distro, pytest is suffixed with different patterns.
>>
>> On the other hand, `python3-pytest' could be invoked correctly,
>> via `python3 -m pytest', the latter is used by our tests, now.
>>
>> Switch to `$python -m pytest` to fix address all incompatible naming.
>>
>> Signed-off-by: Đoàn Trần Công Danh 
>
> THis series looks good to me on my terminal, but does not apply 
> to my tree (HEAD commit: 0e4695ab (origin/master) test: regression tests for 
> n_indexopts_{get,set}_decrypt_policy)
>
> Tomi

Yes, I had the the same problem, but I managed to get the patches to
apply with some trickery involving "patch". I'm still not sure what the
issue was, I guess the patches were based on an old tree because the
changes to configure were offset by two lines.

Series is applied to master now.
d
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 01/19] test: use keys with group 'test' in T590-libconfig

2020-08-08 Thread David Bremner
In a future commit we want to interoperate better with glib KeyFiles,
which need groups for all keys.
---
 test/T590-libconfig.sh | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 360e45b0..8c34acf9 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -28,18 +28,18 @@ EOF
 test_begin_subtest "notmuch_database_{set,get}_config"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
 {
-   EXPECT0(notmuch_database_set_config (db, "testkey1", "testvalue1"));
-   EXPECT0(notmuch_database_set_config (db, "testkey2", "testvalue2"));
-   EXPECT0(notmuch_database_get_config (db, "testkey1", ));
-   printf("testkey1 = %s\n", val);
-   EXPECT0(notmuch_database_get_config (db, "testkey2", ));
-   printf("testkey2 = %s\n", val);
+   EXPECT0(notmuch_database_set_config (db, "test.key1", "testvalue1"));
+   EXPECT0(notmuch_database_set_config (db, "test.key2", "testvalue2"));
+   EXPECT0(notmuch_database_get_config (db, "test.key1", ));
+   printf("test.key1 = %s\n", val);
+   EXPECT0(notmuch_database_get_config (db, "test.key2", ));
+   printf("test.key2 = %s\n", val);
 }
 EOF
 cat <<'EOF' >EXPECTED
 == stdout ==
-testkey1 = testvalue1
-testkey2 = testvalue2
+test.key1 = testvalue1
+test.key2 = testvalue2
 == stderr ==
 EOF
 test_expect_equal_file EXPECTED OUTPUT
@@ -93,8 +93,8 @@ EOF
 cat <<'EOF' >EXPECTED
 == stdout ==
 aaabefore beforeval
-testkey1 testvalue1
-testkey2 testvalue2
+test.key1 testvalue1
+test.key2 testvalue2
 zzzafter afterval
 == stderr ==
 EOF
@@ -115,8 +115,8 @@ EOF
 cat <<'EOF' >EXPECTED
 == stdout ==
 aaabefore 1
-testkey1 1
-testkey2 1
+test.key1 1
+test.key2 1
 zzzafter 1
 == stderr ==
 EOF
@@ -126,7 +126,7 @@ test_begin_subtest "notmuch_database_get_config_list: one 
prefix"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
 {
notmuch_config_list_t *list;
-   EXPECT0(notmuch_database_get_config_list (db, "testkey", ));
+   EXPECT0(notmuch_database_get_config_list (db, "test.key", ));
for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next 
(list)) {
   printf("%s %s\n", notmuch_config_list_key (list), 
notmuch_config_list_value(list));
}
@@ -135,8 +135,8 @@ cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
 EOF
 cat <<'EOF' >EXPECTED
 == stdout ==
-testkey1 testvalue1
-testkey2 testvalue2
+test.key1 testvalue1
+test.key2 testvalue2
 == stderr ==
 EOF
 test_expect_equal_file EXPECTED OUTPUT
@@ -152,8 +152,8 @@ cat <<'EOF' >EXPECTED
 #notmuch-dump batch-tag:3 config
 #@ aaabefore beforeval
 #@ key%20with%20spaces value,%20with,%20spaces%21
-#@ testkey1 testvalue1
-#@ testkey2 testvalue2
+#@ test.key1 testvalue1
+#@ test.key2 testvalue2
 #@ zzzafter afterval
 EOF
 test_expect_equal_file EXPECTED OUTPUT
@@ -162,7 +162,7 @@ test_begin_subtest "restore config"
 notmuch dump --include=config >EXPECTED
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
 {
-EXPECT0(notmuch_database_set_config (db, "testkey1", "mutatedvalue"));
+EXPECT0(notmuch_database_set_config (db, "test.key1", "mutatedvalue"));
 }
 EOF
 notmuch restore --include=config 

[PATCH 04/19] WIP: add notmuch_config_get

2020-08-08 Thread David Bremner
this just accesses the cached config data

API is to be decided; maybe we should return a status value.
---
 lib/config.cc  |  6 ++
 lib/notmuch.h  |  2 ++
 test/T590-libconfig.sh | 15 +++
 3 files changed, 23 insertions(+)

diff --git a/lib/config.cc b/lib/config.cc
index 2d4c3801..0a91ec03 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -219,3 +219,9 @@ _notmuch_config_load_from_database (notmuch_database_t 
*notmuch)
 
 return status;
 }
+
+const char *
+notmuch_config_get (notmuch_database_t *notmuch, const char *key) {
+
+return _notmuch_string_map_get (notmuch->config, key);
+}
diff --git a/lib/notmuch.h b/lib/notmuch.h
index e61634a1..777116bb 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2397,6 +2397,8 @@ notmuch_config_list_move_to_next (notmuch_config_list_t 
*config_list);
 void
 notmuch_config_list_destroy (notmuch_config_list_t *config_list);
 
+const char *
+notmuch_config_get (notmuch_database_t *notmuch, const char *key);
 
 /**
  * get the current default indexing options for a given database.
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 8c34acf9..8a4519e9 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -169,4 +169,19 @@ notmuch restore --include=config OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "notmuch_config_get"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+   printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
+   printf("test.key2 = %s\n", notmuch_config_get (db, "test.key2"));
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+test.key1 = testvalue1
+test.key2 = testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 05/19] WIP: add notmuch_config_set

2020-08-08 Thread David Bremner
To be decided: is the write_through paramater a good idea? Should we
simplify the API?
---
 lib/config.cc  | 16 
 lib/notmuch-private.h  |  5 +
 lib/notmuch.h  |  5 +
 lib/string-map.c   | 16 
 test/T590-libconfig.sh | 30 ++
 5 files changed, 72 insertions(+)

diff --git a/lib/config.cc b/lib/config.cc
index 0a91ec03..2cfd2882 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -225,3 +225,19 @@ notmuch_config_get (notmuch_database_t *notmuch, const 
char *key) {
 
 return _notmuch_string_map_get (notmuch->config, key);
 }
+
+notmuch_status_t
+notmuch_config_set (notmuch_database_t *notmuch,
+   const char *key,
+   const char *val,
+   notmuch_bool_t write_through)
+{
+notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+
+_notmuch_string_map_set (notmuch->config, key, val);
+
+if (write_through)
+   status = notmuch_database_set_config (notmuch, key, val);
+
+return status;
+}
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 0f26b371..b545fc46 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -638,6 +638,11 @@ _notmuch_string_map_append (notmuch_string_map_t *map,
const char *key,
const char *value);
 
+void
+_notmuch_string_map_set (notmuch_string_map_t *map,
+   const char *key,
+   const char *value);
+
 const char *
 _notmuch_string_map_get (notmuch_string_map_t *map, const char *key);
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 777116bb..e147d5e6 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2400,6 +2400,11 @@ notmuch_config_list_destroy (notmuch_config_list_t 
*config_list);
 const char *
 notmuch_config_get (notmuch_database_t *notmuch, const char *key);
 
+notmuch_status_t
+notmuch_config_set (notmuch_database_t *notmuch, const char *key,
+   const char *val,
+   notmuch_bool_t write_through);
+
 /**
  * get the current default indexing options for a given database.
  *
diff --git a/lib/string-map.c b/lib/string-map.c
index a88404c7..9774dbe8 100644
--- a/lib/string-map.c
+++ b/lib/string-map.c
@@ -143,6 +143,22 @@ bsearch_first (notmuch_string_pair_t *array, size_t len, 
const char *key, bool e
 
 }
 
+void
+_notmuch_string_map_set (notmuch_string_map_t *map, const char *key, const 
char *val)
+{
+notmuch_string_pair_t *pair;
+
+/* this means that calling string_map_set invalidates iterators */
+_notmuch_string_map_sort (map);
+pair = bsearch_first (map->pairs, map->length, key, true);
+if (! pair)
+   _notmuch_string_map_append (map, key, val);
+else {
+   talloc_free (pair->value);
+   pair->value = talloc_strdup (map->pairs, val);
+}
+}
+
 const char *
 _notmuch_string_map_get (notmuch_string_map_t *map, const char *key)
 {
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 8a4519e9..c2bce4a2 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -184,4 +184,34 @@ test.key2 = testvalue2
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+backup_database
+test_begin_subtest "notmuch_config_set"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+   char *val;
+   printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
+   EXPECT0(notmuch_config_set (db, "test.key1", "overridden", FALSE));
+   printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
+   printf("test.key2 = %s\n", notmuch_config_get (db, "test.key2"));
+   EXPECT0(notmuch_database_get_config (db, "test.key1", ));
+   printf("test.key1 (db) = %s\n", val);
+   EXPECT0(notmuch_config_set (db, "test.key2", "overridden2", TRUE));
+   printf("test.key2 = %s\n", notmuch_config_get (db, "test.key2"));
+   EXPECT0(notmuch_database_get_config (db, "test.key2", ));
+   printf("test.key2 (db) = %s\n", val);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+test.key1 = testvalue1
+test.key1 = overridden
+test.key2 = testvalue2
+test.key1 (db) = testvalue1
+test.key2 = overridden2
+test.key2 (db) = overridden2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_done
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 09/19] lib: factor out feature name related code.

2020-08-08 Thread David Bremner
database.cc is uncomfortably large, and some of the static data
structures do not need to be shared as much as they are.

This is a somewhat small piece to factor out, but it will turn out to
be helpful to further refactoring.
---
 lib/Makefile.local |   3 +-
 lib/database-private.h |  14 +
 lib/database.cc| 116 +
 lib/features.cc| 114 
 4 files changed, 131 insertions(+), 116 deletions(-)
 create mode 100644 lib/features.cc

diff --git a/lib/Makefile.local b/lib/Makefile.local
index 5dc057c0..b95ae216 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -59,7 +59,8 @@ libnotmuch_cxx_srcs = \
$(dir)/config.cc\
$(dir)/regexp-fields.cc \
$(dir)/thread.cc \
-   $(dir)/thread-fp.cc
+   $(dir)/thread-fp.cc \
+   $(dir)/features.cc
 
 libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
 
diff --git a/lib/database-private.h b/lib/database-private.h
index bfeef869..3b365c41 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -32,6 +32,8 @@
 
 #include "notmuch-private.h"
 
+#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+
 #ifdef SILENCE_XAPIAN_DEPRECATION_WARNINGS
 #define XAPIAN_DEPRECATED(D) D
 #endif
@@ -266,4 +268,16 @@ _notmuch_database_find_doc_ids (notmuch_database_t 
*notmuch,
const char *value,
Xapian::PostingIterator *begin,
Xapian::PostingIterator *end);
+
+#define NOTMUCH_DATABASE_VERSION 3
+
+/* features.cc */
+
+_notmuch_features
+_notmuch_database_parse_features (const void *ctx, const char *features, 
unsigned int version,
+ char mode, char **incompat_out);
+
+char *
+_notmuch_database_print_features (const void *ctx, unsigned int features);
+
 #endif
diff --git a/lib/database.cc b/lib/database.cc
index 93fef107..ceba6dd5 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -39,8 +39,6 @@
 
 using namespace std;
 
-#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
-
 typedef struct {
 const char *name;
 const char *prefix;
@@ -458,41 +456,6 @@ _notmuch_database_prefix (notmuch_database_t *notmuch, 
const char *name)
 return NULL;
 }
 
-static const struct {
-/* NOTMUCH_FEATURE_* value. */
-_notmuch_features value;
-/* Feature name as it appears in the database.  This name should
- * be appropriate for displaying to the user if an older version
- * of notmuch doesn't support this feature. */
-const char *name;
-/* Compatibility flags when this feature is declared. */
-const char *flags;
-} feature_names[] = {
-{ NOTMUCH_FEATURE_FILE_TERMS,
-  "multiple paths per message", "rw" },
-{ NOTMUCH_FEATURE_DIRECTORY_DOCS,
-  "relative directory paths", "rw" },
-/* Header values are not required for reading a database because a
- * reader can just refer to the message file. */
-{ NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES,
-  "from/subject/message-ID in database", "w" },
-{ NOTMUCH_FEATURE_BOOL_FOLDER,
-  "exact folder:/path: search", "rw" },
-{ NOTMUCH_FEATURE_GHOSTS,
-  "mail documents for missing messages", "w" },
-/* Knowledge of the index mime-types are not required for reading
- * a database because a reader will just be unable to query
- * them. */
-{ NOTMUCH_FEATURE_INDEXED_MIMETYPES,
-  "indexed MIME types", "w" },
-{ NOTMUCH_FEATURE_LAST_MOD,
-  "modification tracking", "w" },
-/* Existing databases will work fine for all queries not involving
- * 'body:' */
-{ NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
-  "index body and headers separately", "w" },
-};
-
 const char *
 notmuch_status_to_string (notmuch_status_t status)
 {
@@ -817,83 +780,6 @@ _notmuch_database_new_revision (notmuch_database_t 
*notmuch)
 return new_revision;
 }
 
-/* Parse a database features string from the given database version.
- * Returns the feature bit set.
- *
- * For version < 3, this ignores the features string and returns a
- * hard-coded set of features.
- *
- * If there are unrecognized features that are required to open the
- * database in mode (which should be 'r' or 'w'), return a
- * comma-separated list of unrecognized but required features in
- * *incompat_out suitable for presenting to the user.  *incompat_out
- * will be allocated from ctx.
- */
-static _notmuch_features
-_parse_features (const void *ctx, const char *features, unsigned int version,
-char mode, char **incompat_out)
-{
-_notmuch_features res = static_cast<_notmuch_features>(0);
-unsigned int namelen, i;
-size_t llen = 0;
-const char *flags;
-
-/* Prior to database version 3, features were implied by the
- * version number. */
-if (version == 0)
-   return NOTMUCH_FEATURES_V0;
-else if (version == 1)
-   return 

[PATCH 06/19] WIP: initial retrieval of database path from config file

2020-08-08 Thread David Bremner
---
 lib/database.cc | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/lib/database.cc b/lib/database.cc
index 350abb11..2ab9170d 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -935,12 +935,27 @@ notmuch_database_open_with_config (const char 
*database_path,
 void *local = talloc_new (NULL);
 notmuch_database_t *notmuch = NULL;
 char *notmuch_path, *xapian_path, *incompat_features;
+char *configured_database_path = NULL;
 char *message = NULL;
 struct stat st;
 int err;
 unsigned int i, version;
+GKeyFile *key_file = NULL;
 static int initialized = 0;
 
+/* XXX TODO: default locations for NULL case, handle profiles */
+if (config_path != NULL && ! EMPTY_STRING (config_path)) {
+   key_file = g_key_file_new ();
+   if (! g_key_file_load_from_file (key_file, config_path, 
G_KEY_FILE_NONE, NULL)) {
+   status = NOTMUCH_STATUS_FILE_ERROR;
+   goto DONE;
+   }
+   configured_database_path = g_key_file_get_value (key_file, "database", 
"path", NULL);
+}
+
+if (database_path == NULL)
+   database_path = configured_database_path;
+
 if (database_path == NULL) {
message = strdup ("Error: Cannot open a database for a NULL path.\n");
status = NOTMUCH_STATUS_NULL_POINTER;
@@ -1100,6 +1115,9 @@ notmuch_database_open_with_config (const char 
*database_path,
   DONE:
 talloc_free (local);
 
+if (key_file)
+   g_key_file_free (key_file);
+
 if (message) {
if (status_string)
*status_string = message;
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 08/19] WIP: add _notmuch_config_load_from_file

2020-08-08 Thread David Bremner
---
 lib/config.cc  | 34 ++
 lib/database.cc|  4 
 lib/notmuch-private.h  |  3 +++
 test/T590-libconfig.sh | 23 ++-
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/lib/config.cc b/lib/config.cc
index 2cfd2882..f5def3aa 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -241,3 +241,37 @@ notmuch_config_set (notmuch_database_t *notmuch,
 
 return status;
 }
+
+notmuch_status_t
+_notmuch_config_load_from_file (notmuch_database_t *notmuch,
+   GKeyFile *file)
+{
+notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+gchar **groups,**keys, *val;
+
+if (notmuch->config == NULL)
+   notmuch->config = _notmuch_string_map_create (notmuch);
+
+if (unlikely(notmuch->config == NULL)) {
+   status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+   goto DONE;
+}
+
+for (groups = g_key_file_get_groups (file, NULL); *groups; groups++) {
+   for (keys = g_key_file_get_keys (file, *groups, NULL, NULL); *keys; 
keys++) {
+   char *absolute_key = talloc_asprintf(notmuch, "%s.%s", *groups,  
*keys);
+   val = g_key_file_get_value (file, *groups, *keys, NULL);
+   if (! val) {
+   status = NOTMUCH_STATUS_FILE_ERROR;
+   goto DONE;
+   }
+   status = notmuch_config_set (notmuch, absolute_key, val, FALSE);
+   talloc_free (absolute_key);
+   if (status)
+   goto DONE;
+   }
+}
+
+ DONE:
+return status;
+}
diff --git a/lib/database.cc b/lib/database.cc
index 2ab9170d..93fef107 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1104,6 +1104,10 @@ notmuch_database_open_with_config (const char 
*database_path,
 
if (status == NOTMUCH_STATUS_SUCCESS)
status = _notmuch_config_load_from_database (notmuch);
+
+   if (status == NOTMUCH_STATUS_SUCCESS && key_file)
+   status = _notmuch_config_load_from_file (notmuch, key_file);
+
 } catch (const Xapian::Error ) {
IGNORE_RESULT (asprintf (, "A Xapian exception occurred opening 
database: %s\n",
 error.get_msg ().c_str ()));
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index b545fc46..192a0771 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -707,6 +707,9 @@ struct _notmuch_indexopts {
 /* config.cc */
 notmuch_status_t
 _notmuch_config_load_from_database (notmuch_database_t * db);
+
+notmuch_status_t
+_notmuch_config_load_from_file (notmuch_database_t * db, GKeyFile *file);
 NOTMUCH_END_DECLS
 
 #ifdef __cplusplus
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index a34eae0b..a303319d 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -128,7 +128,7 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "notmuch_database_get_config_list: one prefix"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
notmuch_config_list_t *list;
EXPECT0(notmuch_database_get_config_list (db, "test.key", ));
@@ -219,4 +219,25 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+backup_database
+test_begin_subtest "override config from file"
+notmuch config set test.key1 overridden
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
+{
+   printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
+   EXPECT0(notmuch_database_get_config (db, "test.key1", ));
+   printf("test.key1 (db) = %s\n", val);
+   printf("test.key2 = %s\n", notmuch_config_get (db, "test.key2"));
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+test.key1 = overridden
+test.key1 (db) = testvalue1
+test.key2 = testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_done
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 14/19] WIP: add strsplit_len

2020-08-08 Thread David Bremner
---
 util/string-util.c | 23 +++
 util/string-util.h | 14 ++
 2 files changed, 37 insertions(+)

diff --git a/util/string-util.c b/util/string-util.c
index de8430b2..27f8a26b 100644
--- a/util/string-util.c
+++ b/util/string-util.c
@@ -24,6 +24,7 @@
 
 #include 
 #include 
+#include 
 
 char *
 strtok_len (char *s, const char *delim, size_t *len)
@@ -37,6 +38,28 @@ strtok_len (char *s, const char *delim, size_t *len)
 return *len ? s : NULL;
 }
 
+const char *
+strsplit_len (const char *s, char delim, size_t *len)
+{
+bool escaping = false;
+size_t count = 0;
+
+/* Skip initial unescaped delimiters */
+while (*s && *s == delim)
+   s++;
+
+while (s[count] && (escaping || s[count] != delim)) {
+   escaping = (s[count] == '\\');
+   count++;
+}
+
+if (count==0)
+   return NULL;
+
+*len = count;
+return s;
+}
+
 const char *
 strtok_len_c (const char *s, const char *delim, size_t *len)
 {
diff --git a/util/string-util.h b/util/string-util.h
index fb95a740..80647c5f 100644
--- a/util/string-util.h
+++ b/util/string-util.h
@@ -26,6 +26,20 @@ char *strtok_len (char *s, const char *delim, size_t *len);
 /* Const version of strtok_len. */
 const char *strtok_len_c (const char *s, const char *delim, size_t *len);
 
+/* Simplified version of strtok_len, with a single delimiter.
+ * Handles escaping delimiters with \
+ * Usage pattern:
+ *
+ * const char *tok = input;
+ * const char *delim = ';';
+ * size_t tok_len = 0;
+ *
+ * while ((tok = strsplit_len (tok + tok_len, delim, _len)) != NULL) {
+ * // do stuff with string tok of length tok_len
+ * }
+ */
+const char *strsplit_len (const char *s, char delim, size_t *len);
+
 /* Return a talloced string with str sanitized.
  *
  * Whitespace characters (tabs and newlines) are replaced with spaces,
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 03/19] lib: cache configuration information from database

2020-08-08 Thread David Bremner
The main goal is to allow configuration information to be temporarily
overridden by a separate config file.
---
 lib/config.cc  | 25 +
 lib/database-private.h |  3 +++
 lib/database.cc|  4 
 lib/notmuch-private.h  |  3 +++
 4 files changed, 35 insertions(+)

diff --git a/lib/config.cc b/lib/config.cc
index dae0ff0e..2d4c3801 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -194,3 +194,28 @@ notmuch_config_list_destroy (notmuch_config_list_t *list)
 {
 talloc_free (list);
 }
+
+notmuch_status_t
+_notmuch_config_load_from_database (notmuch_database_t *notmuch)
+{
+notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+notmuch_config_list_t *list;
+
+if (notmuch->config == NULL)
+   notmuch->config = _notmuch_string_map_create (notmuch);
+
+if (unlikely(notmuch->config == NULL))
+   return NOTMUCH_STATUS_OUT_OF_MEMORY;
+
+status = notmuch_database_get_config_list (notmuch, "", );
+if (status)
+   return status;
+
+for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next 
(list)) {
+   _notmuch_string_map_append (notmuch->config,
+   notmuch_config_list_key (list),
+   notmuch_config_list_value (list));
+}
+
+return status;
+}
diff --git a/lib/database-private.h b/lib/database-private.h
index 041602cd..bfeef869 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -226,6 +226,9 @@ struct _notmuch_database {
  * here, but at least they are small */
 notmuch_string_map_t *user_prefix;
 notmuch_string_map_t *user_header;
+
+/* Cached and possibly overridden configuration */
+notmuch_string_map_t *config;
 };
 
 /* Prior to database version 3, features were implied by the database
diff --git a/lib/database.cc b/lib/database.cc
index acc686c0..350abb11 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -987,6 +987,7 @@ notmuch_database_open_with_config (const char 
*database_path,
 notmuch = talloc_zero (NULL, notmuch_database_t);
 notmuch->exception_reported = false;
 notmuch->status_string = NULL;
+notmuch->config = NULL;
 notmuch->path = talloc_strdup (notmuch, database_path);
 
 strip_trailing (notmuch->path, '/');
@@ -1085,6 +1086,9 @@ notmuch_database_open_with_config (const char 
*database_path,
}
}
status = _setup_user_query_fields (notmuch);
+
+   if (status == NOTMUCH_STATUS_SUCCESS)
+   status = _notmuch_config_load_from_database (notmuch);
 } catch (const Xapian::Error ) {
IGNORE_RESULT (asprintf (, "A Xapian exception occurred opening 
database: %s\n",
 error.get_msg ().c_str ()));
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 57ec7f72..0f26b371 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -699,6 +699,9 @@ struct _notmuch_indexopts {
 
 #define EMPTY_STRING(s) ((s)[0] == '\0')
 
+/* config.cc */
+notmuch_status_t
+_notmuch_config_load_from_database (notmuch_database_t * db);
 NOTMUCH_END_DECLS
 
 #ifdef __cplusplus
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 12/19] WIP: adding fallbacks for NULL config_path

2020-08-08 Thread David Bremner
still need to test combinations of NULL and non-NULL arguments
---
 lib/open.cc|  95 
 test/T590-libconfig.sh | 138 +
 2 files changed, 209 insertions(+), 24 deletions(-)

diff --git a/lib/open.cc b/lib/open.cc
index 9b7da161..213dc21e 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -37,6 +37,82 @@ notmuch_database_open_verbose (const char *path,
  database, status_string);
 }
 
+static const char *
+_xdg_dir (void *ctx,
+ const char *xdg_root_variable,
+ const char *xdg_prefix,
+ const char *profile_name)
+{
+const char *xdg_root = getenv (xdg_root_variable);
+const char *home = getenv ("HOME");
+
+if (! xdg_root) {
+   if (! home) return NULL;
+
+   xdg_root = talloc_asprintf (ctx,
+   "%s/%s",
+   home,
+   xdg_prefix);
+}
+
+if (! profile_name)
+   profile_name = getenv ("NOTMUCH_PROFILE");
+
+if (! profile_name)
+   profile_name = "default";
+
+return talloc_asprintf (ctx,
+   "%s/notmuch/%s",
+   xdg_root,
+   profile_name);
+}
+
+static notmuch_status_t
+_load_key_file (const char *path,
+   const char *profile,
+   GKeyFile **key_file)
+{
+notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+void *local = talloc_new (NULL);
+
+if (path && EMPTY_STRING (path))
+   goto DONE;
+
+if (! path)
+   path = getenv ("NOTMUCH_CONFIG");
+
+if (! path) {
+   const char *dir = _xdg_dir (local, "XDG_CONFIG_HOME", ".config", 
profile);
+
+   if (dir) {
+   path = talloc_asprintf (local, "%s/config", dir);
+   if (access (path, R_OK) !=0)
+   path = NULL;
+   }
+}
+
+if (! path) {
+   const char *home = getenv ("HOME");
+
+   path = talloc_asprintf (local, "%s/.notmuch-config", home);
+
+   if (! profile)
+   profile = getenv ("NOTMUCH_PROFILE");
+
+   if (profile)
+   path = talloc_asprintf (local, "%s.%s", path, profile);
+}
+
+*key_file = g_key_file_new ();
+if (! g_key_file_load_from_file (*key_file, path, G_KEY_FILE_NONE, NULL)) {
+   status = NOTMUCH_STATUS_FILE_ERROR;
+}
+
+DONE:
+talloc_free (local);
+return status;
+}
+
 notmuch_status_t
 notmuch_database_open_with_config (const char *database_path,
   notmuch_database_mode_t mode,
@@ -49,7 +125,6 @@ notmuch_database_open_with_config (const char *database_path,
 void *local = talloc_new (NULL);
 notmuch_database_t *notmuch = NULL;
 char *notmuch_path, *xapian_path, *incompat_features;
-char *configured_database_path = NULL;
 char *message = NULL;
 struct stat st;
 int err;
@@ -57,18 +132,14 @@ notmuch_database_open_with_config (const char 
*database_path,
 GKeyFile *key_file = NULL;
 static int initialized = 0;
 
-/* XXX TODO: default locations for NULL case, handle profiles */
-if (config_path != NULL && ! EMPTY_STRING (config_path)) {
-   key_file = g_key_file_new ();
-   if (! g_key_file_load_from_file (key_file, config_path, 
G_KEY_FILE_NONE, NULL)) {
-   status = NOTMUCH_STATUS_FILE_ERROR;
-   goto DONE;
-   }
-   configured_database_path = g_key_file_get_value (key_file, "database", 
"path", NULL);
+status = _load_key_file (config_path, profile, _file);
+if (status) {
+   message = strdup ("Error: cannot load config file");
+   goto DONE;
 }
-
-if (database_path == NULL)
-   database_path = configured_database_path;
+   
+if (! database_path && key_file)
+   database_path = g_key_file_get_value (key_file, "database", "path", 
NULL);
 
 if (database_path == NULL) {
message = strdup ("Error: Cannot open a database for a NULL path.\n");
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index a303319d..cc814efa 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -15,14 +15,21 @@ int main (int argc, char** argv)
notmuch_database_t *db;
char *val;
notmuch_status_t stat;
+   char *msg = NULL;
 
-   EXPECT0(notmuch_database_open_with_config (argv[1],
+   for (int i=1; i c_tail
@@ -51,7 +58,7 @@ test_expect_equal_file EXPECTED OUTPUT
 
 
 test_begin_subtest "notmuch_database_get_config_list: empty list"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
 {
notmuch_config_list_t *list;
EXPECT0(notmuch_database_get_config_list (db, "nonexistent", ));
@@ -83,7 +90,7 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "notmuch_database_get_config_list: all pairs"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
+cat c_head - 

[PATCH 10/19] lib: factor out prefix related code to its own file

2020-08-08 Thread David Bremner
Reduce the size of database.cc, and limit the scope of prefix_table,
make sure it's accessed via a well-defined internal API.
---
 lib/Makefile.local |   4 +-
 lib/database-private.h |   7 ++
 lib/database.cc| 204 ++-
 lib/prefix.cc  | 210 +
 4 files changed, 229 insertions(+), 196 deletions(-)
 create mode 100644 lib/prefix.cc

diff --git a/lib/Makefile.local b/lib/Makefile.local
index b95ae216..15e71ef8 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -60,7 +60,9 @@ libnotmuch_cxx_srcs = \
$(dir)/regexp-fields.cc \
$(dir)/thread.cc \
$(dir)/thread-fp.cc \
-   $(dir)/features.cc
+   $(dir)/features.cc  \
+   $(dir)/prefix.cc
+
 
 libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
 
diff --git a/lib/database-private.h b/lib/database-private.h
index 3b365c41..d83cf0d0 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -280,4 +280,11 @@ _notmuch_database_parse_features (const void *ctx, const 
char *features, unsigne
 char *
 _notmuch_database_print_features (const void *ctx, unsigned int features);
 
+/* prefix.cc */
+notmuch_status_t
+_notmuch_database_setup_standard_query_fields (notmuch_database_t *notmuch);
+
+notmuch_status_t
+_notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch);
+
 #endif
diff --git a/lib/database.cc b/lib/database.cc
index ceba6dd5..0620de5a 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -263,80 +263,6 @@ _notmuch_database_mode (notmuch_database_t *notmuch)
  * same thread.
  */
 
-/* With these prefix values we follow the conventions published here:
- *
- * https://xapian.org/docs/omega/termprefixes.html
- *
- * as much as makes sense. Note that I took some liberty in matching
- * the reserved prefix values to notmuch concepts, (for example, 'G'
- * is documented as "newsGroup (or similar entity - e.g. a web forum
- * name)", for which I think the thread is the closest analogue in
- * notmuch. This in spite of the fact that we will eventually be
- * storing mailing-list messages where 'G' for "mailing list name"
- * might be even a closer analogue. I'm treating the single-character
- * prefixes preferentially for core notmuch concepts (which will be
- * nearly universal to all mail messages).
- */
-
-static const
-prefix_t prefix_table[] = {
-/* nameterm prefix flags */
-{ "type",   "T",NOTMUCH_FIELD_NO_FLAGS },
-{ "reference",  "XREFERENCE",   NOTMUCH_FIELD_NO_FLAGS },
-{ "replyto","XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
-{ "directory",  "XDIRECTORY",   NOTMUCH_FIELD_NO_FLAGS },
-{ "file-direntry",  "XFDIRENTRY",   NOTMUCH_FIELD_NO_FLAGS },
-{ "directory-direntry", "XDDIRENTRY",   NOTMUCH_FIELD_NO_FLAGS },
-{ "body",   "", NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC },
-{ "thread", "G",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "tag","K",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "is", "K",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "id", "Q",NOTMUCH_FIELD_EXTERNAL },
-{ "mid","Q",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "path",   "P",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "property",   "XPROPERTY",NOTMUCH_FIELD_EXTERNAL },
-/*
- * Unconditionally add ':' to reduce potential ambiguity with
- * overlapping prefixes and/or terms that start with capital
- * letters. See Xapian document termprefixes.html for related
- * discussion.
- */
-{ "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "date",   NULL,   NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "query",  NULL,   NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "from",   "XFROM",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC |
-  NOTMUCH_FIELD_PROCESSOR },
-{ "to", "XTO",  NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC },
-{ "attachment", "XATTACHMENT",  NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC },
-{ "mimetype",   "XMIMETYPE",NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC },
-{ "subject","XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
-  NOTMUCH_FIELD_PROBABILISTIC |
-  NOTMUCH_FIELD_PROCESSOR },
-};
-
-static void
-_setup_query_field_default 

[PATCH 16/19] test: add regression test for searching with alternate config

2020-08-08 Thread David Bremner
Make sure upcoming changes to config handling do not break command
line specification.
---
 test/T140-excludes.sh | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/test/T140-excludes.sh b/test/T140-excludes.sh
index 0cf69975..cef07095 100755
--- a/test/T140-excludes.sh
+++ b/test/T140-excludes.sh
@@ -39,6 +39,16 @@ deleted_id=$gen_msg_id
 output=$(notmuch search subject:deleted | notmuch_search_sanitize)
 test_expect_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; 
Not deleted (inbox unread)"
 
+test_begin_subtest "Search, exclude \"deleted\" messages; alternate config 
file"
+cp ${NOTMUCH_CONFIG} alt-config
+notmuch config set search.exclude_tags
+notmuch --config=alt-config search subject:deleted | notmuch_search_sanitize > 
OUTPUT
+cp alt-config ${NOTMUCH_CONFIG}
+cat < EXPECTED
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_begin_subtest "Search, exclude \"deleted\" messages from message search"
 output=$(notmuch search --output=messages subject:deleted | 
notmuch_search_sanitize)
 test_expect_equal "$output" "id:$not_deleted_id"
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 19/19] WIP: switch notmuch-show to new config framework

2020-08-08 Thread David Bremner
---
 notmuch-show.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index dd836add..094cd689 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1234,6 +1234,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, 
char *argv[])
 bool entire_thread_set = false;
 bool single_message;
 bool unthreaded = FALSE;
+char *status_string = NULL;
 
 notmuch_opt_desc_t options[] = {
{ .opt_keyword = , .name = "format", .keywords =
@@ -1323,7 +1324,20 @@ notmuch_show_command (notmuch_config_t *config, int 
argc, char *argv[])
fprintf (stderr, "Warning: --include-html only implemented for 
format=text, format=json and format=sexp\n");
 }
 
-query_string = query_string_from_args (config, argc - opt_index, argv + 
opt_index);
+notmuch_database_mode_t mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
+if (params.crypto.decrypt == NOTMUCH_DECRYPT_TRUE)
+   mode = NOTMUCH_DATABASE_MODE_READ_WRITE;
+if (notmuch_database_open_with_config (NULL,
+  mode,
+  _notmuch_config_get_path (config),
+  NULL,
+  ,
+  _string))
+   return EXIT_FAILURE;
+
+notmuch_exit_if_unmatched_db_uuid (notmuch);
+
+query_string = query_string_from_args (notmuch, argc - opt_index, argv + 
opt_index);
 if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return EXIT_FAILURE;
@@ -1334,15 +1348,6 @@ notmuch_show_command (notmuch_config_t *config, int 
argc, char *argv[])
return EXIT_FAILURE;
 }
 
-notmuch_database_mode_t mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
-if (params.crypto.decrypt == NOTMUCH_DECRYPT_TRUE)
-   mode = NOTMUCH_DATABASE_MODE_READ_WRITE;
-if (notmuch_database_open (notmuch_config_get_database_path (config),
-  mode, ))
-   return EXIT_FAILURE;
-
-notmuch_exit_if_unmatched_db_uuid (notmuch);
-
 query = notmuch_query_create (notmuch, query_string);
 if (query == NULL) {
fprintf (stderr, "Out of memory\n");
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 02/19] lib: add stub for notmuch_database_open_with_config

2020-08-08 Thread David Bremner
Initially document the intended API and copy the code from
notmuch_database_open_verbose. Most of the documented functionality is
not there yet.
---
 lib/database.cc |  21 ++--
 lib/notmuch.h   | 138 ++--
 2 files changed, 127 insertions(+), 32 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 75189685..acc686c0 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -918,6 +918,18 @@ notmuch_database_open_verbose (const char *path,
   notmuch_database_mode_t mode,
   notmuch_database_t **database,
   char **status_string)
+{
+return notmuch_database_open_with_config (path, mode, "", NULL,
+ database, status_string);
+}
+
+notmuch_status_t
+notmuch_database_open_with_config (const char *database_path,
+  notmuch_database_mode_t mode,
+  const char *config_path,
+  const char *profile,
+  notmuch_database_t **database,
+  char **status_string)
 {
 notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
 void *local = talloc_new (NULL);
@@ -929,19 +941,19 @@ notmuch_database_open_verbose (const char *path,
 unsigned int i, version;
 static int initialized = 0;
 
-if (path == NULL) {
+if (database_path == NULL) {
message = strdup ("Error: Cannot open a database for a NULL path.\n");
status = NOTMUCH_STATUS_NULL_POINTER;
goto DONE;
 }
 
-if (path[0] != '/') {
+if (database_path[0] != '/') {
message = strdup ("Error: Database path must be absolute.\n");
status = NOTMUCH_STATUS_PATH_ERROR;
goto DONE;
 }
 
-if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) 
{
+if (! (notmuch_path = talloc_asprintf (local, "%s/%s", database_path, 
".notmuch"))) {
message = strdup ("Out of memory\n");
status = NOTMUCH_STATUS_OUT_OF_MEMORY;
goto DONE;
@@ -975,7 +987,7 @@ notmuch_database_open_verbose (const char *path,
 notmuch = talloc_zero (NULL, notmuch_database_t);
 notmuch->exception_reported = false;
 notmuch->status_string = NULL;
-notmuch->path = talloc_strdup (notmuch, path);
+notmuch->path = talloc_strdup (notmuch, database_path);
 
 strip_trailing (notmuch->path, '/');
 
@@ -1101,7 +1113,6 @@ notmuch_database_open_verbose (const char *path,
 
 return status;
 }
-
 notmuch_status_t
 notmuch_database_close (notmuch_database_t *notmuch)
 {
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f3cb0fe2..e61634a1 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -301,52 +301,136 @@ typedef enum {
 } notmuch_database_mode_t;
 
 /**
- * Open an existing notmuch database located at 'path'.
+ * Deprecated alias for notmuch_database_open_with_config with
+ * config_path=error_message=NULL
+ * @deprecated Deprecated as of libnotmuch 5.4 (notmuch 0.32)
+ */
+/* NOTMUCH_DEPRECATED(5, 4) */
+notmuch_status_t
+notmuch_database_open (const char *path,
+  notmuch_database_mode_t mode,
+  notmuch_database_t **database);
+/**
+ * Deprecated alias for notmuch_database_open_with_config with
+ * config_path=NULL
+ *
+ * @deprecated Deprecated as of libnotmuch 5.4 (notmuch 0.32)
+ *
+ */
+/* NOTMUCH_DEPRECATED(5, 4) */
+notmuch_status_t
+notmuch_database_open_verbose (const char *path,
+  notmuch_database_mode_t mode,
+  notmuch_database_t **database,
+  char **error_message);
+
+/**
+ * Open an existing notmuch database located at 'database_path', using
+ * configuration in 'config_path'.
+ *
+ * @param[in]  database_path
+ * @parblock
+ * Path to existing database.
+ *
+ * A notmuch database is a Xapian database containing appropriate
+ * metadata.
  *
  * The database should have been created at some time in the past,
  * (not necessarily by this process), by calling
- * notmuch_database_create with 'path'. By default the database should be
- * opened for reading only. In order to write to the database you need to
- * pass the NOTMUCH_DATABASE_MODE_READ_WRITE mode.
+ * notmuch_database_create.
+ *
+ * If 'database_path' is NULL, use the location specified
+ *
+ * - in the environment variable NOTMUCH_DATABASE, if non-empty
+ *
+ * - by $XDG_DATA_HOME/notmuch/$PROFILE where XDG_DATA_HOME defaults
+ *   to "$HOME/.local/share" and PROFILE as as discussed in
+ *   'profile'
+ *
+ * If 'database_path' is non-NULL, but does not appear to be a Xapian
+ * database, check for a directory '.notmuch/xapian' below
+ * 'database_path' (this is the behavior of
+ * notmuch_database_open_verbose pre-0.32).
+ *
+ * @endparblock
+ * @param[in]  mode
+ * @parblock
+ * Mode to open database. Use one of 

[PATCH 13/19] lib/config: delay setting talloc destructor

2020-08-08 Thread David Bremner
If Xapian has thrown an exception, it is not safe to invoke the
destuctor when freeing the list struct.
---
 lib/config.cc | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index f5def3aa..ca7ac2a8 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -113,7 +113,6 @@ notmuch_database_get_config_list (notmuch_database_t 
*notmuch,
goto DONE;
 }
 
-talloc_set_destructor (list, _notmuch_config_list_destroy);
 list->notmuch = notmuch;
 list->current_key = NULL;
 list->current_val = NULL;
@@ -133,8 +132,15 @@ notmuch_database_get_config_list (notmuch_database_t 
*notmuch,
 *out = list;
 
   DONE:
-if (status && list)
-   talloc_free (list);
+if (status) {
+   if (list) {
+   talloc_free (list);
+   if (status != NOTMUCH_STATUS_XAPIAN_EXCEPTION)
+   _notmuch_config_list_destroy (list);
+   }
+}  else {
+   talloc_set_destructor (list, _notmuch_config_list_destroy);
+}
 
 return status;
 }
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 11/19] lib: factor out notmuch_database_open* related code to own file

2020-08-08 Thread David Bremner
Reduce the size of database.cc, and prepare for adding missing features to
notmuch_database_open_with_config (to match API documentation already
in notmuch.h).
---
 lib/Makefile.local |   3 +-
 lib/database.cc| 255 -
 lib/open.cc| 253 
 3 files changed, 255 insertions(+), 256 deletions(-)
 create mode 100644 lib/open.cc

diff --git a/lib/Makefile.local b/lib/Makefile.local
index 15e71ef8..01d3b34b 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -61,7 +61,8 @@ libnotmuch_cxx_srcs = \
$(dir)/thread.cc \
$(dir)/thread-fp.cc \
$(dir)/features.cc  \
-   $(dir)/prefix.cc
+   $(dir)/prefix.cc\
+   $(dir)/open.cc
 
 
 libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
diff --git a/lib/database.cc b/lib/database.cc
index 0620de5a..0f4e2ff9 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -19,10 +19,6 @@
  */
 
 #include "database-private.h"
-#include "parse-time-vrp.h"
-#include "query-fp.h"
-#include "thread-fp.h"
-#include "regexp-fields.h"
 #include "string-util.h"
 
 #include 
@@ -50,12 +46,6 @@ typedef struct {
 #define STRINGIFY(s) _SUB_STRINGIFY (s)
 #define _SUB_STRINGIFY(s) #s
 
-#if HAVE_XAPIAN_DB_RETRY_LOCK
-#define DB_ACTION (Xapian::DB_CREATE_OR_OPEN | Xapian::DB_RETRY_LOCK)
-#else
-#define DB_ACTION Xapian::DB_CREATE_OR_OPEN
-#endif
-
 #define LOG_XAPIAN_EXCEPTION(message, error) _log_xapian_exception 
(__location__, message, error)
 
 static void
@@ -594,251 +584,6 @@ _notmuch_database_new_revision (notmuch_database_t 
*notmuch)
 return new_revision;
 }
 
-notmuch_status_t
-notmuch_database_open (const char *path,
-  notmuch_database_mode_t mode,
-  notmuch_database_t **database)
-{
-char *status_string = NULL;
-notmuch_status_t status;
-
-status = notmuch_database_open_verbose (path, mode, database,
-   _string);
-
-if (status_string) {
-   fputs (status_string, stderr);
-   free (status_string);
-}
-
-return status;
-}
-
-notmuch_status_t
-notmuch_database_open_verbose (const char *path,
-  notmuch_database_mode_t mode,
-  notmuch_database_t **database,
-  char **status_string)
-{
-return notmuch_database_open_with_config (path, mode, "", NULL,
- database, status_string);
-}
-
-notmuch_status_t
-notmuch_database_open_with_config (const char *database_path,
-  notmuch_database_mode_t mode,
-  const char *config_path,
-  const char *profile,
-  notmuch_database_t **database,
-  char **status_string)
-{
-notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
-void *local = talloc_new (NULL);
-notmuch_database_t *notmuch = NULL;
-char *notmuch_path, *xapian_path, *incompat_features;
-char *configured_database_path = NULL;
-char *message = NULL;
-struct stat st;
-int err;
-unsigned version;
-GKeyFile *key_file = NULL;
-static int initialized = 0;
-
-/* XXX TODO: default locations for NULL case, handle profiles */
-if (config_path != NULL && ! EMPTY_STRING (config_path)) {
-   key_file = g_key_file_new ();
-   if (! g_key_file_load_from_file (key_file, config_path, 
G_KEY_FILE_NONE, NULL)) {
-   status = NOTMUCH_STATUS_FILE_ERROR;
-   goto DONE;
-   }
-   configured_database_path = g_key_file_get_value (key_file, "database", 
"path", NULL);
-}
-
-if (database_path == NULL)
-   database_path = configured_database_path;
-
-if (database_path == NULL) {
-   message = strdup ("Error: Cannot open a database for a NULL path.\n");
-   status = NOTMUCH_STATUS_NULL_POINTER;
-   goto DONE;
-}
-
-if (database_path[0] != '/') {
-   message = strdup ("Error: Database path must be absolute.\n");
-   status = NOTMUCH_STATUS_PATH_ERROR;
-   goto DONE;
-}
-
-if (! (notmuch_path = talloc_asprintf (local, "%s/%s", database_path, 
".notmuch"))) {
-   message = strdup ("Out of memory\n");
-   status = NOTMUCH_STATUS_OUT_OF_MEMORY;
-   goto DONE;
-}
-
-err = stat (notmuch_path, );
-if (err) {
-   IGNORE_RESULT (asprintf (, "Error opening database at %s: %s\n",
-notmuch_path, strerror (errno)));
-   status = NOTMUCH_STATUS_FILE_ERROR;
-   goto DONE;
-}
-
-if (! (xapian_path = talloc_asprintf (local, "%s/%s", notmuch_path, 
"xapian"))) {
-   message = strdup ("Out of memory\n");
-   status = NOTMUCH_STATUS_OUT_OF_MEMORY;
-   goto DONE;
-}
-
-/* Initialize the GLib type system and threads */
-#if ! 

[PATCH 17/19] cli/config: add accessor for config file name

2020-08-08 Thread David Bremner
This is intended for use in temporary code transitioning to the new
configuration system. The name is chosen to avoid cluttering the
notmuch_config_* namespace further with non-library functions.
---
 notmuch-client.h | 2 ++
 notmuch-config.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/notmuch-client.h b/notmuch-client.h
index ebd43e8d..2ec84678 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -332,6 +332,8 @@ void
 notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
const char *list[],
size_t length);
+const char *
+_notmuch_config_get_path (notmuch_config_t *config);
 
 int
 notmuch_run_hook (const char *db_path, const char *hook);
diff --git a/notmuch-config.c b/notmuch-config.c
index 19c2ddb3..c7b05d8c 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -510,6 +510,9 @@ notmuch_config_close (notmuch_config_t *config)
 talloc_free (config);
 }
 
+const char *_notmuch_config_get_path (notmuch_config_t *config) {
+return config->filename;
+}
 /* Save any changes made to the notmuch configuration.
  *
  * Any comments originally in the file will be preserved.
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 15/19] WIP: add config values iterator

2020-08-08 Thread David Bremner
---
 lib/config.cc | 49 +
 lib/notmuch.h | 17 +
 2 files changed, 66 insertions(+)

diff --git a/lib/config.cc b/lib/config.cc
index ca7ac2a8..dd042ab2 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -31,6 +31,11 @@ struct _notmuch_config_list {
 char *current_val;
 };
 
+struct _notmuch_config_values {
+const char *iterator;
+size_t tok_len;
+};
+
 static int
 _notmuch_config_list_destroy (notmuch_config_list_t *list)
 {
@@ -232,6 +237,50 @@ notmuch_config_get (notmuch_database_t *notmuch, const 
char *key) {
 return _notmuch_string_map_get (notmuch->config, key);
 }
 
+notmuch_config_values_t *
+notmuch_config_get_values (notmuch_database_t *notmuch, const char *key)
+{
+notmuch_config_values_t *values;
+
+const char *str;
+str  = _notmuch_string_map_get (notmuch->config, key);
+if (! str)
+   return NULL;
+
+values = talloc (notmuch, notmuch_config_values_t);
+if (unlikely(! values))
+   return NULL;
+
+values->iterator = str;
+values->tok_len = 0;
+return values;
+}
+
+notmuch_bool_t
+notmuch_config_values_valid (notmuch_config_values_t *values) {
+if (! values)
+   return false;
+
+return (values->iterator != NULL);
+}
+
+const char *
+notmuch_config_values_get (notmuch_config_values_t *values) {
+return talloc_strndup (values, values->iterator, values->tok_len);
+}
+
+void
+notmuch_config_values_move_to_next (notmuch_config_values_t *values) {
+values->iterator += values->tok_len;
+values->iterator = strsplit_len (values->iterator, ';', 
&(values->tok_len));
+}
+
+void
+notmuch_config_values_destroy (notmuch_config_values_t *values) {
+talloc_free (values);
+}
+
+
 notmuch_status_t
 notmuch_config_set (notmuch_database_t *notmuch,
const char *key,
diff --git a/lib/notmuch.h b/lib/notmuch.h
index e147d5e6..7ae69265 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -236,6 +236,7 @@ typedef struct _notmuch_tags notmuch_tags_t;
 typedef struct _notmuch_directory notmuch_directory_t;
 typedef struct _notmuch_filenames notmuch_filenames_t;
 typedef struct _notmuch_config_list notmuch_config_list_t;
+typedef struct _notmuch_config_values notmuch_config_values_t;
 typedef struct _notmuch_indexopts notmuch_indexopts_t;
 #endif /* __DOXYGEN__ */
 
@@ -2405,6 +2406,22 @@ notmuch_config_set (notmuch_database_t *notmuch, const 
char *key,
const char *val,
notmuch_bool_t write_through);
 
+
+notmuch_config_values_t *
+notmuch_config_get_values (notmuch_database_t *notmuch, const char *key);
+
+notmuch_bool_t
+notmuch_config_values_valid (notmuch_config_values_t *values);
+
+const char *
+notmuch_config_values_get (notmuch_config_values_t *values);
+
+void
+notmuch_config_values_move_to_next (notmuch_config_values_t *values);
+
+void
+notmuch_config_values_destroy (notmuch_config_values_t *values);
+
 /**
  * get the current default indexing options for a given database.
  *
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 18/19] WIP converting notmuch search to new style config

2020-08-08 Thread David Bremner
this breaks passing the config file as a command line argument, but
that is not currently tested for notmuch-search
---
 notmuch-search.c | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/notmuch-search.c b/notmuch-search.c
index 2805d960..4a5a57c9 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -52,6 +52,7 @@ typedef enum {
 
 typedef struct {
 notmuch_database_t *notmuch;
+void *talloc_ctx;
 int format_sel;
 sprinter_t *format;
 int exclude;
@@ -677,28 +678,32 @@ do_search_tags (const search_context_t *ctx)
 }
 
 static int
-_notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int 
argc, char *argv[])
+_notmuch_search_prepare (search_context_t *ctx,
+const char  *config_path,
+int argc, char *argv[])
 {
 char *query_str;
-unsigned int i;
 char *status_string = NULL;
 
+if (! ctx->talloc_ctx)
+   ctx->talloc_ctx = talloc_new (NULL);
+
 switch (ctx->format_sel) {
 case NOTMUCH_FORMAT_TEXT:
-   ctx->format = sprinter_text_create (config, stdout);
+   ctx->format = sprinter_text_create (ctx->talloc_ctx, stdout);
break;
 case NOTMUCH_FORMAT_TEXT0:
if (ctx->output == OUTPUT_SUMMARY) {
fprintf (stderr, "Error: --format=text0 is not compatible with 
--output=summary.\n");
return EXIT_FAILURE;
}
-   ctx->format = sprinter_text0_create (config, stdout);
+   ctx->format = sprinter_text0_create (ctx->talloc_ctx, stdout);
break;
 case NOTMUCH_FORMAT_JSON:
-   ctx->format = sprinter_json_create (config, stdout);
+   ctx->format = sprinter_json_create (ctx->talloc_ctx, stdout);
break;
 case NOTMUCH_FORMAT_SEXP:
-   ctx->format = sprinter_sexp_create (config, stdout);
+   ctx->format = sprinter_sexp_create (ctx->talloc_ctx, stdout);
break;
 default:
/* this should never happen */
@@ -707,9 +712,12 @@ _notmuch_search_prepare (search_context_t *ctx, 
notmuch_config_t *config, int ar
 
 notmuch_exit_if_unsupported_format ();
 
-if (notmuch_database_open_verbose (
-   notmuch_config_get_database_path (config),
-   NOTMUCH_DATABASE_MODE_READ_ONLY, >notmuch, _string)) {
+if (notmuch_database_open_with_config (
+   NULL,
+   NOTMUCH_DATABASE_MODE_READ_ONLY,
+   config_path,
+   NULL,
+   >notmuch, _string)) {
 
if (status_string) {
fputs (status_string, stderr);
@@ -748,21 +756,20 @@ _notmuch_search_prepare (search_context_t *ctx, 
notmuch_config_t *config, int ar
 }
 
 if (ctx->exclude != NOTMUCH_EXCLUDE_FALSE) {
-   const char **search_exclude_tags;
-   size_t search_exclude_tags_length;
+   notmuch_config_values_t *exclude_tags;
notmuch_status_t status;
 
-   search_exclude_tags = notmuch_config_get_search_exclude_tags (
-   config, _exclude_tags_length);
+   for (exclude_tags = notmuch_config_get_values (ctx->notmuch, 
"search.exclude_tags");
+notmuch_config_values_valid (exclude_tags);
+notmuch_config_values_move_to_next (exclude_tags)) {
 
-   for (i = 0; i < search_exclude_tags_length; i++) {
-   status = notmuch_query_add_tag_exclude (ctx->query, 
search_exclude_tags[i]);
+   status = notmuch_query_add_tag_exclude (ctx->query,
+   notmuch_config_values_get 
(exclude_tags));
if (status && status != NOTMUCH_STATUS_IGNORED) {
print_status_query ("notmuch search", ctx->query, status);
return EXIT_FAILURE;
}
}
-
notmuch_query_set_omit_excluded (ctx->query, ctx->exclude);
 }
 
@@ -845,7 +852,8 @@ notmuch_search_command (notmuch_config_t *config, int argc, 
char *argv[])
return EXIT_FAILURE;
 }
 
-if (_notmuch_search_prepare (ctx, config,
+if (_notmuch_search_prepare (ctx,
+_notmuch_config_get_path (config),
 argc - opt_index, argv + opt_index))
return EXIT_FAILURE;
 
@@ -911,7 +919,8 @@ notmuch_address_command (notmuch_config_t *config, int 
argc, char *argv[])
return EXIT_FAILURE;
 }
 
-if (_notmuch_search_prepare (ctx, config,
+if (_notmuch_search_prepare (ctx,
+_notmuch_config_get_path (config),
 argc - opt_index, argv + opt_index))
return EXIT_FAILURE;
 
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH 07/19] test/libconfig; use n_database_open_with_config

2020-08-08 Thread David Bremner
This allows testing the "override database config with file
functionality". It also requires passing a config file explicitly to
each test program.
---
 test/T590-libconfig.sh | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index c2bce4a2..a34eae0b 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -16,7 +16,12 @@ int main (int argc, char** argv)
char *val;
notmuch_status_t stat;
 
-   EXPECT0(notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, 
));
+   EXPECT0(notmuch_database_open_with_config (argv[1],
+  NOTMUCH_DATABASE_MODE_READ_WRITE,
+  argv[2],
+  NULL,
+  ,
+  NULL));
 
 EOF
 
@@ -26,7 +31,7 @@ cat < c_tail
 EOF
 
 test_begin_subtest "notmuch_database_{set,get}_config"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
EXPECT0(notmuch_database_set_config (db, "test.key1", "testvalue1"));
EXPECT0(notmuch_database_set_config (db, "test.key2", "testvalue2"));
@@ -46,7 +51,7 @@ test_expect_equal_file EXPECTED OUTPUT
 
 
 test_begin_subtest "notmuch_database_get_config_list: empty list"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
notmuch_config_list_t *list;
EXPECT0(notmuch_database_get_config_list (db, "nonexistent", ));
@@ -78,7 +83,7 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "notmuch_database_get_config_list: all pairs"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
notmuch_config_list_t *list;
EXPECT0(notmuch_database_set_config (db, "zzzafter", "afterval"));
@@ -142,7 +147,7 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "dump config"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
 EXPECT0(notmuch_database_set_config (db, "key with spaces", "value, with, 
spaces!"));
 }
@@ -160,7 +165,7 @@ test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "restore config"
 notmuch dump --include=config >EXPECTED
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
 EXPECT0(notmuch_database_set_config (db, "test.key1", "mutatedvalue"));
 }
@@ -170,7 +175,7 @@ notmuch dump --include=config >OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "notmuch_config_get"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
printf("test.key2 = %s\n", notmuch_config_get (db, "test.key2"));
@@ -186,7 +191,7 @@ test_expect_equal_file EXPECTED OUTPUT
 
 backup_database
 test_begin_subtest "notmuch_config_set"
-cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
char *val;
printf("test.key1 = %s\n", notmuch_config_get (db, "test.key1"));
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Initial implementation of merged config

2020-08-08 Thread David Bremner
This follow-up to

 id:20200703134338.3311659-1-da...@tethera.net

is a first draft of a rewrite of the notmuch configuration system. It
aims to remove several annoyances including:

- not being able to have certain configuration items in a plain text config file
- bindings support for configuration being somewhat half-baked
- not supporting XDG_foo

Not all of that promise is realized (or at least tested) in this
initial draft. On the other hand, hopefully a bunch of new tests in
T590-libconfig.sh make the intended API more clear. 

This patch implements the logic for finding config files:

 [PATCH 12/19] WIP: adding fallbacks for NULL config_path

Something similar needs to be done for finding database files.

In the last two commands you can see roughly how much
work is needed to convert to the style of config handling

 [PATCH 18/19] WIP converting notmuch search to new style config
 [PATCH 19/19] WIP: switch notmuch-show to new config framework

The is some awkardness due to converting one subcommand at a time: the
subcommand table uses a fixed function signature and we can't change
that until all the subcommands are updated. So we end up re-opening the config 
file in the modified subcommands.

Some design questions people might like to give feedback on

- the switch in notmuch-search.c to using the string
  "search.exclude_tags" directly to fetch tags.  I'm hoping that a
  reduction in boilerplate compensates for a decrease in "type safety"
  here, compared to the existing
  notmuch_config_get_search_exclude_tags. I'm hoping substantial
  portions of notmuch-config.c can disappear during this rewrite.

- the use of simple keys for the new merged notmuch_config_{get,set}_*
  in lib/config.cc, rather than the section, pair file suggested by the glib 
key_file format. 


My rough plan is to do a release 0.31 with all the cleanup we have
accumulated since 0.30, and target these changes for 0.32
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 32/34] emacs: Do not abuse advice to monkey patch while testing

2020-08-08 Thread Jonas Bernoulli
Use `cl-letf*' instead.
---
 test/T310-emacs.sh | 14 --
 test/test-lib.el   |  8 
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 5f74305d..78ac19a8 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -40,12 +40,14 @@ test_emacs '(notmuch-search "tag:inbox")
 test_expect_equal_file $EXPECTED/notmuch-search-tag-inbox OUTPUT
 
 test_begin_subtest "Incremental parsing of search results"
-test_emacs "(ad-enable-advice 'notmuch-search-process-filter 'around 'pessimal)
-   (ad-activate 'notmuch-search-process-filter)
-   (notmuch-search \"tag:inbox\")
-   (notmuch-test-wait)
-   (ad-disable-advice 'notmuch-search-process-filter 'around 'pessimal)
-   (ad-activate 'notmuch-search-process-filter)
+test_emacs "(cl-letf* (((symbol-function 'orig)
+   (symbol-function 'notmuch-search-process-filter))
+  ((symbol-function 'notmuch-search-process-filter)
+   (lambda (proc string)
+ (cl-loop for char across string
+  do (orig proc (char-to-string char))
+ (notmuch-search \"tag:inbox\")
+ (notmuch-test-wait))
(test-output)"
 test_expect_equal_file $EXPECTED/notmuch-search-tag-inbox OUTPUT
 
diff --git a/test/test-lib.el b/test/test-lib.el
index 044c2da4..ec16c59c 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -97,14 +97,6 @@ (defvar notmuch-hello-refresh-hook-counter -100
 (add-hook 'notmuch-hello-refresh-hook
  (lambda () (cl-incf notmuch-hello-refresh-hook-counter)))
 
-(defadvice notmuch-search-process-filter (around pessimal activate disable)
-  "Feed notmuch-search-process-filter one character at a time."
-  (let ((string (ad-get-arg 1)))
-(cl-loop for char across string
-do (progn
- (ad-set-arg 1 (char-to-string char))
- ad-do-it
-
 (defun notmuch-test-mark-links ()
   "Enclose links in the current buffer with << and >>."
   ;; Links are often created by jit-lock functions
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 34/34] try-emacs-mua: Trim `require' advice for Emacs 25

2020-08-08 Thread Jonas Bernoulli
- Since Emacs 25 comes with `load-prefer-newer' we can remove the
  complicated variant of the advice, which implemented a poorman's
  version of that.

- Since Emacs 25 comes with the new advice mechanism, we can use
  that now for the simple variant of the advice, which just informs
  about the library that is being required.
---
 devel/try-emacs-mua | 26 --
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/devel/try-emacs-mua b/devel/try-emacs-mua
index 041f6216..585d6242 100755
--- a/devel/try-emacs-mua
+++ b/devel/try-emacs-mua
@@ -44,28 +44,10 @@ while looking at: " pdir "emacs\n\nexit emacs (y or n)? ")
try-notmuch-emacs-directory (concat pdir "emacs/")
load-path (cons try-notmuch-emacs-directory load-path)))
 
-;; they say advice doesn't work for primitives (functions from c source)
-;; well, these 'before' advice works for emacs 23.1 - 24.5 (at least)
-;; ...and for our purposes 24.3 is enough (there is no load-prefer-newer there)
-;; note also that the old, "obsolete" defadvice mechanism was used, but that
-;; is the only one available for emacs 23 and 24 up to 24.3.
-
-(if (boundp 'load-prefer-newer)
-(defadvice require (before before-require activate)
-  (unless (featurep feature)
-   (message "require: %s" feature)))
-  ;; else: special require "short-circuit"; after load feature is provided...
-  ;; ... in notmuch sources we always use require and there are no loops
-  (defadvice require (before before-require activate)
-(unless (featurep feature)
-  (message "require: %s" feature)
-  (let ((name (symbol-name feature)))
-   (if (and (string-match "^notmuch" name)
-(file-newer-than-file-p
- (concat try-notmuch-emacs-directory name ".el")
- (concat try-notmuch-emacs-directory name ".elc")))
-   (load (concat try-notmuch-emacs-directory name ".el") nil nil t t)
- )
+(define-advice require
+(:before (feature  _filename _noerror) notmuch)
+  (unless (featurep feature)
+(message "require: %s" feature)))
 
 (insert "Found notmuch emacs client in " try-notmuch-emacs-directory "\n")
 
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 33/34] emacs: Use new advice mechanism do advice mm-shr

2020-08-08 Thread Jonas Bernoulli
Also because we now only support Emacs >= 25,
we can remove the check for Emacs >= 24.
---
 emacs/notmuch-lib.el | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 91c94781..118faf1e 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -661,11 +661,9 @@ (defun notmuch-get-bodypart-text (msg part process-crypto 
 cache)
 ;; first loading gnus-art, which defines it, resulting in a
 ;; void-variable error.  Hence, we advise `mm-shr' to ensure gnus-art
 ;; is loaded.
-(when (>= emacs-major-version 24)
-  (defadvice mm-shr (before load-gnus-arts activate)
-(require 'gnus-art nil t)
-(ad-disable-advice 'mm-shr 'before 'load-gnus-arts)
-(ad-activate 'mm-shr)))
+(define-advice mm-shr (:before (_handle) notmuch--load-gnus-args)
+  "Require `gnus-art' since we use its variables."
+  (require 'gnus-art nil t))
 
 (defun notmuch-mm-display-part-inline (msg part content-type process-crypto)
   "Use the mm-decode/mm-view functions to display a part in the
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 31/34] emacs: Drop old advices that were only need for Emacs 23

2020-08-08 Thread Jonas Bernoulli
---
 emacs/notmuch-mua.el | 14 --
 test/test-lib.el | 17 -
 2 files changed, 31 deletions(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index f321e0c6..dcddca76 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -425,20 +425,6 @@ (defcustom notmuch-always-prompt-for-sender nil
 
 (defvar notmuch-mua-sender-history nil)
 
-;; Workaround: Running `ido-completing-read' in emacs 23.1, 23.2 and 23.3
-;; without some explicit initialization fill freeze the operation.
-;; Hence, we advice `ido-completing-read' to ensure required initialization
-;; is done.
-(when (and (= emacs-major-version 23)
-  (< emacs-minor-version 4))
-  (defadvice ido-completing-read (before notmuch-ido-mode-init activate)
-(ido-init-completion-maps)
-(add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup)
-(add-hook 'choose-completion-string-functions
- 'ido-choose-completion-string)
-(ad-disable-advice 'ido-completing-read 'before 'notmuch-ido-mode-init)
-(ad-activate 'ido-completing-read)))
-
 (defun notmuch-mua-prompt-for-sender ()
   "Prompt for a sender from the user's configured identities."
   (if notmuch-identities
diff --git a/test/test-lib.el b/test/test-lib.el
index 2def7ffe..044c2da4 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -34,23 +34,6 @@ (require 'smtpmail)
 ;; `read' call.
 (setq read-file-name-function (lambda ( _) (read)))
 
-;; Work around a bug in emacs 23.1 and emacs 23.2 which prevents
-;; noninteractive (kill-emacs) from emacsclient.
-(when (and (= emacs-major-version 23) (< emacs-minor-version 3))
-  (defadvice kill-emacs (before disable-yes-or-no-p activate)
-"Disable yes-or-no-p before executing kill-emacs"
-(defun yes-or-no-p (prompt) t)))
-
-;; Emacs bug #2930:
-;; 23.0.92; `accept-process-output' and `sleep-for' do not run sentinels
-;; seems to be present in Emacs 23.1.
-;; Running `list-processes' after `accept-process-output' seems to work
-;; around this problem.
-(when (and (= emacs-major-version 23) (= emacs-minor-version 1))
-  (defadvice accept-process-output (after run-list-processes activate)
-"run list-processes after executing accept-process-output"
-(list-processes)))
-
 (defun notmuch-test-wait ()
   "Wait for process completion."
   (while (get-buffer-process (current-buffer))
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 28/34] emacs: Use cl-incf where appropriate

2020-08-08 Thread Jonas Bernoulli
It's shorter.  That's it pretty much.
---
 emacs/notmuch-hello.el | 2 +-
 emacs/notmuch-lib.el   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 876d8ef1..c127bba9 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -609,7 +609,7 @@ (defun notmuch-hello-insert-buttons (searches)
   name)
(setq column-indent
  (1+ (max 0 (- column-width (length name)))
-   (setq count (1+ count))
+   (cl-incf count)
(when (eq (% count tags-per-line) 0)
  (setq column-indent 0)
  (widget-insert "\n")))
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 11f6858e..91c94781 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -413,7 +413,7 @@ (defun notmuch-subkeymap-help ()
 (i 0))
 (while (< i (length prefix))
   (aset prefix i (aref key i))
-  (setq i (1+ i)))
+  (cl-incf i))
 (let* ((subkeymap (key-binding prefix))
   (ua-keys (where-is-internal 'universal-argument nil t))
   (prefix-string (notmuch-prefix-key-description prefix))
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 30/34] emacs: Remove notmuch-read-char-choice

2020-08-08 Thread Jonas Bernoulli
Just use `read-char-choice', which existed since Emacs 24.1.
---
 emacs/notmuch-compat.el  | 56 
 emacs/notmuch-maildir-fcc.el |  4 +--
 2 files changed, 2 insertions(+), 58 deletions(-)

diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index fafc64f3..3ede6b36 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -40,62 +40,6 @@ (defun notmuch-message--fold-long-headers ()
 (unless (fboundp 'message--fold-long-headers)
   (add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
 
-(if (fboundp 'read-char-choice)
-(defalias 'notmuch-read-char-choice 'read-char-choice)
-  (defun notmuch-read-char-choice (prompt chars  
inhibit-keyboard-quit)
-"Read and return one of CHARS, prompting for PROMPT.
-Any input that is not one of CHARS is ignored.
-
-If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
-keyboard-quit events while waiting for a valid input.
-
-This is an exact copy of this function from emacs 24 for use on
-emacs 23, except with the one emacs 24 only function it calls
-inlined."
-(unless (consp chars)
-  (error "Called `read-char-choice' without valid char choices"))
-(let (char done show-help (helpbuf " *Char Help*"))
-  (let ((cursor-in-echo-area t)
-   (executing-kbd-macro executing-kbd-macro)
-   (esc-flag nil))
-   (save-window-excursion; in case we call help-form-show
- (while (not done)
-   (unless (get-text-property 0 'face prompt)
- (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
-   (setq char (let ((inhibit-quit inhibit-keyboard-quit))
-(read-key prompt)))
-   (and show-help (buffer-live-p (get-buffer helpbuf))
-(kill-buffer helpbuf))
-   (cond
-((not (numberp char)))
-;; If caller has set help-form, that's enough.
-;; They don't explicitly have to add help-char to chars.
-((and help-form
-  (eq char help-char)
-  (setq show-help t)
-  ;; This is an inlined copy of help-form-show as that
-  ;; was introduced in emacs 24 too.
-  (let ((msg (eval help-form)))
-(when (stringp msg)
-  (with-output-to-temp-buffer " *Char Help*"
-(princ msg))
-((memq char chars)
- (setq done t))
-((and executing-kbd-macro (= char -1))
- ;; read-event returns -1 if we are in a kbd macro and
- ;; there are no more events in the macro.  Attempt to
- ;; get an event interactively.
- (setq executing-kbd-macro nil))
-((not inhibit-keyboard-quit)
- (cond
-  ((and (null esc-flag) (eq char ?\e))
-   (setq esc-flag t))
-  ((memq char '(?\C-g ?\e))
-   (keyboard-quit
-  ;; Display the question with the answer.  But without 
cursor-in-echo-area.
-  (message "%s%s" prompt (char-to-string char))
-  char)))
-
 ;; End of compatibility functions
 
 (provide 'notmuch-compat)
diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el
index aa07b26a..a9103a20 100644
--- a/emacs/notmuch-maildir-fcc.el
+++ b/emacs/notmuch-maildir-fcc.el
@@ -242,7 +242,7 @@ (defun notmuch-maildir-fcc-with-notmuch-insert (fcc-header 
 create)
   ;; typo, or just the user want a new folder, let the user decide
   ;; how to deal with it.
   (error
-   (let ((response (notmuch-read-char-choice "Insert failed: \
+   (let ((response (read-char-choice "Insert failed: \
 \(r)etry, (c)reate folder, (i)gnore, or (e)dit the header? " '(?r ?c ?i ?e
 (cl-case response
   (?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header))
@@ -327,7 +327,7 @@ (defun notmuch-maildir-fcc-file-fcc (fcc-header)
 ;; fix it in some way.
 (let* ((prompt (format "Fcc %s is not a maildir: \
 \(r)etry, (c)reate folder, (i)gnore, or (e)dit the header? " fcc-header))
-  (response (notmuch-read-char-choice prompt '(?r ?c ?i ?e
+  (response (read-char-choice prompt '(?r ?c ?i ?e
   (cl-case response
(?r (notmuch-maildir-fcc-file-fcc fcc-header))
(?c (if (file-writable-p fcc-header)
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 26/34] NEWS: Add stub for 0.31

2020-08-08 Thread Jonas Bernoulli
---
 NEWS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/NEWS b/NEWS
index 9f0db031..3790204b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+Notmuch 0.31 (UNRELEASED)
+=
+
 Notmuch 0.30 (2020-07-10)
 =
 
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 27/34] NEWS: At least Emacs 25.1 is required now

2020-08-08 Thread Jonas Bernoulli
Some backward incompatible changes follow in the next few commits
and going forward contributors don't have to worry about Emacs 24
at all anymore.
---
 NEWS  | 5 +
 emacs/notmuch-pkg.el.tmpl | 3 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 3790204b..4160e39c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 Notmuch 0.31 (UNRELEASED)
 =
 
+Emacs
+-
+
+The minimum supported major version of GNU Emacs is now 25.1.
+
 Notmuch 0.30 (2020-07-10)
 =
 
diff --git a/emacs/notmuch-pkg.el.tmpl b/emacs/notmuch-pkg.el.tmpl
index 9d0999c1..85c631de 100644
--- a/emacs/notmuch-pkg.el.tmpl
+++ b/emacs/notmuch-pkg.el.tmpl
@@ -3,5 +3,4 @@
   "notmuch"
   %VERSION%
   "Emacs based front-end (MUA) for notmuch"
-  '((emacs "24")
-(cl-lib "0.6.1")))
+  '((emacs "25.1")))
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 29/34] emacs: Remove notmuch-setq-local

2020-08-08 Thread Jonas Bernoulli
Just use setq-local, which existed since Emacs 24.3.
---
 emacs/notmuch-address.el | 4 ++--
 emacs/notmuch-company.el | 2 +-
 emacs/notmuch-compat.el  | 8 
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index cd0ffb67..8a6d299c 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -172,11 +172,11 @@ (defun notmuch-address-toggle-internal-completion ()
   (interactive)
   (if (local-variable-p 'notmuch-address-command)
   (kill-local-variable 'notmuch-address-command)
-(notmuch-setq-local notmuch-address-command 'internal))
+(setq-local notmuch-address-command 'internal))
   (when (boundp 'company-idle-delay)
 (if (local-variable-p 'company-idle-delay)
(kill-local-variable 'company-idle-delay)
-  (notmuch-setq-local company-idle-delay nil
+  (setq-local company-idle-delay nil
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index 24e7446c..9ee8ceca 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -62,7 +62,7 @@ (defun notmuch-company-setup ()
   ;; internal completion) can still be accessed via standard company
   ;; functions, e.g., company-complete.
   (unless (eq notmuch-address-command 'internal)
-(notmuch-setq-local company-idle-delay nil)))
+(setq-local company-idle-delay nil)))
 
 ;;;###autoload
 (defun notmuch-company (command  arg  _ignore)
diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index 370cafa1..fafc64f3 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -40,14 +40,6 @@ (defun notmuch-message--fold-long-headers ()
 (unless (fboundp 'message--fold-long-headers)
   (add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
 
-(if (fboundp 'setq-local)
-(defalias 'notmuch-setq-local 'setq-local)
-  (defmacro notmuch-setq-local (var val)
-"Set variable VAR to value VAL in current buffer.
-
-Backport of setq-local for emacs without setq-local (pre 24.3)."
-`(set (make-local-variable ',var) ,val)))
-
 (if (fboundp 'read-char-choice)
 (defalias 'notmuch-read-char-choice 'read-char-choice)
   (defun notmuch-read-char-choice (prompt chars  
inhibit-keyboard-quit)
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 19/34] emacs: Increase consistency of library headers

2020-08-08 Thread Jonas Bernoulli
---
 emacs/make-deps.el|  2 +-
 emacs/notmuch-company.el  | 37 +++--
 emacs/notmuch-compat.el   | 22 +---
 emacs/notmuch-crypto.el   |  2 +-
 emacs/notmuch-lib.el  |  2 --
 emacs/notmuch-maildir-fcc.el  | 39 +--
 emacs/notmuch-print.el|  2 +-
 emacs/notmuch-show.el |  2 +-
 emacs/notmuch-tag.el  |  3 +--
 emacs/notmuch-tree.el |  2 +-
 emacs/notmuch-version.el.tmpl |  3 +--
 emacs/notmuch.el  |  4 ++--
 12 files changed, 68 insertions(+), 52 deletions(-)

diff --git a/emacs/make-deps.el b/emacs/make-deps.el
index 91f4ef3d..a7699fb1 100644
--- a/emacs/make-deps.el
+++ b/emacs/make-deps.el
@@ -1,4 +1,4 @@
-;; make-deps.el --- compute make dependencies for Elisp sources
+;;; make-deps.el --- compute make dependencies for Elisp sources
 ;;
 ;; Copyright © Austin Clements
 ;;
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index c1f3594e..24e7446c 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -1,29 +1,34 @@
 ;;; notmuch-company.el --- Mail address completion for notmuch via 
company-mode  -*- lexical-binding: t -*-
-
-;; Authors: Trevor Jim 
-;; Michal Sojka 
 ;;
-;; Keywords: mail, completion
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
+;; Copyright © Trevor Jim
+;; Copyright © Michal Sojka
+;;
+;; This file is part of Notmuch.
+;;
+;; Notmuch is free software: you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
 ;; the Free Software Foundation, either version 3 of the License, or
 ;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
+;;
+;; Notmuch is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
 ;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see .
+;; along with Notmuch.  If not, see .
+;;
+;; Authors: Trevor Jim 
+;; Michal Sojka 
+;; Keywords: mail, completion
 
 ;;; Commentary:
 
-;; To enable this, install company mode (https://company-mode.github.io/)
+;; Mail address completion for notmuch via company-mode.  To enable
+;; this, install company mode from .
 ;;
 ;; NB company-minimum-prefix-length defaults to 3 so you don't get
-;; completion unless you type 3 characters
+;; completion unless you type 3 characters.
 
 ;;; Code:
 
diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index 3340918f..9d82a729 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -1,10 +1,26 @@
-;; Compatibility functions for earlier versions of emacs
-
+;;; notmuch-compat.el --- compatibility functions for earlier versions of emacs
+;;
 ;; The functions in this file are copied from more modern versions of
 ;; emacs and are Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2017
 ;; Free Software Foundation, Inc.
+;;
+;; This file is part of Notmuch.
+;;
+;; Notmuch is free software: you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Notmuch is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Notmuch.  If not, see .
+
+;;; Code:
 
-
 ;; emacs master has a bugfix for folding long headers when sending
 ;; messages. Include the fix for earlier versions of emacs. To avoid
 ;; interfering with gnus we only run the hook when called from
diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
index e6bf8339..6df1dd64 100644
--- a/emacs/notmuch-crypto.el
+++ b/emacs/notmuch-crypto.el
@@ -1,4 +1,4 @@
-;;; notmuch-crypto.el --- functions for handling display of cryptographic 
metadata.
+;;; notmuch-crypto.el --- functions for handling display of cryptographic 
metadata
 ;;
 ;; Copyright © Jameson Rollins
 ;;
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 05d86ea1..fded2d7b 100644
--- a/emacs/notmuch-lib.el
+++ 

[PATCH v3 24/34] emacs: Provide 'rstdoc' feature at end of file

2020-08-08 Thread Jonas Bernoulli
Features should nearly always be provided at the very end of their
libraries.  This feature isn't one of the rare exceptions.
---
 emacs/rstdoc.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/rstdoc.el b/emacs/rstdoc.el
index 41390bbe..63fa2794 100644
--- a/emacs/rstdoc.el
+++ b/emacs/rstdoc.el
@@ -32,8 +32,6 @@
 
 ;;; Code:
 
-(provide 'rstdoc)
-
 (defun rstdoc-batch-extract ()
   "Extract docstrings to and from the files on the command line."
   (apply #'rstdoc-extract command-line-args-left))
@@ -82,4 +80,6 @@ (defun rstdoc--rst-quote-string (str)
(replace-match (cdr pair
 (buffer-substring (point-min) (point-max
 
+(provide 'rstdoc)
+
 ;;; rstdoc.el ends here
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 25/34] emacs: Add end-of-file line to libraries that lack it

2020-08-08 Thread Jonas Bernoulli
---
 emacs/notmuch-compat.el | 2 ++
 emacs/notmuch-tag.el| 2 ++
 2 files changed, 4 insertions(+)

diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index 9d82a729..370cafa1 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -107,3 +107,5 @@ (if (fboundp 'read-char-choice)
 ;; End of compatibility functions
 
 (provide 'notmuch-compat)
+
+;;; notmuch-compat.el ends here
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index c7a1e322..5d4a6865 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -550,3 +550,5 @@ (defun notmuch-tag-jump (reverse)
 ;;
 
 (provide 'notmuch-tag)
+
+;;; notmuch-tag.el ends here
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 20/34] Fix typos

2020-08-08 Thread Jonas Bernoulli
---
 NEWS   |  2 +-
 bindings/python-cffi/notmuch2/__init__.py  |  2 +-
 bindings/python-cffi/notmuch2/_base.py |  6 +++---
 bindings/python-cffi/notmuch2/_database.py |  8 
 bindings/python-cffi/notmuch2/_message.py  |  4 ++--
 bindings/python-cffi/notmuch2/_tags.py |  8 
 bindings/python-cffi/tests/conftest.py |  2 +-
 bindings/python/notmuch/database.py| 12 ++--
 bindings/python/notmuch/query.py   |  2 +-
 emacs/notmuch-crypto.el|  2 +-
 emacs/notmuch-lib.el   |  2 +-
 emacs/notmuch-mua.el   |  2 +-
 lib/notmuch.h  |  4 ++--
 tag-util.c |  2 +-
 tag-util.h |  2 +-
 test/T610-message-property.sh  |  2 +-
 test/T710-message-id.sh|  2 +-
 test/random-corpus.c   |  2 +-
 test/test-lib.el   |  2 +-
 19 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/NEWS b/NEWS
index 0d8b930f..9f0db031 100644
--- a/NEWS
+++ b/NEWS
@@ -116,7 +116,7 @@ information about cryptographic protections for the Subject 
header.
 Emacs
 -
 
-Optionally check for missing attachements in outgoing messages (see
+Optionally check for missing attachments in outgoing messages (see
 function `notmuch-mua-attachment-check`).
 
 Bind `B` to browse URLs in current message.
diff --git a/bindings/python-cffi/notmuch2/__init__.py 
b/bindings/python-cffi/notmuch2/__init__.py
index 613317e0..f281edc1 100644
--- a/bindings/python-cffi/notmuch2/__init__.py
+++ b/bindings/python-cffi/notmuch2/__init__.py
@@ -10,7 +10,7 @@ should consider their signatures implementation details.
 Errors
 ==
 
-All errors occuring due to errors from the underlying notmuch database
+All errors occurring due to errors from the underlying notmuch database
 are subclasses of the :exc:`NotmuchError`.  Due to memory management
 it is possible to try and use an object after it has been freed.  In
 this case a :exc:`ObjectDestroyedError` will be raised.
diff --git a/bindings/python-cffi/notmuch2/_base.py 
b/bindings/python-cffi/notmuch2/_base.py
index 31258149..1cf03c88 100644
--- a/bindings/python-cffi/notmuch2/_base.py
+++ b/bindings/python-cffi/notmuch2/_base.py
@@ -29,7 +29,7 @@ class NotmuchObject(metaclass=abc.ABCMeta):
 However during some peculiar situations, e.g. interpreter
 shutdown, it is possible for the :meth:`__del__` method to have
 been called, whele there are still references to an object.  This
-could result in child objects asking their memeory to be freed
+could result in child objects asking their memory to be freed
 after the parent has already freed the memory, making things
 rather unhappy as double frees are not taken lightly in C.  To
 handle this case all objects need to follow the same protocol to
@@ -73,7 +73,7 @@ class NotmuchObject(metaclass=abc.ABCMeta):
 def _destroy(self):
 """Destroy the object, freeing all memory.
 
-This method needs to destory the object on the
+This method needs to destroy the object on the
 libnotmuch-level.  It must ensure it's not been destroyed by
 it's parent object yet before doing so.  It also must be
 idempotent.
@@ -134,7 +134,7 @@ class BinString(str):
 
 Most data in libnotmuch should be valid ASCII or valid UTF-8.
 However since it is a C library these are represented as
-bytestrings intead which means on an API level we can not
+bytestrings instead which means on an API level we can not
 guarantee that decoding this to UTF-8 will both succeed and be
 lossless.  This string type converts bytes to unicode in a lossy
 way, but also makes the raw bytes available.
diff --git a/bindings/python-cffi/notmuch2/_database.py 
b/bindings/python-cffi/notmuch2/_database.py
index 7db5a7f8..5ab0f20a 100644
--- a/bindings/python-cffi/notmuch2/_database.py
+++ b/bindings/python-cffi/notmuch2/_database.py
@@ -422,7 +422,7 @@ class Database(base.NotmuchObject):
of it as ``dup = db.remove_message(name); if dup: ...``.
 :rtype: bool
 
-:raises XapianError: A Xapian exception ocurred.
+:raises XapianError: A Xapian exception occurred.
 :raises ReadOnlyDatabaseError: The database is opened in
READ_ONLY mode.
 :raises UpgradeRequiredError: The database must be upgraded
@@ -458,7 +458,7 @@ class Database(base.NotmuchObject):
 :raises LookupError: If no message was found.
 :raises OutOfMemoryError: When there is no memory to allocate
the message instance.
-:raises XapianError: A Xapian exception ocurred.
+:raises XapianError: A Xapian exception occurred.
 :raises ObjectDestroyedError: if used after destroyed.
 """
 msg_pp = capi.ffi.new('notmuch_message_t **')
@@ 

[PATCH v3 18/34] emacs: Various cosmetic changes

2020-08-08 Thread Jonas Bernoulli
---
 emacs/make-deps.el  |  3 ++-
 emacs/notmuch-lib.el|  8 +++-
 emacs/notmuch-parser.el |  9 +++--
 emacs/notmuch-show.el   | 18 +++---
 emacs/rstdoc.el |  9 -
 test/test-lib.el| 31 +++
 6 files changed, 34 insertions(+), 44 deletions(-)

diff --git a/emacs/make-deps.el b/emacs/make-deps.el
index dcac319c..91f4ef3d 100644
--- a/emacs/make-deps.el
+++ b/emacs/make-deps.el
@@ -36,7 +36,8 @@ (defun make-deps ( dir)
 This prints make dependencies to `standard-output' based on the
 top-level `require' expressions in the current buffer.  Paths in
 rules will be given relative to DIR, or `default-directory'."
-  (setq dir (or dir default-directory))
+  (unless dir
+(setq dir default-directory))
   (save-excursion
 (goto-char (point-min))
 (condition-case nil
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index b86c44ed..05d86ea1 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -53,9 +53,8 @@ (defgroup notmuch-show nil
 
 (defgroup notmuch-send nil
   "Sending messages from Notmuch."
-  :group 'notmuch)
-
-(custom-add-to-group 'notmuch-send 'message 'custom-group)
+  :group 'notmuch
+  :group 'message)
 
 (defgroup notmuch-tag nil
   "Tags and tagging in Notmuch."
@@ -782,8 +781,7 @@ (defun notmuch-logged-error (msg  extra)
(insert extra)
(unless (bolp)
  (newline)
-  (error "%s"
-(concat msg (and extra " (see *Notmuch errors* for more details)"
+  (error "%s%s" msg (if extra " (see *Notmuch errors* for more details)" "")))
 
 (defun notmuch-check-async-exit-status (proc msg  command err)
   "If PROC exited abnormally, pop up an error buffer and signal an error.
diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
index fbcfc2ef..3aa5bd8f 100644
--- a/emacs/notmuch-parser.el
+++ b/emacs/notmuch-parser.el
@@ -39,12 +39,9 @@ (defun notmuch-sexp-create-parser ()
 buffer.  Hence, the caller is allowed to delete any data before
 point and may resynchronize after an error by moving point."
   (vector 'notmuch-sexp-parser
- ;; List depth
- 0
- ;; Partial parse position marker
- nil
- ;; Partial parse state
- nil))
+ 0 ; List depth
+ nil   ; Partial parse position marker
+ nil)) ; Partial parse state
 
 (defmacro notmuch-sexp--depth (sp) `(aref ,sp 1))
 (defmacro notmuch-sexp--partial-pos (sp)   `(aref ,sp 2))
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 015edb0c..5640346f 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -499,21 +499,17 @@ (define-button-type 'notmuch-show-part-button-type
 
 (defun notmuch-show-insert-part-header (nth content-type declared-type
 name comment)
-  (let ((button)
-   (base-label (concat (and name (concat name ": "))
+  (let ((base-label (concat (and name (concat name ": "))
declared-type
(and (not (string-equal declared-type content-type))
 (concat " (as " content-type ")"))
comment)))
-(setq button
- (insert-button
-  (concat "[ " base-label " ]")
-  :base-label base-label
-  :type 'notmuch-show-part-button-type
-  :notmuch-part-hidden nil))
-(insert "\n")
-;; return button
-button))
+(prog1 (insert-button
+   (concat "[ " base-label " ]")
+   :base-label base-label
+   :type 'notmuch-show-part-button-type
+   :notmuch-part-hidden nil)
+  (insert "\n"
 
 (defun notmuch-show-toggle-part-invisibility ( button)
   (interactive)
diff --git a/emacs/rstdoc.el b/emacs/rstdoc.el
index 92a337c8..41390bbe 100644
--- a/emacs/rstdoc.el
+++ b/emacs/rstdoc.el
@@ -24,7 +24,6 @@
 ;;
 
 ;;; Commentary:
-;;
 
 ;; Rstdoc provides a facility to extract all of the docstrings defined in
 ;; an elisp source file. Usage:
@@ -68,10 +67,10 @@ (defun rstdoc--insert-docstring (symbol docstring)
   (insert "\n"))
 
 (defvar rst--escape-alist
-  '( ("='" . "'")
- ("\\([^\\]\\)'" . "\\1`")
- ("^[[:space:]\t]*$" . "|br|")
- ("^[[:space:]\t]" . "|indent| "))
+  '(("='" . "'")
+("\\([^\\]\\)'" . "\\1`")
+("^[[:space:]\t]*$" . "|br|")
+("^[[:space:]\t]" . "|indent| "))
   "List of (regex . replacement) pairs.")
 
 (defun rstdoc--rst-quote-string (str)
diff --git a/test/test-lib.el b/test/test-lib.el
index 6a39bbe2..e9e7c379 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -154,22 +154,21 @@ (defun notmuch-test-report-unexpected (output expected)
 
 (defun notmuch-test-expect-equal (output expected)
   "Compare OUTPUT with EXPECTED. Report any discrepencies."
-  (if (equal output expected)
-  t
-(cond
- ((and (listp output)
-  (listp expected))
-  ;; Reporting the difference between two lists is done by
-  

[PATCH v3 22/34] test: Fix indentation

2020-08-08 Thread Jonas Bernoulli
Fix it to consistently match the style we have configured in
".dir-locals.el".
---
 test/test-lib.sh | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 527c9e8b..c23a0d20 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -136,16 +136,16 @@ add_gpgsm_home ()
 at_exit_function _gnupg_exit
 mkdir -p -m 0700 "$GNUPGHOME"
 openssl pkcs12 -export -passout pass: -inkey 
"$NOTMUCH_SRCDIR/test/smime/key+cert.pem" \
-< "$NOTMUCH_SRCDIR/test/smime/test.crt" | \
-gpgsm --batch --no-tty --no-common-certs-import 
--pinentry-mode=loopback --passphrase-fd 3 \
-  --disable-dirmngr --import  >"$GNUPGHOME"/import.log 2>&1 3<<<''
+   < "$NOTMUCH_SRCDIR/test/smime/test.crt" | \
+   gpgsm --batch --no-tty --no-common-certs-import 
--pinentry-mode=loopback --passphrase-fd 3 \
+ --disable-dirmngr --import  >"$GNUPGHOME"/import.log 2>&1 3<<<''
 fpr=$(gpgsm --batch --list-key test_su...@notmuchmail.org | sed -n 
's/.*fingerprint: //p')
 echo "$fpr S relax" >> "$GNUPGHOME/trustlist.txt"
 gpgsm --quiet --batch --no-tty --no-common-certs-import --disable-dirmngr 
--import < $NOTMUCH_SRCDIR/test/smime/ca.crt
 echo "4D:E0:FF:63:C0:E9:EC:01:29:11:C8:7A:EE:DA:3A:9A:7F:6E:C1:0D S" >> 
"$GNUPGHOME/trustlist.txt"
 printf '%s::1\n' include-certs disable-crl-checks | gpgconf --output 
/dev/null --change-options gpgsm
 gpgsm --batch --no-tty --no-common-certs-import --pinentry-mode=loopback 
--passphrase-fd 3 \
-  --disable-dirmngr --import "$NOTMUCH_SRCDIR/test/smime/bob.p12" 
>>"$GNUPGHOME"/import.log 2>&1 3<<<''
+ --disable-dirmngr --import "$NOTMUCH_SRCDIR/test/smime/bob.p12" 
>>"$GNUPGHOME"/import.log 2>&1 3<<<''
 test_debug "cat $GNUPGHOME/import.log"
 }
 
@@ -394,8 +394,8 @@ emacs_fcc_message ()
 local nmn_args subject body
 nmn_args=''
 while [[ "$1" =~ ^-- ]]; do
-nmn_args="$nmn_args $1"
-shift
+   nmn_args="$nmn_args $1"
+   shift
 done
 subject="$1"
 body="$2"
@@ -405,7 +405,7 @@ emacs_fcc_message ()
 
 test_emacs \
"(let ((message-send-mail-function (lambda () t))
-   (mail-host-address \"example.com\"))
+  (mail-host-address \"example.com\"))
   (notmuch-mua-mail)
   (message-goto-to)
   (insert \"test_su...@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 
-\")
@@ -524,9 +524,9 @@ test_expect_equal_json () {
 # override Python's stdio encoding defaults.
 script='import json, sys; json.dump(json.load(sys.stdin), sys.stdout, 
sort_keys=True, indent=4)'
 output=$(echo "$1" | PYTHONIOENCODING=utf-8 $NOTMUCH_PYTHON -c "$script" \
-|| echo "$1")
+   || echo "$1")
 expected=$(echo "$2" | PYTHONIOENCODING=utf-8 $NOTMUCH_PYTHON -c "$script" 
\
-|| echo "$2")
+   || echo "$2")
 shift 2
 test_expect_equal "$output" "$expected" "$@"
 }
@@ -540,15 +540,15 @@ test_valid_json () {
 # Sort the top-level list of JSON data from stdin.
 test_sort_json () {
 PYTHONIOENCODING=utf-8 $NOTMUCH_PYTHON -c \
-"import sys, json; json.dump(sorted(json.load(sys.stdin)),sys.stdout)"
+   "import sys, json; json.dump(sorted(json.load(sys.stdin)),sys.stdout)"
 }
 
 # test for json objects:
 # read the source of test/json_check_nodes.py (or the output when
 # invoking it without arguments) for an explanation of the syntax.
 test_json_nodes () {
-local output
-exec 1>&6 2>&7 # Restore stdout and stderr
+   local output
+   exec 1>&6 2>&7  # Restore stdout and stderr
if [ -z "$inside_subtest" ]; then
error "bug in the test script: test_json_eval without 
test_begin_subtest"
fi
@@ -662,7 +662,7 @@ notmuch_json_show_sanitize ()
-e 's|"filename": "signature.asc",||g' \
-e 's|"filename": \["/[^"]*"\],|"filename": \["Y"\],|g' \
-e 's|"timestamp": 97...|"timestamp": 42|g' \
--e 's|"content-length": [1-9][0-9]*|"content-length": "NONZERO"|g'
+   -e 's|"content-length": [1-9][0-9]*|"content-length": "NONZERO"|g'
 }
 
 notmuch_emacs_error_sanitize ()
@@ -673,7 +673,7 @@ notmuch_emacs_error_sanitize ()
 for file in "$@"; do
echo "=== $file ==="
cat "$file"
-done | sed  \
+done | sed \
-e 's/^\[.*\]$/[XXX]/' \
-e "s|^\(command: \)\{0,1\}/.*/$command|\1YYY/$command|"
 }
@@ -929,8 +929,8 @@ test_expect_code () {
 # but is a prefix that can be used in the test script, like:
 #
 #  test_expect_success 'complain and die' '
-#   do something &&
-#   do something else &&
+#  do something &&
+#  do something else &&
 #  test_must_fail git checkout ../outerspace
 #  '
 #
@@ -1020,8 +1020,8 @@ export NOTMUCH_CONFIG=$NOTMUCH_CONFIG
 
 # Here's what we are using here:
 #
-# --quick  Use 

[PATCH v3 12/34] emacs: No longer define notmuch-hello-mode-map as a function

2020-08-08 Thread Jonas Bernoulli
It was defined as such for a decade; ever since
a56010ac8b89a2489eee5c78469f05cee85ec858 but there
wasn't a reason to do that then nor is there now.
---
 emacs/notmuch-hello.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index c17b46bc..876d8ef1 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -687,7 +687,6 @@ (defvar notmuch-hello-mode-map
 (define-key map (kbd "") 'widget-backward)
 map)
   "Keymap for \"notmuch hello\" buffers.")
-(fset 'notmuch-hello-mode-map notmuch-hello-mode-map)
 
 (define-derived-mode notmuch-hello-mode fundamental-mode "notmuch-hello"
   "Major mode for convenient notmuch navigation. This is your entry portal 
into notmuch.
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 23/34] .gitignore: Sort using sort-lines

2020-08-08 Thread Jonas Bernoulli
---
 .gitignore | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8f3ebec0..3edd1768 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,20 +1,20 @@
-/.first-build-message
-/Makefile.config
-/sh.config
-/version.stamp
-TAGS
-tags
-*cscope*
-/.deps
-/notmuch
-/notmuch-shared
-/lib/libnotmuch.so*
-/lib/libnotmuch*.dylib
 *.[ao]
+*.stamp
+*cscope*
 *~
 .*.swp
-/releases
+/.deps
+/.first-build-message
 /.stamps
-*.stamp
+/Makefile.config
 /bindings/python-cffi/build/
+/lib/libnotmuch*.dylib
+/lib/libnotmuch.so*
+/notmuch
+/notmuch-shared
+/releases
+/sh.config
 /sphinx.config
+/version.stamp
+TAGS
+tags
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 14/34] emacs: Use makefile-gmake-mode in Makefile*s

2020-08-08 Thread Jonas Bernoulli
Use `makefile-gmake-mode' instead of `makefile-mode' because the
former also highlights ifdef et al. while the latter does not.

"./Makefile.global" and one "Makefile.local" failed to specify any
major mode at all but doing so is necessary because Emacs does not
automatically figure out that these are Makefiles (of any flavor).
---
 Makefile.global  | 1 +
 Makefile.local   | 2 +-
 bindings/Makefile.local  | 2 +-
 compat/Makefile.local| 2 +-
 completion/Makefile.local| 2 +-
 doc/Makefile.local   | 2 +-
 emacs/Makefile.local | 2 +-
 lib/Makefile.local   | 2 +-
 parse-time-string/Makefile.local | 2 ++
 performance-test/Makefile.local  | 2 +-
 test/Makefile.local  | 2 +-
 util/Makefile.local  | 2 +-
 12 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/Makefile.global b/Makefile.global
index 4fd796e3..cd489ef2 100644
--- a/Makefile.global
+++ b/Makefile.global
@@ -1,3 +1,4 @@
+# -*- makefile-gmake -*-
 # Here's the (hopefully simple) versioning scheme.
 #
 # Releases of notmuch have a two-digit version (0.1, 0.2, etc.). We
diff --git a/Makefile.local b/Makefile.local
index 39f36d50..156c8ce1 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 .PHONY: all
 all: notmuch notmuch-shared build-man build-info ruby-bindings 
python-cffi-bindings
diff --git a/bindings/Makefile.local b/bindings/Makefile.local
index 19ddd6ea..bc960bbc 100644
--- a/bindings/Makefile.local
+++ b/bindings/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := bindings
 
diff --git a/compat/Makefile.local b/compat/Makefile.local
index bcb9f0ec..2ee1b399 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := compat
 extra_cflags += -I$(srcdir)/$(dir)
diff --git a/completion/Makefile.local b/completion/Makefile.local
index 8e86c9d2..54df463c 100644
--- a/completion/Makefile.local
+++ b/completion/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := completion
 
diff --git a/doc/Makefile.local b/doc/Makefile.local
index 30411341..60bd7184 100644
--- a/doc/Makefile.local
+++ b/doc/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := doc
 
diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 141f5868..d1b320c3 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := emacs
 emacs_sources := \
diff --git a/lib/Makefile.local b/lib/Makefile.local
index 5dc057c0..a6400126 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := lib
 
diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local
index 53534f3e..ee8030cc 100644
--- a/parse-time-string/Makefile.local
+++ b/parse-time-string/Makefile.local
@@ -1,3 +1,5 @@
+# -*- makefile-gmake -*-
+
 dir := parse-time-string
 extra_cflags += -I$(srcdir)/$(dir)
 
diff --git a/performance-test/Makefile.local b/performance-test/Makefile.local
index 9dc260e3..b9f580c7 100644
--- a/performance-test/Makefile.local
+++ b/performance-test/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := performance-test
 
diff --git a/test/Makefile.local b/test/Makefile.local
index 47244e8f..40574739 100644
--- a/test/Makefile.local
+++ b/test/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := test
 
diff --git a/util/Makefile.local b/util/Makefile.local
index f5d72f79..7ef029a5 100644
--- a/util/Makefile.local
+++ b/util/Makefile.local
@@ -1,4 +1,4 @@
-# -*- makefile -*-
+# -*- makefile-gmake -*-
 
 dir := util
 extra_cflags += -I$(srcdir)/$(dir)
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 01/34] emacs: Shorten long lines

2020-08-08 Thread Jonas Bernoulli
---
 emacs/coolj.el   |   2 +-
 emacs/notmuch-address.el |  38 +++--
 emacs/notmuch-company.el |  17 --
 emacs/notmuch-crypto.el  |  16 +++---
 emacs/notmuch-draft.el   |  12 ++--
 emacs/notmuch-hello.el   |  43 ++-
 emacs/notmuch-jump.el|   7 ++-
 emacs/notmuch-lib.el |  62 +
 emacs/notmuch-maildir-fcc.el |  14 ++---
 emacs/notmuch-message.el |   3 +-
 emacs/notmuch-mua.el |  78 +++---
 emacs/notmuch-show.el| 103 +++
 emacs/notmuch-tag.el |  14 +++--
 emacs/notmuch-tree.el|  55 +--
 emacs/notmuch-wash.el|  19 +--
 emacs/notmuch.el |  27 ++---
 emacs/rstdoc.el  |   3 +-
 17 files changed, 326 insertions(+), 187 deletions(-)

diff --git a/emacs/coolj.el b/emacs/coolj.el
index 350d537f..5d311170 100644
--- a/emacs/coolj.el
+++ b/emacs/coolj.el
@@ -1,6 +1,6 @@
 ;;; coolj.el --- automatically wrap long lines  -*- coding:utf-8 -*-
 
-;; Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008, 2009 Free Software 
Foundation, Inc.
+;; Copyright (C) 2000, 2001, 2004-2009 Free Software Foundation, Inc.
 
 ;; Authors:Kai Grossjohann 
 ;; Alex Schroeder 
diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 0d56fba7..2a9c411a 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -195,10 +195,11 @@ (defun notmuch-address-options (original)
((eq notmuch-address-command 'internal)
 (unless (notmuch-address--harvest-ready)
   ;; First, run quick synchronous harvest based on what the user
-  ;; entered so far
+  ;; entered so far.
   (notmuch-address-harvest original t))
 (prog1 (notmuch-address-matching original)
-  ;; Then start the (potentially long-running) full asynchronous harvest 
if necessary
+  ;; Then start the (potentially long-running) full asynchronous
+  ;; harvest if necessary.
   (notmuch-address-harvest-trigger)))
(t
 (process-lines notmuch-address-command original
@@ -241,7 +242,8 @@ (defun notmuch-address-expand-name ()
(push chosen notmuch-address-history)
(delete-region beg end)
(insert chosen)
-   (run-hook-with-args 'notmuch-address-post-completion-functions 
chosen))
+   (run-hook-with-args 'notmuch-address-post-completion-functions
+   chosen))
(message "No matches.")
(ding
(t nil)))
@@ -393,10 +395,11 @@ (defun notmuch-address--save-address-hash ()
  ;; The file exists, check it is a file we saved
(notmuch-address--get-address-hash))
(with-temp-file notmuch-address-save-filename
- (let ((save-plist (list :version notmuch-address--save-hash-version
- :completion-settings 
notmuch-address-internal-completion
- :last-harvest notmuch-address-last-harvest
- :completions notmuch-address-completions)))
+ (let ((save-plist
+(list :version notmuch-address--save-hash-version
+  :completion-settings notmuch-address-internal-completion
+  :last-harvest notmuch-address-last-harvest
+  :completions notmuch-address-completions)))
(print "notmuch-address-hash" (current-buffer))
(print save-plist (current-buffer
   (message "\
@@ -408,16 +411,17 @@ (defun notmuch-address-harvest-trigger ()
   (let ((now (float-time)))
 (when (> (- now notmuch-address-last-harvest) 86400)
   (setq notmuch-address-last-harvest now)
-  (notmuch-address-harvest nil nil
-  (lambda (proc event)
-;; If harvest fails, we want to try
-;; again when the trigger is next
-;; called
-(if (string= event "finished\n")
-(progn
-  (notmuch-address--save-address-hash)
-  (setq 
notmuch-address-full-harvest-finished t))
-  (setq notmuch-address-last-harvest 0)))
+  (notmuch-address-harvest
+   nil nil
+   (lambda (proc event)
+;; If harvest fails, we want to try
+;; again when the trigger is next
+;; called
+(if (string= event "finished\n")
+(progn
+  (notmuch-address--save-address-hash)
+  (setq notmuch-address-full-harvest-finished t))
+  (setq notmuch-address-last-harvest 0)))
 
 ;;
 
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index ac998f9b..c1f3594e 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -69,9 +69,11 @@ 

[PATCH v3 08/34] emacs: Use 'when' instead of 'if' when there is no ELSE part

2020-08-08 Thread Jonas Bernoulli
---
 emacs/notmuch-address.el |   8 ++--
 emacs/notmuch-compat.el  |   6 +--
 emacs/notmuch-hello.el   |   8 ++--
 emacs/notmuch-jump.el|  54 ++---
 emacs/notmuch-lib.el |  10 ++--
 emacs/notmuch-mua.el |  24 +-
 emacs/notmuch-query.el   |   4 +-
 emacs/notmuch-show.el|  93 ++--
 emacs/notmuch-tree.el|  30 ++--
 emacs/notmuch-wash.el|  68 +-
 emacs/notmuch.el | 100 +++
 test/test-lib.el |   4 +-
 12 files changed, 206 insertions(+), 203 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 2dd08661..85531489 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -171,10 +171,10 @@ (defun notmuch-address-toggle-internal-completion ()
   (if (local-variable-p 'notmuch-address-command)
   (kill-local-variable 'notmuch-address-command)
 (notmuch-setq-local notmuch-address-command 'internal))
-  (if (boundp 'company-idle-delay)
-  (if (local-variable-p 'company-idle-delay)
- (kill-local-variable 'company-idle-delay)
-   (notmuch-setq-local company-idle-delay nil
+  (when (boundp 'company-idle-delay)
+(if (local-variable-p 'company-idle-delay)
+   (kill-local-variable 'company-idle-delay)
+  (notmuch-setq-local company-idle-delay nil
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index 388ef70f..3340918f 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -68,9 +68,9 @@ (if (fboundp 'read-char-choice)
   ;; This is an inlined copy of help-form-show as that
   ;; was introduced in emacs 24 too.
   (let ((msg (eval help-form)))
-(if (stringp msg)
-(with-output-to-temp-buffer " *Char Help*"
-  (princ msg))
+(when (stringp msg)
+  (with-output-to-temp-buffer " *Char Help*"
+(princ msg))
 ((memq char chars)
  (setq done t))
 ((and executing-kbd-macro (= char -1))
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 1c0b1848..c17b46bc 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -589,8 +589,8 @@ (defun notmuch-hello-insert-buttons (searches)
 (mapc (lambda (elem)
;; (not elem) indicates an empty slot in the matrix.
(when elem
- (if (> column-indent 0)
- (widget-insert (make-string column-indent ? )))
+ (when (> column-indent 0)
+   (widget-insert (make-string column-indent ? )))
  (let* ((name (plist-get elem :name))
 (query (plist-get elem :query))
 (oldest-first (cl-case (plist-get elem :sort-order)
@@ -890,8 +890,8 @@ (defun notmuch-hello-insert-searches (title query-list 
 options)
the same values as :filter. If :filter and :filter-count are specified, this
will be used instead of :filter, not in conjunction with it."
   (widget-insert title ": ")
-  (if (and notmuch-hello-first-run (plist-get options :initially-hidden))
-  (add-to-list 'notmuch-hello-hidden-sections title))
+  (when (and notmuch-hello-first-run (plist-get options :initially-hidden))
+(add-to-list 'notmuch-hello-hidden-sections title))
   (let ((is-hidden (member title notmuch-hello-hidden-sections))
(start (point)))
 (if is-hidden
diff --git a/emacs/notmuch-jump.el b/emacs/notmuch-jump.el
index adf79650..e302fe00 100644
--- a/emacs/notmuch-jump.el
+++ b/emacs/notmuch-jump.el
@@ -169,37 +169,37 @@ (defun notmuch-jump--make-keymap (action-map prompt)
   (let ((map (make-sparse-keymap)))
 (set-keymap-parent map notmuch-jump-minibuffer-map)
 (pcase-dolist (`(,key ,name ,fn) action-map)
-  (if (= (length key) 1)
- (define-key map key
-   `(lambda () (interactive)
-  (setq notmuch-jump--action ',fn)
-  (exit-minibuffer)
+  (when (= (length key) 1)
+   (define-key map key
+ `(lambda () (interactive)
+(setq notmuch-jump--action ',fn)
+(exit-minibuffer)
 ;; By doing this in two passes (and checking if we already have a
 ;; binding) we avoid problems if the user specifies a binding which
 ;; is a prefix of another binding.
 (pcase-dolist (`(,key ,name ,fn) action-map)
-  (if (> (length key) 1)
- (let* ((key (elt key 0))
-(keystr (string key))
-(new-prompt (concat prompt (format-kbd-macro keystr) " "))
-(action-submap nil))
-   (unless (lookup-key map keystr)
- (pcase-dolist (`(,k ,n ,f) action-map)
-   (when (= key (elt k 0))
- 

[PATCH v3 02/34] emacs: Remove excess empty lines

2020-08-08 Thread Jonas Bernoulli
Most people who write lots of lisp tend to only sparsely use empty
"separator" lines within forms.  In lisp they feel unnecessary and
since most files stick to this convention we get a bit confused
when there are extra empty lines.  It feels like the s-expressions
are falling into pieces.

All of this is especially true between a function's doc-string and
body because the doc-string is colored differently, which visually
already separates it quite sufficiently from the code that follows.
---
 emacs/make-deps.el   |  2 -
 emacs/notmuch-address.el |  2 -
 emacs/notmuch-crypto.el  |  4 --
 emacs/notmuch-hello.el   | 18 -
 emacs/notmuch-jump.el|  5 ---
 emacs/notmuch-lib.el | 10 -
 emacs/notmuch-maildir-fcc.el |  7 
 emacs/notmuch-mua.el | 26 -
 emacs/notmuch-parser.el  |  5 ---
 emacs/notmuch-show.el| 75 ++--
 emacs/notmuch-tag.el |  3 --
 emacs/notmuch-tree.el|  9 -
 emacs/notmuch-wash.el| 18 +
 emacs/notmuch.el |  7 
 14 files changed, 5 insertions(+), 186 deletions(-)

diff --git a/emacs/make-deps.el b/emacs/make-deps.el
index 5b6db698..dcac319c 100644
--- a/emacs/make-deps.el
+++ b/emacs/make-deps.el
@@ -23,7 +23,6 @@
 
 (defun batch-make-deps ()
   "Invoke `make-deps' for each file on the command line."
-
   (setq debug-on-error t)
   (dolist (file command-line-args-left)
 (let ((default-directory command-line-default-directory))
@@ -37,7 +36,6 @@ (defun make-deps ( dir)
 This prints make dependencies to `standard-output' based on the
 top-level `require' expressions in the current buffer.  Paths in
 rules will be given relative to DIR, or `default-directory'."
-
   (setq dir (or dir default-directory))
   (save-excursion
 (goto-char (point-min))
diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 2a9c411a..ca4da3f3 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -302,7 +302,6 @@ (defun notmuch-address-harvest ( addr-prefix 
synchronous callback)
 Address harvesting may take some time so the address collection runs
 asynchronously unless SYNCHRONOUS is t. In case of asynchronous
 execution, CALLBACK is called when harvesting finishes."
-
   (let* ((sent (eq (car notmuch-address-internal-completion) 'sent))
 (config-query (cadr notmuch-address-internal-completion))
 (prefix-query (when addr-prefix
@@ -335,7 +334,6 @@ (defun notmuch-address-harvest ( addr-prefix 
synchronous callback)
;; Kill any existing process
(when current-proc
  (kill-buffer (process-buffer current-proc))) ; this also kills the 
process
-
(setq current-proc
  (apply 'notmuch-start-notmuch proc-name proc-buf
 callback   ; process sentinel
diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
index 2327ff1f..58947a20 100644
--- a/emacs/notmuch-crypto.el
+++ b/emacs/notmuch-crypto.el
@@ -123,17 +123,14 @@ (defun notmuch-crypto-insert-sigstatus-button (sigstatus 
from)
face 'notmuch-crypto-signature-good-key))
(setq button-action 'notmuch-crypto-sigstatus-good-callback
  help-msg (concat "Click to list key ID 0x" fingerprint "."
-
  ((string= status "error")
   (setq label (concat "Unknown key ID " keyid " or unsupported algorithm")
button-action 'notmuch-crypto-sigstatus-error-callback
help-msg (concat "Click to retrieve key ID " keyid
 " from keyserver.")))
-
  ((string= status "bad")
   (setq label (concat "Bad signature (claimed key ID " keyid ")")
face 'notmuch-crypto-signature-bad))
-
  (status
   (setq label (concat "Unknown signature status: " status)))
  (t
@@ -232,7 +229,6 @@ (defun notmuch-crypto-sigstatus-error-callback (button)
(process-put p :notmuch-show-buffer (current-buffer))
(process-put p :notmuch-show-point (point))
(message "Getting the GPG key %s asynchronously..." keyid)))
-
   (let ((window (display-buffer buffer)))
(with-selected-window window
  (with-current-buffer buffer
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 11c625ea..e71e55f3 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -150,7 +150,6 @@ (defcustom notmuch-saved-searches
 ;; The saved-search format is also used by the all-tags notmuch-hello
 ;; section. This section generates its own saved-search list in one of
 ;; the latter two forms.
-
   :get 'notmuch-hello--saved-searches-to-plist
   :type '(repeat notmuch-saved-search-plist)
   :tag "List of Saved Searches"
@@ -482,20 +481,17 @@ (defun notmuch-hello-tags-per-line (widest)
   ;; Count is 9 wide (8 digits plus space), 1 for the space
   ;; after the name.
   (+ 9 1 (max notmuch-column-control 

[PATCH v3 17/34] emacs: Autoload notmuch-jump using an autoload cookie

2020-08-08 Thread Jonas Bernoulli
Doing that is better than using an `autoload' form because the latter
may result in dependencies getting hidden and indeed it turns out we
have to declare `notmuch-jump' in "notmuch-tag.el".
---
 emacs/notmuch-jump.el | 1 +
 emacs/notmuch-tag.el  | 3 +--
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-jump.el b/emacs/notmuch-jump.el
index e302fe00..1e2d0497 100644
--- a/emacs/notmuch-jump.el
+++ b/emacs/notmuch-jump.el
@@ -73,6 +73,7 @@ (defun notmuch-jump-search ()
 
 (defvar notmuch-jump--action nil)
 
+;;;###autoload
 (defun notmuch-jump (action-map prompt)
   "Interactively prompt for one of the keys in ACTION-MAP.
 
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 1cef17e1..ccc1321f 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -36,8 +36,7 @@ (declare-function notmuch-search-tag "notmuch"
  (tag-changes  beg end only-matched))
 (declare-function notmuch-show-tag "notmuch-show" (tag-changes))
 (declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
-
-(autoload 'notmuch-jump "notmuch-jump")
+(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
 
 (define-widget 'notmuch-tag-key-type 'list
   "A single key tagging binding."
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 15/34] emacs: Improve doc-strings

2020-08-08 Thread Jonas Bernoulli
- The first sentence should fit on the first line in full.  This is
  even the case when that causes the line to get a bit long.  If it
  gets very long, then it should be made shorter.

- Even even the second sentence would fit on the first line, if it
  just provides some details, then it shouldn't be done.

- Symbols are quoted like `so'.

- There is no clear rule on how to (not) quote non-atomic
  s-expressions, but quoting like '(this) is definitely weird.

- It is a good idea to remember that \" becomes " and to take
  that in mind when adjusting the automatic filling by hand.

- Use the imperative form.

- Arguments are written in all uppercase.
---
 emacs/notmuch-address.el | 42 +---
 emacs/notmuch-query.el   | 19 +-
 emacs/notmuch-show.el|  4 ++--
 emacs/notmuch-tree.el|  5 +++--
 emacs/notmuch.el |  9 -
 emacs/rstdoc.el  |  6 +++---
 6 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 85531489..cd0ffb67 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -36,9 +36,9 @@ (defvar notmuch-address-completions (make-hash-table :test 
'equal)
 This variable is set by calling `notmuch-address-harvest'.")
 
 (defvar notmuch-address-full-harvest-finished nil
-  "t indicates that full completion address harvesting has been
-finished. Use notmuch-address--harvest-ready to access as that
-will load a saved hash if necessary (and available).")
+  "t indicates that full completion address harvesting has been finished.
+Use notmuch-address--harvest-ready to access as that will load a
+saved hash if necessary (and available).")
 
 (defun notmuch-address--harvest-ready ()
   "Return t if there is a full address hash available.
@@ -54,9 +54,9 @@ (defcustom notmuch-address-command 'internal
 which must take a single argument (searched string) and output a
 list of completion candidates, one per line.
 
-Alternatively, it can be the symbol 'internal, in which case
+Alternatively, it can be the symbol `internal', in which case
 internal completion is used; the variable
-`notmuch-address-internal-completion` can be used to customize
+`notmuch-address-internal-completion' can be used to customize
 this case.
 
 Finally, if this variable is nil then address completion is
@@ -72,12 +72,12 @@ (defcustom notmuch-address-command 'internal
 (defcustom notmuch-address-internal-completion '(sent nil)
   "Determines how internal address completion generates candidates.
 
-This should be a list of the form '(DIRECTION FILTER), where
+This should be a list of the form (DIRECTION FILTER), where
 DIRECTION is either sent or received and specifies whether the
 candidates are searched in messages sent by the user or received
 by the user (note received by is much faster), and FILTER is
-either nil or a filter-string, such as \"date:1y..\" to append
-to the query."
+either nil or a filter-string, such as \"date:1y..\" to append to
+the query."
   :type '(list :tag "Use internal address completion"
   (radio
:tag "Base completion on messages you have"
@@ -101,8 +101,8 @@ (defcustom notmuch-address-save-filename nil
   "Filename to save the cached completion addresses.
 
 All the addresses notmuch uses for address completion will be
-cached in this file. This has obvious privacy implications so you
-should make sure it is not somewhere publicly readable."
+cached in this file.  This has obvious privacy implications so
+you should make sure it is not somewhere publicly readable."
   :type '(choice (const :tag "Off" nil)
 (file :tag "Filename"))
   :group 'notmuch-send
@@ -110,12 +110,14 @@ (defcustom notmuch-address-save-filename nil
   :group 'notmuch-external)
 
 (defcustom notmuch-address-selection-function 
'notmuch-address-selection-function
-  "The function to select address from given list. The function is
-called with PROMPT, COLLECTION, and INITIAL-INPUT as arguments
-(subset of what `completing-read' can be called with).
-While executed the value of `completion-ignore-case' is t.
-See documentation of function `notmuch-address-selection-function'
-to know how address selection is made by default."
+  "The function to select address from given list.
+
+The function is called with PROMPT, COLLECTION, and INITIAL-INPUT
+as arguments (subset of what `completing-read' can be called
+with).  While executed the value of `completion-ignore-case'
+is t.  See documentation of function
+`notmuch-address-selection-function' to know how address
+selection is made by default."
   :type 'function
   :group 'notmuch-send
   :group 'notmuch-address
@@ -188,9 +190,9 @@ (defun notmuch-address-matching (substring)
 candidates))
 
 (defun notmuch-address-options (original)
-  "Returns a list of completion candidates. Uses either
-elisp-based implementation or older implementation requiring
-external commands."
+  "Return a list 

[PATCH v3 21/34] .dir-locals.el: Set variables for correct "shell" mode

2020-08-08 Thread Jonas Bernoulli
The major mode used for shell scripts is named 'sh-mode'.
'shell-mode' on the other hand implements an interactive
shell in emacs-lisp.
---
 .dir-locals.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.dir-locals.el b/.dir-locals.el
index fc75ae61..b3ddffe8 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -15,7 +15,7 @@ ((c-mode
  (emacs-lisp-mode
   (indent-tabs-mode . t)
   (tab-width . 8))
- (shell-mode
+ (sh-mode
   (indent-tabs-mode . t)
   (tab-width . 8)
   (sh-basic-offset . 4)
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 16/34] emacs: Autoload notmuch-jump-search only once

2020-08-08 Thread Jonas Bernoulli
This function is being autoloaded using an autoload cookie, so it
shouldn't additionally be autoloaded using an `autoload' form.

When building libraries we don't actually load the autoloads file and
dropping the `autoload' form results in an error, which reveals a so
far unspecified dependency: `notmuch-tree' needs `notmuch-jump'.

Before this commit compiling (or even just loading) `notmuch-tree'
resulted in `notmuch-jump' being loaded because the former requires
`notmuch-lib', which autoloaded `notmuch-jump-search'.

The bug was that this dependency was not explicitly specified, which
we fix by adding the respective `require' form.
---
 emacs/notmuch-lib.el  | 3 ---
 emacs/notmuch-tree.el | 1 +
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 6ff351d7..b86c44ed 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -35,9 +35,6 @@ (unless (require 'notmuch-version nil t)
   (defconst notmuch-emacs-version "unknown"
 "Placeholder variable when notmuch-version.el[c] is not available."))
 
-(autoload 'notmuch-jump-search "notmuch-jump"
-  "Jump to a saved search by shortcut key." t)
-
 (defgroup notmuch nil
   "Notmuch mail reader for Emacs."
   :group 'mail)
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 364da240..b538cef9 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -33,6 +33,7 @@ (require 'notmuch-query)
 (require 'notmuch-show)
 (require 'notmuch-tag)
 (require 'notmuch-parser)
+(require 'notmuch-jump)
 
 (declare-function notmuch-search "notmuch"
  ( query oldest-first target-thread target-line))
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 03/34] emacs: Fix indentation

2020-08-08 Thread Jonas Bernoulli
---
 emacs/coolj.el |  16 ++---
 emacs/notmuch-address.el   |  18 +++---
 emacs/notmuch-compat.el|  86 -
 emacs/notmuch-draft.el |  18 +++---
 emacs/notmuch-hello.el |  24 +++
 emacs/notmuch-lib.el   |  56 -
 emacs/notmuch-maildir-fcc.el   |  58 -
 emacs/notmuch-mua.el   |  42 +++--
 emacs/notmuch-query.el |   6 +-
 emacs/notmuch-show.el  | 111 +
 emacs/notmuch-tag.el   |   4 +-
 emacs/notmuch-tree.el  | 102 +++---
 emacs/notmuch-wash.el  |   2 +-
 emacs/notmuch.el   |  76 +++---
 test/emacs-address-cleaning.el |   2 +-
 15 files changed, 312 insertions(+), 309 deletions(-)

diff --git a/emacs/coolj.el b/emacs/coolj.el
index 5d311170..961db606 100644
--- a/emacs/coolj.el
+++ b/emacs/coolj.el
@@ -108,11 +108,11 @@ (defun coolj-set-breakpoint (prefix)
 line."
   (move-to-column fill-column)
   (if (and (re-search-forward "[^ ]" (line-end-position) 1)
-   (> (current-column) fill-column))
+  (> (current-column) fill-column))
   ;; This line is too long.  Can we break it?
   (or (coolj-find-break-backward prefix)
-  (progn (move-to-column fill-column)
- (coolj-find-break-forward)
+ (progn (move-to-column fill-column)
+(coolj-find-break-forward)
 
 (defun coolj-find-break-backward (prefix)
   "Move point backward to the first available breakpoint and return t.
@@ -135,12 +135,12 @@ (defun coolj-find-break-forward ()
 If no break point is found, return nil."
   (and (search-forward " " (line-end-position) 1)
(progn (skip-chars-forward " " (line-end-position))
-  (null (eolp)))
+ (null (eolp)))
(if (and fill-nobreak-predicate
-(run-hook-with-args-until-success
- 'fill-nobreak-predicate))
-   (coolj-find-break-forward)
- t)))
+   (run-hook-with-args-until-success
+'fill-nobreak-predicate))
+  (coolj-find-break-forward)
+t)))
 
 (provide 'coolj)
 
diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index ca4da3f3..09dda247 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -153,14 +153,14 @@ (defcustom notmuch-address-use-company t
 
 (defun notmuch-address-setup ()
   (let* ((setup-company (and notmuch-address-use-company
-  (require 'company nil t)))
+(require 'company nil t)))
 (pair (cons notmuch-address-completion-headers-regexp
-  #'notmuch-address-expand-name)))
-  (when setup-company
-   (notmuch-company-setup))
-  (unless (member pair message-completion-alist)
-   (setq message-completion-alist
- (push pair message-completion-alist)
+#'notmuch-address-expand-name)))
+(when setup-company
+  (notmuch-company-setup))
+(unless (member pair message-completion-alist)
+  (setq message-completion-alist
+   (push pair message-completion-alist)
 
 (defun notmuch-address-toggle-internal-completion ()
   "Toggle use of internal completion for current buffer.
@@ -323,7 +323,7 @@ (defun notmuch-address-harvest ( addr-prefix 
synchronous callback)
 ,query)))
 (if synchronous
(mapc #'notmuch-address-harvest-addr
-  (apply 'notmuch-call-notmuch-sexp args))
+ (apply 'notmuch-call-notmuch-sexp args))
   ;; Asynchronous
   (let* ((current-proc (if addr-prefix
   (car notmuch-address-harvest-procs)
@@ -390,7 +390,7 @@ (defun notmuch-address--load-address-hash ()
 (defun notmuch-address--save-address-hash ()
   (when notmuch-address-save-filename
 (if (or (not (file-exists-p notmuch-address-save-filename))
- ;; The file exists, check it is a file we saved
+   ;; The file exists, check it is a file we saved
(notmuch-address--get-address-hash))
(with-temp-file notmuch-address-save-filename
  (let ((save-plist
diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index 2cedd39d..388ef70f 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -35,7 +35,7 @@ (if (fboundp 'setq-local)
 (if (fboundp 'read-char-choice)
 (defalias 'notmuch-read-char-choice 'read-char-choice)
   (defun notmuch-read-char-choice (prompt chars  
inhibit-keyboard-quit)
-  "Read and return one of CHARS, prompting for PROMPT.
+"Read and return one of CHARS, prompting for PROMPT.
 Any input that is not one of CHARS is ignored.
 
 If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
@@ -44,49 +44,49 @@ (if (fboundp 'read-char-choice)
 This is an exact copy of this function from emacs 24 for use on
 emacs 23, except 

[PATCH v3 05/34] emacs: Only set one variable per setq form

2020-08-08 Thread Jonas Bernoulli
It's a bit weird to avoid having to write the "(setq ... )" more than
once, just because we can.  In a language that uses '=' for the same
purpose we also happily use that once per assignment.

While there are no benefit to using just one 'setq' there are some
drawbacks.  It is not always clear on first what is a key and what a
value and as a result it is easy to make a mistake.  Also it becomes
harder to comment out just one assignment.
---
 emacs/notmuch-address.el |  6 +++---
 emacs/notmuch-crypto.el  | 23 ---
 emacs/notmuch-lib.el |  8 
 emacs/notmuch-show.el| 26 ++
 emacs/notmuch-tree.el|  4 ++--
 emacs/notmuch.el | 35 ++-
 6 files changed, 53 insertions(+), 49 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 09dda247..4db7096c 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -381,9 +381,9 @@ (defun notmuch-address--load-address-hash ()
  notmuch-address-internal-completion)
   (equal (plist-get load-plist :version)
  notmuch-address--save-hash-version))
-  (setq notmuch-address-last-harvest (plist-get load-plist :last-harvest)
-   notmuch-address-completions (plist-get load-plist :completions)
-   notmuch-address-full-harvest-finished t)
+  (setq notmuch-address-last-harvest (plist-get load-plist :last-harvest))
+  (setq notmuch-address-completions (plist-get load-plist :completions))
+  (setq notmuch-address-full-harvest-finished t)
   ;; Return t to say load was successful.
   t)))
 
diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
index 58947a20..420b008f 100644
--- a/emacs/notmuch-crypto.el
+++ b/emacs/notmuch-crypto.el
@@ -117,20 +117,21 @@ (defun notmuch-crypto-insert-sigstatus-button (sigstatus 
from)
(userid (plist-get sigstatus :userid)))
;; If userid is present it has full or greater validity.
(if userid
-   (setq label (concat "Good signature by: " userid)
- face 'notmuch-crypto-signature-good)
- (setq label (concat "Good signature by key: " fingerprint)
-   face 'notmuch-crypto-signature-good-key))
-   (setq button-action 'notmuch-crypto-sigstatus-good-callback
- help-msg (concat "Click to list key ID 0x" fingerprint "."
+   (progn
+ (setq label (concat "Good signature by: " userid))
+ (setq face 'notmuch-crypto-signature-good))
+ (setq label (concat "Good signature by key: " fingerprint))
+ (setq face 'notmuch-crypto-signature-good-key))
+   (setq button-action 'notmuch-crypto-sigstatus-good-callback)
+   (setq help-msg (concat "Click to list key ID 0x" fingerprint "."
  ((string= status "error")
-  (setq label (concat "Unknown key ID " keyid " or unsupported algorithm")
-   button-action 'notmuch-crypto-sigstatus-error-callback
-   help-msg (concat "Click to retrieve key ID " keyid
+  (setq label (concat "Unknown key ID " keyid " or unsupported algorithm"))
+  (setq button-action 'notmuch-crypto-sigstatus-error-callback)
+  (setq help-msg (concat "Click to retrieve key ID " keyid
 " from keyserver.")))
  ((string= status "bad")
-  (setq label (concat "Bad signature (claimed key ID " keyid ")")
-   face 'notmuch-crypto-signature-bad))
+  (setq label (concat "Bad signature (claimed key ID " keyid ")"))
+  (setq face 'notmuch-crypto-signature-bad))
  (status
   (setq label (concat "Unknown signature status: " status)))
  (t
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index f8958a91..886da99f 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -861,8 +861,8 @@ (defun notmuch-call-notmuch--helper (destination args)
   (let (stdin-string)
 (while (keywordp (car args))
   (cl-case (car args)
-   (:stdin-string (setq stdin-string (cadr args)
-args (cddr args)))
+   (:stdin-string (setq stdin-string (cadr args))
+  (setq args (cddr args)))
(otherwise
 (error "Unknown keyword argument: %s" (car args)
 (if (null stdin-string)
@@ -939,8 +939,8 @@ (defun notmuch-start-notmuch (name buffer sentinel  
args)
  :buffer buffer
  :command (cons command args)
  :connection-type 'pipe
- :stderr err-buffer)
-   err-proc (get-buffer-process err-buffer))
+ :stderr err-buffer))
+ (setq err-proc (get-buffer-process err-buffer))
  (process-put proc 'err-buffer err-buffer)
 
  (process-put err-proc 'err-file err-file)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 8592936f..a0a6c09d 100644
--- a/emacs/notmuch-show.el
+++ 

[PATCH v3 13/34] emacs: notmuch-poll: Let the user know we are polling

2020-08-08 Thread Jonas Bernoulli
It is done synchronously and it can take a while,
so we should let the user know what is going on.
---
 emacs/notmuch-lib.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 4496ecd2..6ff351d7 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -259,11 +259,13 @@ (defun notmuch-poll ()
 Invokes `notmuch-poll-script', \"notmuch new\", or does nothing
 depending on the value of `notmuch-poll-script'."
   (interactive)
+  (message "Polling mail...")
   (if (stringp notmuch-poll-script)
   (unless (string= notmuch-poll-script "")
(unless (equal (call-process notmuch-poll-script nil nil) 0)
  (error "Notmuch: poll script `%s' failed!" notmuch-poll-script)))
-(notmuch-call-notmuch-process "new")))
+(notmuch-call-notmuch-process "new"))
+  (message "Polling mail...done"))
 
 (defun notmuch-bury-or-kill-this-buffer ()
   "Undisplay the current buffer.
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 11/34] emacs: Fix some function declarations

2020-08-08 Thread Jonas Bernoulli
---
 emacs/notmuch-tag.el | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index e71de041..1cef17e1 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -32,9 +32,10 @@ (require 'crm)
 
 (require 'notmuch-lib)
 
-(declare-function notmuch-search-tag "notmuch" tag-changes)
-(declare-function notmuch-show-tag "notmuch-show" tag-changes)
-(declare-function notmuch-tree-tag "notmuch-tree" tag-changes)
+(declare-function notmuch-search-tag "notmuch"
+ (tag-changes  beg end only-matched))
+(declare-function notmuch-show-tag "notmuch-show" (tag-changes))
+(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
 
 (autoload 'notmuch-jump "notmuch-jump")
 
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 06/34] emacs: Use 'and' instead of 'when' when the return value matters

2020-08-08 Thread Jonas Bernoulli
Also do so for some 'if' forms that lack an ELSE part.
Even go as far as using 'and' and 'not' instead of 'unless'.
---
 emacs/coolj.el   | 12 +++---
 emacs/notmuch-address.el | 72 ++--
 emacs/notmuch-crypto.el  |  2 +-
 emacs/notmuch-draft.el   |  2 +-
 emacs/notmuch-lib.el | 37 +-
 emacs/notmuch-maildir-fcc.el |  4 +-
 emacs/notmuch-mua.el | 13 +++
 emacs/notmuch-show.el| 45 +++---
 emacs/notmuch-tree.el|  4 +-
 emacs/notmuch-wash.el|  8 ++--
 emacs/notmuch.el | 28 --
 11 files changed, 114 insertions(+), 113 deletions(-)

diff --git a/emacs/coolj.el b/emacs/coolj.el
index 961db606..39a8de2b 100644
--- a/emacs/coolj.el
+++ b/emacs/coolj.el
@@ -107,12 +107,12 @@ (defun coolj-set-breakpoint (prefix)
 If the line should not be broken, return nil; point remains on the
 line."
   (move-to-column fill-column)
-  (if (and (re-search-forward "[^ ]" (line-end-position) 1)
-  (> (current-column) fill-column))
-  ;; This line is too long.  Can we break it?
-  (or (coolj-find-break-backward prefix)
- (progn (move-to-column fill-column)
-(coolj-find-break-forward)
+  (and (re-search-forward "[^ ]" (line-end-position) 1)
+   (> (current-column) fill-column)
+   ;; This line is too long.  Can we break it?
+   (or (coolj-find-break-backward prefix)
+  (progn (move-to-column fill-column)
+ (coolj-find-break-forward)
 
 (defun coolj-find-break-backward (prefix)
   "Move point backward to the first available breakpoint and return t.
diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 4db7096c..2dd08661 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -252,20 +252,20 @@ (defun notmuch-address-expand-name ()
 (defun notmuch-address-locate-command (command)
   "Return non-nil if `command' is an executable either on
 `exec-path' or an absolute pathname."
-  (when (stringp command)
-(if (and (file-name-absolute-p command)
-(file-executable-p command))
-   command
-  (setq command (file-name-nondirectory command))
-  (catch 'found-command
-   (let (bin)
- (dolist (dir exec-path)
-   (setq bin (expand-file-name command dir))
-   (when (or (and (file-executable-p bin)
-  (not (file-directory-p bin)))
- (and (file-executable-p (setq bin (concat bin ".exe")))
-  (not (file-directory-p bin
- (throw 'found-command bin
+  (and (stringp command)
+   (if (and (file-name-absolute-p command)
+   (file-executable-p command))
+  command
+(setq command (file-name-nondirectory command))
+(catch 'found-command
+  (let (bin)
+(dolist (dir exec-path)
+  (setq bin (expand-file-name command dir))
+  (when (or (and (file-executable-p bin)
+ (not (file-directory-p bin)))
+(and (file-executable-p (setq bin (concat bin ".exe")))
+ (not (file-directory-p bin
+(throw 'found-command bin
 
 (defun notmuch-address-harvest-addr (result)
   (let ((name-addr (plist-get result :name-addr)))
@@ -304,18 +304,20 @@ (defun notmuch-address-harvest ( addr-prefix 
synchronous callback)
 execution, CALLBACK is called when harvesting finishes."
   (let* ((sent (eq (car notmuch-address-internal-completion) 'sent))
 (config-query (cadr notmuch-address-internal-completion))
-(prefix-query (when addr-prefix
-(format "%s:%s*" (if sent "to" "from") addr-prefix)))
+(prefix-query (and addr-prefix
+   (format "%s:%s*"
+   (if sent "to" "from")
+   addr-prefix)))
 (from-or-to-me-query
  (mapconcat (lambda (x)
   (concat (if sent "from:" "to:") x))
 (notmuch-user-emails) " or "))
 (query (if (or prefix-query config-query)
(concat (format "(%s)" from-or-to-me-query)
-   (when prefix-query
- (format " and (%s)" prefix-query))
-   (when config-query
- (format " and (%s)" config-query)))
+   (and prefix-query
+(format " and (%s)" prefix-query))
+   (and config-query
+(format " and (%s)" config-query)))
  from-or-to-me-query))
 (args `("address" "--format=sexp" "--format-version=4"
 ,(if sent "--output=recipients" "--output=sender")
@@ -354,21 +356,21 @@ (defun notmuch-address--get-address-hash ()
 
 Returns 

[PATCH v3 00/34] A great number of cosmetic changes

2020-08-08 Thread Jonas Bernoulli
David Bremner  writes:

> Tomi Ollila  writes:

>> So we have 3 options:
>>
>> 1) apply this patch and now drop support for emacs 24
>>
>> 2) apply this patch and somehow infor emacs 24 users to install cl-lib from
>> ELPA
>
> I'm fine with either of these options. I'd hope we can specify what
> versions we need in emacs/notmuch-pkg.el.templ

I went with option 1: drop support for emacs 24.  Instead of just
adding a NEWS entry and bump a number, I also removed some old cruft
that was only necessary for emacs 24 (and in some cases emacs 23!).

That resulted in a few new commits of course, marked with * below.
And since I had to add some commit anyway, I also added three other
minor commits, marked with ^ below.

 Cheers,
 Jonas

Jonas Bernoulli (34):
  emacs: Shorten long lines
  emacs: Remove excess empty lines
  emacs: Fix indentation
  emacs: Closing parenthesis go on the same line
  emacs: Only set one variable per setq form
  emacs: Use 'and' instead of 'when' when the return value matters
  emacs: Use 'unless' instead of 'when' and 'not'
  emacs: Use 'when' instead of 'if' when there is no ELSE part
  emacs: Use one or three lines for 'if' forms
  emacs: Extend face to window edge again
  emacs: Fix some function declarations
  emacs: No longer define notmuch-hello-mode-map as a function
  emacs: notmuch-poll: Let the user know we are polling
  emacs: Use makefile-gmake-mode in Makefile*s
  emacs: Improve doc-strings
  emacs: Autoload notmuch-jump-search only once
  emacs: Autoload notmuch-jump using an autoload cookie
  emacs: Various cosmetic changes
  emacs: Increase consistency of library headers
  Fix typos
  .dir-locals.el: Set variables for correct "shell" mode
  test: Fix indentation
^ .gitignore: Sort using sort-lines
^ emacs: Provide 'rstdoc' feature at end of file
^ emacs: Add end-of-file line to libraries that lack it
* NEWS: Add stub for 0.31
* NEWS: At least Emacs 25.1 is required now
* emacs: Use cl-incf where appropriate
* emacs: Remove notmuch-setq-local
* emacs: Remove notmuch-read-char-choice
* emacs: Drop old advices that were only need for Emacs 23
* emacs: Do not abuse advice to monkey patch while testing
* emacs: Use new advice mechanism do advice mm-shr
* try-emacs-mua: Trim `require' advice for Emacs 25

 .dir-locals.el |   2 +-
 .gitignore |  28 +-
 Makefile.global|   1 +
 Makefile.local |   2 +-
 NEWS   |  10 +-
 bindings/Makefile.local|   2 +-
 bindings/python-cffi/notmuch2/__init__.py  |   2 +-
 bindings/python-cffi/notmuch2/_base.py |   6 +-
 bindings/python-cffi/notmuch2/_database.py |   8 +-
 bindings/python-cffi/notmuch2/_message.py  |   4 +-
 bindings/python-cffi/notmuch2/_tags.py |   8 +-
 bindings/python-cffi/tests/conftest.py |   2 +-
 bindings/python/notmuch/database.py|  12 +-
 bindings/python/notmuch/query.py   |   2 +-
 compat/Makefile.local  |   2 +-
 completion/Makefile.local  |   2 +-
 devel/try-emacs-mua|  26 +-
 doc/Makefile.local |   2 +-
 emacs/Makefile.local   |   2 +-
 emacs/coolj.el |  24 +-
 emacs/make-deps.el |   7 +-
 emacs/notmuch-address.el   | 188 -
 emacs/notmuch-company.el   |  56 +--
 emacs/notmuch-compat.el|  88 +
 emacs/notmuch-crypto.el|  49 ++-
 emacs/notmuch-draft.el |  24 +-
 emacs/notmuch-hello.el | 102 +++--
 emacs/notmuch-jump.el  |  61 ++-
 emacs/notmuch-lib.el   | 202 +-
 emacs/notmuch-maildir-fcc.el   | 122 +++---
 emacs/notmuch-message.el   |   3 +-
 emacs/notmuch-mua.el   | 185 -
 emacs/notmuch-parser.el|  16 +-
 emacs/notmuch-pkg.el.tmpl  |   3 +-
 emacs/notmuch-print.el |   2 +-
 emacs/notmuch-query.el |  29 +-
 emacs/notmuch-show.el  | 439 ++---
 emacs/notmuch-tag.el   |  43 +-
 emacs/notmuch-tree.el  | 189 -
 emacs/notmuch-version.el.tmpl  |   3 +-
 emacs/notmuch-wash.el  | 109 +++--
 emacs/notmuch.el   | 278 ++---
 emacs/rstdoc.el|  22 +-
 lib/Makefile.local |   2 +-
 lib/notmuch.h  |   4 +-
 parse-time-string/Makefile.local   |   2 +
 performance-test/Makefile.local|   2 +-
 tag-util.c |   2 +-
 tag-util.h |   2 +-
 test/Makefile.local|  

[PATCH v3 10/34] emacs: Extend face to window edge again

2020-08-08 Thread Jonas Bernoulli
Since Emacs 27 each face has to be explicitly configured to "extend
to the edge of the window".  Without doing that the face used for
the newline character only has an effect that spans "one character"
(i.e. it looks like there is a single trailing space character).

We don't want that so extend the face in Emacs 27, so that it looks
the same as it did in older Emacs releases.  We have to do this
conditionally, otherwise older Emacsen would choke on it.
---
 emacs/notmuch.el | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 4fc338e2..5562ad10 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -273,8 +273,12 @@ (defun notmuch-search-first-thread ()
   (goto-char (point-min)))
 
 (defface notmuch-message-summary-face
-  'class color) (background light)) (:background "#f0f0f0"))
-(((class color) (background dark)) (:background "#303030")))
+  `class color) (background light))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ (:background "#f0f0f0"))
+(((class color) (background dark))
+ ,@(and (>= emacs-major-version 27) '(:extend t))
+ (:background "#303030")))
   "Face for the single-line message summary in notmuch-show-mode."
   :group 'notmuch-show
   :group 'notmuch-faces)
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 09/34] emacs: Use one or three lines for 'if' forms

2020-08-08 Thread Jonas Bernoulli
Putting the COND and THEN parts on the same line but ELSE on a
separate line makes it harder to determine if there actually is
an ELSE part.
---
 emacs/notmuch-lib.el  | 6 --
 emacs/notmuch-tag.el  | 3 ++-
 emacs/notmuch-tree.el | 3 ++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index da48bb86..4496ecd2 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -611,7 +611,8 @@ (defun notmuch--get-bodypart-raw (msg part process-crypto 
binaryp cache)
   ,@(and process-crypto '("--decrypt=true"))
   ,(notmuch-id-to-query (plist-get msg :id
   (coding-system-for-read
-   (if binaryp 'no-conversion
+   (if binaryp
+   'no-conversion
  (let ((coding-system
 (mm-charset-to-coding-system
  (plist-get part :content-charset
@@ -680,7 +681,8 @@ (defun notmuch-mm-display-part-inline (msg part 
content-type process-crypto)
   ;; `gnus-decoded' charset.  Otherwise, we'll fetch the binary
   ;; part content and let mm-* decode it.
   (let* ((have-content (plist-member part :content))
-(charset (if have-content 'gnus-decoded
+(charset (if have-content
+ 'gnus-decoded
(plist-get part :content-charset)))
 (handle (mm-make-handle (current-buffer)
 `(,content-type (charset . ,charset)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 1067f185..e71de041 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -532,7 +532,8 @@ (defun notmuch-tag-jump (reverse)
   (and (symbolp name)
(symbol-name name
 (name-string (if name
- (if reverse (concat "Reverse " name)
+ (if reverse
+ (concat "Reverse " name)
name)
(mapconcat #'identity tag-change " "
(push (list key name-string
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 6a619ec2..b498db07 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -1009,7 +1009,8 @@ (defun notmuch-tree-worker (basic-query  
query-context target open-targ
   (setq notmuch-tree-basic-query basic-query)
   (setq notmuch-tree-query-context (if (or (string= query-context "")
   (string= query-context "*"))
-  nil query-context))
+  nil
+query-context))
   (setq notmuch-tree-target-msg target)
   (setq notmuch-tree-open-target open-target)
   ;; Set the default value for `notmuch-show-process-crypto' in this
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 07/34] emacs: Use 'unless' instead of 'when' and 'not'

2020-08-08 Thread Jonas Bernoulli
Also use 'unless' in a few cases where previously 'if' was used with
'not' but without an ELSE part.
---
 emacs/notmuch-hello.el  | 6 +++---
 emacs/notmuch-mua.el| 4 ++--
 emacs/notmuch-parser.el | 2 +-
 emacs/notmuch-show.el   | 3 +--
 emacs/notmuch-tag.el| 4 ++--
 emacs/notmuch-tree.el   | 8 
 emacs/notmuch.el| 4 ++--
 test/test-lib.el| 6 +++---
 8 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 89e03c36..1c0b1848 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -638,7 +638,7 @@ (defun notmuch-hello-window-configuration-change ()
 (dolist (window (window-list))
   (let ((last-buf (window-parameter window 'notmuch-hello-last-buffer))
(cur-buf (window-buffer window)))
-   (when (not (eq last-buf cur-buf))
+   (unless (eq last-buf cur-buf)
  ;; This window changed or is new.  Update recorded buffer
  ;; for next time.
  (set-window-parameter window 'notmuch-hello-last-buffer cur-buf)
@@ -652,7 +652,7 @@ (defun notmuch-hello-window-configuration-change ()
   ;; 24, we can't do it right here because something in this
   ;; hook's call stack overrides hello's point placement.
   (run-at-time nil nil #'notmuch-hello t))
-(when (null hello-buf)
+(unless hello-buf
   ;; Clean up hook
   (remove-hook 'window-configuration-change-hook
   #'notmuch-hello-window-configuration-change
@@ -908,7 +908,7 @@ (defun notmuch-hello-insert-searches (title query-list 
 options)
(notmuch-hello-update))
 "hide"))
 (widget-insert "\n")
-(when (not is-hidden)
+(unless is-hidden
   (let ((searches (apply 'notmuch-hello-query-counts query-list options)))
(when (or (not (plist-get options :hide-if-empty))
  searches)
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index f6d8ffc5..dc1f518c 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -198,7 +198,7 @@ (defun notmuch-mua-user-agent-emacs ()
 (defun notmuch-mua-add-more-hidden-headers ()
   "Add some headers to the list that are hidden by default."
   (mapc (lambda (header)
- (when (not (member header message-hidden-headers))
+ (unless (member header message-hidden-headers)
(push header message-hidden-headers)))
notmuch-mua-hidden-headers))
 
@@ -368,7 +368,7 @@ (defun notmuch-mua-mail ( to subject other-headers 
continue
   (interactive)
   (when notmuch-mua-user-agent-function
 (let ((user-agent (funcall notmuch-mua-user-agent-function)))
-  (when (not (string= "" user-agent))
+  (unless (string= "" user-agent)
(push (cons 'User-Agent user-agent) other-headers
   (unless (assq 'From other-headers)
 (push (cons 'From (message-make-from
diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
index 06e7487b..fbcfc2ef 100644
--- a/emacs/notmuch-parser.el
+++ b/emacs/notmuch-parser.el
@@ -78,7 +78,7 @@ (defun notmuch-sexp-read (sp)
 ;; parse, extend the partial parse to figure out when we
 ;; have a complete list.
 (catch 'return
-  (when (null (notmuch-sexp--partial-state sp))
+  (unless (notmuch-sexp--partial-state sp)
 (let ((start (point)))
   (condition-case nil
   (throw 'return (read (current-buffer)))
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 211be091..6102ca2e 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1060,8 +1060,7 @@ (defun notmuch-show-insert-msg (msg depth)
   ;; If the subject of this message is the same as that of the
   ;; previous message, don't display it when this message is
   ;; collapsed.
-  (when (not (string= notmuch-show-previous-subject
- bare-subject))
+  (unless (string= notmuch-show-previous-subject bare-subject)
(forward-line 1))
   (setq headers-start (point-marker)))
 (setq headers-end (point-marker))
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 2fcf5a9e..1067f185 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -382,8 +382,8 @@ (defun notmuch-tag-completions ( search-terms)
   "Return a list of tags for messages matching SEARCH-TERMS.
 
 Returns all tags if no search terms are given."
-  (if (null search-terms)
-  (setq search-terms (list "*")))
+  (unless search-terms
+(setq search-terms (list "*")))
   (split-string
(with-output-to-string
  (with-current-buffer standard-output
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 37a5d1c8..a5ae0edb 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -1063,10 +1063,10 @@ (defun notmuch-tree ( query query-context 
target buffer-name open-targe
   OPEN-TARGET: If TRUE open the target message in the message pane.
   UNTHREADED: If TRUE only show 

[PATCH v3 04/34] emacs: Closing parenthesis go on the same line

2020-08-08 Thread Jonas Bernoulli
---
 emacs/notmuch-lib.el  |  6 ++
 emacs/notmuch-show.el | 19 ---
 emacs/notmuch-tree.el |  4 ++--
 emacs/notmuch.el  |  6 ++
 4 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 7994d5ad..f8958a91 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -555,13 +555,11 @@ (defun notmuch-match-content-type (t1 t2)
   (string= (downcase t1) (downcase t2)
 
 (defvar notmuch-multipart/alternative-discouraged
-  '(
-;; Avoid HTML parts.
+  '(;; Avoid HTML parts.
 "text/html"
 ;; multipart/related usually contain a text/html part and some
 ;; associated graphics.
-"multipart/related"
-))
+"multipart/related"))
 
 (defun notmuch-multipart/alternative-determine-discouraged (msg)
   "Return the discouraged alternatives for the specified message."
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index f38866b0..8592936f 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -297,13 +297,12 @@ (defun notmuch-show-view-all-mime-parts ()
;;
;; Any MIME part not explicitly mentioned here will be handled by an
;; external viewer as configured in the various mailcap files.
-   (let ((mm-inline-media-tests '(
- ("text/.*" ignore identity)
- ("application/pgp-signature" ignore identity)
- ("multipart/alternative" ignore identity)
- ("multipart/mixed" ignore identity)
- ("multipart/related" ignore identity)
- )))
+   (let ((mm-inline-media-tests
+ '(("text/.*" ignore identity)
+   ("application/pgp-signature" ignore identity)
+   ("multipart/alternative" ignore identity)
+   ("multipart/mixed" ignore identity)
+   ("multipart/related" ignore identity
  (mm-display-parts (mm-dissect-buffer)
 
 (defun notmuch-show-save-attachments ()
@@ -1785,10 +1784,8 @@ (defun notmuch-show-get-message-ids-for-open-messages ()
(if (notmuch-show-message-visible-p)
(setq message-ids
  (append message-ids (list (notmuch-show-get-message-id)
-   (setq done (not (notmuch-show-goto-message-next)))
-   )
-  message-ids
-  )))
+   (setq done (not (notmuch-show-goto-message-next
+  message-ids)))
 
 ;; Commands typically bound to keys.
 
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 6ac0c62d..b1bb40b1 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -1020,8 +1020,8 @@ (defun notmuch-tree-worker (basic-query  
query-context target open-targ
   (erase-buffer)
   (goto-char (point-min))
   (let* ((search-args (concat basic-query
- (if query-context (concat " and (" query-context 
")"))
- ))
+ (if query-context
+ (concat " and (" query-context ")"
 (message-arg (if unthreaded "--unthreaded" "--entire-thread")))
 (if (equal (car (process-lines notmuch-command "count" search-args)) "0")
(setq search-args basic-query))
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 2e84cd34..d6e0a9d5 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -910,8 +910,7 @@ (defun notmuch-search-buffer-title (query)
query)
   "*"))
  (t
-  (concat "*notmuch-search-" query "*"))
- )))
+  (concat "*notmuch-search-" query "*")
 
 (defun notmuch-read-query (prompt)
   "Read a notmuch-query from the minibuffer with completion.
@@ -1003,8 +1002,7 @@ (defun notmuch-search ( query oldest-first 
target-thread target-line no
 (let ((proc (get-buffer-process (current-buffer)))
  (inhibit-read-only t))
   (if proc
- (error "notmuch search process already running for query `%s'" query)
-   )
+ (error "notmuch search process already running for query `%s'" query))
   (erase-buffer)
   (goto-char (point-min))
   (save-excursion
-- 
2.28.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org