aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile.local6
-rw-r--r--NEWS10
-rw-r--r--bindings/ruby/message.c2
-rw-r--r--command-line-arguments.c69
-rw-r--r--compat/have_d_type.c10
-rw-r--r--completion/notmuch-completion.bash2
-rwxr-xr-xconfigure24
-rw-r--r--devel/doxygen.cfg304
-rwxr-xr-xdevel/nmbug/nmbug-status447
-rw-r--r--emacs/Makefile.local20
-rw-r--r--emacs/notmuch-hello.el11
-rw-r--r--emacs/notmuch-lib.el57
-rw-r--r--emacs/notmuch-mua.el46
-rw-r--r--emacs/notmuch-show.el4
-rw-r--r--emacs/notmuch-tag.el17
-rw-r--r--emacs/notmuch-tree.el47
-rw-r--r--emacs/notmuch.el1
-rw-r--r--lib/message.cc34
-rw-r--r--lib/notmuch.h453
-rw-r--r--lib/query.cc3
-rw-r--r--lib/thread.cc2
-rw-r--r--man/man1/notmuch-dump.154
-rw-r--r--man/man1/notmuch-new.15
-rw-r--r--man/man1/notmuch-tag.12
-rw-r--r--man/man1/notmuch.12
-rw-r--r--notmuch-compact.c8
-rw-r--r--notmuch-config.c109
-rw-r--r--notmuch-count.c16
-rw-r--r--notmuch-dump.c23
-rw-r--r--notmuch-insert.c49
-rw-r--r--notmuch-new.c273
-rw-r--r--notmuch-reply.c20
-rw-r--r--notmuch-restore.c23
-rw-r--r--notmuch-search.c18
-rw-r--r--notmuch-setup.c15
-rw-r--r--notmuch-show.c24
-rw-r--r--notmuch-tag.c22
-rw-r--r--notmuch.c48
-rw-r--r--performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc14
-rw-r--r--performance-test/perf-test-lib.sh72
-rw-r--r--performance-test/version.sh2
-rw-r--r--test/Makefile.local7
-rw-r--r--test/README8
-rwxr-xr-xtest/T000-basic.sh (renamed from test/basic)22
-rwxr-xr-xtest/T010-help-test.sh (renamed from test/help-test)0
-rwxr-xr-xtest/T020-compact.sh (renamed from test/compact)0
-rwxr-xr-xtest/T030-config.sh (renamed from test/config)0
-rwxr-xr-xtest/T040-setup.sh (renamed from test/setup)0
-rwxr-xr-xtest/T050-new.sh (renamed from test/new)15
-rwxr-xr-xtest/T060-count.sh (renamed from test/count)0
-rwxr-xr-xtest/T070-insert.sh (renamed from test/insert)10
-rwxr-xr-xtest/T080-search.sh (renamed from test/search)0
-rwxr-xr-xtest/T090-search-output.sh (renamed from test/search-output)0
-rwxr-xr-xtest/T100-search-by-folder.sh (renamed from test/search-by-folder)0
-rwxr-xr-xtest/T110-search-position-overlap-bug.sh (renamed from test/search-position-overlap-bug)0
-rwxr-xr-xtest/T120-search-insufficient-from-quoting.sh (renamed from test/search-insufficient-from-quoting)0
-rwxr-xr-xtest/T130-search-limiting.sh (renamed from test/search-limiting)0
-rwxr-xr-xtest/T140-excludes.sh (renamed from test/excludes)0
-rwxr-xr-xtest/T150-tagging.sh (renamed from test/tagging)0
-rwxr-xr-xtest/T160-json.sh (renamed from test/json)0
-rwxr-xr-xtest/T170-sexp.sh (renamed from test/sexp)0
-rwxr-xr-xtest/T180-text.sh (renamed from test/text)0
-rwxr-xr-xtest/T190-multipart.sh (renamed from test/multipart)0
-rwxr-xr-xtest/T200-thread-naming.sh (renamed from test/thread-naming)0
-rwxr-xr-xtest/T210-raw.sh (renamed from test/raw)0
-rwxr-xr-xtest/T220-reply.sh (renamed from test/reply)0
-rwxr-xr-xtest/T230-reply-to-sender.sh (renamed from test/reply-to-sender)0
-rwxr-xr-xtest/T240-dump-restore.sh (renamed from test/dump-restore)0
-rwxr-xr-xtest/T250-uuencode.sh (renamed from test/uuencode)0
-rwxr-xr-xtest/T260-thread-order.sh (renamed from test/thread-order)0
-rwxr-xr-xtest/T270-author-order.sh (renamed from test/author-order)0
-rwxr-xr-xtest/T280-from-guessing.sh (renamed from test/from-guessing)0
-rwxr-xr-xtest/T290-long-id.sh (renamed from test/long-id)0
-rwxr-xr-xtest/T300-encoding.sh (renamed from test/encoding)0
-rwxr-xr-xtest/T310-emacs.sh (renamed from test/emacs)6
-rwxr-xr-xtest/T320-emacs-large-search-buffer.sh (renamed from test/emacs-large-search-buffer)0
-rwxr-xr-xtest/T330-emacs-subject-to-filename.sh (renamed from test/emacs-subject-to-filename)0
-rwxr-xr-xtest/T340-maildir-sync.sh (renamed from test/maildir-sync)0
-rwxr-xr-xtest/T350-crypto.sh (renamed from test/crypto)0
-rwxr-xr-xtest/T360-symbol-hiding.sh (renamed from test/symbol-hiding)0
-rwxr-xr-xtest/T370-search-folder-coherence.sh (renamed from test/search-folder-coherence)0
-rwxr-xr-xtest/T380-atomicity.sh (renamed from test/atomicity)0
-rwxr-xr-xtest/T390-python.sh (renamed from test/python)0
-rwxr-xr-xtest/T400-hooks.sh (renamed from test/hooks)0
-rwxr-xr-xtest/T410-argument-parsing.sh (renamed from test/argument-parsing)0
-rwxr-xr-xtest/T420-emacs-test-functions.sh (renamed from test/emacs-test-functions)0
-rwxr-xr-xtest/T430-emacs-address-cleaning.sh (renamed from test/emacs-address-cleaning)0
-rwxr-xr-xtest/T440-emacs-hello.sh (renamed from test/emacs-hello)0
-rwxr-xr-xtest/T450-emacs-show.sh (renamed from test/emacs-show)0
-rwxr-xr-xtest/T460-emacs-tree.sh (renamed from test/emacs-tree)38
-rwxr-xr-xtest/T470-missing-headers.sh (renamed from test/missing-headers)0
-rwxr-xr-xtest/T480-hex-escaping.sh (renamed from test/hex-escaping)0
-rwxr-xr-xtest/T490-parse-time-string.sh (renamed from test/parse-time-string)0
-rwxr-xr-xtest/T500-search-date.sh (renamed from test/search-date)0
-rwxr-xr-xtest/T510-thread-replies.sh (renamed from test/thread-replies)0
-rwxr-xr-xtest/T520-show.sh13
-rwxr-xr-xtest/notmuch-test57
-rw-r--r--test/test-lib.sh30
-rw-r--r--test/test.expected-output/test-verbose-no1
-rw-r--r--test/test.expected-output/test-verbose-yes1
-rw-r--r--test/tree.expected-output/notmuch-tree-single-thread8
-rw-r--r--test/tree.expected-output/notmuch-tree-tag-inbox104
-rw-r--r--test/tree.expected-output/notmuch-tree-tag-inbox-tagged104
-rw-r--r--test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged104
104 files changed, 1838 insertions, 1058 deletions
diff --git a/Makefile.local b/Makefile.local
index 72524eb3..174506c5 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -236,11 +236,11 @@ endif
quiet ?= $($(shell echo $1 | sed -e s'/ .*//'))
%.o: %.cc $(global_deps)
- @mkdir -p .deps/$(@D)
+ @mkdir -p $(patsubst %/.,%,.deps/$(@D))
$(call quiet,CXX $(CPPFLAGS) $(CXXFLAGS)) -c $(FINAL_CXXFLAGS) $< -o $@ -MD -MP -MF .deps/$*.d
%.o: %.c $(global_deps)
- @mkdir -p .deps/$(@D)
+ @mkdir -p $(patsubst %/.,%,.deps/$(@D))
$(call quiet,CC $(CPPFLAGS) $(CFLAGS)) -c $(FINAL_CFLAGS) $< -o $@ -MD -MP -MF .deps/$*.d
.PHONY : clean
@@ -325,3 +325,5 @@ DISTCLEAN := $(DISTCLEAN) .first-build-message Makefile.config
DEPS := $(SRCS:%.c=.deps/%.d)
DEPS := $(DEPS:%.cc=.deps/%.d)
-include $(DEPS)
+
+.SUFFIXES: # Delete the default suffixes. Old-Fashioned Suffix Rules not used.
diff --git a/NEWS b/NEWS
index 28788d8d..65679ebb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+Notmuch 0.18 (UNRELEASED)
+=========================
+
+Command-Line Interface
+----------------------
+
+`notmuch dump` now defaults to `batch-tag` format.
+
+ The old format is still available with `--format=sup`.
+
Notmuch 0.17 (2013-12-30)
=========================
diff --git a/bindings/ruby/message.c b/bindings/ruby/message.c
index eed4b31b..4ff6097f 100644
--- a/bindings/ruby/message.c
+++ b/bindings/ruby/message.c
@@ -111,7 +111,7 @@ notmuch_rb_message_get_filename (VALUE self)
}
/*
- * call-seq: MESSAGE.filanames => FILENAMES
+ * call-seq: MESSAGE.filenames => FILENAMES
*
* Get all filenames for the email corresponding to MESSAGE.
*/
diff --git a/command-line-arguments.c b/command-line-arguments.c
index bf9aecab..844d6c3d 100644
--- a/command-line-arguments.c
+++ b/command-line-arguments.c
@@ -129,40 +129,41 @@ parse_option (const char *arg,
const notmuch_opt_desc_t *try;
for (try = options; try->opt_type != NOTMUCH_OPT_END; try++) {
- if (try->name && strncmp (arg, try->name, strlen (try->name)) == 0) {
- char next = arg[strlen (try->name)];
- const char *value= arg+strlen(try->name)+1;
-
- /* If we have not reached the end of the argument
- (i.e. the next character is not a space or delimiter)
- then the argument could still match a longer option
- name later in the option table.
- */
- if (next != '=' && next != ':' && next != '\0')
- continue;
-
- if (try->output_var == NULL)
- INTERNAL_ERROR ("output pointer NULL for option %s", try->name);
-
- switch (try->opt_type) {
- case NOTMUCH_OPT_KEYWORD:
- return _process_keyword_arg (try, next, value);
- break;
- case NOTMUCH_OPT_BOOLEAN:
- return _process_boolean_arg (try, next, value);
- break;
- case NOTMUCH_OPT_INT:
- return _process_int_arg (try, next, value);
- break;
- case NOTMUCH_OPT_STRING:
- return _process_string_arg (try, next, value);
- break;
- case NOTMUCH_OPT_POSITION:
- case NOTMUCH_OPT_END:
- default:
- INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type);
- /*UNREACHED*/
- }
+ if (! try->name)
+ continue;
+
+ if (strncmp (arg, try->name, strlen (try->name)) != 0)
+ continue;
+
+ char next = arg[strlen (try->name)];
+ const char *value = arg + strlen(try->name) + 1;
+
+ /*
+ * If we have not reached the end of the argument (i.e. the
+ * next character is not a space or delimiter) then the
+ * argument could still match a longer option name later in
+ * the option table.
+ */
+ if (next != '=' && next != ':' && next != '\0')
+ continue;
+
+ if (try->output_var == NULL)
+ INTERNAL_ERROR ("output pointer NULL for option %s", try->name);
+
+ switch (try->opt_type) {
+ case NOTMUCH_OPT_KEYWORD:
+ return _process_keyword_arg (try, next, value);
+ case NOTMUCH_OPT_BOOLEAN:
+ return _process_boolean_arg (try, next, value);
+ case NOTMUCH_OPT_INT:
+ return _process_int_arg (try, next, value);
+ case NOTMUCH_OPT_STRING:
+ return _process_string_arg (try, next, value);
+ case NOTMUCH_OPT_POSITION:
+ case NOTMUCH_OPT_END:
+ default:
+ INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type);
+ /*UNREACHED*/
}
}
fprintf (stderr, "Unrecognized option: --%s\n", arg);
diff --git a/compat/have_d_type.c b/compat/have_d_type.c
new file mode 100644
index 00000000..9ca6c6e0
--- /dev/null
+++ b/compat/have_d_type.c
@@ -0,0 +1,10 @@
+#include <dirent.h>
+
+int main()
+{
+ struct dirent ent;
+
+ (void) ent.d_type;
+
+ return 0;
+}
diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index 04324bbb..0f132043 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -208,7 +208,7 @@ _notmuch_new()
case "${cur}" in
-*)
- local options="--no-hooks"
+ local options="--no-hooks --quiet"
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
;;
esac
diff --git a/configure b/configure
index 13b60620..2eaed4a1 100755
--- a/configure
+++ b/configure
@@ -360,6 +360,14 @@ else
have_valgrind=0
fi
+printf "Checking for bash-completion (>= 1.90)... "
+if pkg-config --atleast-version=1.90 bash-completion; then
+ printf "Yes.\n"
+else
+ printf "No (will not install bash completion).\n"
+ WITH_BASH=0
+fi
+
if [ -z "${EMACSLISPDIR}" ]; then
if pkg-config --exists emacs; then
EMACSLISPDIR=$(pkg-config emacs --variable sitepkglispdir)
@@ -570,6 +578,17 @@ else
fi
rm -f compat/have_timegm
+printf "Checking for dirent.d_type... "
+if ${CC} -o compat/have_d_type "$srcdir"/compat/have_d_type.c > /dev/null 2>&1
+then
+ printf "Yes.\n"
+ have_d_type="1"
+else
+ printf "No (will use stat instead).\n"
+ have_d_type="0"
+fi
+rm -f compat/have_d_type
+
printf "Checking for standard version of getpwuid_r... "
if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1
then
@@ -761,6 +780,9 @@ HAVE_STRCASESTR = ${have_strcasestr}
# build its own version)
HAVE_STRSEP = ${have_strsep}
+# Whether struct dirent has d_type (if not, then notmuch will use stat)
+HAVE_D_TYPE = ${have_d_type}
+
# Whether the Xapian version in use supports compaction
HAVE_XAPIAN_COMPACT = ${have_xapian_compact}
@@ -821,6 +843,7 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\$(VALGRIND_CFLAGS) \\
-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
-DHAVE_STRSEP=\$(HAVE_STRSEP) \\
+ -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\
-DSTD_GETPWUID=\$(STD_GETPWUID) \\
-DSTD_ASCTIME=\$(STD_ASCTIME) \\
-DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
@@ -831,6 +854,7 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
-DHAVE_STRSEP=\$(HAVE_STRSEP) \\
+ -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\
-DSTD_GETPWUID=\$(STD_GETPWUID) \\
-DSTD_ASCTIME=\$(STD_ASCTIME) \\
-DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
diff --git a/devel/doxygen.cfg b/devel/doxygen.cfg
new file mode 100644
index 00000000..65d5fb50
--- /dev/null
+++ b/devel/doxygen.cfg
@@ -0,0 +1,304 @@
+# Doxyfile 1.8.4
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = "Notmuch 0.17"
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = YES
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_FILES = NO
+SHOW_NAMESPACES = NO
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = YES
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = lib/notmuch.h
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = NO
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = YES
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = NO
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = __DOXYGEN__
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = NO
+EXTERNAL_PAGES = NO
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = NO
+INCLUDED_BY_GRAPH = NO
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = NO
+DIRECTORY_GRAPH = NO
+DOT_IMAGE_FORMAT = png
+INTERACTIVE_SVG = NO
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = YES
+GENERATE_LEGEND = NO
+DOT_CLEANUP = YES
diff --git a/devel/nmbug/nmbug-status b/devel/nmbug/nmbug-status
index 934c895f..6b2572c1 100755
--- a/devel/nmbug/nmbug-status
+++ b/devel/nmbug/nmbug-status
@@ -6,185 +6,330 @@
# - python 2.6 for json
# - argparse; either python 2.7, or install separately
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import codecs
+import collections
import datetime
-import rfc822
-import urllib
+import email.utils
+try: # Python 3
+ from urllib.parse import quote
+except ImportError: # Python 2
+ from urllib import quote
import json
import argparse
import os
+import re
import sys
import subprocess
+import xml.sax.saxutils
+
+
+_ENCODING = 'UTF-8'
+_PAGES = {}
+
+
+if not hasattr(collections, 'OrderedDict'): # Python 2.6 or earlier
+ class _OrderedDict (dict):
+ "Just enough of a stub to get through Page._get_threads"
+ def __init__(self, *args, **kwargs):
+ super(_OrderedDict, self).__init__(*args, **kwargs)
+ self._keys = [] # record key order
+
+ def __setitem__(self, key, value):
+ super(_OrderedDict, self).__setitem__(key, value)
+ self._keys.append(key)
+
+ def values(self):
+ for key in self._keys:
+ yield self[key]
+
+
+ collections.OrderedDict = _OrderedDict
+
+
+def read_config(path=None, encoding=None):
+ "Read config from json file"
+ if not encoding:
+ encoding = _ENCODING
+ if path:
+ fp = open(path)
+ else:
+ nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug'))
+
+ # read only the first line from the pipe
+ sha1_bytes = subprocess.Popen(
+ ['git', '--git-dir', nmbhome, 'show-ref', '-s', 'config'],
+ stdout=subprocess.PIPE).stdout.readline()
+ sha1 = sha1_bytes.decode(encoding).rstrip()
+
+ fp_byte_stream = subprocess.Popen(
+ ['git', '--git-dir', nmbhome, 'cat-file', 'blob',
+ sha1+':status-config.json'],
+ stdout=subprocess.PIPE).stdout
+ fp = codecs.getreader(encoding=encoding)(stream=fp_byte_stream)
+
+ return json.load(fp)
+
+
+class Thread (list):
+ def __init__(self):
+ self.running_data = {}
+
+
+class Page (object):
+ def __init__(self, header=None, footer=None):
+ self.header = header
+ self.footer = footer
+
+ def write(self, database, views, stream=None):
+ if not stream:
+ try: # Python 3
+ byte_stream = sys.stdout.buffer
+ except AttributeError: # Python 2
+ byte_stream = sys.stdout
+ stream = codecs.getwriter(encoding=_ENCODING)(stream=byte_stream)
+ self._write_header(views=views, stream=stream)
+ for view in views:
+ self._write_view(database=database, view=view, stream=stream)
+ self._write_footer(views=views, stream=stream)
+
+ def _write_header(self, views, stream):
+ if self.header:
+ stream.write(self.header)
+
+ def _write_footer(self, views, stream):
+ if self.footer:
+ stream.write(self.footer)
+
+ def _write_view(self, database, view, stream):
+ if 'query-string' not in view:
+ query = view['query']
+ view['query-string'] = ' and '.join(query)
+ q = notmuch.Query(database, view['query-string'])
+ q.set_sort(notmuch.Query.SORT.OLDEST_FIRST)
+ threads = self._get_threads(messages=q.search_messages())
+ self._write_view_header(view=view, stream=stream)
+ self._write_threads(threads=threads, stream=stream)
+
+ def _get_threads(self, messages):
+ threads = collections.OrderedDict()
+ for message in messages:
+ thread_id = message.get_thread_id()
+ if thread_id in threads:
+ thread = threads[thread_id]
+ else:
+ thread = Thread()
+ threads[thread_id] = thread
+ thread.running_data, display_data = self._message_display_data(
+ running_data=thread.running_data, message=message)
+ thread.append(display_data)
+ return list(threads.values())
+
+ def _write_view_header(self, view, stream):
+ pass
+
+ def _write_threads(self, threads, stream):
+ for thread in threads:
+ for message_display_data in thread:
+ stream.write(
+ ('{date:10.10s} {from:20.20s} {subject:40.40s}\n'
+ '{message-id-term:>72}\n'
+ ).format(**message_display_data))
+ if thread != threads[-1]:
+ stream.write('\n')
+
+ def _message_display_data(self, running_data, message):
+ headers = ('thread-id', 'message-id', 'date', 'from', 'subject')
+ data = {}
+ for header in headers:
+ if header == 'thread-id':
+ value = message.get_thread_id()
+ elif header == 'message-id':
+ value = message.get_message_id()
+ data['message-id-term'] = 'id:"{0}"'.format(value)
+ elif header == 'date':
+ value = str(datetime.datetime.utcfromtimestamp(
+ message.get_date()).date())
+ else:
+ value = message.get_header(header)
+ if header == 'from':
+ (value, addr) = email.utils.parseaddr(value)
+ if not value:
+ value = addr.split('@')[0]
+ data[header] = value
+ next_running_data = data.copy()
+ for header, value in data.items():
+ if header in ['message-id', 'subject']:
+ continue
+ if value == running_data.get(header, None):
+ data[header] = ''
+ return (next_running_data, data)
+
+
+class HtmlPage (Page):
+ _slug_regexp = re.compile('\W+')
+
+ def _write_header(self, views, stream):
+ super(HtmlPage, self)._write_header(views=views, stream=stream)
+ stream.write('<ul>\n')
+ for view in views:
+ if 'id' not in view:
+ view['id'] = self._slug(view['title'])
+ stream.write(
+ '<li><a href="#{id}">{title}</a></li>\n'.format(**view))
+ stream.write('</ul>\n')
+
+ def _write_view_header(self, view, stream):
+ stream.write('<h3 id="{id}">{title}</h3>\n'.format(**view))
+ stream.write('<p>\n')
+ if 'comment' in view:
+ stream.write(view['comment'])
+ stream.write('\n')
+ for line in [
+ 'The view is generated from the following query:',
+ '</p>',
+ '<p>',
+ ' <code>',
+ view['query-string'],
+ ' </code>',
+ '</p>',
+ ]:
+ stream.write(line)
+ stream.write('\n')
+
+ def _write_threads(self, threads, stream):
+ if not threads:
+ return
+ stream.write('<table>\n')
+ for thread in threads:
+ stream.write(' <tbody>\n')
+ for message_display_data in thread:
+ stream.write((
+ ' <tr class="message-first">\n'
+ ' <td>{date}</td>\n'
+ ' <td><code>{message-id-term}</code></td>\n'
+ ' </tr>\n'
+ ' <tr class="message-last">\n'
+ ' <td>{from}</td>\n'
+ ' <td>{subject}</td>\n'
+ ' </tr>\n'
+ ).format(**message_display_data))
+ stream.write(' </tbody>\n')
+ if thread != threads[-1]:
+ stream.write(
+ ' <tbody><tr><td colspan="2"><br /></td></tr></tbody>\n')
+ stream.write('</table>\n')
+
+ def _message_display_data(self, *args, **kwargs):
+ running_data, display_data = super(
+ HtmlPage, self)._message_display_data(
+ *args, **kwargs)
+ if 'subject' in display_data and 'message-id' in display_data:
+ d = {
+ 'message-id': quote(display_data['message-id']),
+ 'subject': xml.sax.saxutils.escape(display_data['subject']),
+ }
+ display_data['subject'] = (
+ '<a href="http://mid.gmane.org/{message-id}">{subject}</a>'
+ ).format(**d)
+ for key in ['message-id', 'from']:
+ if key in display_data:
+ display_data[key] = xml.sax.saxutils.escape(display_data[key])
+ return (running_data, display_data)
+
+ def _slug(self, string):
+ return self._slug_regexp.sub('-', string)
+
+
+_PAGES['text'] = Page()
+_PAGES['html'] = HtmlPage(
+ header='''<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset={encoding}" />
+ <title>Notmuch Patches</title>
+ <style media="screen" type="text/css">
+ table {{
+ border-spacing: 0;
+ }}
+ tr.message-first td {{
+ padding-top: {inter_message_padding};
+ }}
+ tr.message-last td {{
+ padding-bottom: {inter_message_padding};
+ }}
+ td {{
+ padding-left: {border_radius};
+ padding-right: {border_radius};
+ }}
+ tr:first-child td:first-child {{
+ border-top-left-radius: {border_radius};
+ }}
+ tr:first-child td:last-child {{
+ border-top-right-radius: {border_radius};
+ }}
+ tr:last-child td:first-child {{
+ border-bottom-left-radius: {border_radius};
+ }}
+ tr:last-child td:last-child {{
+ border-bottom-right-radius: {border_radius};
+ }}
+ tbody:nth-child(4n+1) tr td {{
+ background-color: #ffd96e;
+ }}
+ tbody:nth-child(4n+3) tr td {{
+ background-color: #bce;
+ }}
+ </style>
+</head>
+<body>
+<h2>Notmuch Patches</h2>
+<p>
+Generated: {date}<br />
+For more infomation see <a href="http://notmuchmail.org/nmbug">nmbug</a>
+</p>
+<h3>Views</h3>
+'''.format(date=datetime.datetime.utcnow().date(),
+ encoding=_ENCODING,
+ inter_message_padding='0.25em',
+ border_radius='0.5em'),
+ footer='</body>\n</html>\n',
+ )
-# parse command line arguments
parser = argparse.ArgumentParser()
parser.add_argument('--text', help='output plain text format',
action='store_true')
-parser.add_argument('--config', help='load config from given file')
+parser.add_argument('--config', help='load config from given file',
+ metavar='PATH')
parser.add_argument('--list-views', help='list views',
action='store_true')
-parser.add_argument('--get-query', help='get query for view')
+parser.add_argument('--get-query', help='get query for view',
+ metavar='VIEW')
args = parser.parse_args()
-# read config from json file
-
-if args.config != None:
- fp = open(args.config)
-else:
- nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug'))
-
- # read only the first line from the pipe
- sha1 = subprocess.Popen(['git', '--git-dir', nmbhome,
- 'show-ref', '-s', 'config'],
- stdout=subprocess.PIPE).stdout.readline()
-
- sha1 = sha1.rstrip()
-
- fp = subprocess.Popen(['git', '--git-dir', nmbhome,
- 'cat-file', 'blob', sha1+':status-config.json'],
- stdout=subprocess.PIPE).stdout
-
-config = json.load(fp)
+config = read_config(path=args.config)
if args.list_views:
for view in config['views']:
- print view['title']
+ print(view['title'])
sys.exit(0)
elif args.get_query != None:
for view in config['views']:
if args.get_query == view['title']:
- print ' and '.join(view['query'])
+ print(' and '.join(view['query']))
sys.exit(0)
else:
# only import notmuch if needed
import notmuch
if args.text:
- output_format = 'text'
+ page = _PAGES['text']
else:
- output_format = 'html'
-
-class Thread:
- def __init__(self, last, lines):
- self.last = last
- self.lines = lines
-
- def join_utf8_with_newlines(self):
- return '\n'.join( (line.encode('utf-8') for line in self.lines) )
-
-def output_with_separator(threadlist, sep):
- outputs = (thread.join_utf8_with_newlines() for thread in threadlist)
- print sep.join(outputs)
-
-headers = ['date', 'from', 'subject']
-
-def print_view(title, query, comment):
-
- query_string = ' and '.join(query)
- q_new = notmuch.Query(db, query_string)
- q_new.set_sort(notmuch.Query.SORT.OLDEST_FIRST)
-
- last_thread_id = ''
- threads = {}
- threadlist = []
- out = {}
- last = None
- lines = None
-
- if output_format == 'html':
- print '<h3><a name="%s" />%s</h3>' % (title, title)
- print comment
- print 'The view is generated from the following query:'
- print '<blockquote>'
- print query_string
- print '</blockquote>'
- print '<table>\n'
-
- for m in q_new.search_messages():
-
- thread_id = m.get_thread_id()
-
- if thread_id != last_thread_id:
- if threads.has_key(thread_id):
- last = threads[thread_id].last
- lines = threads[thread_id].lines
- else:
- last = {}
- lines = []
- thread = Thread(last, lines)
- threads[thread_id] = thread
- for h in headers:
- last[h] = ''
- threadlist.append(thread)
- last_thread_id = thread_id
-
- for header in headers:
- val = m.get_header(header)
-
- if header == 'date':
- val = str.join(' ', val.split(None)[1:4])
- val = str(datetime.datetime.strptime(val, '%d %b %Y').date())
- elif header == 'from':
- (val, addr) = rfc822.parseaddr(val)
- if val == '':
- val = addr.split('@')[0]
-
- if header != 'subject' and last[header] == val:
- out[header] = ''
- else:
- out[header] = val
- last[header] = val
-
- mid = m.get_message_id()
- out['id'] = 'id:"%s"' % mid
-
- if output_format == 'html':
-
- out['subject'] = '<a href="http://mid.gmane.org/%s">%s</a>' \
- % (urllib.quote(mid), out['subject'])
-
- lines.append(' <tr><td>%s' % out['date'])
- lines.append('</td><td>%s' % out['id'])
- lines.append('</td></tr>')
- lines.append(' <tr><td>%s' % out['from'])
- lines.append('</td><td>%s' % out['subject'])
- lines.append('</td></tr>')
- else:
- lines.append('%(date)-10.10s %(from)-20.20s %(subject)-40.40s\n%(id)72s' % out)
-
- if output_format == 'html':
- output_with_separator(threadlist,
- '\n<tr><td colspan="2"><br /></td></tr>\n')
- print '</table>'
- else:
- output_with_separator(threadlist, '\n\n')
-
-# main program
-
-db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
-
-if output_format == 'html':
- print '''<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Notmuch Patches</title>
-</head>
-<body>'''
- print '<h2>Notmuch Patches</h2>'
- print 'Generated: %s<br />' % datetime.datetime.utcnow().date()
- print 'For more infomation see <a href="http://notmuchmail.org/nmbug">nmbug</a>'
-
- print '<h3>Views</h3>'
- print '<ul>'
- for view in config['views']:
- print '<li><a href="#%(title)s">%(title)s</a></li>' % view
- print '</ul>'
-
-for view in config['views']:
- print_view(**view)
+ page = _PAGES['html']
-if output_format == 'html':
- print '</body>\n</html>'
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_ONLY)
+page.write(database=db, views=config['views'])
diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 92467a31..6a39b32d 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -29,19 +29,33 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
# the byte compiler may load an old .elc file when processing a
# "require" or we may fail to rebuild a .elc that depended on a macro
# from an updated file.
+ifeq ($(HAVE_EMACS),1)
$(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
-f batch-make-deps $(emacs_sources) > $@.tmp && \
- (cmp -s $@.tmp $@ || mv $@.tmp $@)
--include $(dir)/.eldeps
-CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
+ mv $@.tmp $@
+# We could include .eldeps directly, but that would cause a make
+# restart whenever any .el file was modified, even if dependencies
+# didn't change, because the mtime of .eldeps will change. Instead,
+# we include a second file, .eldeps.x, which we ensure always has the
+# same content as .eldeps, but its mtime only changes when dependency
+# information changes, in which case a make restart is necessary
+# anyway.
+$(dir)/.eldeps.x: $(dir)/.eldeps
+ @cmp -s $^ $@ || cp $^ $@
+-include $(dir)/.eldeps.x
+endif
+CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
+ifeq ($(HAVE_EMACS),1)
%.elc: %.el $(global_deps)
$(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $<
+endif
ifeq ($(WITH_EMACS),1)
ifeq ($(HAVE_EMACS),1)
all: $(emacs_bytecode)
+install-emacs: $(emacs_bytecode)
endif
install: install-emacs
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 55c416ac..e325cd3b 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -399,10 +399,12 @@ options will be handled as specified for
(third elem)
(cdr elem))))
(insert
- (notmuch-hello-filtered-query count-query
- (or (plist-get options :filter-count)
- (plist-get options :filter)))
- "\n")))
+ (replace-regexp-in-string
+ "\n" " "
+ (notmuch-hello-filtered-query count-query
+ (or (plist-get options :filter-count)
+ (plist-get options :filter))))
+ "\n")))
(unless (= (call-process-region (point-min) (point-max) notmuch-command
t t nil "count" "--batch") 0)
@@ -788,6 +790,7 @@ following:
"Run notmuch and display saved searches, known tags, etc."
(interactive)
+ (notmuch-assert-cli-sane)
;; This may cause a window configuration change, so if the
;; auto-refresh hook is already installed, avoid recursive refresh.
(let ((notmuch-hello-auto-refresh nil))
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 49fe6445..2fefdadc 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -168,6 +168,24 @@ Otherwise the output will be returned"
(notmuch-check-exit-status status (cons notmuch-command args) output)
output)))
+(defvar notmuch--cli-sane-p nil
+ "Cache whether the CLI seems to be configured sanely.")
+
+(defun notmuch-cli-sane-p ()
+ "Return t if the cli seems to be configured sanely."
+ (unless notmuch--cli-sane-p
+ (let ((status (call-process notmuch-command nil nil nil
+ "config" "get" "user.primary_email")))
+ (setq notmuch--cli-sane-p (= status 0))))
+ notmuch--cli-sane-p)
+
+(defun notmuch-assert-cli-sane ()
+ (unless (notmuch-cli-sane-p)
+ (notmuch-logged-error
+ "notmuch cli seems misconfigured or unconfigured."
+"Perhaps you haven't run \"notmuch setup\" yet? Try running this
+on the command line, and then retry your notmuch command")))
+
(defun notmuch-version ()
"Return a string with the notmuch version number."
(let ((long-string
@@ -180,8 +198,13 @@ Otherwise the output will be returned"
(defun notmuch-config-get (item)
"Return a value from the notmuch configuration."
- ;; Trim off the trailing newline
- (substring (notmuch-command-to-string "config" "get" item) 0 -1))
+ (let* ((val (notmuch-command-to-string "config" "get" item))
+ (len (length val)))
+ ;; Trim off the trailing newline (if the value is empty or not
+ ;; configured, there will be no newline)
+ (if (and (> len 0) (= (aref val (- len 1)) ?\n))
+ (substring val 0 -1)
+ val)))
(defun notmuch-database-path ()
"Return the database.path value from the notmuch configuration."
@@ -197,7 +220,7 @@ Otherwise the output will be returned"
(defun notmuch-user-other-email ()
"Return the user.other_email value (as a list) from the notmuch configuration."
- (split-string (notmuch-config-get "user.other_email") "\n"))
+ (split-string (notmuch-config-get "user.other_email") "\n" t))
(defun notmuch-poll ()
"Run \"notmuch new\" or an external script to import mail.
@@ -231,7 +254,8 @@ depending on the value of `notmuch-poll-script'."
"Given a prefix key code, return a human-readable string representation.
This is basically just `format-kbd-macro' but we also convert ESC to M-."
- (let ((desc (format-kbd-macro (vector key))))
+ (let* ((key-vector (if (vectorp key) key (vector key)))
+ (desc (format-kbd-macro key-vector)))
(if (string= desc "ESC")
"M-"
(concat desc " "))))
@@ -337,6 +361,28 @@ of its command symbol."
(set-buffer-modified-p nil)
(view-buffer (current-buffer) 'kill-buffer-if-not-modified))))
+(defun notmuch-subkeymap-help ()
+ "Show help for a subkeymap."
+ (interactive)
+ (let* ((key (this-command-keys-vector))
+ (prefix (make-vector (1- (length key)) nil))
+ (i 0))
+ (while (< i (length prefix))
+ (aset prefix i (aref key i))
+ (setq i (1+ i)))
+
+ (let* ((subkeymap (key-binding prefix))
+ (ua-keys (where-is-internal 'universal-argument nil t))
+ (prefix-string (notmuch-prefix-key-description prefix))
+ (desc-alist (notmuch-describe-keymap subkeymap ua-keys subkeymap prefix-string))
+ (desc-list (mapcar (lambda (arg) (concat (car arg) "\t" (cdr arg))) desc-alist))
+ (desc (mapconcat #'identity desc-list "\n")))
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (insert "\nPress 'q' to quit this window.\n\n")
+ (insert desc)))
+ (pop-to-buffer (help-buffer)))))
+
(defvar notmuch-buffer-refresh-function nil
"Function to call to refresh the current buffer.")
(make-variable-buffer-local 'notmuch-buffer-refresh-function)
@@ -490,7 +536,8 @@ the given type."
(if (>= 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-disable-advice 'mm-shr 'before 'load-gnus-arts)
+ (ad-activate 'mm-shr)))
(defun notmuch-mm-display-part-inline (msg part nth content-type process-crypto)
"Use the mm-decode/mm-view functions to display a part in the
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 00cd9808..f2df770e 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -231,21 +231,6 @@ list."
(message-goto-body)
(set-buffer-modified-p nil))
-(defun notmuch-mua-forward-message ()
- (funcall (notmuch-mua-get-switch-function) (current-buffer))
- (message-forward)
-
- (when notmuch-mua-user-agent-function
- (let ((user-agent (funcall notmuch-mua-user-agent-function)))
- (when (not (string= "" user-agent))
- (message-add-header (format "User-Agent: %s" user-agent)))))
- (message-sort-headers)
- (message-hide-headers)
- (set-buffer-modified-p nil)
- (notmuch-mua-maybe-set-window-dedicated)
-
- (message-goto-to))
-
(defun notmuch-mua-mail (&optional to subject other-headers &rest other-args)
"Invoke the notmuch mail composition window.
@@ -287,6 +272,19 @@ the From: header is already filled in by notmuch."
(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.
+(if (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 ()
(interactive)
(let (name addresses one-name-only)
@@ -332,13 +330,17 @@ The current buffer must contain an RFC2822 message to forward.
If PROMPT-FOR-SENDER is non-nil, the user will be prompted for
the From: address first."
- (if (or prompt-for-sender notmuch-always-prompt-for-sender)
- (let* ((sender (notmuch-mua-prompt-for-sender))
- (address-components (mail-extract-address-components sender))
- (user-full-name (car address-components))
- (user-mail-address (cadr address-components)))
- (notmuch-mua-forward-message))
- (notmuch-mua-forward-message)))
+ (let* ((cur (current-buffer))
+ (message-forward-decoded-p nil)
+ (subject (message-make-forward-subject))
+ (other-headers
+ (when (or prompt-for-sender notmuch-always-prompt-for-sender)
+ (list (cons 'From (notmuch-mua-prompt-for-sender))))))
+ (notmuch-mua-mail nil subject other-headers nil (notmuch-mua-get-switch-function))
+ (message-forward-make-body cur)
+ ;; `message-forward-make-body' shows the User-agent header. Hide
+ ;; it again.
+ (message-hide-headers)))
(defun notmuch-mua-new-reply (query-string &optional prompt-for-sender reply-all)
"Compose a reply to the message identified by QUERY-STRING.
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 784644cd..88752f17 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -171,7 +171,7 @@ each attachment handler is logged in buffers with names beginning
(defcustom notmuch-show-stash-mlarchive-link-alist
'(("Gmane" . "http://mid.gmane.org/")
("MARC" . "http://marc.info/?i=")
- ("Mail Archive, The" . "http://mail-archive.com/search?l=mid&q=")
+ ("Mail Archive, The" . "http://mid.mail-archive.com/")
("LKML" . "http://lkml.kernel.org/r/")
;; FIXME: can these services be searched by `Message-Id' ?
;; ("MarkMail" . "http://markmail.org/")
@@ -1241,6 +1241,7 @@ reset based on the original query."
(define-key map "t" 'notmuch-show-stash-to)
(define-key map "l" 'notmuch-show-stash-mlarchive-link)
(define-key map "L" 'notmuch-show-stash-mlarchive-link-and-go)
+ (define-key map "?" 'notmuch-subkeymap-help)
map)
"Submap for stash commands")
(fset 'notmuch-show-stash-map notmuch-show-stash-map)
@@ -1251,6 +1252,7 @@ reset based on the original query."
(define-key map "v" 'notmuch-show-view-part)
(define-key map "o" 'notmuch-show-interactively-view-part)
(define-key map "|" 'notmuch-show-pipe-part)
+ (define-key map "?" 'notmuch-subkeymap-help)
map)
"Submap for part commands")
(fset 'notmuch-show-part-map notmuch-show-part-map)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index b60f46c7..908e7ade 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -148,15 +148,16 @@ This can be used with `notmuch-tag-format-image-data'."
(dolist (format (cdr formats) tag)
(setq tag (eval format))))))))
-(defun notmuch-tag-format-tags (tags)
+(defun notmuch-tag-format-tags (tags &optional face)
"Return a string representing formatted TAGS."
- (notmuch-combine-face-text-property-string
- (mapconcat #'identity
- ;; nil indicated that the tag was deliberately hidden
- (delq nil (mapcar #'notmuch-tag-format-tag tags))
- " ")
- 'notmuch-tag-face
- t))
+ (let ((face (or face 'notmuch-tag-face)))
+ (notmuch-combine-face-text-property-string
+ (mapconcat #'identity
+ ;; nil indicated that the tag was deliberately hidden
+ (delq nil (mapcar #'notmuch-tag-format-tag tags))
+ " ")
+ face
+ t)))
(defcustom notmuch-before-tag-hook nil
"Hooks that are run before tags of a message are modified.
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 8d59e65f..4f2ac028 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -70,8 +70,14 @@ Note the author string should not contain
:group 'notmuch-tree)
;; Faces for messages that match the query.
-(defface notmuch-tree-match-date-face
+(defface notmuch-tree-match-face
'((t :inherit default))
+ "Default face used in tree mode face for matching messages"
+ :group 'notmuch-tree
+ :group 'notmuch-faces)
+
+(defface notmuch-tree-match-date-face
+ nil
"Face used in tree mode for the date in messages matching the query."
:group 'notmuch-tree
:group 'notmuch-faces)
@@ -90,13 +96,13 @@ Note the author string should not contain
:group 'notmuch-faces)
(defface notmuch-tree-match-subject-face
- '((t :inherit default))
+ nil
"Face used in tree mode for the subject in messages matching the query."
:group 'notmuch-tree
:group 'notmuch-faces)
(defface notmuch-tree-match-tree-face
- '((t :inherit default))
+ nil
"Face used in tree mode for the thread tree block graphics in messages matching the query."
:group 'notmuch-tree
:group 'notmuch-faces)
@@ -115,32 +121,38 @@ Note the author string should not contain
:group 'notmuch-faces)
;; Faces for messages that do not match the query.
-(defface notmuch-tree-no-match-date-face
+(defface notmuch-tree-no-match-face
'((t (:foreground "gray")))
+ "Default face used in tree mode face for non-matching messages"
+ :group 'notmuch-tree
+ :group 'notmuch-faces)
+
+(defface notmuch-tree-no-match-date-face
+ nil
"Face used in tree mode for non-matching dates."
:group 'notmuch-tree
:group 'notmuch-faces)
(defface notmuch-tree-no-match-subject-face
- '((t (:foreground "gray")))
+ nil
"Face used in tree mode for non-matching subjects."
:group 'notmuch-tree
:group 'notmuch-faces)
(defface notmuch-tree-no-match-tree-face
- '((t (:foreground "gray")))
+ nil
"Face used in tree mode for the thread tree block graphics in messages matching the query."
:group 'notmuch-tree
:group 'notmuch-faces)
(defface notmuch-tree-no-match-author-face
- '((t (:foreground "gray")))
+ nil
"Face used in tree mode for the date in messages matching the query."
:group 'notmuch-tree
:group 'notmuch-faces)
(defface notmuch-tree-no-match-tag-face
- '((t (:foreground "gray")))
+ nil
"Face used in tree mode face for non-matching tags."
:group 'notmuch-tree
:group 'notmuch-faces)
@@ -319,11 +331,13 @@ correct message properties."
"Return the tags of the current message."
(notmuch-tree-get-prop :tags))
-(defun notmuch-tree-get-message-id ()
+(defun notmuch-tree-get-message-id (&optional bare)
"Return the message id of the current message."
(let ((id (notmuch-tree-get-prop :id)))
(if id
- (notmuch-id-to-query id)
+ (if bare
+ id
+ (notmuch-id-to-query id))
nil)))
(defun notmuch-tree-get-match ()
@@ -690,17 +704,18 @@ unchanged ADDRESS if parsing fails."
(face (if match
'notmuch-tree-match-tag-face
'notmuch-tree-no-match-tag-face)))
- (propertize (format format-string
- (mapconcat #'identity tags ", "))
- 'face face))))))
-
+ (format format-string (notmuch-tag-format-tags tags face)))))))
(defun notmuch-tree-format-field-list (field-list msg)
"Format fields of MSG according to FIELD-LIST and return string"
- (let (result-string)
+ (let ((face (if (plist-get msg :match)
+ 'notmuch-tree-match-face
+ 'notmuch-tree-no-match-face))
+ (result-string))
(dolist (spec field-list result-string)
(let ((field-string (notmuch-tree-format-field (car spec) (cdr spec) msg)))
- (setq result-string (concat result-string field-string))))))
+ (setq result-string (concat result-string field-string))))
+ (notmuch-combine-face-text-property-string result-string face t)))
(defun notmuch-tree-insert-msg (msg)
"Insert the message MSG according to notmuch-tree-result-format"
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index c9bc2f22..04717500 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -165,6 +165,7 @@ To enter a line break in customize, press \\[quoted-insert] C-j."
(defvar notmuch-search-stash-map
(let ((map (make-sparse-keymap)))
(define-key map "i" 'notmuch-search-stash-thread-id)
+ (define-key map "?" 'notmuch-subkeymap-help)
map)
"Submap for stash commands")
(fset 'notmuch-search-stash-map notmuch-search-stash-map)
diff --git a/lib/message.cc b/lib/message.cc
index 1b463795..c91f3a59 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -412,19 +412,27 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message)
const char *
notmuch_message_get_header (notmuch_message_t *message, const char *header)
{
- std::string value;
+ try {
+ std::string value;
- /* Fetch header from the appropriate xapian value field if
- * available */
- if (strcasecmp (header, "from") == 0)
- value = message->doc.get_value (NOTMUCH_VALUE_FROM);
- else if (strcasecmp (header, "subject") == 0)
- value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
- else if (strcasecmp (header, "message-id") == 0)
- value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID);
+ /* Fetch header from the appropriate xapian value field if
+ * available */
+ if (strcasecmp (header, "from") == 0)
+ value = message->doc.get_value (NOTMUCH_VALUE_FROM);
+ else if (strcasecmp (header, "subject") == 0)
+ value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
+ else if (strcasecmp (header, "message-id") == 0)
+ value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID);
- if (!value.empty())
- return talloc_strdup (message, value.c_str ());
+ if (!value.empty())
+ return talloc_strdup (message, value.c_str ());
+
+ } catch (Xapian::Error &error) {
+ fprintf (stderr, "A Xapian exception occurred when reading header: %s\n",
+ error.get_msg().c_str());
+ message->notmuch->exception_reported = TRUE;
+ return NULL;
+ }
/* Otherwise fall back to parsing the file */
_notmuch_message_ensure_message_file (message);
@@ -766,7 +774,9 @@ notmuch_message_get_date (notmuch_message_t *message)
try {
value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
} catch (Xapian::Error &error) {
- INTERNAL_ERROR ("Failed to read timestamp value from document.");
+ fprintf (stderr, "A Xapian exception occurred when reading date: %s\n",
+ error.get_msg().c_str());
+ message->notmuch->exception_reported = TRUE;
return 0;
}
diff --git a/lib/notmuch.h b/lib/notmuch.h
index d30768d9..350bed8b 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -18,9 +18,19 @@
* Author: Carl Worth <cworth@cworth.org>
*/
+/**
+ * @defgroup notmuch The notmuch API
+ *
+ * Not much of an email library, (just index and search)
+ *
+ * @{
+ */
+
#ifndef NOTMUCH_H
#define NOTMUCH_H
+#ifndef __DOXYGEN__
+
#ifdef __cplusplus
# define NOTMUCH_BEGIN_DECLS extern "C" {
# define NOTMUCH_END_DECLS }
@@ -49,19 +59,28 @@ NOTMUCH_BEGIN_DECLS
#define LIBNOTMUCH_MINOR_VERSION 1
#define LIBNOTMUCH_MICRO_VERSION 0
-/*
+#endif /* __DOXYGEN__ */
+
+/**
* Check the version of the notmuch library being compiled against.
*
* Return true if the library being compiled against is of the
* specified version or above. For example:
*
+ * @code
* #if LIBNOTMUCH_CHECK_VERSION(3, 1, 0)
* (code requiring libnotmuch 3.1.0 or above)
* #endif
+ * @endcode
*
- * LIBNOTMUCH_CHECK_VERSION has been defined since version 3.1.0; you
- * can use #if !defined(NOTMUCH_CHECK_VERSION) to check for versions
- * prior to that.
+ * LIBNOTMUCH_CHECK_VERSION has been defined since version 3.1.0; to
+ * check for versions prior to that, use:
+ *
+ * @code
+ * #if !defined(NOTMUCH_CHECK_VERSION)
+ * (code requiring libnotmuch prior to 3.1.0)
+ * #endif
+ * @endcode
*/
#define LIBNOTMUCH_CHECK_VERSION (major, minor, micro) \
(LIBNOTMUCH_MAJOR_VERSION > (major) || \
@@ -69,72 +88,86 @@ NOTMUCH_BEGIN_DECLS
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \
LIBNOTMUCH_MICRO_VERSION >= (micro)))
+/**
+ * Notmuch boolean type.
+ */
typedef int notmuch_bool_t;
-/* Status codes used for the return values of most functions.
+/**
+ * Status codes used for the return values of most functions.
*
* A zero value (NOTMUCH_STATUS_SUCCESS) indicates that the function
- * completed without error. Any other value indicates an error as
- * follows:
- *
- * NOTMUCH_STATUS_SUCCESS: No error occurred.
- *
- * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory
- *
- * XXX: We don't really want to expose this lame XAPIAN_EXCEPTION
- * value. Instead we should map to things like DATABASE_LOCKED or
- * whatever.
- *
- * NOTMUCH_STATUS_READ_ONLY_DATABASE: An attempt was made to write to
- * a database opened in read-only mode.
- *
- * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
- *
- * NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to read or
- * write to a file (this could be file not found, permission
- * denied, etc.)
- *
- * NOTMUCH_STATUS_FILE_NOT_EMAIL: A file was presented that doesn't
- * appear to be an email message.
- *
- * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: A file contains a message ID
- * that is identical to a message already in the database.
- *
- * NOTMUCH_STATUS_NULL_POINTER: The user erroneously passed a NULL
- * pointer to a notmuch function.
- *
- * NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long (exceeds
- * NOTMUCH_TAG_MAX)
- *
- * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw
- * function has been called more times than notmuch_message_freeze.
- *
- * NOTMUCH_STATUS_UNBALANCED_ATOMIC: notmuch_database_end_atomic has
- * been called more times than notmuch_database_begin_atomic.
- *
- * And finally:
- *
- * NOTMUCH_STATUS_LAST_STATUS: Not an actual status value. Just a way
- * to find out how many valid status values there are.
+ * completed without error. Any other value indicates an error.
*/
typedef enum _notmuch_status {
+ /**
+ * No error occurred.
+ */
NOTMUCH_STATUS_SUCCESS = 0,
+ /**
+ * Out of memory.
+ */
NOTMUCH_STATUS_OUT_OF_MEMORY,
+ /**
+ * An attempt was made to write to a database opened in read-only
+ * mode.
+ */
NOTMUCH_STATUS_READ_ONLY_DATABASE,
+ /**
+ * A Xapian exception occurred.
+ */
NOTMUCH_STATUS_XAPIAN_EXCEPTION,
+ /**
+ * An error occurred trying to read or write to a file (this could
+ * be file not found, permission denied, etc.)
+ *
+ * @todo We don't really want to expose this lame XAPIAN_EXCEPTION
+ * value. Instead we should map to things like DATABASE_LOCKED or
+ * whatever.
+ */
NOTMUCH_STATUS_FILE_ERROR,
+ /**
+ * A file was presented that doesn't appear to be an email
+ * message.
+ */
NOTMUCH_STATUS_FILE_NOT_EMAIL,
+ /**
+ * A file contains a message ID that is identical to a message
+ * already in the database.
+ */
NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID,
+ /**
+ * The user erroneously passed a NULL pointer to a notmuch
+ * function.
+ */
NOTMUCH_STATUS_NULL_POINTER,
+ /**
+ * A tag value is too long (exceeds NOTMUCH_TAG_MAX).
+ */
NOTMUCH_STATUS_TAG_TOO_LONG,
+ /**
+ * The notmuch_message_thaw function has been called more times
+ * than notmuch_message_freeze.
+ */
NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
+ /**
+ * notmuch_database_end_atomic has been called more times than
+ * notmuch_database_begin_atomic.
+ */
NOTMUCH_STATUS_UNBALANCED_ATOMIC,
+ /**
+ * The operation is not supported.
+ */
NOTMUCH_STATUS_UNSUPPORTED_OPERATION,
-
+ /**
+ * Not an actual status value. Just a way to find out how many
+ * valid status values there are.
+ */
NOTMUCH_STATUS_LAST_STATUS
} notmuch_status_t;
-/* Get a string representation of a notmuch_status_t value.
+/**
+ * Get a string representation of a notmuch_status_t value.
*
* The result is read-only.
*/
@@ -143,6 +176,7 @@ notmuch_status_to_string (notmuch_status_t status);
/* Various opaque data types. For each notmuch_<foo>_t see the various
* notmuch_<foo> functions below. */
+#ifndef __DOXYGEN__
typedef struct _notmuch_database notmuch_database_t;
typedef struct _notmuch_query notmuch_query_t;
typedef struct _notmuch_threads notmuch_threads_t;
@@ -152,8 +186,10 @@ typedef struct _notmuch_message notmuch_message_t;
typedef struct _notmuch_tags notmuch_tags_t;
typedef struct _notmuch_directory notmuch_directory_t;
typedef struct _notmuch_filenames notmuch_filenames_t;
+#endif /* __DOXYGEN__ */
-/* Create a new, empty notmuch database located at 'path'.
+/**
+ * Create a new, empty notmuch database located at 'path'.
*
* The path should be a top-level directory to a collection of
* plain-text email messages (one message per file). This call will
@@ -189,12 +225,22 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
notmuch_status_t
notmuch_database_create (const char *path, notmuch_database_t **database);
+/**
+ * Database open mode for notmuch_database_open.
+ */
typedef enum {
+ /**
+ * Open database for reading only.
+ */
NOTMUCH_DATABASE_MODE_READ_ONLY = 0,
+ /**
+ * Open database for reading and writing.
+ */
NOTMUCH_DATABASE_MODE_READ_WRITE
} notmuch_database_mode_t;
-/* Open an existing notmuch database located at 'path'.
+/**
+ * Open an existing notmuch database located at 'path'.
*
* The database should have been created at some time in the past,
* (not necessarily by this process), by calling
@@ -230,7 +276,8 @@ notmuch_database_open (const char *path,
notmuch_database_mode_t mode,
notmuch_database_t **database);
-/* Close the given notmuch database.
+/**
+ * Close the given notmuch database.
*
* After notmuch_database_close has been called, calls to other
* functions on objects derived from this database may either behave
@@ -244,12 +291,14 @@ notmuch_database_open (const char *path,
void
notmuch_database_close (notmuch_database_t *database);
-/* A callback invoked by notmuch_database_compact to notify the user
+/**
+ * A callback invoked by notmuch_database_compact to notify the user
* of the progress of the compaction process.
*/
typedef void (*notmuch_compact_status_cb_t)(const char *message, void *closure);
-/* Compact a notmuch database, backing up the original database to the
+/**
+ * Compact a notmuch database, backing up the original database to the
* given path.
*
* The database will be opened with NOTMUCH_DATABASE_MODE_READ_WRITE
@@ -265,33 +314,41 @@ notmuch_database_compact (const char* path,
notmuch_compact_status_cb_t status_cb,
void *closure);
-/* Destroy the notmuch database, closing it if necessary and freeing
+/**
+ * Destroy the notmuch database, closing it if necessary and freeing
* all associated resources.
*/
void
notmuch_database_destroy (notmuch_database_t *database);
-/* Return the database path of the given database.
+/**
+ * Return the database path of the given database.
*
* The return value is a string owned by notmuch so should not be
- * modified nor freed by the caller. */
+ * modified nor freed by the caller.
+ */
const char *
notmuch_database_get_path (notmuch_database_t *database);
-/* Return the database format version of the given database. */
+/**
+ * Return the database format version of the given database.
+ */
unsigned int
notmuch_database_get_version (notmuch_database_t *database);
-/* Does this database need to be upgraded before writing to it?
+/**
+ * Does this database need to be upgraded before writing to it?
*
* If this function returns TRUE then no functions that modify the
* database (notmuch_database_add_message, notmuch_message_add_tag,
* notmuch_directory_set_mtime, etc.) will work unless the function
- * notmuch_database_upgrade is called successfully first. */
+ * notmuch_database_upgrade is called successfully first.
+ */
notmuch_bool_t
notmuch_database_needs_upgrade (notmuch_database_t *database);
-/* Upgrade the current database.
+/**
+ * Upgrade the current database.
*
* After opening a database in read-write mode, the client should
* check if an upgrade is needed (notmuch_database_needs_upgrade) and
@@ -310,7 +367,8 @@ notmuch_database_upgrade (notmuch_database_t *database,
double progress),
void *closure);
-/* Begin an atomic database operation.
+/**
+ * Begin an atomic database operation.
*
* Any modifications performed between a successful begin and a
* notmuch_database_end_atomic will be applied to the database
@@ -331,7 +389,8 @@ notmuch_database_upgrade (notmuch_database_t *database,
notmuch_status_t
notmuch_database_begin_atomic (notmuch_database_t *notmuch);
-/* Indicate the end of an atomic database operation.
+/**
+ * Indicate the end of an atomic database operation.
*
* Return value:
*
@@ -346,7 +405,8 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch);
notmuch_status_t
notmuch_database_end_atomic (notmuch_database_t *notmuch);
-/* Retrieve a directory object from the database for 'path'.
+/**
+ * Retrieve a directory object from the database for 'path'.
*
* Here, 'path' should be a path relative to the path of 'database'
* (see notmuch_database_get_path), or else should be an absolute path
@@ -355,6 +415,10 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch);
* If this directory object does not exist in the database, this
* returns NOTMUCH_STATUS_SUCCESS and sets *directory to NULL.
*
+ * Otherwise the returned directory object is owned by the database
+ * and as such, will only be valid until notmuch_database_destroy is
+ * called.
+ *
* Return value:
*
* NOTMUCH_STATUS_SUCCESS: Successfully retrieved directory.
@@ -369,7 +433,8 @@ notmuch_database_get_directory (notmuch_database_t *database,
const char *path,
notmuch_directory_t **directory);
-/* Add a new message to the given notmuch database or associate an
+/**
+ * Add a new message to the given notmuch database or associate an
* additional filename with an existing message.
*
* Here, 'filename' should be a path relative to the path of
@@ -420,7 +485,8 @@ notmuch_database_add_message (notmuch_database_t *database,
const char *filename,
notmuch_message_t **message);
-/* Remove a message filename from the given notmuch database. If the
+/**
+ * Remove a message filename from the given notmuch database. If the
* message has no more filenames, remove the message.
*
* If the same message (as determined by the message ID) is still
@@ -448,7 +514,8 @@ notmuch_status_t
notmuch_database_remove_message (notmuch_database_t *database,
const char *filename);
-/* Find a message with the given message_id.
+/**
+ * Find a message with the given message_id.
*
* If a message with the given message_id is found then, on successful return
* (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message
@@ -475,7 +542,8 @@ notmuch_database_find_message (notmuch_database_t *database,
const char *message_id,
notmuch_message_t **message);
-/* Find a message with the given filename.
+/**
+ * Find a message with the given filename.
*
* If the database contains a message with the given filename then, on
* successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to
@@ -502,7 +570,8 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
const char *filename,
notmuch_message_t **message);
-/* Return a list of all tags found in the database.
+/**
+ * Return a list of all tags found in the database.
*
* This function creates a list of all tags found in the database. The
* resulting list contains all tags from all messages found in the database.
@@ -512,7 +581,8 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
notmuch_tags_t *
notmuch_database_get_all_tags (notmuch_database_t *db);
-/* Create a new query for 'database'.
+/**
+ * Create a new query for 'database'.
*
* Here, 'database' should be an open database, (see
* notmuch_database_open and notmuch_database_create).
@@ -540,19 +610,36 @@ notmuch_query_t *
notmuch_query_create (notmuch_database_t *database,
const char *query_string);
-/* Sort values for notmuch_query_set_sort */
+/**
+ * Sort values for notmuch_query_set_sort.
+ */
typedef enum {
+ /**
+ * Oldest first.
+ */
NOTMUCH_SORT_OLDEST_FIRST,
+ /**
+ * Newest first.
+ */
NOTMUCH_SORT_NEWEST_FIRST,
+ /**
+ * Sort by message-id.
+ */
NOTMUCH_SORT_MESSAGE_ID,
+ /**
+ * Do not sort.
+ */
NOTMUCH_SORT_UNSORTED
} notmuch_sort_t;
-/* Return the query_string of this query. See notmuch_query_create. */
+/**
+ * Return the query_string of this query. See notmuch_query_create.
+ */
const char *
notmuch_query_get_query_string (notmuch_query_t *query);
-/* Exclude values for notmuch_query_set_omit_excluded. The strange
+/**
+ * Exclude values for notmuch_query_set_omit_excluded. The strange
* order is to maintain backward compatibility: the old FALSE/TRUE
* options correspond to the new
* NOTMUCH_EXCLUDE_FLAG/NOTMUCH_EXCLUDE_TRUE options.
@@ -564,7 +651,8 @@ typedef enum {
NOTMUCH_EXCLUDE_ALL
} notmuch_exclude_t;
-/* Specify whether to omit excluded results or simply flag them. By
+/**
+ * Specify whether to omit excluded results or simply flag them. By
* default, this is set to TRUE.
*
* If set to TRUE or ALL, notmuch_query_search_messages will omit excluded
@@ -594,21 +682,29 @@ void
notmuch_query_set_omit_excluded (notmuch_query_t *query,
notmuch_exclude_t omit_excluded);
-/* Specify the sorting desired for this query. */
+/**
+ * Specify the sorting desired for this query.
+ */
void
notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
-/* Return the sort specified for this query. See notmuch_query_set_sort. */
+/**
+ * Return the sort specified for this query. See
+ * notmuch_query_set_sort.
+ */
notmuch_sort_t
notmuch_query_get_sort (notmuch_query_t *query);
-/* Add a tag that will be excluded from the query results by default.
+/**
+ * Add a tag that will be excluded from the query results by default.
* This exclusion will be overridden if this tag appears explicitly in
- * the query. */
+ * the query.
+ */
void
notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag);
-/* Execute a query for threads, returning a notmuch_threads_t object
+/**
+ * Execute a query for threads, returning a notmuch_threads_t object
* which can be used to iterate over the results. The returned threads
* object is owned by the query and as such, will only be valid until
* notmuch_query_destroy.
@@ -649,7 +745,8 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag);
notmuch_threads_t *
notmuch_query_search_threads (notmuch_query_t *query);
-/* Execute a query for messages, returning a notmuch_messages_t object
+/**
+ * Execute a query for messages, returning a notmuch_messages_t object
* which can be used to iterate over the results. The returned
* messages object is owned by the query and as such, will only be
* valid until notmuch_query_destroy.
@@ -690,7 +787,8 @@ notmuch_query_search_threads (notmuch_query_t *query);
notmuch_messages_t *
notmuch_query_search_messages (notmuch_query_t *query);
-/* Destroy a notmuch_query_t along with any associated resources.
+/**
+ * Destroy a notmuch_query_t along with any associated resources.
*
* This will in turn destroy any notmuch_threads_t and
* notmuch_messages_t objects generated by this query, (and in
@@ -701,19 +799,23 @@ notmuch_query_search_messages (notmuch_query_t *query);
void
notmuch_query_destroy (notmuch_query_t *query);
-/* Is the given 'threads' iterator pointing at a valid thread.
+/**
+ * Is the given 'threads' iterator pointing at a valid thread.
*
* When this function returns TRUE, notmuch_threads_get will return a
* valid object. Whereas when this function returns FALSE,
* notmuch_threads_get will return NULL.
*
+ * If passed a NULL pointer, this function returns FALSE
+ *
* See the documentation of notmuch_query_search_threads for example
* code showing how to iterate over a notmuch_threads_t object.
*/
notmuch_bool_t
notmuch_threads_valid (notmuch_threads_t *threads);
-/* Get the current thread from 'threads' as a notmuch_thread_t.
+/**
+ * Get the current thread from 'threads' as a notmuch_thread_t.
*
* Note: The returned thread belongs to 'threads' and has a lifetime
* identical to it (and the query to which it belongs).
@@ -727,7 +829,8 @@ notmuch_threads_valid (notmuch_threads_t *threads);
notmuch_thread_t *
notmuch_threads_get (notmuch_threads_t *threads);
-/* Move the 'threads' iterator to the next thread.
+/**
+ * Move the 'threads' iterator to the next thread.
*
* If 'threads' is already pointing at the last thread then the
* iterator will be moved to a point just beyond that last thread,
@@ -740,7 +843,8 @@ notmuch_threads_get (notmuch_threads_t *threads);
void
notmuch_threads_move_to_next (notmuch_threads_t *threads);
-/* Destroy a notmuch_threads_t object.
+/**
+ * Destroy a notmuch_threads_t object.
*
* It's not strictly necessary to call this function. All memory from
* the notmuch_threads_t object will be reclaimed when the
@@ -749,7 +853,8 @@ notmuch_threads_move_to_next (notmuch_threads_t *threads);
void
notmuch_threads_destroy (notmuch_threads_t *threads);
-/* Return an estimate of the number of messages matching a search
+/**
+ * Return an estimate of the number of messages matching a search.
*
* This function performs a search and returns Xapian's best
* guess as to number of matching messages.
@@ -759,8 +864,9 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
*/
unsigned
notmuch_query_count_messages (notmuch_query_t *query);
-
-/* Return the number of threads matching a search.
+
+/**
+ * Return the number of threads matching a search.
*
* This function performs a search and returns the number of unique thread IDs
* in the matching messages. This is the same as number of threads matching a
@@ -774,7 +880,8 @@ notmuch_query_count_messages (notmuch_query_t *query);
unsigned
notmuch_query_count_threads (notmuch_query_t *query);
-/* Get the thread ID of 'thread'.
+/**
+ * Get the thread ID of 'thread'.
*
* The returned string belongs to 'thread' and as such, should not be
* modified by the caller and will only be valid for as long as the
@@ -784,7 +891,8 @@ notmuch_query_count_threads (notmuch_query_t *query);
const char *
notmuch_thread_get_thread_id (notmuch_thread_t *thread);
-/* Get the total number of messages in 'thread'.
+/**
+ * Get the total number of messages in 'thread'.
*
* This count consists of all messages in the database belonging to
* this thread. Contrast with notmuch_thread_get_matched_messages() .
@@ -792,7 +900,8 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread);
int
notmuch_thread_get_total_messages (notmuch_thread_t *thread);
-/* Get a notmuch_messages_t iterator for the top-level messages in
+/**
+ * Get a notmuch_messages_t iterator for the top-level messages in
* 'thread' in oldest-first order.
*
* This iterator will not necessarily iterate over all of the messages
@@ -804,7 +913,8 @@ notmuch_thread_get_total_messages (notmuch_thread_t *thread);
notmuch_messages_t *
notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread);
-/* Get a notmuch_thread_t iterator for all messages in 'thread' in
+/**
+ * Get a notmuch_thread_t iterator for all messages in 'thread' in
* oldest-first order.
*
* The returned list will be destroyed when the thread is destroyed.
@@ -812,7 +922,8 @@ notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread);
notmuch_messages_t *
notmuch_thread_get_messages (notmuch_thread_t *thread);
-/* Get the number of messages in 'thread' that matched the search.
+/**
+ * Get the number of messages in 'thread' that matched the search.
*
* This count includes only the messages in this thread that were
* matched by the search from which the thread was created and were
@@ -823,7 +934,8 @@ notmuch_thread_get_messages (notmuch_thread_t *thread);
int
notmuch_thread_get_matched_messages (notmuch_thread_t *thread);
-/* Get the authors of 'thread' as a UTF-8 string.
+/**
+ * Get the authors of 'thread' as a UTF-8 string.
*
* The returned string is a comma-separated list of the names of the
* authors of mail messages in the query results that belong to this
@@ -837,7 +949,8 @@ notmuch_thread_get_matched_messages (notmuch_thread_t *thread);
const char *
notmuch_thread_get_authors (notmuch_thread_t *thread);
-/* Get the subject of 'thread' as a UTF-8 string.
+/**
+ * Get the subject of 'thread' as a UTF-8 string.
*
* The subject is taken from the first message (according to the query
* order---see notmuch_query_set_sort) in the query results that
@@ -851,17 +964,20 @@ notmuch_thread_get_authors (notmuch_thread_t *thread);
const char *
notmuch_thread_get_subject (notmuch_thread_t *thread);
-/* Get the date of the oldest message in 'thread' as a time_t value.
+/**
+ * Get the date of the oldest message in 'thread' as a time_t value.
*/
time_t
notmuch_thread_get_oldest_date (notmuch_thread_t *thread);
-/* Get the date of the newest message in 'thread' as a time_t value.
+/**
+ * Get the date of the newest message in 'thread' as a time_t value.
*/
time_t
notmuch_thread_get_newest_date (notmuch_thread_t *thread);
-/* Get the tags for 'thread', returning a notmuch_tags_t object which
+/**
+ * Get the tags for 'thread', returning a notmuch_tags_t object which
* can be used to iterate over all tags.
*
* Note: In the Notmuch database, tags are stored on individual
@@ -884,7 +1000,7 @@ notmuch_thread_get_newest_date (notmuch_thread_t *thread);
*
* for (tags = notmuch_thread_get_tags (thread);
* notmuch_tags_valid (tags);
- * notmuch_result_move_to_next (tags))
+ * notmuch_tags_move_to_next (tags))
* {
* tag = notmuch_tags_get (tags);
* ....
@@ -900,11 +1016,14 @@ notmuch_thread_get_newest_date (notmuch_thread_t *thread);
notmuch_tags_t *
notmuch_thread_get_tags (notmuch_thread_t *thread);
-/* Destroy a notmuch_thread_t object. */
+/**
+ * Destroy a notmuch_thread_t object.
+ */
void
notmuch_thread_destroy (notmuch_thread_t *thread);
-/* Is the given 'messages' iterator pointing at a valid message.
+/**
+ * Is the given 'messages' iterator pointing at a valid message.
*
* When this function returns TRUE, notmuch_messages_get will return a
* valid object. Whereas when this function returns FALSE,
@@ -916,7 +1035,8 @@ notmuch_thread_destroy (notmuch_thread_t *thread);
notmuch_bool_t
notmuch_messages_valid (notmuch_messages_t *messages);
-/* Get the current message from 'messages' as a notmuch_message_t.
+/**
+ * Get the current message from 'messages' as a notmuch_message_t.
*
* Note: The returned message belongs to 'messages' and has a lifetime
* identical to it (and the query to which it belongs).
@@ -930,7 +1050,8 @@ notmuch_messages_valid (notmuch_messages_t *messages);
notmuch_message_t *
notmuch_messages_get (notmuch_messages_t *messages);
-/* Move the 'messages' iterator to the next message.
+/**
+ * Move the 'messages' iterator to the next message.
*
* If 'messages' is already pointing at the last message then the
* iterator will be moved to a point just beyond that last message,
@@ -943,7 +1064,8 @@ notmuch_messages_get (notmuch_messages_t *messages);
void
notmuch_messages_move_to_next (notmuch_messages_t *messages);
-/* Destroy a notmuch_messages_t object.
+/**
+ * Destroy a notmuch_messages_t object.
*
* It's not strictly necessary to call this function. All memory from
* the notmuch_messages_t object will be reclaimed when the containing
@@ -952,7 +1074,8 @@ notmuch_messages_move_to_next (notmuch_messages_t *messages);
void
notmuch_messages_destroy (notmuch_messages_t *messages);
-/* Return a list of tags from all messages.
+/**
+ * Return a list of tags from all messages.
*
* The resulting list is guaranteed not to contain duplicated tags.
*
@@ -967,7 +1090,8 @@ notmuch_messages_destroy (notmuch_messages_t *messages);
notmuch_tags_t *
notmuch_messages_collect_tags (notmuch_messages_t *messages);
-/* Get the message ID of 'message'.
+/**
+ * Get the message ID of 'message'.
*
* The returned string belongs to 'message' and as such, should not be
* modified by the caller and will only be valid for as long as the
@@ -981,7 +1105,8 @@ notmuch_messages_collect_tags (notmuch_messages_t *messages);
const char *
notmuch_message_get_message_id (notmuch_message_t *message);
-/* Get the thread ID of 'message'.
+/**
+ * Get the thread ID of 'message'.
*
* The returned string belongs to 'message' and as such, should not be
* modified by the caller and will only be valid for as long as the
@@ -995,7 +1120,8 @@ notmuch_message_get_message_id (notmuch_message_t *message);
const char *
notmuch_message_get_thread_id (notmuch_message_t *message);
-/* Get a notmuch_messages_t iterator for all of the replies to
+/**
+ * Get a notmuch_messages_t iterator for all of the replies to
* 'message'.
*
* Note: This call only makes sense if 'message' was ultimately
@@ -1015,7 +1141,8 @@ notmuch_message_get_thread_id (notmuch_message_t *message);
notmuch_messages_t *
notmuch_message_get_replies (notmuch_message_t *message);
-/* Get a filename for the email corresponding to 'message'.
+/**
+ * Get a filename for the email corresponding to 'message'.
*
* The returned filename is an absolute filename, (the initial
* component will match notmuch_database_get_path() ).
@@ -1033,7 +1160,8 @@ notmuch_message_get_replies (notmuch_message_t *message);
const char *
notmuch_message_get_filename (notmuch_message_t *message);
-/* Get all filenames for the email corresponding to 'message'.
+/**
+ * Get all filenames for the email corresponding to 'message'.
*
* Returns a notmuch_filenames_t iterator listing all the filenames
* associated with 'message'. These files may not have identical
@@ -1045,31 +1173,40 @@ notmuch_message_get_filename (notmuch_message_t *message);
notmuch_filenames_t *
notmuch_message_get_filenames (notmuch_message_t *message);
-/* Message flags */
+/**
+ * Message flags.
+ */
typedef enum _notmuch_message_flag {
NOTMUCH_MESSAGE_FLAG_MATCH,
NOTMUCH_MESSAGE_FLAG_EXCLUDED
} notmuch_message_flag_t;
-/* Get a value of a flag for the email corresponding to 'message'. */
+/**
+ * Get a value of a flag for the email corresponding to 'message'.
+ */
notmuch_bool_t
notmuch_message_get_flag (notmuch_message_t *message,
notmuch_message_flag_t flag);
-/* Set a value of a flag for the email corresponding to 'message'. */
+/**
+ * Set a value of a flag for the email corresponding to 'message'.
+ */
void
notmuch_message_set_flag (notmuch_message_t *message,
notmuch_message_flag_t flag, notmuch_bool_t value);
-/* Get the date of 'message' as a time_t value.
+/**
+ * Get the date of 'message' as a time_t value.
*
* For the original textual representation of the Date header from the
* message call notmuch_message_get_header() with a header value of
- * "date". */
+ * "date".
+ */
time_t
notmuch_message_get_date (notmuch_message_t *message);
-/* Get the value of the specified header from 'message' as a UTF-8 string.
+/**
+ * Get the value of the specified header from 'message' as a UTF-8 string.
*
* Common headers are stored in the database when the message is
* indexed and will be returned from the database. Other headers will
@@ -1087,7 +1224,8 @@ notmuch_message_get_date (notmuch_message_t *message);
const char *
notmuch_message_get_header (notmuch_message_t *message, const char *header);
-/* Get the tags for 'message', returning a notmuch_tags_t object which
+/**
+ * Get the tags for 'message', returning a notmuch_tags_t object which
* can be used to iterate over all tags.
*
* The tags object is owned by the message and as such, will only be
@@ -1104,7 +1242,7 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header);
*
* for (tags = notmuch_message_get_tags (message);
* notmuch_tags_valid (tags);
- * notmuch_result_move_to_next (tags))
+ * notmuch_tags_move_to_next (tags))
* {
* tag = notmuch_tags_get (tags);
* ....
@@ -1120,10 +1258,13 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header);
notmuch_tags_t *
notmuch_message_get_tags (notmuch_message_t *message);
-/* The longest possible tag value. */
+/**
+ * The longest possible tag value.
+ */
#define NOTMUCH_TAG_MAX 200
-/* Add a tag to the given message.
+/**
+ * Add a tag to the given message.
*
* Return value:
*
@@ -1140,7 +1281,8 @@ notmuch_message_get_tags (notmuch_message_t *message);
notmuch_status_t
notmuch_message_add_tag (notmuch_message_t *message, const char *tag);
-/* Remove a tag from the given message.
+/**
+ * Remove a tag from the given message.
*
* Return value:
*
@@ -1157,7 +1299,8 @@ notmuch_message_add_tag (notmuch_message_t *message, const char *tag);
notmuch_status_t
notmuch_message_remove_tag (notmuch_message_t *message, const char *tag);
-/* Remove all tags from the given message.
+/**
+ * Remove all tags from the given message.
*
* See notmuch_message_freeze for an example showing how to safely
* replace tag values.
@@ -1168,7 +1311,8 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag);
notmuch_status_t
notmuch_message_remove_all_tags (notmuch_message_t *message);
-/* Add/remove tags according to maildir flags in the message filename(s)
+/**
+ * Add/remove tags according to maildir flags in the message filename(s).
*
* This function examines the filenames of 'message' for maildir
* flags, and adds or removes tags on 'message' as follows when these
@@ -1202,7 +1346,8 @@ notmuch_message_remove_all_tags (notmuch_message_t *message);
notmuch_status_t
notmuch_message_maildir_flags_to_tags (notmuch_message_t *message);
-/* Rename message filename(s) to encode tags as maildir flags
+/**
+ * Rename message filename(s) to encode tags as maildir flags.
*
* Specifically, for each filename corresponding to this message:
*
@@ -1238,7 +1383,8 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message);
notmuch_status_t
notmuch_message_tags_to_maildir_flags (notmuch_message_t *message);
-/* Freeze the current state of 'message' within the database.
+/**
+ * Freeze the current state of 'message' within the database.
*
* This means that changes to the message state, (via
* notmuch_message_add_tag, notmuch_message_remove_tag, and
@@ -1281,7 +1427,8 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message);
notmuch_status_t
notmuch_message_freeze (notmuch_message_t *message);
-/* Thaw the current 'message', synchronizing any changes that may have
+/**
+ * Thaw the current 'message', synchronizing any changes that may have
* occurred while 'message' was frozen into the notmuch database.
*
* See notmuch_message_freeze for an example of how to use this
@@ -1304,7 +1451,8 @@ notmuch_message_freeze (notmuch_message_t *message);
notmuch_status_t
notmuch_message_thaw (notmuch_message_t *message);
-/* Destroy a notmuch_message_t object.
+/**
+ * Destroy a notmuch_message_t object.
*
* It can be useful to call this function in the case of a single
* query object with many messages in the result, (such as iterating
@@ -1315,7 +1463,8 @@ notmuch_message_thaw (notmuch_message_t *message);
void
notmuch_message_destroy (notmuch_message_t *message);
-/* Is the given 'tags' iterator pointing at a valid tag.
+/**
+ * Is the given 'tags' iterator pointing at a valid tag.
*
* When this function returns TRUE, notmuch_tags_get will return a
* valid string. Whereas when this function returns FALSE,
@@ -1327,7 +1476,8 @@ notmuch_message_destroy (notmuch_message_t *message);
notmuch_bool_t
notmuch_tags_valid (notmuch_tags_t *tags);
-/* Get the current tag from 'tags' as a string.
+/**
+ * Get the current tag from 'tags' as a string.
*
* Note: The returned string belongs to 'tags' and has a lifetime
* identical to it (and the query to which it ultimately belongs).
@@ -1338,7 +1488,8 @@ notmuch_tags_valid (notmuch_tags_t *tags);
const char *
notmuch_tags_get (notmuch_tags_t *tags);
-/* Move the 'tags' iterator to the next tag.
+/**
+ * Move the 'tags' iterator to the next tag.
*
* If 'tags' is already pointing at the last tag then the iterator
* will be moved to a point just beyond that last tag, (where
@@ -1351,7 +1502,8 @@ notmuch_tags_get (notmuch_tags_t *tags);
void
notmuch_tags_move_to_next (notmuch_tags_t *tags);
-/* Destroy a notmuch_tags_t object.
+/**
+ * Destroy a notmuch_tags_t object.
*
* It's not strictly necessary to call this function. All memory from
* the notmuch_tags_t object will be reclaimed when the containing
@@ -1360,7 +1512,8 @@ notmuch_tags_move_to_next (notmuch_tags_t *tags);
void
notmuch_tags_destroy (notmuch_tags_t *tags);
-/* Store an mtime within the database for 'directory'.
+/**
+ * Store an mtime within the database for 'directory'.
*
* The 'directory' should be an object retrieved from the database
* with notmuch_database_get_directory for a particular path.
@@ -1400,35 +1553,44 @@ notmuch_status_t
notmuch_directory_set_mtime (notmuch_directory_t *directory,
time_t mtime);
-/* Get the mtime of a directory, (as previously stored with
+/**
+ * Get the mtime of a directory, (as previously stored with
* notmuch_directory_set_mtime).
*
* Returns 0 if no mtime has previously been stored for this
- * directory.*/
+ * directory.
+ */
time_t
notmuch_directory_get_mtime (notmuch_directory_t *directory);
-/* Get a notmuch_filenames_t iterator listing all the filenames of
+/**
+ * Get a notmuch_filenames_t iterator listing all the filenames of
* messages in the database within the given directory.
*
* The returned filenames will be the basename-entries only (not
- * complete paths). */
+ * complete paths).
+ */
notmuch_filenames_t *
notmuch_directory_get_child_files (notmuch_directory_t *directory);
-/* Get a notmuch_filenams_t iterator listing all the filenames of
+/**
+ * Get a notmuch_filenams_t iterator listing all the filenames of
* sub-directories in the database within the given directory.
*
* The returned filenames will be the basename-entries only (not
- * complete paths). */
+ * complete paths).
+ */
notmuch_filenames_t *
notmuch_directory_get_child_directories (notmuch_directory_t *directory);
-/* Destroy a notmuch_directory_t object. */
+/**
+ * Destroy a notmuch_directory_t object.
+ */
void
notmuch_directory_destroy (notmuch_directory_t *directory);
-/* Is the given 'filenames' iterator pointing at a valid filename.
+/**
+ * Is the given 'filenames' iterator pointing at a valid filename.
*
* When this function returns TRUE, notmuch_filenames_get will return
* a valid string. Whereas when this function returns FALSE,
@@ -1440,7 +1602,8 @@ notmuch_directory_destroy (notmuch_directory_t *directory);
notmuch_bool_t
notmuch_filenames_valid (notmuch_filenames_t *filenames);
-/* Get the current filename from 'filenames' as a string.
+/**
+ * Get the current filename from 'filenames' as a string.
*
* Note: The returned string belongs to 'filenames' and has a lifetime
* identical to it (and the directory to which it ultimately belongs).
@@ -1451,7 +1614,8 @@ notmuch_filenames_valid (notmuch_filenames_t *filenames);
const char *
notmuch_filenames_get (notmuch_filenames_t *filenames);
-/* Move the 'filenames' iterator to the next filename.
+/**
+ * Move the 'filenames' iterator to the next filename.
*
* If 'filenames' is already pointing at the last filename then the
* iterator will be moved to a point just beyond that last filename,
@@ -1464,7 +1628,8 @@ notmuch_filenames_get (notmuch_filenames_t *filenames);
void
notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);
-/* Destroy a notmuch_filenames_t object.
+/**
+ * Destroy a notmuch_filenames_t object.
*
* It's not strictly necessary to call this function. All memory from
* the notmuch_filenames_t object will be reclaimed when the
@@ -1476,6 +1641,8 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);
void
notmuch_filenames_destroy (notmuch_filenames_t *filenames);
+/* @} */
+
NOTMUCH_END_DECLS
#endif
diff --git a/lib/query.cc b/lib/query.cc
index ec60e2e4..60ff8bd9 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -462,6 +462,9 @@ notmuch_threads_valid (notmuch_threads_t *threads)
{
unsigned int doc_id;
+ if (! threads)
+ return FALSE;
+
while (threads->doc_id_pos < threads->doc_ids->len) {
doc_id = g_array_index (threads->doc_ids, unsigned int,
threads->doc_id_pos);
diff --git a/lib/thread.cc b/lib/thread.cc
index 4dcf7053..8f53e122 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -524,7 +524,7 @@ _notmuch_thread_create (void *ctx,
_resolve_thread_relationships (thread);
/* Commit to returning thread. */
- talloc_steal (ctx, thread);
+ (void) talloc_steal (ctx, thread);
DONE:
talloc_free (local);
diff --git a/man/man1/notmuch-dump.1 b/man/man1/notmuch-dump.1
index 0c52d1b7..16e72eb0 100644
--- a/man/man1/notmuch-dump.1
+++ b/man/man1/notmuch-dump.1
@@ -28,6 +28,34 @@ per line, followed by a list of tags.
.RS 4
.TP 4
+.B batch-tag
+
+The default
+.B batch-tag
+dump format is intended to more robust against malformed message-ids
+and tags containing whitespace or non-\fBascii\fR(7) characters.
+Each line has the form
+
+.RS 4
+.RI "+<" "encoded-tag" "> " "" "+<" "encoded-tag" "> ... -- " "" " id:<" quoted-message-id >
+
+Tags are hex-encoded by replacing every byte not matching the regex
+.B [A-Za-z0-9@=.,_+-]
+with
+.B %nn
+where nn is the two digit hex encoding. The message ID is a valid Xapian
+query, quoted using Xapian boolean term quoting rules: if the ID contains
+whitespace or a close paren or starts with a double quote, it must be
+enclosed in double quotes and double quotes inside the ID must be doubled.
+The astute reader will notice this is a special case of the batch input
+format for \fBnotmuch-tag\fR(1); note that the single message-id query is
+mandatory for \fBnotmuch-restore\fR(1).
+
+.RE
+.RE
+
+.RS 4
+.TP 4
.B sup
The
@@ -53,32 +81,6 @@ that tags with spaces will not be correctly restored with this format.
.RE
.RE
-.RS 4
-.TP 4
-.B batch-tag
-
-The
-.B batch-tag
-dump format is intended to more robust against malformed message-ids
-and tags containing whitespace or non-\fBascii\fR(7) characters.
-Each line has the form
-
-.RS 4
-.RI "+<" "encoded-tag" "> " "" "+<" "encoded-tag" "> ... -- " "" " id:<" quoted-message-id >
-
-Tags are hex-encoded by replacing every byte not matching the regex
-.B [A-Za-z0-9@=.,_+-]
-with
-.B %nn
-where nn is the two digit hex encoding. The message ID is a valid Xapian
-query, quoted using Xapian boolean term quoting rules: if the ID contains
-whitespace or a close paren or starts with a double quote, it must be
-enclosed in double quotes and double quotes inside the ID must be doubled.
-The astute reader will notice this is a special case of the batch input
-format for \fBnotmuch-tag\fR(1); note that the single message-id query is
-mandatory for \fBnotmuch-restore\fR(1).
-
-.RE
With no search terms, a dump of all messages in the database will be
diff --git a/man/man1/notmuch-new.1 b/man/man1/notmuch-new.1
index 5725b7d8..7e719262 100644
--- a/man/man1/notmuch-new.1
+++ b/man/man1/notmuch-new.1
@@ -60,6 +60,11 @@ include
Prevents hooks from being run.
.RE
+.RS 4
+.TP 4
+.BR \-\-quiet
+Do not print progress or results.
+.RE
.RE
.SH SEE ALSO
diff --git a/man/man1/notmuch-tag.1 b/man/man1/notmuch-tag.1
index 710fae6a..f4fb1f32 100644
--- a/man/man1/notmuch-tag.1
+++ b/man/man1/notmuch-tag.1
@@ -126,7 +126,7 @@ of the tag
+space%20in%20tags -- Two
# add tag '(tags)', among other stunts.
-+crazy{ +(tags) +&are +#possible\ -- tag:"space in tags"
++crazy{ +(tags) +&are +#possible\e -- tag:"space in tags"
+match*crazy -- tag:crazy{
+some_tag -- id:"this is ""nauty)"""
.fi
diff --git a/man/man1/notmuch.1 b/man/man1/notmuch.1
index 605b5146..ba902e16 100644
--- a/man/man1/notmuch.1
+++ b/man/man1/notmuch.1
@@ -146,7 +146,7 @@ purposes, and to restore from that dump.
The
.B config
-command can be used to get or set settings int the notmuch
+command can be used to get or set settings in the notmuch
configuration file.
.SH ENVIRONMENT
diff --git a/notmuch-compact.c b/notmuch-compact.c
index 8b820c0d..2fc012a9 100644
--- a/notmuch-compact.c
+++ b/notmuch-compact.c
@@ -32,7 +32,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
const char *path = notmuch_config_get_database_path (config);
const char *backup_path = NULL;
notmuch_status_t ret;
- notmuch_bool_t quiet;
+ notmuch_bool_t quiet = FALSE;
int opt_index;
notmuch_opt_desc_t options[] = {
@@ -42,7 +42,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0)
- return 1;
+ return EXIT_FAILURE;
if (! quiet)
printf ("Compacting database...\n");
@@ -50,7 +50,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
quiet ? NULL : status_update_cb, NULL);
if (ret) {
fprintf (stderr, "Compaction failed: %s\n", notmuch_status_to_string (ret));
- return 1;
+ return EXIT_FAILURE;
}
if (! quiet) {
@@ -60,5 +60,5 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
printf ("Done.\n");
}
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/notmuch-config.c b/notmuch-config.c
index 6845e3c3..8d286538 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -496,6 +496,32 @@ notmuch_config_is_new (notmuch_config_t *config)
return config->is_new;
}
+static const char *
+_config_get (notmuch_config_t *config, char **field,
+ const char *group, const char *key)
+{
+ /* read from config file and cache value, if not cached already */
+ if (*field == NULL) {
+ char *value;
+ value = g_key_file_get_string (config->key_file, group, key, NULL);
+ if (value) {
+ *field = talloc_strdup (config, value);
+ free (value);
+ }
+ }
+ return *field;
+}
+
+static void
+_config_set (notmuch_config_t *config, char **field,
+ const char *group, const char *key, const char *value)
+{
+ g_key_file_set_string (config->key_file, group, key, value);
+
+ /* drop the cached value */
+ talloc_free (*field);
+ *field = NULL;
+}
static const char **
_config_get_list (notmuch_config_t *config,
@@ -504,6 +530,7 @@ _config_get_list (notmuch_config_t *config,
{
assert(outlist);
+ /* read from config file and cache value, if not cached already */
if (*outlist == NULL) {
char **inlist = g_key_file_get_string_list (config->key_file,
@@ -535,6 +562,8 @@ _config_set_list (notmuch_config_t *config,
size_t length, const char ***config_var )
{
g_key_file_set_string_list (config->key_file, group, name, list, length);
+
+ /* drop the cached value */
talloc_free (*config_var);
*config_var = NULL;
}
@@ -542,85 +571,40 @@ _config_set_list (notmuch_config_t *config,
const char *
notmuch_config_get_database_path (notmuch_config_t *config)
{
- char *path;
-
- if (config->database_path == NULL) {
- path = g_key_file_get_string (config->key_file,
- "database", "path", NULL);
- if (path) {
- config->database_path = talloc_strdup (config, path);
- free (path);
- }
- }
-
- return config->database_path;
+ return _config_get (config, &config->database_path, "database", "path");
}
void
notmuch_config_set_database_path (notmuch_config_t *config,
const char *database_path)
{
- g_key_file_set_string (config->key_file,
- "database", "path", database_path);
-
- talloc_free (config->database_path);
- config->database_path = NULL;
+ _config_set (config, &config->database_path, "database", "path", database_path);
}
const char *
notmuch_config_get_user_name (notmuch_config_t *config)
{
- char *name;
-
- if (config->user_name == NULL) {
- name = g_key_file_get_string (config->key_file,
- "user", "name", NULL);
- if (name) {
- config->user_name = talloc_strdup (config, name);
- free (name);
- }
- }
-
- return config->user_name;
+ return _config_get (config, &config->user_name, "user", "name");
}
void
notmuch_config_set_user_name (notmuch_config_t *config,
const char *user_name)
{
- g_key_file_set_string (config->key_file,
- "user", "name", user_name);
-
- talloc_free (config->user_name);
- config->user_name = NULL;
+ _config_set (config, &config->user_name, "user", "name", user_name);
}
const char *
notmuch_config_get_user_primary_email (notmuch_config_t *config)
{
- char *email;
-
- if (config->user_primary_email == NULL) {
- email = g_key_file_get_string (config->key_file,
- "user", "primary_email", NULL);
- if (email) {
- config->user_primary_email = talloc_strdup (config, email);
- free (email);
- }
- }
-
- return config->user_primary_email;
+ return _config_get (config, &config->user_primary_email, "user", "primary_email");
}
void
notmuch_config_set_user_primary_email (notmuch_config_t *config,
const char *primary_email)
{
- g_key_file_set_string (config->key_file,
- "user", "primary_email", primary_email);
-
- talloc_free (config->user_primary_email);
- config->user_primary_email = NULL;
+ _config_set (config, &config->user_primary_email, "user", "primary_email", primary_email);
}
const char **
@@ -839,34 +823,39 @@ notmuch_config_command_list (notmuch_config_t *config)
int
notmuch_config_command (notmuch_config_t *config, int argc, char *argv[])
{
+ int ret;
+
argc--; argv++; /* skip subcommand argument */
if (argc < 1) {
fprintf (stderr, "Error: notmuch config requires at least one argument.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (strcmp (argv[0], "get") == 0) {
if (argc != 2) {
fprintf (stderr, "Error: notmuch config get requires exactly "
"one argument.\n");
- return 1;
+ return EXIT_FAILURE;
}
- return notmuch_config_command_get (config, argv[1]);
+ ret = notmuch_config_command_get (config, argv[1]);
} else if (strcmp (argv[0], "set") == 0) {
if (argc < 2) {
fprintf (stderr, "Error: notmuch config set requires at least "
"one argument.\n");
- return 1;
+ return EXIT_FAILURE;
}
- return notmuch_config_command_set (config, argv[1], argc - 2, argv + 2);
+ ret = notmuch_config_command_set (config, argv[1], argc - 2, argv + 2);
} else if (strcmp (argv[0], "list") == 0) {
- return notmuch_config_command_list (config);
+ ret = notmuch_config_command_list (config);
+ } else {
+ fprintf (stderr, "Unrecognized argument for notmuch config: %s\n",
+ argv[0]);
+ return EXIT_FAILURE;
}
- fprintf (stderr, "Unrecognized argument for notmuch config: %s\n",
- argv[0]);
- return 1;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+
}
notmuch_bool_t
diff --git a/notmuch-count.c b/notmuch-count.c
index 01e4e301..6058f7c9 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -150,10 +150,8 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
if (input_file_name) {
batch = TRUE;
@@ -161,23 +159,23 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])
if (input == NULL) {
fprintf (stderr, "Error opening %s for reading: %s\n",
input_file_name, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
}
if (batch && opt_index != argc) {
fprintf (stderr, "--batch and query string are not compatible\n");
- return 1;
+ return EXIT_FAILURE;
}
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
- return 1;
+ return EXIT_FAILURE;
query_str = query_string_from_args (config, argc-opt_index, argv+opt_index);
if (query_str == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (exclude == EXCLUDE_TRUE) {
@@ -197,5 +195,5 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])
if (input != stdin)
fclose (input);
- return ret;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch-dump.c b/notmuch-dump.c
index 2024e303..158142f5 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -35,12 +35,12 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
- return 1;
+ return EXIT_FAILURE;
char *output_file_name = NULL;
int opt_index;
- int output_format = DUMP_FORMAT_SUP;
+ int output_format = DUMP_FORMAT_BATCH_TAG;
notmuch_opt_desc_t options[] = {
{ NOTMUCH_OPT_KEYWORD, &output_format, "format", 'f',
@@ -52,18 +52,15 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
if (output_file_name) {
output = fopen (output_file_name, "w");
if (output == NULL) {
fprintf (stderr, "Error opening %s for writing: %s\n",
output_file_name, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
}
@@ -72,14 +69,14 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
query_str = query_string_from_args (notmuch, argc - opt_index, argv + opt_index);
if (query_str == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
}
query = notmuch_query_create (notmuch, query_str);
if (query == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
/* Don't ask xapian to sort by Message-ID. Xapian optimizes returning the
* first results quickly at the expense of total time.
@@ -131,7 +128,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
&buffer, &buffer_size) != HEX_SUCCESS) {
fprintf (stderr, "Error: failed to hex-encode tag %s\n",
tag_str);
- return 1;
+ return EXIT_FAILURE;
}
fprintf (output, "+%s", buffer);
}
@@ -144,7 +141,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
&buffer, &buffer_size)) {
fprintf (stderr, "Error quoting message id %s: %s\n",
message_id, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
fprintf (output, " -- %s\n", buffer);
}
@@ -158,5 +155,5 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_query_destroy (query);
notmuch_database_destroy (notmuch);
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/notmuch-insert.c b/notmuch-insert.c
index 2207b1e8..cd6de88f 100644
--- a/notmuch-insert.c
+++ b/notmuch-insert.c
@@ -295,7 +295,7 @@ copy_stdin (int fdin, int fdout)
* The file is renamed to encode notmuch tags as maildir flags. */
static void
add_file_to_database (notmuch_database_t *notmuch, const char *path,
- tag_op_list_t *tag_ops)
+ tag_op_list_t *tag_ops, notmuch_bool_t synchronize_flags)
{
notmuch_message_t *message;
notmuch_status_t status;
@@ -323,11 +323,15 @@ add_file_to_database (notmuch_database_t *notmuch, const char *path,
if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
/* Don't change tags of an existing message. */
- status = notmuch_message_tags_to_maildir_flags (message);
- if (status != NOTMUCH_STATUS_SUCCESS)
- fprintf (stderr, "Error: failed to sync tags to maildir flags\n");
+ if (synchronize_flags) {
+ status = notmuch_message_tags_to_maildir_flags (message);
+ if (status != NOTMUCH_STATUS_SUCCESS)
+ fprintf (stderr, "Error: failed to sync tags to maildir flags\n");
+ }
} else {
- tag_op_list_apply (message, tag_ops, TAG_FLAG_MAILDIR_SYNC);
+ tag_op_flag_t flags = synchronize_flags ? TAG_FLAG_MAILDIR_SYNC : 0;
+
+ tag_op_list_apply (message, tag_ops, flags);
}
notmuch_message_destroy (message);
@@ -335,7 +339,8 @@ add_file_to_database (notmuch_database_t *notmuch, const char *path,
static notmuch_bool_t
insert_message (void *ctx, notmuch_database_t *notmuch, int fdin,
- const char *dir, tag_op_list_t *tag_ops)
+ const char *dir, tag_op_list_t *tag_ops,
+ notmuch_bool_t synchronize_flags)
{
char *tmppath;
char *newpath;
@@ -377,7 +382,7 @@ insert_message (void *ctx, notmuch_database_t *notmuch, int fdin,
/* Even if adding the message to the notmuch database fails,
* the message is on disk and we consider the delivery completed. */
- add_file_to_database (notmuch, newpath, tag_ops);
+ add_file_to_database (notmuch, newpath, tag_ops, synchronize_flags);
return TRUE;
@@ -400,6 +405,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
char *query_string = NULL;
const char *folder = NULL;
notmuch_bool_t create_folder = FALSE;
+ notmuch_bool_t synchronize_flags;
const char *maildir;
int opt_index;
unsigned int i;
@@ -412,32 +418,30 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
db_path = notmuch_config_get_database_path (config);
new_tags = notmuch_config_get_new_tags (config, &new_tags_length);
+ synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
tag_ops = tag_op_list_create (config);
if (tag_ops == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
for (i = 0; i < new_tags_length; i++) {
if (tag_op_list_append (tag_ops, new_tags[i], FALSE))
- return 1;
+ return EXIT_FAILURE;
}
if (parse_tag_command_line (config, argc - opt_index, argv + opt_index,
&query_string, tag_ops))
- return 1;
+ return EXIT_FAILURE;
if (*query_string != '\0') {
fprintf (stderr, "Error: unexpected query string: %s\n", query_string);
- return 1;
+ return EXIT_FAILURE;
}
if (folder == NULL) {
@@ -445,17 +449,17 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
} else {
if (! check_folder_name (folder)) {
fprintf (stderr, "Error: bad folder name: %s\n", folder);
- return 1;
+ return EXIT_FAILURE;
}
maildir = talloc_asprintf (config, "%s/%s", db_path, folder);
if (! maildir) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
if (create_folder && ! maildir_create_folder (config, maildir)) {
fprintf (stderr, "Error: creating maildir %s: %s\n",
maildir, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
}
@@ -469,11 +473,12 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))
- return 1;
+ return EXIT_FAILURE;
- ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops);
+ ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops,
+ synchronize_flags);
notmuch_database_destroy (notmuch);
- return (ret) ? 0 : 1;
+ return ret ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/notmuch-new.c b/notmuch-new.c
index ba05cb41..8529fdd3 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -34,9 +34,15 @@ typedef struct _filename_list {
_filename_node_t **tail;
} _filename_list_t;
+enum verbosity {
+ VERBOSITY_QUIET,
+ VERBOSITY_NORMAL,
+ VERBOSITY_VERBOSE,
+};
+
typedef struct {
int output_is_a_tty;
- notmuch_bool_t verbose;
+ enum verbosity verbosity;
notmuch_bool_t debug;
const char **new_tags;
size_t new_tags_length;
@@ -167,7 +173,7 @@ dirent_type (const char *path, const struct dirent *entry)
char *abspath;
int err, saved_errno;
-#ifdef _DIRENT_HAVE_D_TYPE
+#if HAVE_D_TYPE
/* Mapping from d_type to stat mode_t. We omit DT_LNK so that
* we'll fall through to stat and get the real file type. */
static const mode_t modes[] = {
@@ -240,6 +246,60 @@ _entry_in_ignore_list (const char *entry, add_files_state_t *state)
return FALSE;
}
+/* Add a single file to the database. */
+static notmuch_status_t
+add_file (notmuch_database_t *notmuch, const char *filename,
+ add_files_state_t *state)
+{
+ notmuch_message_t *message = NULL;
+ const char **tag;
+ notmuch_status_t status;
+
+ status = notmuch_database_begin_atomic (notmuch);
+ if (status)
+ goto DONE;
+
+ status = notmuch_database_add_message (notmuch, filename, &message);
+ switch (status) {
+ /* Success. */
+ case NOTMUCH_STATUS_SUCCESS:
+ state->added_messages++;
+ notmuch_message_freeze (message);
+ for (tag = state->new_tags; *tag != NULL; tag++)
+ notmuch_message_add_tag (message, *tag);
+ if (state->synchronize_flags)
+ notmuch_message_maildir_flags_to_tags (message);
+ notmuch_message_thaw (message);
+ break;
+ /* Non-fatal issues (go on to next file). */
+ case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
+ if (state->synchronize_flags)
+ notmuch_message_maildir_flags_to_tags (message);
+ break;
+ case NOTMUCH_STATUS_FILE_NOT_EMAIL:
+ fprintf (stderr, "Note: Ignoring non-mail file: %s\n", filename);
+ break;
+ /* Fatal issues. Don't process anymore. */
+ case NOTMUCH_STATUS_READ_ONLY_DATABASE:
+ case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
+ case NOTMUCH_STATUS_OUT_OF_MEMORY:
+ fprintf (stderr, "Error: %s. Halting processing.\n",
+ notmuch_status_to_string (status));
+ goto DONE;
+ default:
+ INTERNAL_ERROR ("add_message returned unexpected value: %d", status);
+ goto DONE;
+ }
+
+ status = notmuch_database_end_atomic (notmuch);
+
+ DONE:
+ if (message)
+ notmuch_message_destroy (message);
+
+ return status;
+}
+
/* Examine 'path' recursively as follows:
*
* o Ask the filesystem for the mtime of 'path' (fs_mtime)
@@ -291,7 +351,6 @@ add_files (notmuch_database_t *notmuch,
char *next = NULL;
time_t fs_mtime, db_mtime;
notmuch_status_t status, ret = NOTMUCH_STATUS_SUCCESS;
- notmuch_message_t *message = NULL;
struct dirent **fs_entries = NULL;
int i, num_fs_entries = 0, entry_type;
notmuch_directory_t *directory;
@@ -300,7 +359,6 @@ add_files (notmuch_database_t *notmuch,
time_t stat_time;
struct stat st;
notmuch_bool_t is_maildir;
- const char **tag;
if (stat (path, &st)) {
fprintf (stderr, "Error reading directory %s: %s\n",
@@ -514,76 +572,23 @@ add_files (notmuch_database_t *notmuch,
state->processed_files++;
- if (state->verbose) {
+ if (state->verbosity >= VERBOSITY_VERBOSE) {
if (state->output_is_a_tty)
printf("\r\033[K");
- printf ("%i/%i: %s",
- state->processed_files,
- state->total_files,
+ printf ("%i/%i: %s", state->processed_files, state->total_files,
next);
putchar((state->output_is_a_tty) ? '\r' : '\n');
fflush (stdout);
}
- status = notmuch_database_begin_atomic (notmuch);
+ status = add_file (notmuch, next, state);
if (status) {
ret = status;
goto DONE;
}
- status = notmuch_database_add_message (notmuch, next, &message);
- switch (status) {
- /* success */
- case NOTMUCH_STATUS_SUCCESS:
- state->added_messages++;
- notmuch_message_freeze (message);
- for (tag=state->new_tags; *tag != NULL; tag++)
- notmuch_message_add_tag (message, *tag);
- if (state->synchronize_flags == TRUE)
- notmuch_message_maildir_flags_to_tags (message);
- notmuch_message_thaw (message);
- break;
- /* Non-fatal issues (go on to next file) */
- case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
- if (state->synchronize_flags == TRUE)
- notmuch_message_maildir_flags_to_tags (message);
- break;
- case NOTMUCH_STATUS_FILE_NOT_EMAIL:
- fprintf (stderr, "Note: Ignoring non-mail file: %s\n",
- next);
- break;
- /* Fatal issues. Don't process anymore. */
- case NOTMUCH_STATUS_READ_ONLY_DATABASE:
- case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
- case NOTMUCH_STATUS_OUT_OF_MEMORY:
- fprintf (stderr, "Error: %s. Halting processing.\n",
- notmuch_status_to_string (status));
- ret = status;
- goto DONE;
- default:
- case NOTMUCH_STATUS_FILE_ERROR:
- case NOTMUCH_STATUS_NULL_POINTER:
- case NOTMUCH_STATUS_TAG_TOO_LONG:
- case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
- case NOTMUCH_STATUS_UNBALANCED_ATOMIC:
- case NOTMUCH_STATUS_LAST_STATUS:
- INTERNAL_ERROR ("add_message returned unexpected value: %d", status);
- goto DONE;
- }
-
- status = notmuch_database_end_atomic (notmuch);
- if (status) {
- ret = status;
- goto DONE;
- }
-
- if (message) {
- notmuch_message_destroy (message);
- message = NULL;
- }
-
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Processed", "files", state->tv_start,
@@ -701,10 +706,9 @@ count_files (const char *path, int *count, add_files_state_t *state)
{
struct dirent *entry = NULL;
char *next;
- struct stat st;
struct dirent **fs_entries = NULL;
int num_fs_entries = scandir (path, &fs_entries, 0, dirent_sort_inode);
- int i = 0;
+ int entry_type, i;
if (num_fs_entries == -1) {
fprintf (stderr, "Warning: failed to open directory %s: %s\n",
@@ -712,11 +716,8 @@ count_files (const char *path, int *count, add_files_state_t *state)
goto DONE;
}
- while (!interrupted) {
- if (i == num_fs_entries)
- break;
-
- entry = fs_entries[i++];
+ for (i = 0; i < num_fs_entries && ! interrupted; i++) {
+ entry = fs_entries[i];
/* Ignore special directories to avoid infinite recursion.
* Also ignore the .notmuch directory and files/directories
@@ -727,7 +728,7 @@ count_files (const char *path, int *count, add_files_state_t *state)
strcmp (entry->d_name, ".notmuch") == 0 ||
_entry_in_ignore_list (entry->d_name, state))
{
- if (_entry_in_ignore_list (entry->d_name, state) && state->debug)
+ if (state->debug && _entry_in_ignore_list (entry->d_name, state))
printf ("(D) count_files: explicitly ignoring %s/%s\n",
path,
entry->d_name);
@@ -741,15 +742,14 @@ count_files (const char *path, int *count, add_files_state_t *state)
continue;
}
- stat (next, &st);
-
- if (S_ISREG (st.st_mode)) {
+ entry_type = dirent_type (path, entry);
+ if (entry_type == S_IFREG) {
*count = *count + 1;
- if (*count % 1000 == 0) {
+ if (*count % 1000 == 0 && state->verbosity >= VERBOSITY_NORMAL) {
printf ("Found %d files so far.\r", *count);
fflush (stdout);
}
- } else if (S_ISDIR (st.st_mode)) {
+ } else if (entry_type == S_IFDIR) {
count_files (next, count, state);
}
@@ -868,13 +868,49 @@ _remove_directory (void *ctx,
return status;
}
+static void
+print_results (const add_files_state_t *state)
+{
+ double elapsed;
+ struct timeval tv_now;
+
+ gettimeofday (&tv_now, NULL);
+ elapsed = notmuch_time_elapsed (state->tv_start, tv_now);
+
+ if (state->processed_files) {
+ printf ("Processed %d %s in ", state->processed_files,
+ state->processed_files == 1 ? "file" : "total files");
+ notmuch_time_print_formatted_seconds (elapsed);
+ if (elapsed > 1)
+ printf (" (%d files/sec.).\033[K\n",
+ (int) (state->processed_files / elapsed));
+ else
+ printf (".\033[K\n");
+ }
+
+ if (state->added_messages)
+ printf ("Added %d new %s to the database.", state->added_messages,
+ state->added_messages == 1 ? "message" : "messages");
+ else
+ printf ("No new mail.");
+
+ if (state->removed_messages)
+ printf (" Removed %d %s.", state->removed_messages,
+ state->removed_messages == 1 ? "message" : "messages");
+
+ if (state->renamed_messages)
+ printf (" Detected %d file %s.", state->renamed_messages,
+ state->renamed_messages == 1 ? "rename" : "renames");
+
+ printf ("\n");
+}
+
int
notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
{
notmuch_database_t *notmuch;
add_files_state_t add_files_state;
- double elapsed;
- struct timeval tv_now, tv_start;
+ struct timeval tv_start;
int ret = 0;
struct stat st;
const char *db_path;
@@ -885,23 +921,29 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
int i;
notmuch_bool_t timer_is_active = FALSE;
notmuch_bool_t no_hooks = FALSE;
+ notmuch_bool_t quiet = FALSE, verbose = FALSE;
- add_files_state.verbose = FALSE;
+ add_files_state.verbosity = VERBOSITY_NORMAL;
add_files_state.debug = FALSE;
add_files_state.output_is_a_tty = isatty (fileno (stdout));
notmuch_opt_desc_t options[] = {
- { NOTMUCH_OPT_BOOLEAN, &add_files_state.verbose, "verbose", 'v', 0 },
+ { NOTMUCH_OPT_BOOLEAN, &quiet, "quiet", 'q', 0 },
+ { NOTMUCH_OPT_BOOLEAN, &verbose, "verbose", 'v', 0 },
{ NOTMUCH_OPT_BOOLEAN, &add_files_state.debug, "debug", 'd', 0 },
{ NOTMUCH_OPT_BOOLEAN, &no_hooks, "no-hooks", 'n', 0 },
{ 0, 0, 0, 0, 0 }
};
opt_index = parse_arguments (argc, argv, options, 1);
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
+
+ /* quiet trumps verbose */
+ if (quiet)
+ add_files_state.verbosity = VERBOSITY_QUIET;
+ else if (verbose)
+ add_files_state.verbosity = VERBOSITY_VERBOSE;
add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
add_files_state.new_ignore = notmuch_config_get_new_ignore (config, &add_files_state.new_ignore_length);
@@ -911,7 +953,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
if (!no_hooks) {
ret = notmuch_run_hook (db_path, "pre-new");
if (ret)
- return ret;
+ return EXIT_FAILURE;
}
dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch");
@@ -922,23 +964,27 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
count = 0;
count_files (db_path, &count, &add_files_state);
if (interrupted)
- return 1;
+ return EXIT_FAILURE;
- printf ("Found %d total files (that's not much mail).\n", count);
+ if (add_files_state.verbosity >= VERBOSITY_NORMAL)
+ printf ("Found %d total files (that's not much mail).\n", count);
if (notmuch_database_create (db_path, &notmuch))
- return 1;
+ return EXIT_FAILURE;
add_files_state.total_files = count;
} else {
if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
&notmuch))
- return 1;
+ return EXIT_FAILURE;
if (notmuch_database_needs_upgrade (notmuch)) {
- printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n");
+ if (add_files_state.verbosity >= VERBOSITY_NORMAL)
+ printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n");
gettimeofday (&add_files_state.tv_start, NULL);
- notmuch_database_upgrade (notmuch, upgrade_print_progress,
+ notmuch_database_upgrade (notmuch,
+ add_files_state.verbosity >= VERBOSITY_NORMAL ? upgrade_print_progress : NULL,
&add_files_state);
- printf ("Your notmuch database has now been upgraded to database format version %u.\n",
+ if (add_files_state.verbosity >= VERBOSITY_NORMAL)
+ printf ("Your notmuch database has now been upgraded to database format version %u.\n",
notmuch_database_get_version (notmuch));
}
@@ -946,7 +992,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
}
if (notmuch == NULL)
- return 1;
+ return EXIT_FAILURE;
/* Setup our handler for SIGINT. We do this after having
* potentially done a database upgrade we this interrupt handler
@@ -969,8 +1015,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
add_files_state.removed_directories = _filename_list_create (config);
add_files_state.directory_mtimes = _filename_list_create (config);
- if (! debugger_is_active () && add_files_state.output_is_a_tty
- && ! add_files_state.verbose) {
+ if (add_files_state.verbosity == VERBOSITY_NORMAL &&
+ add_files_state.output_is_a_tty && ! debugger_is_active ()) {
setup_progress_printing_timer ();
timer_is_active = TRUE;
}
@@ -1023,45 +1069,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
if (timer_is_active)
stop_progress_printing_timer ();
- gettimeofday (&tv_now, NULL);
- elapsed = notmuch_time_elapsed (add_files_state.tv_start,
- tv_now);
-
- if (add_files_state.processed_files) {
- printf ("Processed %d %s in ", add_files_state.processed_files,
- add_files_state.processed_files == 1 ?
- "file" : "total files");
- notmuch_time_print_formatted_seconds (elapsed);
- if (elapsed > 1) {
- printf (" (%d files/sec.).\033[K\n",
- (int) (add_files_state.processed_files / elapsed));
- } else {
- printf (".\033[K\n");
- }
- }
-
- if (add_files_state.added_messages) {
- printf ("Added %d new %s to the database.",
- add_files_state.added_messages,
- add_files_state.added_messages == 1 ?
- "message" : "messages");
- } else {
- printf ("No new mail.");
- }
-
- if (add_files_state.removed_messages) {
- printf (" Removed %d %s.",
- add_files_state.removed_messages,
- add_files_state.removed_messages == 1 ? "message" : "messages");
- }
-
- if (add_files_state.renamed_messages) {
- printf (" Detected %d file %s.",
- add_files_state.renamed_messages,
- add_files_state.renamed_messages == 1 ? "rename" : "renames");
- }
-
- printf ("\n");
+ if (add_files_state.verbosity >= VERBOSITY_NORMAL)
+ print_results (&add_files_state);
if (ret)
fprintf (stderr, "Note: A fatal error was encountered: %s\n",
@@ -1072,5 +1081,5 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
if (!no_hooks && !ret && !interrupted)
ret = notmuch_run_hook (db_path, "post-new");
- return ret || interrupted;
+ return ret || interrupted ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 9d6f8436..79cdc833 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -704,7 +704,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_database_t *notmuch;
notmuch_query_t *query;
char *query_string;
- int opt_index, ret = 0;
+ int opt_index;
int (*reply_format_func) (void *ctx,
notmuch_config_t *config,
notmuch_query_t *query,
@@ -739,10 +739,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
if (format == FORMAT_HEADERS_ONLY) {
reply_format_func = notmuch_reply_format_headers_only;
@@ -761,30 +759,30 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
if (*query_string == '\0') {
fprintf (stderr, "Error: notmuch reply requires at least one search term.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
- return 1;
+ return EXIT_FAILURE;
query = notmuch_query_create (notmuch, query_string);
if (query == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
if (reply_format_func (config, config, query, &params, reply_all, sp) != 0)
- return 1;
+ return EXIT_FAILURE;
notmuch_crypto_cleanup (&params.crypto);
notmuch_query_destroy (query);
notmuch_database_destroy (notmuch);
- return ret;
+ return EXIT_SUCCESS;
}
diff --git a/notmuch-restore.c b/notmuch-restore.c
index 1419621c..f23ab983 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -140,7 +140,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))
- return 1;
+ return EXIT_FAILURE;
if (notmuch_config_get_maildir_synchronize_flags (config))
flags |= TAG_FLAG_MAILDIR_SYNC;
@@ -157,11 +157,8 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
if (! accumulate)
flags |= TAG_FLAG_REMOVE_ALL;
@@ -171,21 +168,19 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
if (input == NULL) {
fprintf (stderr, "Error opening %s for reading: %s\n",
input_file_name, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
}
if (opt_index < argc) {
- fprintf (stderr,
- "Unused positional parameter: %s\n",
- argv[opt_index]);
- return 1;
+ fprintf (stderr, "Unused positional parameter: %s\n", argv[opt_index]);
+ return EXIT_FAILURE;
}
tag_ops = tag_op_list_create (config);
if (tag_ops == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
do {
@@ -193,7 +188,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
/* empty input file not considered an error */
if (line_len < 0)
- return 0;
+ return EXIT_SUCCESS;
} while ((line_len == 0) ||
(line[0] == '#') ||
@@ -275,5 +270,5 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
if (input != stdin)
fclose (input);
- return ret;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch-search.c b/notmuch-search.c
index 7c973b3d..91b5d105 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -401,10 +401,8 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
-
- if (opt_index < 0) {
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
switch (format_sel) {
case NOTMUCH_FORMAT_TEXT:
@@ -413,7 +411,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
case NOTMUCH_FORMAT_TEXT0:
if (output == OUTPUT_SUMMARY) {
fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n");
- return 1;
+ return EXIT_FAILURE;
}
format = sprinter_text0_create (config, stdout);
break;
@@ -432,22 +430,22 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
- return 1;
+ return EXIT_FAILURE;
query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index);
if (query_str == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (*query_str == '\0') {
fprintf (stderr, "Error: notmuch search requires at least one search term.\n");
- return 1;
+ return EXIT_FAILURE;
}
query = notmuch_query_create (notmuch, query_str);
if (query == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
notmuch_query_set_sort (query, sort);
@@ -491,5 +489,5 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
talloc_free (format);
- return ret;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch-setup.c b/notmuch-setup.c
index 475248b1..36a6171a 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -140,7 +140,7 @@ notmuch_setup_command (notmuch_config_t *config,
fflush (stdout); \
if (getline (&response, &response_size, stdin) < 0) { \
printf ("Exiting.\n"); \
- exit (1); \
+ exit (EXIT_FAILURE); \
} \
chomp_newline (response); \
} while (0)
@@ -223,12 +223,11 @@ notmuch_setup_command (notmuch_config_t *config,
g_ptr_array_free (tags, TRUE);
}
+ if (notmuch_config_save (config))
+ return EXIT_FAILURE;
- if (! notmuch_config_save (config)) {
- if (notmuch_config_is_new (config))
- welcome_message_post_setup ();
- return 0;
- } else {
- return 1;
- }
+ if (notmuch_config_is_new (config))
+ welcome_message_post_setup ();
+
+ return EXIT_SUCCESS;
}
diff --git a/notmuch-show.c b/notmuch-show.c
index c07f8871..d416fbd5 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1015,9 +1015,13 @@ do_show (void *ctx,
notmuch_messages_t *messages;
notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
+ threads = notmuch_query_search_threads (query);
+ if (! threads)
+ return 1;
+
sp->begin_list (sp);
- for (threads = notmuch_query_search_threads (query);
+ for ( ;
notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads))
{
@@ -1113,10 +1117,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
};
opt_index = parse_arguments (argc, argv, options, 1);
- if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
- }
+ if (opt_index < 0)
+ return EXIT_FAILURE;
/* decryption implies verification */
if (params.crypto.decrypt)
@@ -1143,7 +1145,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
case NOTMUCH_FORMAT_MBOX:
if (params.part > 0) {
fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n");
- return 1;
+ return EXIT_FAILURE;
}
format = &format_mbox;
@@ -1193,22 +1195,22 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
if (*query_string == '\0') {
fprintf (stderr, "Error: notmuch show requires at least one search term.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
- return 1;
+ return EXIT_FAILURE;
query = notmuch_query_create (notmuch, query_string);
if (query == NULL) {
fprintf (stderr, "Out of memory\n");
- return 1;
+ return EXIT_FAILURE;
}
/* Create structure printer. */
@@ -1242,5 +1244,5 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_query_destroy (query);
notmuch_database_destroy (notmuch);
- return ret;
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 3b09df99..5b2f1e48 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -193,7 +193,7 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
FILE *input = stdin;
char *input_file_name = NULL;
int opt_index;
- int ret = 0;
+ int ret;
/* Setup our handler for SIGINT */
memset (&action, 0, sizeof (struct sigaction));
@@ -211,7 +211,7 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0)
- return 1;
+ return EXIT_FAILURE;
if (input_file_name) {
batch = TRUE;
@@ -219,44 +219,44 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
if (input == NULL) {
fprintf (stderr, "Error opening %s for reading: %s\n",
input_file_name, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
}
if (batch) {
if (opt_index != argc) {
fprintf (stderr, "Can't specify both cmdline and stdin!\n");
- return 1;
+ return EXIT_FAILURE;
}
if (remove_all) {
fprintf (stderr, "Can't specify both --remove-all and --batch\n");
- return 1;
+ return EXIT_FAILURE;
}
} else {
tag_ops = tag_op_list_create (config);
if (tag_ops == NULL) {
fprintf (stderr, "Out of memory.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (parse_tag_command_line (config, argc - opt_index, argv + opt_index,
&query_string, tag_ops))
- return 1;
+ return EXIT_FAILURE;
if (tag_op_list_size (tag_ops) == 0 && ! remove_all) {
fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");
- return 1;
+ return EXIT_FAILURE;
}
if (*query_string == '\0') {
fprintf (stderr, "Error: notmuch tag requires at least one search term.\n");
- return 1;
+ return EXIT_FAILURE;
}
}
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))
- return 1;
+ return EXIT_FAILURE;
if (notmuch_config_get_maildir_synchronize_flags (config))
tag_flags |= TAG_FLAG_MAILDIR_SYNC;
@@ -274,5 +274,5 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
if (input != stdin)
fclose (input);
- return ret || interrupted;
+ return ret || interrupted ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/notmuch.c b/notmuch.c
index 54f46c68..b3fa9f37 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -22,6 +22,12 @@
#include "notmuch-client.h"
+/*
+ * Notmuch subcommand hook.
+ *
+ * The return value will be used as notmuch exit status code,
+ * preferrably EXIT_SUCCESS or EXIT_FAILURE.
+ */
typedef int (*command_function_t) (notmuch_config_t *config, int argc, char *argv[]);
typedef struct command {
@@ -156,7 +162,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[])
if (argc == 0) {
printf ("The notmuch mail system.\n\n");
usage (stdout);
- return 0;
+ return EXIT_SUCCESS;
}
if (strcmp (argv[0], "help") == 0) {
@@ -165,7 +171,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[])
"\tof difficulties check that MANPATH includes the pages\n"
"\tinstalled by notmuch.\n\n"
"\tTry \"notmuch help\" for a list of topics.\n");
- return 0;
+ return EXIT_SUCCESS;
}
command = find_command (argv[0]);
@@ -183,7 +189,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[])
fprintf (stderr,
"\nSorry, %s is not a known command. There's not much I can do to help.\n\n",
argv[0]);
- return 1;
+ return EXIT_FAILURE;
}
/* Handle the case of "notmuch" being invoked with no command
@@ -211,7 +217,7 @@ notmuch_command (notmuch_config_t *config,
if (errno != ENOENT) {
fprintf (stderr, "Error looking for notmuch database at %s: %s\n",
db_path, strerror (errno));
- return 1;
+ return EXIT_FAILURE;
}
printf ("Notmuch is configured, but there's not yet a database at\n\n\t%s\n\n",
db_path);
@@ -219,7 +225,7 @@ notmuch_command (notmuch_config_t *config,
"Note that the first run of \"notmuch new\" can take a very long time\n"
"and that the resulting database will use roughly the same amount of\n"
"storage space as the email being indexed.\n\n");
- return 0;
+ return EXIT_SUCCESS;
}
printf ("Notmuch is configured and appears to have a database. Excellent!\n\n"
@@ -239,7 +245,7 @@ notmuch_command (notmuch_config_t *config,
notmuch_config_get_user_name (config),
notmuch_config_get_user_primary_email (config));
- return 0;
+ return EXIT_SUCCESS;
}
int
@@ -250,10 +256,10 @@ main (int argc, char *argv[])
const char *command_name = NULL;
command_t *command;
char *config_file_name = NULL;
- notmuch_config_t *config;
+ notmuch_config_t *config = NULL;
notmuch_bool_t print_help=FALSE, print_version=FALSE;
int opt_index;
- int ret = 0;
+ int ret;
notmuch_opt_desc_t options[] = {
{ NOTMUCH_OPT_BOOLEAN, &print_help, "help", 'h', 0 },
@@ -276,16 +282,19 @@ main (int argc, char *argv[])
opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0) {
- /* diagnostics already printed */
- return 1;
+ ret = EXIT_FAILURE;
+ goto DONE;
}
- if (print_help)
- return notmuch_help_command (NULL, argc - 1, &argv[1]);
+ if (print_help) {
+ ret = notmuch_help_command (NULL, argc - 1, &argv[1]);
+ goto DONE;
+ }
if (print_version) {
printf ("notmuch " STRINGIFY(NOTMUCH_VERSION) "\n");
- return 0;
+ ret = EXIT_SUCCESS;
+ goto DONE;
}
if (opt_index < argc)
@@ -295,16 +304,21 @@ main (int argc, char *argv[])
if (!command) {
fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
command_name);
- return 1;
+ ret = EXIT_FAILURE;
+ goto DONE;
}
config = notmuch_config_open (local, config_file_name, command->create_config);
- if (!config)
- return 1;
+ if (!config) {
+ ret = EXIT_FAILURE;
+ goto DONE;
+ }
ret = (command->function)(config, argc - opt_index, argv + opt_index);
- notmuch_config_close (config);
+ DONE:
+ if (config)
+ notmuch_config_close (config);
talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");
if (talloc_report && strcmp (talloc_report, "") != 0) {
diff --git a/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc b/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc
new file mode 100644
index 00000000..72dedd8b
--- /dev/null
+++ b/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc
@@ -0,0 +1,14 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.15 (GNU/Linux)
+
+iQGcBAABCAAGBQJSdaDkAAoJEPIClx2kp54sQ54L/ikkvF1fy88hjLitN59v6g2J
+vw85YNRifNHyp/UXI6nt2eXFzyWJiRHuvHFoBgmEsJVxauOKw61Gs2zd53x9Ear4
+MGcQWyiM1cnwX/nD7GvxRQNh33f+FEamTjg+QhG47K0A2YdLWcDC7r9GMatGT11x
+5KE24WQGOqtgQn/9qNtJvkiKIehpRiDTaW/QJ7mTCYeJFjIHJUY8dxyfiTtkJ0z7
+cJ6omehvWSw4STbEg65XJgqykxMdltNEavfvSbAT73FgmkkyXxul0s5hDZ/esd0n
+re3dyDxGt085POiAgPti05a4tJI5EQC2wLBUFri0s2JdMtazcD6yVuHNbVzZ4Do3
+nL/sgwKGUq5wRrPqPWp6HXtZ9zG+/V7hFNrr/l42qGrLqsSh0bqvEnUiwczZLBGy
+NEs4G8VjmfS2cMKePsWaekBAvFUtb47PSB6JIPwpCNvKXDrcCb28eOQVB2atgj1h
+9SktOtWYJhWIQp2YW9iae30Z6lhCcdPRRHTFMQq2nQ==
+=eSMY
+-----END PGP SIGNATURE-----
diff --git a/performance-test/perf-test-lib.sh b/performance-test/perf-test-lib.sh
index 9ee76613..44708cfd 100644
--- a/performance-test/perf-test-lib.sh
+++ b/performance-test/perf-test-lib.sh
@@ -41,52 +41,70 @@ add_email_corpus ()
{
rm -rf ${MAIL_DIR}
- case "$corpus_size" in
- small)
- mail_subdir="mail/enron/bailey-s"
- check_for="${TEST_DIRECTORY}/corpus/$mail_subdir"
- ;;
- medium)
- mail_subdir="mail/notmuch-archive"
- check_for="${TEST_DIRECTORY}/corpus/$mail_subdir"
- ;;
- *)
- mail_subdir=mail
- check_for="${TEST_DIRECTORY}/corpus/$mail_subdir/enron/wolfe-j"
- esac
+ CORPUS_DIR=${TEST_DIRECTORY}/corpus
+ mkdir -p "${CORPUS_DIR}"
- MAIL_CORPUS="${TEST_DIRECTORY}/corpus/$mail_subdir"
- TAG_CORPUS="${TEST_DIRECTORY}/corpus/tags"
+ MAIL_CORPUS="${CORPUS_DIR}/mail.${corpus_size}"
+ TAG_CORPUS="${CORPUS_DIR}/tags"
- args=()
- if [ ! -d "$TAG_CORPUS" ] ; then
- args+=("notmuch-email-corpus/tags")
+ if command -v pixz > /dev/null; then
+ XZ=pixz
+ else
+ XZ=xz
fi
- if [ ! -d "$check_for" ] ; then
- args+=("notmuch-email-corpus/$mail_subdir")
+ if [ ! -d "${CORPUS_DIR}/manifest" ]; then
+
+ printf "Unpacking manifests\n"
+ tar --extract --use-compress-program ${XZ} --strip-components=1 \
+ --directory ${TEST_DIRECTORY}/corpus \
+ --wildcards --file ../download/notmuch-email-corpus-${PERFTEST_VERSION}.tar.xz \
+ 'notmuch-email-corpus/manifest/*'
fi
- if [[ ${#args[@]} > 0 ]]; then
- if command -v pixz > /dev/null; then
- XZ=pixz
+ file_list=$(mktemp file_listXXXXXX)
+ if [ ! -d "$TAG_CORPUS" ] ; then
+ echo "notmuch-email-corpus/tags" >> $file_list
+ fi
+
+ if [ ! -d "$MAIL_CORPUS" ] ; then
+ if [[ "$corpus_size" != "large" ]]; then
+ sed s,^,notmuch-email-corpus/, < \
+ ${TEST_DIRECTORY}/corpus/manifest/MANIFEST.${corpus_size} >> $file_list
else
- XZ=xz
+ echo "notmuch-email-corpus/mail" >> $file_list
fi
+ fi
- printf "Unpacking corpus\n"
- mkdir -p "${TEST_DIRECTORY}/corpus"
+ if [[ -s $file_list ]]; then
+ printf "Unpacking corpus\n"
tar --checkpoint=.5000 --extract --strip-components=1 \
--directory ${TEST_DIRECTORY}/corpus \
--use-compress-program ${XZ} \
--file ../download/notmuch-email-corpus-${PERFTEST_VERSION}.tar.xz \
- "${args[@]}"
+ --anchored --recursion \
+ --files-from $file_list
printf "\n"
+ if [[ ! -d ${MAIL_CORPUS} ]]; then
+ printf "creating link farm\n"
+
+ if [[ "$corpus_size" = large ]]; then
+ cp -rl ${TEST_DIRECTORY}/corpus/mail ${MAIL_CORPUS}
+ else
+ while read -r file; do
+ tdir=${MAIL_CORPUS}/$(dirname $file)
+ mkdir -p $tdir
+ ln ${TEST_DIRECTORY}/corpus/$file $tdir
+ done <${TEST_DIRECTORY}/corpus/manifest/MANIFEST.${corpus_size}
+ fi
+ fi
+
fi
+ rm $file_list
cp -lr $TAG_CORPUS $TMP_DIRECTORY/corpus.tags
cp -lr $MAIL_CORPUS $MAIL_DIR
}
diff --git a/performance-test/version.sh b/performance-test/version.sh
index afafc737..f02527a7 100644
--- a/performance-test/version.sh
+++ b/performance-test/version.sh
@@ -1,3 +1,3 @@
# this should be both a valid Makefile fragment and valid POSIX(ish) shell.
-PERFTEST_VERSION=0.3
+PERFTEST_VERSION=0.4
diff --git a/test/Makefile.local b/test/Makefile.local
index 8870ca37..99324ba1 100644
--- a/test/Makefile.local
+++ b/test/Makefile.local
@@ -50,11 +50,6 @@ test: all test-binaries
check: test
SRCS := $(SRCS) $(smtp_dummy_srcs)
-CLEAN := $(CLEAN) $(dir)/smtp-dummy $(dir)/smtp-dummy.o \
- $(dir)/symbol-test $(dir)/symbol-test.o \
- $(dir)/arg-test $(dir)/arg-test.o \
- $(dir)/hex-xcode $(dir)/hex-xcode.o \
+CLEAN += $(TEST_BINARIES) $(addsuffix .o,$(TEST_BINARIES)) \
$(dir)/database-test.o \
- $(dir)/random-corpus $(dir)/random-corpus.o \
- $(dir)/parse-time $(dir)/parse-time.o \
$(dir)/corpus.mail $(dir)/test-results $(dir)/tmp.*
diff --git a/test/README b/test/README
index d12cff24..79a9b1b2 100644
--- a/test/README
+++ b/test/README
@@ -76,6 +76,14 @@ the tests in one of the following ways.
TEST_EMACS=my-special-emacs TEST_EMACSCLIENT=my-emacsclient ./emacs
make test TEST_EMACS=my-special-emacs TEST_EMACSCLIENT=my-emacsclient
+Quiet Execution
+---------------
+
+Normally, when new script starts and when test PASSes you get a message
+printed on screen. This printing can be disabled by setting the
+NOTMUCH_TEST_QUIET variable to a non-null value. Message on test
+failures and skips are still printed.
+
Skipping Tests
--------------
If, for any reason, you need to skip one or more tests, you can do so
diff --git a/test/basic b/test/T000-basic.sh
index 64eb7d74..9c94b62c 100755
--- a/test/basic
+++ b/test/T000-basic.sh
@@ -49,24 +49,6 @@ test_expect_code 2 'failure to clean up causes the test to fail' '
test_when_finished "(exit 2)"
'
-# Ensure that all tests are being run
-test_begin_subtest 'Ensure that all available tests will be run by notmuch-test'
-eval $(sed -n -e '/^TESTS="$/,/^"$/p' $TEST_DIRECTORY/notmuch-test)
-tests_in_suite=$(for i in $TESTS; do echo $i; done | sort)
-available=$(find "$TEST_DIRECTORY" -maxdepth 1 -type f \
- '(' -perm -100 -o -perm -10 -o -perm -1 ')' \
- ! -name aggregate-results.sh \
- ! -name arg-test \
- ! -name hex-xcode \
- ! -name notmuch-test \
- ! -name parse-time \
- ! -name random-corpus \
- ! -name smtp-dummy \
- ! -name symbol-test \
- ! -name test-verbose \
- | sed 's,.*/,,' | sort)
-test_expect_equal "$tests_in_suite" "$available"
-
EXPECTED=$TEST_DIRECTORY/test.expected-output
suppress_diff_date() {
sed -e 's/\(.*\-\-\- test-verbose\.4\.\expected\).*/\1/' \
@@ -74,12 +56,12 @@ suppress_diff_date() {
}
test_begin_subtest "Ensure that test output is suppressed unless the test fails"
-output=$(cd $TEST_DIRECTORY; ./test-verbose 2>&1 | suppress_diff_date)
+output=$(cd $TEST_DIRECTORY; NOTMUCH_TEST_QUIET= ./test-verbose 2>&1 | suppress_diff_date)
expected=$(cat $EXPECTED/test-verbose-no | suppress_diff_date)
test_expect_equal "$output" "$expected"
test_begin_subtest "Ensure that -v does not suppress test output"
-output=$(cd $TEST_DIRECTORY; ./test-verbose -v 2>&1 | suppress_diff_date)
+output=$(cd $TEST_DIRECTORY; NOTMUCH_TEST_QUIET= ./test-verbose -v 2>&1 | suppress_diff_date)
expected=$(cat $EXPECTED/test-verbose-yes | suppress_diff_date)
# Do not include the results of test-verbose in totals
rm $TEST_DIRECTORY/test-results/test-verbose
diff --git a/test/help-test b/test/T010-help-test.sh
index f7df725e..f7df725e 100755
--- a/test/help-test
+++ b/test/T010-help-test.sh
diff --git a/test/compact b/test/T020-compact.sh
index ac174cec..ac174cec 100755
--- a/test/compact
+++ b/test/T020-compact.sh
diff --git a/test/config b/test/T030-config.sh
index ca4cf330..ca4cf330 100755
--- a/test/config
+++ b/test/T030-config.sh
diff --git a/test/setup b/test/T040-setup.sh
index 124ef1c8..124ef1c8 100755
--- a/test/setup
+++ b/test/T040-setup.sh
diff --git a/test/new b/test/T050-new.sh
index f27423da..b7668ff0 100755
--- a/test/new
+++ b/test/T050-new.sh
@@ -248,4 +248,19 @@ ln -s i_do_not_exist "${MAIL_DIR}"/broken_link
output=$(NOTMUCH_NEW 2>&1)
test_expect_equal "$output" "No new mail."
+test_begin_subtest "Quiet: No new mail."
+output=$(NOTMUCH_NEW --quiet)
+test_expect_equal "$output" ""
+
+test_begin_subtest "Quiet: new, removed and renamed messages."
+# new
+generate_message
+# deleted
+notmuch search --format=text0 --output=files --limit=1 '*' | xargs -0 rm
+# moved
+mkdir "${MAIL_DIR}"/moved_messages
+notmuch search --format=text0 --output=files --offset=1 --limit=1 '*' | xargs -0 -I {} mv {} "${MAIL_DIR}"/moved_messages
+output=$(NOTMUCH_NEW --quiet)
+test_expect_equal "$output" ""
+
test_done
diff --git a/test/count b/test/T060-count.sh
index da86c8cc..da86c8cc 100755
--- a/test/count
+++ b/test/T060-count.sh
diff --git a/test/insert b/test/T070-insert.sh
index 550b4132..e8dc4c09 100755
--- a/test/insert
+++ b/test/T070-insert.sh
@@ -113,6 +113,16 @@ output=$(notmuch search --output=files id:$gen_msg_id)
dirname=$(dirname "$output")
test_expect_equal "$dirname" "$MAIL_DIR/cur"
+test_begin_subtest "Insert message with maildir sync off goes to new/"
+OLDCONFIG=$(notmuch config get maildir.synchronize_flags)
+notmuch config set maildir.synchronize_flags false
+gen_insert_msg
+notmuch insert +flagged < "$gen_msg_filename"
+output=$(notmuch search --output=files id:$gen_msg_id)
+dirname=$(dirname "$output")
+notmuch config set maildir.synchronize_flags $OLDCONFIG
+test_expect_equal "$dirname" "$MAIL_DIR/new"
+
test_begin_subtest "Insert message into folder"
gen_insert_msg
notmuch insert --folder=Drafts < "$gen_msg_filename"
diff --git a/test/search b/test/T080-search.sh
index a7a0b18d..a7a0b18d 100755
--- a/test/search
+++ b/test/T080-search.sh
diff --git a/test/search-output b/test/T090-search-output.sh
index 5ccfeaf9..5ccfeaf9 100755
--- a/test/search-output
+++ b/test/T090-search-output.sh
diff --git a/test/search-by-folder b/test/T100-search-by-folder.sh
index 5cc2ca8d..5cc2ca8d 100755
--- a/test/search-by-folder
+++ b/test/T100-search-by-folder.sh
diff --git a/test/search-position-overlap-bug b/test/T110-search-position-overlap-bug.sh
index 5da6ad6f..5da6ad6f 100755
--- a/test/search-position-overlap-bug
+++ b/test/T110-search-position-overlap-bug.sh
diff --git a/test/search-insufficient-from-quoting b/test/T120-search-insufficient-from-quoting.sh
index e83ea3d1..e83ea3d1 100755
--- a/test/search-insufficient-from-quoting
+++ b/test/T120-search-insufficient-from-quoting.sh
diff --git a/test/search-limiting b/test/T130-search-limiting.sh
index 303762cf..303762cf 100755
--- a/test/search-limiting
+++ b/test/T130-search-limiting.sh
diff --git a/test/excludes b/test/T140-excludes.sh
index 8bbbc2dd..8bbbc2dd 100755
--- a/test/excludes
+++ b/test/T140-excludes.sh
diff --git a/test/tagging b/test/T150-tagging.sh
index dc118f33..dc118f33 100755
--- a/test/tagging
+++ b/test/T150-tagging.sh
diff --git a/test/json b/test/T160-json.sh
index c1cf649d..c1cf649d 100755
--- a/test/json
+++ b/test/T160-json.sh
diff --git a/test/sexp b/test/T170-sexp.sh
index 667e3195..667e3195 100755
--- a/test/sexp
+++ b/test/T170-sexp.sh
diff --git a/test/text b/test/T180-text.sh
index b5ccefc9..b5ccefc9 100755
--- a/test/text
+++ b/test/T180-text.sh
diff --git a/test/multipart b/test/T190-multipart.sh
index 85cbf672..85cbf672 100755
--- a/test/multipart
+++ b/test/T190-multipart.sh
diff --git a/test/thread-naming b/test/T200-thread-naming.sh
index 1a1a48f6..1a1a48f6 100755
--- a/test/thread-naming
+++ b/test/T200-thread-naming.sh
diff --git a/test/raw b/test/T210-raw.sh
index daf5735c..daf5735c 100755
--- a/test/raw
+++ b/test/T210-raw.sh
diff --git a/test/reply b/test/T220-reply.sh
index b0d854a1..b0d854a1 100755
--- a/test/reply
+++ b/test/T220-reply.sh
diff --git a/test/reply-to-sender b/test/T230-reply-to-sender.sh
index 30e5e385..30e5e385 100755
--- a/test/reply-to-sender
+++ b/test/T230-reply-to-sender.sh
diff --git a/test/dump-restore b/test/T240-dump-restore.sh
index 0004438d..0004438d 100755
--- a/test/dump-restore
+++ b/test/T240-dump-restore.sh
diff --git a/test/uuencode b/test/T250-uuencode.sh
index b3e1ac19..b3e1ac19 100755
--- a/test/uuencode
+++ b/test/T250-uuencode.sh
diff --git a/test/thread-order b/test/T260-thread-order.sh
index 6c3a4b3f..6c3a4b3f 100755
--- a/test/thread-order
+++ b/test/T260-thread-order.sh
diff --git a/test/author-order b/test/T270-author-order.sh
index 6ffeffc7..6ffeffc7 100755
--- a/test/author-order
+++ b/test/T270-author-order.sh
diff --git a/test/from-guessing b/test/T280-from-guessing.sh
index 6dfaa40a..6dfaa40a 100755
--- a/test/from-guessing
+++ b/test/T280-from-guessing.sh
diff --git a/test/long-id b/test/T290-long-id.sh
index 85e620fa..85e620fa 100755
--- a/test/long-id
+++ b/test/T290-long-id.sh
diff --git a/test/encoding b/test/T300-encoding.sh
index b6c86bf0..b6c86bf0 100755
--- a/test/encoding
+++ b/test/T300-encoding.sh
diff --git a/test/emacs b/test/T310-emacs.sh
index 863219d9..00ae96a8 100755
--- a/test/emacs
+++ b/test/T310-emacs.sh
@@ -7,6 +7,10 @@ EXPECTED=$TEST_DIRECTORY/emacs.expected-output
add_email_corpus
+# syntax errors in test-lib.el cause mysterious failures
+test_expect_success 'Syntax of emacs test library' \
+ "${TEST_EMACS} -Q --batch --load $TEST_DIRECTORY/test-lib.el"
+
test_begin_subtest "Basic notmuch-hello view in emacs"
test_emacs '(notmuch-hello)
(test-output)'
@@ -723,7 +727,7 @@ inbox,stashtest
${gen_msg_filename}
http://mid.gmane.org/bought
http://marc.info/?i=bought
-http://mail-archive.com/search?l=mid&q=bought
+http://mid.mail-archive.com/bought
EOF
test_expect_equal_file OUTPUT EXPECTED
diff --git a/test/emacs-large-search-buffer b/test/T320-emacs-large-search-buffer.sh
index 8b1251fe..8b1251fe 100755
--- a/test/emacs-large-search-buffer
+++ b/test/T320-emacs-large-search-buffer.sh
diff --git a/test/emacs-subject-to-filename b/test/T330-emacs-subject-to-filename.sh
index 230c324d..230c324d 100755
--- a/test/emacs-subject-to-filename
+++ b/test/T330-emacs-subject-to-filename.sh
diff --git a/test/maildir-sync b/test/T340-maildir-sync.sh
index 3186e70f..3186e70f 100755
--- a/test/maildir-sync
+++ b/test/T340-maildir-sync.sh
diff --git a/test/crypto b/test/T350-crypto.sh
index 477b397e..477b397e 100755
--- a/test/crypto
+++ b/test/T350-crypto.sh
diff --git a/test/symbol-hiding b/test/T360-symbol-hiding.sh
index 636ec917..636ec917 100755
--- a/test/symbol-hiding
+++ b/test/T360-symbol-hiding.sh
diff --git a/test/search-folder-coherence b/test/T370-search-folder-coherence.sh
index 3f6ec763..3f6ec763 100755
--- a/test/search-folder-coherence
+++ b/test/T370-search-folder-coherence.sh
diff --git a/test/atomicity b/test/T380-atomicity.sh
index 1c786fa2..1c786fa2 100755
--- a/test/atomicity
+++ b/test/T380-atomicity.sh
diff --git a/test/python b/test/T390-python.sh
index 3f03a2e3..3f03a2e3 100755
--- a/test/python
+++ b/test/T390-python.sh
diff --git a/test/hooks b/test/T400-hooks.sh
index 77e8569b..77e8569b 100755
--- a/test/hooks
+++ b/test/T400-hooks.sh
diff --git a/test/argument-parsing b/test/T410-argument-parsing.sh
index 94e90874..94e90874 100755
--- a/test/argument-parsing
+++ b/test/T410-argument-parsing.sh
diff --git a/test/emacs-test-functions b/test/T420-emacs-test-functions.sh
index ca4a7988..ca4a7988 100755
--- a/test/emacs-test-functions
+++ b/test/T420-emacs-test-functions.sh
diff --git a/test/emacs-address-cleaning b/test/T430-emacs-address-cleaning.sh
index 04723467..04723467 100755
--- a/test/emacs-address-cleaning
+++ b/test/T430-emacs-address-cleaning.sh
diff --git a/test/emacs-hello b/test/T440-emacs-hello.sh
index f7296166..f7296166 100755
--- a/test/emacs-hello
+++ b/test/T440-emacs-hello.sh
diff --git a/test/emacs-show b/test/T450-emacs-show.sh
index 2a3a5356..2a3a5356 100755
--- a/test/emacs-show
+++ b/test/T450-emacs-show.sh
diff --git a/test/emacs-tree b/test/T460-emacs-tree.sh
index 4bdfddd2..8e9f37cb 100755
--- a/test/emacs-tree
+++ b/test/T460-emacs-tree.sh
@@ -8,16 +8,14 @@ EXPECTED=$TEST_DIRECTORY/tree.expected-output
add_email_corpus
test_begin_subtest "Basic notmuch-tree view in emacs"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(test-output)
(delete-other-windows)'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox
test_begin_subtest "Refreshed notmuch-tree view in emacs"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(notmuch-tree-refresh-view)
(notmuch-test-wait)
@@ -30,8 +28,7 @@ test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox
# correctly.
test_begin_subtest "Tag message in notmuch tree view (display)"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(forward-line)
(notmuch-tree-tag (list "+test_tag"))
@@ -44,8 +41,7 @@ output=$(notmuch search --output=messages 'tag:test_tag')
test_expect_equal "$output" "id:877h1wv7mg.fsf@inf-8657.int-evry.fr"
test_begin_subtest "Untag message in notmuch tree view"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(forward-line)
(notmuch-tree-tag (list "-test_tag"))
@@ -58,8 +54,7 @@ output=$(notmuch search --output=messages 'tag:test_tag')
test_expect_equal "$output" ""
test_begin_subtest "Tag thread in notmuch tree view"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
;; move to a sizable thread
(forward-line 26)
@@ -80,8 +75,7 @@ id:87iqd9rn3l.fsf@vertex.dottedmag
id:20091117190054.GU3165@dottiness.seas.harvard.edu"
test_begin_subtest "Untag thread in notmuch tree view"
-test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (notmuch-tree "tag:inbox")
+test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
;; move to the same sizable thread as above
(forward-line 26)
@@ -147,26 +141,20 @@ cp OUTPUT /tmp/mjwout
test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-show-window
test_begin_subtest "Stash id"
-output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (require (quote notmuch-tree))
- (notmuch-tree "id:1258498485-sup-142@elly")
+output=$(test_emacs '(notmuch-tree "id:1258498485-sup-142@elly")
(notmuch-test-wait)
(notmuch-show-stash-message-id)')
test_expect_equal "$output" "\"Stashed: id:1258498485-sup-142@elly\""
test_begin_subtest "Move to next matching message"
-output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (require (quote notmuch-tree))
- (notmuch-tree "from:cworth")
+output=$(test_emacs '(notmuch-tree "from:cworth")
(notmuch-test-wait)
(notmuch-tree-next-matching-message)
(notmuch-show-stash-message-id)')
test_expect_equal "$output" "\"Stashed: id:878we4qdqf.fsf@yoom.home.cworth.org\""
test_begin_subtest "Move to next thread"
-output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (require (quote notmuch-tree))
- (notmuch-tree "tag:inbox")
+output=$(test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(forward-line 26)
(notmuch-tree-next-thread)
@@ -174,9 +162,7 @@ output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
test_expect_equal "$output" "\"Stashed: id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net\""
test_begin_subtest "Move to previous thread"
-output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (require (quote notmuch-tree))
- (notmuch-tree "tag:inbox")
+output=$(test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(forward-line 26)
(notmuch-tree-prev-thread)
@@ -184,9 +170,7 @@ output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
test_expect_equal "$output" "\"Stashed: id:20091117190054.GU3165@dottiness.seas.harvard.edu\""
test_begin_subtest "Move to previous previous thread"
-output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'")
- (require (quote notmuch-tree))
- (notmuch-tree "tag:inbox")
+output=$(test_emacs '(notmuch-tree "tag:inbox")
(notmuch-test-wait)
(forward-line 26)
(notmuch-tree-prev-thread)
diff --git a/test/missing-headers b/test/T470-missing-headers.sh
index cb38301c..cb38301c 100755
--- a/test/missing-headers
+++ b/test/T470-missing-headers.sh
diff --git a/test/hex-escaping b/test/T480-hex-escaping.sh
index ad50e1bc..ad50e1bc 100755
--- a/test/hex-escaping
+++ b/test/T480-hex-escaping.sh
diff --git a/test/parse-time-string b/test/T490-parse-time-string.sh
index 8ae0b4c2..8ae0b4c2 100755
--- a/test/parse-time-string
+++ b/test/T490-parse-time-string.sh
diff --git a/test/search-date b/test/T500-search-date.sh
index 70bcf344..70bcf344 100755
--- a/test/search-date
+++ b/test/T500-search-date.sh
diff --git a/test/thread-replies b/test/T510-thread-replies.sh
index eeb70d06..eeb70d06 100755
--- a/test/thread-replies
+++ b/test/T510-thread-replies.sh
diff --git a/test/T520-show.sh b/test/T520-show.sh
new file mode 100755
index 00000000..0657c993
--- /dev/null
+++ b/test/T520-show.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+test_description='"notmuch show"'
+
+. ./test-lib.sh
+
+add_email_corpus
+
+test_begin_subtest "exit code for show invalid query"
+notmuch show foo..
+exit_code=$?
+test_expect_equal 1 $exit_code
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 18593f61..b8437127 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -16,61 +16,7 @@ fi
cd $(dirname "$0")
-TESTS="
- basic
- help-test
- compact
- config
- setup
- new
- count
- insert
- search
- search-output
- search-by-folder
- search-position-overlap-bug
- search-insufficient-from-quoting
- search-limiting
- excludes
- tagging
- json
- sexp
- text
- multipart
- thread-naming
- raw
- reply
- reply-to-sender
- dump-restore
- uuencode
- thread-order
- author-order
- from-guessing
- long-id
- encoding
- emacs
- emacs-large-search-buffer
- emacs-subject-to-filename
- maildir-sync
- crypto
- symbol-hiding
- search-folder-coherence
- atomicity
- python
- hooks
- argument-parsing
- emacs-test-functions
- emacs-address-cleaning
- emacs-hello
- emacs-show
- emacs-tree
- missing-headers
- hex-escaping
- parse-time-string
- search-date
- thread-replies
-"
-TESTS=${NOTMUCH_TESTS:=$TESTS}
+TESTS=${NOTMUCH_TESTS:-`echo T[0-9][0-9][0-9]-*.sh`}
# Clean up any results from a previous run
rm -r test-results >/dev/null 2>/dev/null
@@ -98,6 +44,7 @@ done
trap - HUP INT TERM
# Report results
+echo
./aggregate-results.sh test-results/*
ev=$?
diff --git a/test/test-lib.sh b/test/test-lib.sh
index efa9fb6f..78af170f 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -25,6 +25,10 @@ fi
# Make sure echo builtin does not expand backslash-escape sequences by default.
shopt -u xpg_echo
+this_test=${0##*/}
+this_test=${this_test%.sh}
+this_test_bare=${this_test#T[0-9][0-9][0-9]-}
+
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
case "$GIT_TEST_TEE_STARTED, $* " in
@@ -33,7 +37,7 @@ done,*)
;;
*' --tee '*|*' --va'*)
mkdir -p test-results
- BASE=test-results/$(basename "$0" .sh)
+ BASE=test-results/$this_test
(GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
echo $? > $BASE.exit) | tee $BASE.out
test "$(cat $BASE.exit)" = 0
@@ -187,7 +191,18 @@ then
exit 0
fi
-echo $(basename "$0"): "Testing ${test_description}"
+test_description_printed=
+print_test_description ()
+{
+ test -z "$test_description_printed" || return 0
+ echo
+ echo $this_test_bare: "Testing ${test_description}"
+ test_description_printed=1
+}
+if [ -z "$NOTMUCH_TEST_QUIET" ]
+then
+ print_test_description
+fi
exec 5>&1
@@ -748,6 +763,9 @@ test_ok_ () {
return
fi
test_success=$(($test_success + 1))
+ if test -n "$NOTMUCH_TEST_QUIET"; then
+ return 0
+ fi
say_color pass "%-6s" "PASS"
echo " $test_subtest_name"
}
@@ -758,6 +776,7 @@ test_failure_ () {
return
fi
test_failure=$(($test_failure + 1))
+ print_test_description
test_failure_message_ "FAIL" "$test_subtest_name" "$@"
test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
return 1
@@ -1009,7 +1028,7 @@ test_done () {
GIT_EXIT_OK=t
test_results_dir="$TEST_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
- test_results_path="$test_results_dir/${0%.sh}"
+ test_results_path="$test_results_dir/$this_test"
echo "total $test_count" >> $test_results_path
echo "success $test_success" >> $test_results_path
@@ -1018,8 +1037,6 @@ test_done () {
echo "failed $test_failure" >> $test_results_path
echo "" >> $test_results_path
- echo
-
[ -n "$EMACS_SERVER" ] && test_emacs '(kill-emacs)'
if [ "$test_failure" = "0" ]; then
@@ -1068,7 +1085,7 @@ test_emacs () {
test -z "$missing_dependencies" || return
if [ -z "$EMACS_SERVER" ]; then
- emacs_tests="$(basename $0).el"
+ emacs_tests="${this_test_bare}.el"
if [ -f "$TEST_DIRECTORY/$emacs_tests" ]; then
load_emacs_tests="--eval '(load \"$emacs_tests\")'"
else
@@ -1182,7 +1199,6 @@ else
exec 4>test.output 3>&4
fi
-this_test=${0##*/}
for skp in $NOTMUCH_SKIP_TESTS
do
to_skip=
diff --git a/test/test.expected-output/test-verbose-no b/test/test.expected-output/test-verbose-no
index 0bca7540..1a2ff619 100644
--- a/test/test.expected-output/test-verbose-no
+++ b/test/test.expected-output/test-verbose-no
@@ -1,3 +1,4 @@
+
test-verbose: Testing the verbosity options of the test framework itself.
PASS print something in test_expect_success and pass
FAIL print something in test_expect_success and fail
diff --git a/test/test.expected-output/test-verbose-yes b/test/test.expected-output/test-verbose-yes
index ebe51874..d25466e9 100644
--- a/test/test.expected-output/test-verbose-yes
+++ b/test/test.expected-output/test-verbose-yes
@@ -1,3 +1,4 @@
+
test-verbose: Testing the verbosity options of the test framework itself.
hello stdout
hello stderr
diff --git a/test/tree.expected-output/notmuch-tree-single-thread b/test/tree.expected-output/notmuch-tree-single-thread
index c9e5ef82..2285d10e 100644
--- a/test/tree.expected-output/notmuch-tree-single-thread
+++ b/test/tree.expected-output/notmuch-tree-single-thread
@@ -1,6 +1,6 @@
2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox)
- 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox, unread)
- 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
+ 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox unread)
+ 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
End of search results.
diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox b/test/tree.expected-output/notmuch-tree-tag-inbox
index 484141ec..f28d4856 100644
--- a/test/tree.expected-output/notmuch-tree-tag-inbox
+++ b/test/tree.expected-output/notmuch-tree-tag-inbox
@@ -1,53 +1,53 @@
- 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread)
- 2010-12-16 Olivier Berger ─►Essai accentué (inbox, unread)
- 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread)
- 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread)
- 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread)
- 2009-11-17 Jan Janak ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread)
- 2009-11-18 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, unread)
- 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, unread)
- 2009-11-17 Keith Packard │ ╰┬► ... (inbox, unread)
- 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox, unread)
- 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread)
- 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread)
- 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread)
- 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread)
- 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread)
- 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread)
- 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread)
- 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread)
- 2009-11-17 Carl Worth ╰─► ... (inbox, unread)
+ 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread)
+ 2010-12-16 Olivier Berger ─►Essai accentué (inbox unread)
+ 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread)
+ 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread)
+ 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread)
+ 2009-11-17 Jan Janak ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread)
+ 2009-11-18 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed unread)
+ 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed unread)
+ 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed unread)
+ 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox unread)
+ 2009-11-17 Keith Packard │ ╰┬► ... (inbox unread)
+ 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox unread)
+ 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread)
+ 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread)
+ 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread)
+ 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread)
+ 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread)
+ 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)
+ 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread)
+ 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread)
+ 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread)
+ 2009-11-17 Carl Worth ╰─► ... (inbox unread)
End of search results.
diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox-tagged b/test/tree.expected-output/notmuch-tree-tag-inbox-tagged
index 1f75a34b..428c0ae8 100644
--- a/test/tree.expected-output/notmuch-tree-tag-inbox-tagged
+++ b/test/tree.expected-output/notmuch-tree-tag-inbox-tagged
@@ -1,53 +1,53 @@
- 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread)
- 2010-12-16 Olivier Berger ─►Essai accentué (inbox, test_tag, unread)
- 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread)
- 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread)
- 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread)
- 2009-11-17 Jan Janak ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread)
- 2009-11-18 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, unread)
- 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, unread)
- 2009-11-17 Keith Packard │ ╰┬► ... (inbox, unread)
- 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox, unread)
- 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread)
- 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread)
- 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread)
- 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread)
- 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread)
- 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread)
- 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread)
- 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread)
- 2009-11-17 Carl Worth ╰─► ... (inbox, unread)
+ 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread)
+ 2010-12-16 Olivier Berger ─►Essai accentué (inbox test_tag unread)
+ 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread)
+ 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread)
+ 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread)
+ 2009-11-17 Jan Janak ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread)
+ 2009-11-18 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed unread)
+ 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed unread)
+ 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed unread)
+ 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox unread)
+ 2009-11-17 Keith Packard │ ╰┬► ... (inbox unread)
+ 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox unread)
+ 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread)
+ 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread)
+ 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread)
+ 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread)
+ 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread)
+ 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)
+ 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread)
+ 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread)
+ 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread)
+ 2009-11-17 Carl Worth ╰─► ... (inbox unread)
End of search results.
diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged b/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged
index a7aba6e2..828c5251 100644
--- a/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged
+++ b/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged
@@ -1,53 +1,53 @@
- 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread)
- 2010-12-16 Olivier Berger ─►Essai accentué (inbox, unread)
- 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread)
- 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread)
- 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread)
- 2009-11-18 Keith Packard ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread)
- 2009-11-17 Jan Janak ├─► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread)
- 2009-11-18 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread)
- 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, test_thread_tag, unread)
- 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, test_thread_tag, unread)
- 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, test_thread_tag, unread)
- 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, test_thread_tag, unread)
- 2009-11-17 Keith Packard │ ╰┬► ... (inbox, test_thread_tag, unread)
- 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, test_thread_tag, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, test_thread_tag, unread)
- 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox, unread)
- 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread)
- 2009-11-17 Keith Packard ╰┬► ... (inbox, unread)
- 2009-11-18 Carl Worth ╰─► ... (inbox, unread)
- 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread)
- 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread)
- 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread)
- 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread)
- 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread)
- 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread)
- 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread)
- 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread)
- 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread)
- 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread)
- 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread)
- 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread)
- 2009-11-17 Carl Worth ╰─► ... (inbox, unread)
+ 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread)
+ 2010-12-16 Olivier Berger ─►Essai accentué (inbox unread)
+ 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread)
+ 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread)
+ 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread)
+ 2009-11-18 Keith Packard ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread)
+ 2009-11-17 Jan Janak ├─► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread)
+ 2009-11-18 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
+ 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed test_thread_tag unread)
+ 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed test_thread_tag unread)
+ 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed test_thread_tag unread)
+ 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox test_thread_tag unread)
+ 2009-11-17 Keith Packard │ ╰┬► ... (inbox test_thread_tag unread)
+ 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed test_thread_tag unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox test_thread_tag unread)
+ 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox unread)
+ 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
+ 2009-11-17 Keith Packard ╰┬► ... (inbox unread)
+ 2009-11-18 Carl Worth ╰─► ... (inbox unread)
+ 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread)
+ 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread)
+ 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread)
+ 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread)
+ 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread)
+ 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread)
+ 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread)
+ 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread)
+ 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)
+ 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread)
+ 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread)
+ 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread)
+ 2009-11-17 Carl Worth ╰─► ... (inbox unread)
End of search results.