diff options
| author | David Bremner <bremner@debian.org> | 2023-12-01 07:51:09 -0400 |
|---|---|---|
| committer | David Bremner <bremner@debian.org> | 2023-12-01 07:51:09 -0400 |
| commit | 126347b6942dd4b0291beb67b119431ebd750a2a (patch) | |
| tree | 532c5163cb0972c8b9e6c8b4577b86afb9c6a6a2 /doc | |
Import notmuch_0.38.2.orig.tar.xz
[dgit import orig notmuch_0.38.2.orig.tar.xz]
Diffstat (limited to 'doc')
32 files changed, 5714 insertions, 0 deletions
diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000..bbb749fa --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,3 @@ +*.pyc +/_build +/config.dox diff --git a/doc/INSTALL b/doc/INSTALL new file mode 100644 index 00000000..05854760 --- /dev/null +++ b/doc/INSTALL @@ -0,0 +1,11 @@ +This file contains some more detailed information about building and +installing the documentation. + +- You need sphinx at least version 1.0. + +- You can build build and install man pages with 'make install-man' + +- You can build man, info, html, and pdf versions of the docs + (currently only the man pages) with + + 'make install-{man|info|html|pdf}' diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 00000000..fa25832e --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,5 @@ +all: + $(MAKE) -C .. all + +.DEFAULT: + $(MAKE) -C .. $@ diff --git a/doc/Makefile.local b/doc/Makefile.local new file mode 100644 index 00000000..aafa77a0 --- /dev/null +++ b/doc/Makefile.local @@ -0,0 +1,163 @@ +# -*- makefile-gmake -*- + +dir := doc + +# You can set these variables from the command line. +SPHINXOPTS := -q +SPHINXBUILD = env LD_LIBRARY_PATH=${NOTMUCH_BUILDDIR}/lib sphinx-build +DOCBUILDDIR := $(dir)/_build + +# Internal variables. +ALLSPHINXOPTS := $(SPHINXOPTS) $(srcdir)/$(dir) +APIMAN := $(DOCBUILDDIR)/man/man3/notmuch.3 +DOXYFILE := $(srcdir)/$(dir)/doxygen.cfg + +MAN1_RST := $(wildcard $(srcdir)/doc/man1/*.rst) +MAN5_RST := $(wildcard $(srcdir)/doc/man5/*.rst) +MAN7_RST := $(wildcard $(srcdir)/doc/man7/*.rst) +MAN_RST_FILES := $(MAN1_RST) $(MAN5_RST) $(MAN7_RST) +ALL_RST_FILES := $(MAN_RST_FILES) $(srcdir)/doc/notmuch-emacs.rst + +COPY_ROFF1 := $(patsubst %,$(DOCBUILDDIR)/man/man1/%.1,nmbug notmuch-setup) +MAN1_ROFF := $(patsubst $(srcdir)/doc/%,$(DOCBUILDDIR)/man/%,$(MAN1_RST:.rst=.1)) +MAN1_ROFF := $(MAN1_ROFF) $(COPY_ROFF1) +MAN5_ROFF := $(patsubst $(srcdir)/doc/%,$(DOCBUILDDIR)/man/%,$(MAN5_RST:.rst=.5)) +MAN7_ROFF := $(patsubst $(srcdir)/doc/%,$(DOCBUILDDIR)/man/%,$(MAN7_RST:.rst=.7)) +MAN_ROFF_FILES := $(MAN1_ROFF) $(MAN5_ROFF) $(MAN7_ROFF) + +MAN_GZIP_FILES := $(addsuffix .gz,${MAN_ROFF_FILES}) + +MAN1_TEXI := $(patsubst $(srcdir)/doc/man1/%.rst,$(DOCBUILDDIR)/texinfo/%.texi,$(MAN1_RST)) +MAN5_TEXI := $(patsubst $(srcdir)/doc/man5/%.rst,$(DOCBUILDDIR)/texinfo/%.texi,$(MAN5_RST)) +MAN7_TEXI := $(patsubst $(srcdir)/doc/man7/%.rst,$(DOCBUILDDIR)/texinfo/%.texi,$(MAN7_RST)) +INFO_TEXI_FILES := $(MAN1_TEXI) $(MAN5_TEXI) $(MAN7_TEXI) +ifeq ($(WITH_EMACS),1) + INFO_TEXI_FILES += $(DOCBUILDDIR)/texinfo/notmuch-emacs.texi +endif + +COPY_INFO1 := $(patsubst $(DOCBUILDDIR)/man/man1/%.1,$(DOCBUILDDIR)/texinfo/%.info,$(COPY_ROFF1)) +INFO_INFO_FILES := $(INFO_TEXI_FILES:.texi=.info) $(COPY_INFO1) + +.PHONY: sphinx-html sphinx-texinfo sphinx-info + +.PHONY: install-man build-man apidocs install-apidocs + +%.gz: % + rm -f $@ && gzip --no-name --stdout $^ > $@ + +ifeq ($(WITH_EMACS),1) +$(DOCBUILDDIR)/.roff.stamp $(DOCBUILDDIR)/.html.stamp $(DOCBUILDDIR)/.texi.stamp : docstring.stamp +endif + +ifeq ($(HAVE_PYTHON3_CFFI),1) +DOC_PREREQS=bindings/python-cffi.stamp +else +DOC_PREREQS= +endif + +sphinx-html: $(DOCBUILDDIR)/.html.stamp + +$(DOCBUILDDIR)/.html.stamp: $(ALL_RST_FILES) $(DOC_PREREQS) + $(SPHINXBUILD) -b html -d $(DOCBUILDDIR)/html_doctrees $(ALLSPHINXOPTS) $(DOCBUILDDIR)/html + touch $@ + +sphinx-texinfo: $(DOCBUILDDIR)/.texi.stamp + +$(DOCBUILDDIR)/.texi.stamp: $(ALL_RST_FILES) $(DOC_PREREQS) + $(SPHINXBUILD) -b texinfo -d $(DOCBUILDDIR)/texinfo_doctrees $(ALLSPHINXOPTS) $(DOCBUILDDIR)/texinfo + touch $@ + +sphinx-info: $(DOCBUILDDIR)/.info.stamp + +$(DOCBUILDDIR)/.info.stamp: $(DOCBUILDDIR)/.texi.stamp $(DOC_PREREQS) + $(MAKE) -C $(DOCBUILDDIR)/texinfo info + touch $@ + +# Use the man page converter that is available. We should never depend +# on MAN_ROFF_FILES if a converter is not available. +${MAN_ROFF_FILES}: $(DOCBUILDDIR)/.roff.stamp + +# By using $(DOCBUILDDIR)/.roff.stamp instead of ${MAN_ROFF_FILES}, we +# convey to make that a single invocation of this recipe builds all +# of the roff files. This prevents parallel make from starting an +# instance of this recipe for each roff file. +$(DOCBUILDDIR)/.roff.stamp: ${MAN_RST_FILES} +ifeq ($(HAVE_SPHINX),1) + $(SPHINXBUILD) -b man -d $(DOCBUILDDIR)/man_doctrees $(ALLSPHINXOPTS) $(DOCBUILDDIR)/man + for section in 1 5 7; do \ + mkdir -p $(DOCBUILDDIR)/man/man$${section}; \ + mv $(DOCBUILDDIR)/man/*.$${section} $(DOCBUILDDIR)/man/man$${section}; \ + done +else + @echo "Fatal: build dependency fail." + @false +endif + touch $@ + +install-man: install-apidocs + +ifeq ($(HAVE_DOXYGEN),1) +MAN_GZIP_FILES += ${APIMAN}.gz +apidocs: $(APIMAN) +install-apidocs: ${APIMAN}.gz + mkdir -p "$(DESTDIR)$(mandir)/man3" + install -m0644 $(filter %.3.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man3 + +$(APIMAN): $(dir)/config.dox $(srcdir)/$(dir)/doxygen.cfg $(srcdir)/lib/notmuch.h + mkdir -p $(DOCBUILDDIR)/man/man3 + doxygen $(DOXYFILE) + rm -f $(DOCBUILDDIR)/man/man3/_*.3 + perl -pi -e 's/^[.]RI "\\fI/.RI "\\fP/' $(APIMAN) +else +apidocs: +install-apidocs: +endif + +# Do not try to build or install man pages if a man page converter is +# not available. +ifeq ($(HAVE_SPHINX),0) +build-man: +install-man: + @echo "No sphinx, will not install man pages." +else + +# it should be safe to depend on the stamp file, because it is created +# after all roff files are moved into place. +${MAN_GZIP_FILES}: ${DOCBUILDDIR}/.roff.stamp + +build-man: ${MAN_GZIP_FILES} +install-man: ${MAN_GZIP_FILES} + mkdir -m0755 -p "$(DESTDIR)$(mandir)/man1" + mkdir -m0755 -p "$(DESTDIR)$(mandir)/man5" + mkdir -m0755 -p "$(DESTDIR)$(mandir)/man7" + install -m0644 $(filter %.1.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man1 + install -m0644 $(filter %.5.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man5 + install -m0644 $(filter %.7.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man7 +endif + +ifneq ($(HAVE_SPHINX)$(HAVE_MAKEINFO),11) +build-info: + @echo "Missing sphinx or makeinfo, not building info pages" +else +build-info: $(DOCBUILDDIR)/.info.stamp +endif + +ifneq ($(HAVE_SPHINX)$(HAVE_MAKEINFO)$(HAVE_INSTALL_INFO),111) +install-info: + @echo "Missing prerequisites, not installing info pages" +else +install-info: build-info + mkdir -m0755 -p "$(DESTDIR)$(infodir)" + install -m0644 $(INFO_INFO_FILES) $(DESTDIR)$(infodir) + for file in $(INFO_INFO_FILES); do install-info $$file $(DESTDIR)$(infodir)/dir; done +endif + +$(dir)/config.dox: version.stamp + echo "PROJECT_NAME = \"Notmuch $(VERSION)\"" > $@ + echo "INPUT=${srcdir}/lib/notmuch.h" >> $@ + +CLEAN := $(CLEAN) $(DOCBUILDDIR) $(DOCBUILDDIR)/.roff.stamp $(DOCBUILDDIR)/.texi.stamp +CLEAN := $(CLEAN) $(DOCBUILDDIR)/.html.stamp $(DOCBUILDDIR)/.info.stamp +CLEAN := $(CLEAN) $(MAN_GZIP_FILES) $(MAN_ROFF_FILES) $(dir)/conf.pyc $(dir)/config.dox + +CLEAN := $(CLEAN) $(dir)/__pycache__ diff --git a/doc/command-line.rst b/doc/command-line.rst new file mode 100644 index 00000000..543a5f9e --- /dev/null +++ b/doc/command-line.rst @@ -0,0 +1,36 @@ +Notmuch Command Line Interface +============================== + +Main commands +------------- + +.. toctree:: + :titlesonly: + + man1/notmuch + man1/notmuch-address + man1/notmuch-compact + man1/notmuch-config + man1/notmuch-count + man1/notmuch-dump + man1/notmuch-emacs-mua + man1/notmuch-git + man1/notmuch-insert + man1/notmuch-new + man1/notmuch-reindex + man1/notmuch-reply + man1/notmuch-restore + man1/notmuch-search + man1/notmuch-show + man1/notmuch-tag + man5/notmuch-hooks + +Aliases +------- + +.. toctree:: + :titlesonly: + + nmbug <man1/notmuch-git> + notmuch-setup <man1/notmuch> + diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 00000000..7ac13a5d --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,226 @@ + +# -*- coding: utf-8 -*- + +import sys +import os +from pathlib import Path +sys.path.append(str(Path(__file__).parent)) + +extensions = [ 'sphinx.ext.autodoc', 'elisp' ] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'notmuch' +copyright = u'2009-2023, Carl Worth and many others' + +location = os.path.dirname(__file__) + +for pathdir in ['.', '..']: + version_file = os.path.join(location,pathdir,'version.txt') + if os.path.exists(version_file): + with open(version_file,'r') as infile: + version=infile.read().replace('\n','') + +# for autodoc +sys.path.insert(0, os.path.join(location, '..', 'bindings', 'python-cffi', 'build', 'stage')) + +# read generated config +for pathdir in ['.', '..']: + conf_file = os.path.join(location,pathdir,'sphinx.config') + if os.path.exists(conf_file): + with open(conf_file,'r') as infile: + exec(''.join(infile.readlines())) + +# The full version, including alpha/beta/rc tags. +release = version + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +if tags.has('WITH_EMACS'): + # Hacky reimplementation of include to workaround limitations of + # sphinx-doc + lines = ['.. include:: /../emacs/rstdoc.rsti\n\n'] # in the source tree + for file in ('notmuch.rsti', 'notmuch-lib.rsti', 'notmuch-hello.rsti', 'notmuch-show.rsti', 'notmuch-tag.rsti', 'notmuch-tree.rsti'): + lines.extend(open(rsti_dir+'/'+file)) + rst_epilog = ''.join(lines) + del lines +else: + # If we don't have emacs (or the user configured --without-emacs), + # don't build the notmuch-emacs docs, as they need emacs to generate + # the docstring include files + exclude_patterns.append('notmuch-emacs.rst') + +if not tags.has('WITH_PYTHON'): + exclude_patterns.append('python-bindings.rst') + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# prevent generation of python module index +html_domain_indices=[] + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'notmuchdoc' + +# Disable SmartyPants, as it mangles command lines. +# Despite the name, this actually affects manual pages as well. +html_use_smartypants = False + +# See: +# - https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-manpages_url +# - https://manpages.debian.org/ +manpages_url = 'https://manpages.debian.org/{page}.{section}.html' + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). + +notmuch_authors = u'Carl Worth and many others' + +man_make_section_directory = False + +man_pages = [ + ('man1/notmuch', 'notmuch', + u'thread-based email index, search, and tagging', + [notmuch_authors], 1), + + ('man1/notmuch-address', 'notmuch-address', + u'output addresses from matching messages', + [notmuch_authors], 1), + + ('man1/notmuch-compact', 'notmuch-compact', + u'compact the notmuch database', + [notmuch_authors], 1), + + ('man1/notmuch-config', 'notmuch-config', + u'access notmuch configuration file', + [notmuch_authors], 1), + + ('man1/notmuch-count', 'notmuch-count', + u'count messages matching the given search terms', + [notmuch_authors], 1), + + ('man1/notmuch-dump', 'notmuch-dump', + u'creates a plain-text dump of the tags of each message', + [notmuch_authors], 1), + + ('man1/notmuch-emacs-mua', 'notmuch-emacs-mua', + u'send mail with notmuch and emacs', + [notmuch_authors], 1), + + ('man1/notmuch-git', 'notmuch-git', + u'manage notmuch tags with git', + [notmuch_authors], 1), + + ('man1/notmuch-git', 'nmbug', + u'manage notmuch bugs with git', + [notmuch_authors], 1), + + ('man5/notmuch-hooks', 'notmuch-hooks', + u'hooks for notmuch', + [notmuch_authors], 5), + + ('man1/notmuch-insert', 'notmuch-insert', + u'add a message to the maildir and notmuch database', + [notmuch_authors], 1), + + ('man1/notmuch-new', 'notmuch-new', + u'incorporate new mail into the notmuch database', + [notmuch_authors], 1), + + ('man7/notmuch-properties', 'notmuch-properties', + u'notmuch message property conventions and documentation', + [notmuch_authors], 7), + + ('man1/notmuch-reindex', 'notmuch-reindex', + u're-index matching messages', + [notmuch_authors], 1), + + ('man1/notmuch-reply', 'notmuch-reply', + u'constructs a reply template for a set of messages', + [notmuch_authors], 1), + + ('man1/notmuch-restore', 'notmuch-restore', + u'restores the tags from the given file (see notmuch dump)', + [notmuch_authors], 1), + + ('man1/notmuch-search', 'notmuch-search', + u'search for messages matching the given search terms', + [notmuch_authors], 1), + + ('man7/notmuch-search-terms', 'notmuch-search-terms', + u'syntax for notmuch queries', + [notmuch_authors], 7), + + ('man1/notmuch', 'notmuch-setup', + u'getting started with notmuch', + [notmuch_authors], 1), + + ('man7/notmuch-sexp-queries', 'notmuch-sexp-queries', + u's-expression syntax for notmuch queries', + [notmuch_authors], 7), + + ('man1/notmuch-show', 'notmuch-show', + u'show messages matching the given search terms', + [notmuch_authors], 1), + + ('man1/notmuch-tag', 'notmuch-tag', + u'add/remove tags for all messages matching the search terms', + [notmuch_authors], 1), +] + +# If true, show URL addresses after external links. +#man_show_urls = False + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +# If true, do not generate a @detailmenu in the "Top" node's menu. +texinfo_no_detailmenu = True + +texinfo_documents = [ + ('notmuch-emacs', 'notmuch-emacs', u'notmuch-emacs documentation', + notmuch_authors, 'notmuch-emacs', + 'emacs based front-end for notmuch', 'Miscellaneous'), +] + +# generate texinfo list from man page list +texinfo_documents += [ + ( + x[0], # source start file + x[1], # target name + x[1] + u' documentation', # title + x[3][0], # author + x[1], # dir menu entry + x[2], # description + 'Miscellaneous' # category + ) for x in man_pages] + +def setup(app): + import docutils.nodes + # define nmconfig role and directive for config items. + app.add_object_type('nmconfig','nmconfig', + indextemplate='pair: configuration item; %s', + ref_nodeclass=docutils.nodes.generated, + objname='config item' ) diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg new file mode 100644 index 00000000..4a022de1 --- /dev/null +++ b/doc/doxygen.cfg @@ -0,0 +1,298 @@ +# Doxyfile 1.8.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +@INCLUDE = "doc/config.dox" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = doc/_build +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 = +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= YES +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_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 = https://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_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 +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +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/doc/elisp.py b/doc/elisp.py new file mode 100644 index 00000000..1b0392e6 --- /dev/null +++ b/doc/elisp.py @@ -0,0 +1,445 @@ +# Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors + +# This file is not part of GNU Emacs. + +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. + +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. + +# You should have received a copy of the GNU General Public License along with +# this program. If not, see <http://www.gnu.org/licenses/>. + + +from collections import namedtuple +from sphinx import addnodes +from sphinx.util import ws_re +from sphinx.roles import XRefRole +from sphinx.domains import Domain, ObjType +from sphinx.util.nodes import make_refnode +from sphinx.directives import ObjectDescription + + +def make_target(cell, name): + """Create a target name from ``cell`` and ``name``. + + ``cell`` is the name of a symbol cell, and ``name`` is a symbol name, both + as strings. + + The target names are used as cross-reference targets for Sphinx. + + """ + return '{cell}-{name}'.format(cell=cell, name=name) + + +def to_mode_name(symbol_name): + """Convert ``symbol_name`` to a mode name. + + Split at ``-`` and titlecase each part. + + """ + return ' '.join(p.title() for p in symbol_name.split('-')) + + +class Cell(namedtuple('Cell', 'objtype docname')): + """A cell in a symbol. + + A cell holds the object type and the document name of the description for + the cell. + + Cell objects are used within symbol entries in the domain data. + + """ + + pass + + +class KeySequence(namedtuple('KeySequence', 'keys')): + """A key sequence.""" + + PREFIX_KEYS = {'C-u'} + PREFIX_KEYS.update('M-{}'.format(n) for n in range(10)) + + @classmethod + def fromstring(cls, s): + return cls(s.split()) + + @property + def command_name(self): + """The command name in this key sequence. + + Return ``None`` for key sequences that are no command invocations with + ``M-x``. + + """ + try: + return self.keys[self.keys.index('M-x') + 1] + except ValueError: + return None + + @property + def has_prefix(self): + """Whether this key sequence has a prefix.""" + return self.keys[0] in self.PREFIX_KEYS + + def __str__(self): + return ' '.join(self.keys) + + +class EmacsLispSymbol(ObjectDescription): + """An abstract base class for directives documenting symbols. + + Provide target and index generation and registration of documented symbols + within the domain data. + + Deriving classes must have a ``cell`` attribute which refers to the cell + the documentation goes in, and a ``label`` attribute which provides a + human-readable name for what is documented, used in the index entry. + + """ + + cell_for_objtype = { + 'defcustom': 'variable', + 'defconst': 'variable', + 'defvar': 'variable', + 'defface': 'face' + } + + category_for_objtype = { + 'defcustom': 'Emacs variable (customizable)', + 'defconst': 'Emacs constant', + 'defvar': 'Emacs variable', + 'defface': 'Emacs face' + } + + @property + def cell(self): + """The cell in which to store symbol metadata.""" + return self.cell_for_objtype[self.objtype] + + @property + def label(self): + """The label for the documented object type.""" + return self.objtype + + @property + def category(self): + """Index category""" + return self.category_for_objtype[self.objtype] + + def handle_signature(self, signature, signode): + """Create nodes in ``signode`` for the ``signature``. + + ``signode`` is a docutils node to which to add the nodes, and + ``signature`` is the symbol name. + + Add the object type label before the symbol name and return + ``signature``. + + """ + label = self.label + ' ' + signode += addnodes.desc_annotation(label, label) + signode += addnodes.desc_name(signature, signature) + return signature + + def _add_index(self, name, target): + index_text = '{name}; {label}'.format( + name=name, label=self.category) + self.indexnode['entries'].append( + ('pair', index_text, target, '', None)) + + def _add_target(self, name, sig, signode): + target = make_target(self.cell, name) + if target not in self.state.document.ids: + signode['names'].append(name) + signode['ids'].append(target) + signode['first'] = (not self.names) + self.state.document.note_explicit_target(signode) + + obarray = self.env.domaindata['el']['obarray'] + symbol = obarray.setdefault(name, {}) + if self.cell in symbol: + self.state_machine.reporter.warning( + 'duplicate description of %s %s, ' % (self.objtype, name) + + 'other instance in ' + + self.env.doc2path(symbol[self.cell].docname), + line=self.lineno) + symbol[self.cell] = Cell(self.objtype, self.env.docname) + + return target + + def add_target_and_index(self, name, sig, signode): + target = self._add_target(name, sig, signode) + self._add_index(name, target) + + +class EmacsLispMinorMode(EmacsLispSymbol): + cell = 'function' + label = 'Minor Mode' + + def handle_signature(self, signature, signode): + """Create nodes in ``signode`` for the ``signature``. + + ``signode`` is a docutils node to which to add the nodes, and + ``signature`` is the symbol name. + + Add the object type label before the symbol name and return + ``signature``. + + """ + label = self.label + ' ' + signode += addnodes.desc_annotation(label, label) + signode += addnodes.desc_name(signature, to_mode_name(signature)) + return signature + + def _add_index(self, name, target): + return super()._add_index(to_mode_name(name), target) + + +class EmacsLispFunction(EmacsLispSymbol): + """A directive to document Emacs Lisp functions.""" + + cell_for_objtype = { + 'defun': 'function', + 'defmacro': 'function' + } + + def handle_signature(self, signature, signode): + function_name, *args = ws_re.split(signature) + label = self.label + ' ' + signode += addnodes.desc_annotation(label, label) + signode += addnodes.desc_name(function_name, function_name) + for arg in args: + is_keyword = arg.startswith('&') + node = (addnodes.desc_annotation + if is_keyword + else addnodes.desc_addname) + signode += node(' ' + arg, ' ' + arg) + + return function_name + + +class EmacsLispKey(ObjectDescription): + """A directive to document interactive commands via their bindings.""" + + label = 'Emacs command' + + def handle_signature(self, signature, signode): + """Create nodes to ``signode`` for ``signature``. + + ``signode`` is a docutils node to which to add the nodes, and + ``signature`` is the symbol name. + """ + key_sequence = KeySequence.fromstring(signature) + signode += addnodes.desc_name(signature, str(key_sequence)) + return str(key_sequence) + + def _add_command_target_and_index(self, name, sig, signode): + target_name = make_target('function', name) + if target_name not in self.state.document.ids: + signode['names'].append(name) + signode['ids'].append(target_name) + self.state.document.note_explicit_target(signode) + + obarray = self.env.domaindata['el']['obarray'] + symbol = obarray.setdefault(name, {}) + if 'function' in symbol: + self.state_machine.reporter.warning( + 'duplicate description of %s %s, ' % (self.objtype, name) + + 'other instance in ' + + self.env.doc2path(symbol['function'].docname), + line=self.lineno) + symbol['function'] = Cell(self.objtype, self.env.docname) + + index_text = '{name}; {label}'.format(name=name, label=self.label) + self.indexnode['entries'].append( + ('pair', index_text, target_name, '', None)) + + def _add_binding_target_and_index(self, binding, sig, signode): + reftarget = make_target('key', binding) + + if reftarget not in self.state.document.ids: + signode['names'].append(reftarget) + signode['ids'].append(reftarget) + signode['first'] = (not self.names) + self.state.document.note_explicit_target(signode) + + keymap = self.env.domaindata['el']['keymap'] + if binding in keymap: + self.state_machine.reporter.warning( + 'duplicate description of binding %s, ' % binding + + 'other instance in ' + + self.env.doc2path(keymap[binding]), + line=self.lineno) + keymap[binding] = self.env.docname + + index_text = '{name}; Emacs key binding'.format(name=binding) + self.indexnode['entries'].append( + ('pair', index_text, reftarget, '', None)) + + def add_target_and_index(self, name, sig, signode): + # If unprefixed M-x command index as function and not as key binding + sequence = KeySequence.fromstring(name) + if sequence.command_name and not sequence.has_prefix: + self._add_command_target_and_index(sequence.command_name, + sig, signode) + else: + self._add_binding_target_and_index(name, sig, signode) + + +class XRefModeRole(XRefRole): + """A role to cross-reference a minor mode. + + Like a normal cross-reference role but appends ``-mode`` to the reference + target and title-cases the symbol name like Emacs does when referring to + modes. + + """ + + fix_parens = False + lowercase = False + + def process_link(self, env, refnode, has_explicit_title, title, target): + refnode['reftype'] = 'minor-mode' + target = target + '-mode' + return (title if has_explicit_title else to_mode_name(target), target) + + +class EmacsLispDomain(Domain): + """A domain to document Emacs Lisp code.""" + + name = 'el' + label = '' + + object_types = { + # TODO: Set search prio for object types + # Types for user-facing options and commands + 'minor-mode': ObjType('minor-mode', 'function', 'mode', + cell='function'), + 'define-key': ObjType('key binding', cell='interactive'), + 'defcustom': ObjType('defcustom', 'defcustom', cell='variable'), + 'defface': ObjType('defface', 'defface', cell='face'), + # Object types for code + 'defun': ObjType('defun', 'defun', cell='function'), + 'defmacro': ObjType('defmacro', 'defmacro', cell='function'), + 'defvar': ObjType('defvar', 'defvar', cell='variable'), + 'defconst': ObjType('defconst', 'defconst', cell='variable') + } + directives = { + 'minor-mode': EmacsLispMinorMode, + 'define-key': EmacsLispKey, + 'defcustom': EmacsLispSymbol, + 'defvar': EmacsLispSymbol, + 'defconst': EmacsLispSymbol, + 'defface': EmacsLispSymbol, + 'defun': EmacsLispFunction, + 'defmacro': EmacsLispFunction + } + roles = { + 'mode': XRefModeRole(), + 'defvar': XRefRole(), + 'defconst': XRefRole(), + 'defcustom': XRefRole(), + 'defface': XRefRole(), + 'defun': XRefRole(), + 'defmacro': XRefRole() + } + + data_version = 1 + initial_data = { + # Our domain data attempts to somewhat mirror the semantics of Emacs + # Lisp, so we have an obarray which holds symbols which in turn have + # function, variable, face, etc. cells, and a keymap which holds the + # documentation for key bindings. + 'obarray': {}, + 'keymap': {} + } + + def clear_doc(self, docname): + """Clear all cells documented ``docname``.""" + for symbol in self.data['obarray'].values(): + for cell in list(symbol.keys()): + if docname == symbol[cell].docname: + del symbol[cell] + for binding in list(self.data['keymap']): + if self.data['keymap'][binding] == docname: + del self.data['keymap'][binding] + + def resolve_xref(self, env, fromdocname, builder, + objtype, target, node, contnode): + """Resolve a cross reference to ``target``.""" + if objtype == 'key': + todocname = self.data['keymap'].get(target) + if not todocname: + return None + reftarget = make_target('key', target) + else: + cell = self.object_types[objtype].attrs['cell'] + symbol = self.data['obarray'].get(target, {}) + if cell not in symbol: + return None + reftarget = make_target(cell, target) + todocname = symbol[cell].docname + + return make_refnode(builder, fromdocname, todocname, + reftarget, contnode, target) + + def resolve_any_xref(self, env, fromdocname, builder, + target, node, contnode): + """Return all possible cross references for ``target``.""" + nodes = ((objtype, self.resolve_xref(env, fromdocname, builder, + objtype, target, node, contnode)) + for objtype in ['key', 'defun', 'defvar', 'defface']) + return [('el:{}'.format(objtype), node) for (objtype, node) in nodes + if node is not None] + + def merge_warn_duplicate(self, objname, our_docname, their_docname): + self.env.warn( + their_docname, + "Duplicate declaration: '{}' also defined in '{}'.\n".format( + objname, their_docname)) + + def merge_keymapdata(self, docnames, our_keymap, their_keymap): + for key, docname in their_keymap.items(): + if docname in docnames: + if key in our_keymap: + our_docname = our_keymap[key] + self.merge_warn_duplicate(key, our_docname, docname) + else: + our_keymap[key] = docname + + def merge_obarraydata(self, docnames, our_obarray, their_obarray): + for objname, their_cells in their_obarray.items(): + our_cells = our_obarray.setdefault(objname, dict()) + for cellname, their_cell in their_cells.items(): + if their_cell.docname in docnames: + our_cell = our_cells.get(cellname) + if our_cell: + self.merge_warn_duplicate(objname, our_cell.docname, + their_cell.docname) + else: + our_cells[cellname] = their_cell + + def merge_domaindata(self, docnames, otherdata): + self.merge_keymapdata(docnames, self.data['keymap'], + otherdata['keymap']) + self.merge_obarraydata(docnames, self.data['obarray'], + otherdata['obarray']) + + def get_objects(self): + """Get all documented symbols for use in the search index.""" + for name, symbol in self.data['obarray'].items(): + for cellname, cell in symbol.items(): + yield (name, name, cell.objtype, cell.docname, + make_target(cellname, name), + self.object_types[cell.objtype].attrs['searchprio']) + + +def setup(app): + app.add_domain(EmacsLispDomain) + return {'version': '0.1', 'parallel_read_safe': True} diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 00000000..fec3e6c2 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,20 @@ + +Welcome to notmuch's documentation! +=================================== + +Content +------- + +.. toctree:: + :titlesonly: + + command-line + queries + notmuch-emacs + python-bindings + +Index and search +----------------- + +* :ref:`genindex` +* :ref:`search` diff --git a/doc/man1/notmuch-address.rst b/doc/man1/notmuch-address.rst new file mode 100644 index 00000000..c70dde35 --- /dev/null +++ b/doc/man1/notmuch-address.rst @@ -0,0 +1,141 @@ +.. _notmuch-address(1): + +=============== +notmuch-address +=============== + +SYNOPSIS +======== + +**notmuch** **address** [*option* ...] <*search-term*> ... + +DESCRIPTION +=========== + +Search for messages matching the given search terms, and display the +addresses from them. Duplicate addresses are filtered out. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<search-terms>. + +Supported options for **address** include + +.. program:: address + +.. option:: --format=(json|sexp|text|text0) + + Presents the results in either JSON, S-Expressions, newline + character separated plain-text (default), or null character + separated plain-text (compatible with :manpage:`xargs(1)` -0 + option where available). + +.. option:: --format-version=N + + Use the specified structured output format version. This is + intended for programs that invoke :any:`notmuch(1)` internally. If + omitted, the latest supported version will be used. + +.. option:: --output=(sender|recipients|count|address) + + Controls which information appears in the output. This option can + be given multiple times to combine different outputs. When + neither ``--output=sender`` nor ``--output=recipients`` is + given, ``--output=sender`` is implied. + + sender + Output all addresses from the *From* header. + + Note: Searching for **sender** should be much faster than + searching for **recipients**, because sender addresses are + cached directly in the database whereas other addresses need + to be fetched from message files. + + recipients + Output all addresses from the *To*, *Cc* and *Bcc* headers. + + count + Print the count of how many times was the address encountered + during search. + + Note: With this option, addresses are printed only after the + whole search is finished. This may take long time. + + address + Output only the email addresses instead of the full mailboxes + with names and email addresses. This option has no effect on + the JSON or S-Expression output formats. + +.. option:: --deduplicate=(no|mailbox|address) + + Control the deduplication of results. + + no + Output all occurrences of addresses in the matching + messages. This is not applicable with ``--output=count``. + + mailbox + Deduplicate addresses based on the full, case sensitive name + and email address, or mailbox. This is effectively the same as + piping the ``--deduplicate=no`` output to **sort | uniq**, except + for the order of results. This is the default. + + address + Deduplicate addresses based on the case insensitive address + part of the mailbox. Of all the variants (with different name + or case), print the one occurring most frequently among the + matching messages. If ``--output=count`` is specified, include all + variants in the count. + +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + + However, if either ``--output=count`` or ``--deduplicate=address`` is + specified, this option is ignored and the order of the results is + unspecified. + +.. option:: --exclude=(true|false) + + A message is called "excluded" if it matches at least one tag in + search.exclude\_tags that does not appear explicitly in the search + terms. This option specifies whether to omit excluded messages in + the search process. + + The default value, **true**, prevents excluded messages from + matching the search terms. + + **false** allows excluded messages to match search terms and + appear in displayed results. + +EXIT STATUS +=========== + +This command supports the following special exit status codes + +``20`` + The requested format version is too old. + +``21`` + The requested format version is too new. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-compact.rst b/doc/man1/notmuch-compact.rst new file mode 100644 index 00000000..cb1c858b --- /dev/null +++ b/doc/man1/notmuch-compact.rst @@ -0,0 +1,56 @@ +.. _notmuch-compact(1): + +=============== +notmuch-compact +=============== + +SYNOPSIS +======== + +**notmuch** **compact** [--quiet] [--backup=<*directory*>] + +DESCRIPTION +=========== + +The **compact** command can be used to compact the notmuch database. +This can both reduce the space required by the database and improve +lookup performance. + +The compacted database is built in a temporary directory and is later +moved into the place of the origin database. The original uncompacted +database is discarded, unless the ``--backup=``\ <directory> option is +used. + +Note that the database write lock will be held during the compaction +process (which may be quite long) to protect data integrity. + +Supported options for **compact** include + +.. program:: compact + +.. option:: --backup=<directory> + + Save the current database to the given directory before replacing + it with the compacted database. The backup directory must not + exist and it must reside on the same mounted filesystem as the + current database. + +.. option:: --quiet + + Do not report database compaction progress to stdout. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst new file mode 100644 index 00000000..bd34afa4 --- /dev/null +++ b/doc/man1/notmuch-config.rst @@ -0,0 +1,385 @@ +.. _notmuch-config(1): + +============== +notmuch-config +============== + +SYNOPSIS +======== + +**notmuch** **config** **get** <*section*>.<*item*> + +**notmuch** **config** **set** [--database] <*section*>.<*item*> [*value* ...] + +**notmuch** **config** **list** + +DESCRIPTION +=========== + +The **config** command can be used to get or set settings in the notmuch +configuration file and corresponding database. + +.. program:: config + +.. option:: get + + The value of the specified configuration item is printed to + stdout. If the item has multiple values (it is a list), each value + is separated by a newline character. + +.. option:: set + + The specified configuration item is set to the given value. To + specify a multiple-value item (a list), provide each value as a + separate command-line argument. + + If no values are provided, the specified configuration item will + be removed from the configuration file. + + With the `--database` option, updates configuration metadata + stored in the database, rather than the default (text) + configuration file. + +.. option:: list + + Every configuration item is printed to stdout, each on a separate + line of the form:: + + section.item=value + + No additional whitespace surrounds the dot or equals sign + characters. In a multiple-value item (a list), the values are + separated by semicolon characters. + +The available configuration items are described below. Non-absolute +paths are presumed relative to `$HOME` for items in section +**database**. + +.. nmconfig:: built_with.<name> + + Compile time feature <name>. Current possibilities include + "retry_lock" (configure option, included by default). + (since notmuch 0.30, "compact" and "field_processor" are + always included.) + +.. nmconfig:: database.autocommit + + How often to commit transactions to disk. `0` means wait until + command completes, otherwise an integer `n` specifies to commit to + disk after every `n` completed transactions. + + History: this configuration value was introduced in notmuch 0.33. + +.. nmconfig:: database.backup_dir + + Directory to store tag dumps when upgrading database. + + History: this configuration value was introduced in notmuch 0.32. + + Default: A sibling directory of the Xapian database called + `backups`. + +.. nmconfig:: database.hook_dir + + Directory containing hooks run by notmuch commands. See + :any:`notmuch-hooks(5)`. + + History: this configuration value was introduced in notmuch 0.32. + + Default: See HOOKS, below. + +.. nmconfig:: database.mail_root + + The top-level directory where your mail currently exists and to + where mail will be delivered in the future. Files should be + individual email messages. + + History: this configuration value was introduced in notmuch 0.32. + + Default: For compatibility with older configurations, the value of + database.path is used if :nmconfig:`database.mail_root` is unset. + +.. nmconfig:: database.path + + Notmuch will store its database here, (in + sub-directory named ``.notmuch`` if :nmconfig:`database.mail_root` + is unset). + + Default: see :ref:`database` + +.. nmconfig:: git.path + + Default location for git repository for :any:`notmuch-git`. + +.. nmconfig:: git.safe_fraction + + Some :any:`notmuch-git` operations check that the fraction of + messages changed (in the database or in git, as appropriate) is not + too large. This item controls what fraction of total messages is + considered "not too large". + +.. nmconfig:: git.tag_prefix + + Default tag prefix (filter) for :any:`notmuch-git`. + +.. nmconfig:: index.as_text + + List of regular expressions (without delimiters) for MIME types to + be indexed as text. Currently this applies only to attachments. By + default the regex matches anywhere in the content type; if the + user wants an anchored match, they should include anchors in their + regexes. + + History: This configuration value was introduced in notmuch 0.38. + +.. nmconfig:: index.decrypt + + Policy for decrypting encrypted messages during indexing. Must be + one of: ``false``, ``auto``, ``nostash``, or ``true``. + + When indexing an encrypted e-mail message, if this variable is set + to ``true``, notmuch will try to decrypt the message and index the + cleartext, stashing a copy of any discovered session keys for the + message. If ``auto``, it will try to index the cleartext if a + stashed session key is already known for the message (e.g. from a + previous copy), but will not try to access your secret keys. Use + ``false`` to avoid decrypting even when a stashed session key is + already present. + + ``nostash`` is the same as ``true`` except that it will not stash + newly-discovered session keys in the database. + + From the command line (i.e. during :any:`notmuch-new(1)`, + :any:`notmuch-insert(1)`, or :any:`notmuch-reindex(1)`), the user can + override the database's stored decryption policy with the + ``--decrypt=`` option. + + Here is a table that summarizes the functionality of each of these + policies: + + +------------------------+-------+------+---------+------+ + | | false | auto | nostash | true | + +========================+=======+======+=========+======+ + | Index cleartext using | | X | X | X | + | stashed session keys | | | | | + +------------------------+-------+------+---------+------+ + | Index cleartext | | | X | X | + | using secret keys | | | | | + +------------------------+-------+------+---------+------+ + | Stash session keys | | | | X | + +------------------------+-------+------+---------+------+ + | Delete stashed session | X | | | | + | keys on reindex | | | | | + +------------------------+-------+------+---------+------+ + + Stashed session keys are kept in the database as properties + associated with the message. See ``session-key`` in + :any:`notmuch-properties(7)` for more details about how they can be + useful. + + Be aware that the notmuch index is likely sufficient (and a + stashed session key is certainly sufficient) to reconstruct the + cleartext of the message itself, so please ensure that the notmuch + message index is adequately protected. DO NOT USE + ``index.decrypt=true`` or ``index.decrypt=nostash`` without + considering the security of your index. + + Default: ``auto``. + +.. _index.header: + +.. nmconfig:: index.header.<prefix> + + Define the query prefix <prefix>, based on a mail header. For + example ``index.header.List=List-Id`` will add a probabilistic + prefix ``List:`` that searches the ``List-Id`` field. User + defined prefixes must not start with 'a'...'z'; in particular + adding a prefix with same name as a predefined prefix is not + supported. See :any:`notmuch-search-terms(7)` for a list of existing + prefixes, and an explanation of probabilistic prefixes. + +.. nmconfig:: maildir.synchronize_flags + + If true, then the following maildir flags (in message filenames) + will be synchronized with the corresponding notmuch tags: + + +--------+-----------------------------------------------+ + | Flag | Tag | + +========+===============================================+ + | D | draft | + +--------+-----------------------------------------------+ + | F | flagged | + +--------+-----------------------------------------------+ + | P | passed | + +--------+-----------------------------------------------+ + | R | replied | + +--------+-----------------------------------------------+ + | S | unread (added when 'S' flag is not present) | + +--------+-----------------------------------------------+ + + The :any:`notmuch-new(1)` command will notice flag changes in + filenames and update tags, while the :any:`notmuch-tag(1)` and + :any:`notmuch-restore(1)` commands will notice tag changes and + update flags in filenames. + + If there have been any changes in the maildir (new messages added, + old ones removed or renamed, maildir flags changed, etc.), it is + advisable to run :any:`notmuch-new(1)` before + :any:`notmuch-tag(1)` or :any:`notmuch-restore(1)` commands to + ensure the tag changes are properly synchronized to the maildir + flags, as the commands expect the database and maildir to be in + sync. + + Default: ``true``. + +.. nmconfig:: new.ignore + + A list to specify files and directories that will not be searched + for messages by :any:`notmuch-new(1)`. Each entry in the list is either: + + A file or a directory name, without path, that will be ignored, + regardless of the location in the mail store directory hierarchy. + + Or: + + A regular expression delimited with // that will be matched + against the path of the file or directory relative to the database + path. Matching files and directories will be ignored. The + beginning and end of string must be explicitly anchored. For + example, /.*/foo$/ would match "bar/foo" and "bar/baz/foo", but + not "foo" or "bar/foobar". + + Default: empty list. + +.. nmconfig:: new.tags + + A list of tags that will be added to all messages incorporated by + **notmuch new**. + + Default: ``unread;inbox``. + +.. nmconfig:: query.<name> + + Expansion for named query called <name>. See + :any:`notmuch-search-terms(7)` for more information about named + queries. + +.. nmconfig:: search.exclude_tags + + A list of tags that will be excluded from search results by + default. Using an excluded tag in a query will override that + exclusion. + + Default: empty list. Note that :any:`notmuch-setup(1)` puts + ``deleted;spam`` here when creating new configuration file. + +.. nmconfig:: show.extra_headers + + By default :any:`notmuch-show(1)` includes the following headers + in structured output if they are present in the message: + `Subject`, `From`, `To`, `Cc`, `Bcc`, `Reply-To`, `Date`. This + option allows the specification of a list of further + headers to output. + + History: This configuration value was introduced in notmuch 0.35. + + Default: empty list. + +.. nmconfig:: squery.<name> + + Expansion for named query called <name>, using s-expression syntax. See + :any:`notmuch-sexp-queries(7)` for more information about s-expression + queries. + +.. nmconfig:: user.name + + Your full name. + + Default: ``$NAME`` variable if set, otherwise read from + ``/etc/passwd``. + +.. nmconfig:: user.other_email + + A list of other email addresses at which you receive email + (see also, :nmconfig:`user.primary_email`) + + Default: not set. + +.. nmconfig:: user.primary_email + + Your primary email address. + + Default: ``$EMAIL`` variable if set, otherwise constructed from + the username and hostname of the current machine. + +FILES +===== + +.. _config_search: + +CONFIGURATION +------------- + +Notmuch configuration file search order: + +1. File specified by :option:`notmuch --config` global option; see + :any:`notmuch(1)`. + +2. File specified by :envvar:`NOTMUCH_CONFIG` environment variable. + +3. ``$XDG_CONFIG_HOME/notmuch/<profile>/config`` where ``<profile>`` + is defined by :envvar:`NOTMUCH_PROFILE` environment variable if + set, ``$XDG_CONFIG_HOME/notmuch/default/config`` otherwise. + +4. ``$HOME/.notmuch-config.<profile>`` where ``<profile>`` is defined + by :envvar:`NOTMUCH_PROFILE` environment variable if set, + ``$HOME/.notmuch-config`` otherwise. + +.. _database: + +DATABASE LOCATION +----------------- + +Notmuch database search order: + +1. Directory specified by :envvar:`NOTMUCH_DATABASE` environment variable. + +2. Directory specified by config key ``database.path``. + +3. ``$XDG_DATA_HOME/notmuch/<profile>`` where ``<profile>`` + is defined by :envvar:`NOTMUCH_PROFILE` environment variable if + set, ``$XDG_DATA_HOME/notmuch/default`` otherwise. + +4. Directory specified by :envvar:`MAILDIR` environment variable. + +5. ``$HOME/mail`` + +HOOKS +----- + +Notmuch hook directory search order: + +1. Directory specified by ``database.hook_dir`` configuration option. + +2. ``$XDG_CONFIG_HOME/notmuch/<profile>/hooks`` where ``<profile>`` + is defined by :envvar:`NOTMUCH_PROFILE` environment variable if + set, ``$XDG_CONFIG_HOME/notmuch/default/hooks`` otherwise. + +3. ``<database.path>/.notmuch/hooks`` + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-properties(7)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-count.rst b/doc/man1/notmuch-count.rst new file mode 100644 index 00000000..4c9c9a1c --- /dev/null +++ b/doc/man1/notmuch-count.rst @@ -0,0 +1,81 @@ +.. _notmuch-count(1): + +============= +notmuch-count +============= + +SYNOPSIS +======== + +**notmuch** **count** [*option* ...] <*search-term*> ... + +DESCRIPTION +=========== + +Count messages matching the search terms. + +The number of matching messages (or threads) is output to stdout. + +With no search terms, a count of all messages (or threads) in the +database will be displayed. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<search-terms>. + +Supported options for **count** include + +.. program:: count + +.. option:: --output=(messages|threads|files) + + messages + Output the number of matching messages. This is the default. + + threads + Output the number of matching threads. + + files + Output the number of files associated with matching + messages. This may be bigger than the number of matching + messages due to duplicates (i.e. multiple files having the + same message-id). + +.. option:: --exclude=(true|false) + + Specify whether to omit messages matching search.exclude\_tags from + the count (the default) or not. + +.. option:: --batch + + Read queries from a file (stdin by default), one per line, and + output the number of matching messages (or threads) to stdout, one + per line. On an empty input line the count of all messages (or + threads) in the database will be output. This option is not + compatible with specifying search terms on the command line. + +.. option:: --lastmod + + Append lastmod (counter for number of database updates) and UUID + to the output. lastmod values are only comparable between + databases with the same UUID. + +.. option:: --input=<filename> + + Read input from given file, instead of from stdin. Implies + ``--batch``. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-dump.rst b/doc/man1/notmuch-dump.rst new file mode 100644 index 00000000..a7ca39d0 --- /dev/null +++ b/doc/man1/notmuch-dump.rst @@ -0,0 +1,123 @@ +.. _notmuch-dump(1): + +============ +notmuch-dump +============ + +SYNOPSIS +======== + +**notmuch** **dump** [--gzip] [--format=(batch-tag|sup)] [--output=<*file*>] [--] [<*search-term*> ...] + +DESCRIPTION +=========== + +Dump tags for messages matching the given search terms. + +Output is to the given filename, if any, or to stdout. + +These tags are the only data in the notmuch database that can't be +recreated from the messages themselves. The output of notmuch dump is +therefore the only critical thing to backup (and much more friendly to +incremental backup than the native database files.) + +See :any:`notmuch-search-terms(7)` for details of the supported syntax +for <search-terms>. With no search terms, a dump of all messages in +the database will be generated. A ``--`` argument instructs notmuch that +the remaining arguments are search terms. + +Supported options for **dump** include + +.. program:: dump + +.. option:: --gzip + + Compress the output in a format compatible with :manpage:`gzip(1)`. + +.. option:: --format=(sup|batch-tag) + + Notmuch restore supports two plain text dump formats, both with + one message-id per line, followed by a list of tags. + + batch-tag + The default **batch-tag** dump format is intended to more + robust against malformed message-ids and tags containing + whitespace or non-\ :manpage:`ascii(7)` characters. Each line + has the form:: + + +<*encoded-tag*\ > +<*encoded-tag*\ > ... -- id:<*quoted-message-id*\ > + + Tags are hex-encoded by replacing every byte not matching the + regex **[A-Za-z0-9@=.,\_+-]** with **%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 + :any:`notmuch-tag(1)`; note that the single message-id query is + mandatory for :any:`notmuch-restore(1)`. + + sup + The **sup** dump file format is specifically chosen to be + compatible with the format of files produced by + :manpage:`sup-dump(1)`. So if you've previously been using sup + for mail, then the :any:`notmuch-restore(1)` command provides + you a way to import all of your tags (or labels as sup calls + them). Each line has the following form:: + + <*message-id*\ > **(** <*tag*\ > ... **)** + + with zero or more tags are separated by spaces. Note that + (malformed) message-ids may contain arbitrary non-null + characters. Note also that tags with spaces will not be + correctly restored with this format. + +.. option:: --include=(config|properties|tags) + + Control what kind of metadata is included in the output. + + config + Output configuration data stored in the database. Each line + starts with "#@ ", followed by a space separated key-value + pair. Both key and value are hex encoded if needed. + + properties + Output per-message (key,value) metadata. Each line starts + with "#= ", followed by a message id, and a space separated + list of key=value pairs. Ids, keys and values are hex encoded + if needed. See :any:`notmuch-properties(7)` for more details. + + tags + Output per-message boolean metadata, namely tags. See *format* above + for description of the output. + + The default is to include all available types of data. The option + can be specified multiple times to select some subset. As of + version 3 of the dump format, there is a header line of the + following form:: + + #notmuch-dump <*format*>:<*version*> <*included*> + + where <*included*> is a comma separated list of the above options. + +.. option:: --output=<filename> + + Write output to given file instead of stdout. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-properties(7)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst new file mode 100644 index 00000000..d8af08bd --- /dev/null +++ b/doc/man1/notmuch-emacs-mua.rst @@ -0,0 +1,102 @@ +.. _notmuch-emacs-mua(1): + +================= +notmuch-emacs-mua +================= + +SYNOPSIS +======== + +**notmuch** **emacs-mua** [options ...] [<to-address> ... | <mailto-url>] + +DESCRIPTION +=========== + +Start composing an email in the Notmuch Emacs UI with the specified +subject, recipients, and message body, or mailto: URL. + +Supported options for **emacs-mua** include + +.. program:: emacs-mua + +.. option:: -h, --help + + Display help. + +.. option:: -s, --subject=<subject> + + Specify the subject of the message. + +.. option:: --to=<to-address> + + Specify a recipient (To). + +.. option:: -c, --cc=<cc-address> + + Specify a carbon-copy (Cc) recipient. + +.. option:: -b, --bcc=<bcc-address> + + Specify a blind-carbon-copy (Bcc) recipient. + +.. option:: -i, --body=<file> + + Specify a file to include into the body of the message. + +.. option:: --hello + + Go to the Notmuch hello screen instead of the message composition + window if no message composition parameters are given. + +.. option:: --no-window-system + + Even if a window system is available, use the current terminal. + +.. option:: --client + + Use :manpage:`emacsclient(1)`, rather than + :manpage:`emacs(1)`. For :manpage:`emacsclient(1)` to work, you + need an already running Emacs with a server, or use + ``--auto-daemon``. + +.. option:: --auto-daemon + + Automatically start Emacs in daemon mode, if the Emacs server is + not running. Applicable with ``--client``. Implies + ``--create-frame``. + +.. option:: --create-frame + + Create a new frame instead of trying to use the current Emacs + frame. Applicable with ``--client``. This will be required when + Emacs is running (or automatically started with ``--auto-daemon``) + in daemon mode. + +.. option:: --print + + Output the resulting elisp to stdout instead of evaluating it. + +The supported positional parameters and short options are a compatible +subset of the :manpage:`mutt(1)` MUA command-line options. The options +and positional parameters modifying the message can't be combined with +the mailto: URL. + +Options may be specified multiple times. + +ENVIRONMENT VARIABLES +===================== + +.. envvar:: EMACS + + Name of emacs command to invoke. Defaults to "emacs". + +.. envvar:: EMACSCLIENT + + Name of emacsclient command to invoke. Defaults to "emacsclient". + +SEE ALSO +======== + +:any:`notmuch(1)`, +:manpage:`emacsclient(1)`, +:manpage:`mutt(1)` diff --git a/doc/man1/notmuch-git.rst b/doc/man1/notmuch-git.rst new file mode 100644 index 00000000..33a46f84 --- /dev/null +++ b/doc/man1/notmuch-git.rst @@ -0,0 +1,340 @@ +.. _notmuch-git(1): + +=========== +notmuch-git +=========== + +SYNOPSIS +======== + +**notmuch** **git** [-h] [-N] [-C *repo*] [-p *prefix*] [-v] [-l *log level*] *subcommand* + +**nmbug** [-h] [-C *repo*] [-p *prefix*] [-v] [-l *log level*] *subcommand* + +DESCRIPTION +=========== + +Manage notmuch tags with Git. + +OPTIONS +------- + +Supported options for `notmuch git` include + +.. program:: notmuch-git + +.. option:: -h, --help + + show help message and exit + +.. option:: -N, --nmbug + + Set defaults for :option:`--tag-prefix` and :option:`--git-dir` suitable for the + :any:`notmuch` bug tracker + +.. option:: -C <repo>, --git-dir <repo> + + Operate on git repository *repo*. See :ref:`repo_location` for + defaults. + +.. option:: -p <prefix>, --tag-prefix <prefix> + + Operate only on tags with prefix *prefix*. See :ref:`prefix_val` for + defaults. + +.. option:: -v, --version + + show notmuch-git's version number and exit + +.. option:: -l <level>, --log-level <level> + + Log verbosity, one of: `critical`, `error`, `warning`, `info`, + `debug`. Defaults to `warning`. + +SUBCOMMANDS +----------- + +For help on a particular subcommand, run: 'notmuch-git ... <command> --help'. + +.. program:: notmuch-git + +.. option:: archive [tree-ish] [arg ...] + +Dump a tar archive of a committed tag set using 'git archive'. See +:any:`format` for details of the archive contents. + + .. describe:: tree-ish + + The tree or commit to produce an archive for. Defaults to 'HEAD'. + + .. describe:: arg + + If present, any optional arguments are passed through to + :manpage:`git-archive(1)`. Arguments to `git-archive` are reordered + so that *tree-ish* comes last. + +.. option:: checkout [-f|--force] + +Update the notmuch database from Git. + +This is mainly useful to discard your changes in notmuch relative +to Git. + + .. describe:: [-f|--force] + + Override checks that prevent modifying tags for large fractions of + messages in the database. See also :nmconfig:`git.safe_fraction`. + +.. option:: clone <repository> + +Create a local `notmuch git` repository from a remote source. + +This wraps 'git clone', adding some options to avoid creating a +working tree while preserving remote-tracking branches and +upstreams. + + .. describe:: repository + + The (possibly remote) repository to clone from. See the URLS + section of :manpage:`git-clone(1)` for more information on + specifying repositories. + +.. option:: commit [-f|--force] [message] + +Commit prefix-matching tags from the notmuch database to Git. + + .. describe:: message + + Optional text for the commit message. + + .. describe:: -f|--force + + Override checks that prevent modifying tags for large fractions of + messages in the database. See also :nmconfig:`git.safe_fraction`. + +.. option:: fetch [remote] + +Fetch changes from the remote repository. + + .. describe:: remote + + Override the default configured in `branch.<name>.remote` to fetch + from a particular remote repository (e.g. `origin`). + +.. option:: help + +Show brief help for an `notmuch git` command. + +.. option:: init [--format-version=N] + +Create an empty `notmuch git` repository. + +This wraps 'git init' with a few extra steps to support subsequent +status and commit commands. + + .. describe:: --format-version=N + + Create a repo in format version N. By default :any:`notmuch-git` + uses the highest supported version, which is the best choice for + most use-cases. + +.. option:: log [arg ...] + +A wrapper for 'git log'. + + .. describe:: arg + + Additional arguments are passed through to 'git log'. + +After running `notmuch git fetch`, you can inspect the changes with + +:: + + $ notmuch git log HEAD..@{upstream} + +.. option:: merge [reference] + +Merge changes from 'reference' into HEAD and load the result into notmuch. + + .. describe:: reference + + Reference, usually other branch heads, to merge into our + branch. Defaults to `@{upstream}`. + +.. option:: pull [repository] [refspec ...] + +Pull (merge) remote repository changes to notmuch. + +**pull** is equivalent to **fetch** followed by **merge**. We use the +Git-configured repository for your current branch +(`branch.<name>.repository`, likely `origin`, and `branch.<name>.merge`, +likely `master` or `main`). + + .. describe:: repository + + The "remote" repository that is the source of the pull. This parameter + can be either a URL (see the section GIT URLS in :manpage:`git-pull(1)`) or the + name of a remote (see the section REMOTES in :manpage:`git-pull(1)`). + + .. describe:: refspec + + Refspec (usually a branch name) to fetch and merge. See the + *refspec* entry in the OPTIONS section of :manpage:`git-pull(1`) for + other possibilities. + +.. option:: push [repository] [refspec] + +Push the local `notmuch git` Git state to a remote repository. + + .. describe:: repository + + The "remote" repository that is the destination of the push. This + parameter can be either a URL (see the section GIT URLS in + :manpage:`git-push(1)`) or the name of a remote (see the section + REMOTES in :manpage:`git-push(1)`). + + .. describe:: refspec + + Refspec (usually a branch name) to push. See the *refspec* entry in the OPTIONS section of + :manpage:`git-push(1)` for other possibilities. + +.. option:: status + +Show pending updates in notmuch or git repo. + +Prints lines of the form + +| ng Message-Id tag + +where n is a single character representing notmuch database status + + .. describe:: A + + Tag is present in notmuch database, but not committed to nmbug + (equivalently, tag has been deleted in nmbug repo, e.g. by a + pull, but not restored to notmuch database). + + .. describe:: D + + Tag is present in nmbug repo, but not restored to notmuch + database (equivalently, tag has been deleted in notmuch). + + .. describe:: U + + Message is unknown (missing from local notmuch database). + +The second character *g* (if present) represents a difference between +local and upstream branches. Typically `notmuch git fetch` needs to be +run to update this. + + .. describe:: a + + Tag is present in upstream, but not in the local Git branch. + + .. describe:: d + + Tag is present in local Git branch, but not upstream. + +.. _format: + +REPOSITORY CONTENTS +=================== + +The tags are stored in the git repo (and exported) as a set of empty +files. These empty files are contained within a directory named after +the message-id. + +In what follows `encode()` represents a POSIX filesystem safe +encoding. The encoding preserves alphanumerics, and the characters +`+-_@=.,:`. All other octets are replaced with `%` followed by a two +digit hex number. + +Currently :any:`notmuch-git` can read any format version, but can only +create (via :any:`init`) :ref:`version 1 <format_version_1>` repositories. + +.. _format_version_0: + +Version 0 +--------- + +This is the legacy format created by the `nmbug` tool prior to release +0.37. For a message with Message-Id *id*, for each tag *tag*, there +is an empty file with path + + tags/ `encode` (*id*) / `encode` (*tag*) + +.. _format_version_1: + +Version 1 +--------- + +In format version 1 and later, the format version is contained in a +top level file called FORMAT. + +For a message with Message-Id *id*, for each tag *tag*, there +is an empty file with path + + tags/ `hash1` (*id*) / `hash2` (*id*) `encode` (*id*) / `encode` (*tag*) + +The hash functions each represent one byte of the `blake2b` hex +digest. + +Compared to :ref:`version 0 <format_version_0>`, this reduces the +number of subdirectories within each directory. + +.. _repo_location: + +REPOSITORY LOCATION +=================== + +:any:`notmuch-git` uses the first of the following with a non-empty +value to locate the git repository. + +- Option :option:`--git-dir`. + +- Environment variable :envvar:`NOTMUCH_GIT_DIR`. + +- Configuration item :nmconfig:`git.path` + +- If invoked as `nmbug` or with the :option:`--nmbug` option, + :code:`$HOME/.nmbug`; otherwise + :code:`$XDG_DATA_HOME/notmuch/$NOTMUCH_PROFILE/git`. + +.. _prefix_val: + +PREFIX VALUE +============ + +:any:`notmuch-git` uses the first of the following with a non-null +value to define the tag prefix. + +- Option :option:`--tag-prefix`. + +- Environment variable :envvar:`NOTMUCH_GIT_PREFIX`. + +- Configuration item :nmconfig:`git.tag_prefix`. + +- If invoked as `nmbug` or with the :option:`--nmbug` option, + :code:`notmuch::`, otherwise the empty string. + +ENVIRONMENT +=========== + +Variable :envvar:`NOTMUCH_PROFILE` influences :ref:`repo_location`. +If it is unset, 'default' is assumed. + +.. envvar:: NOTMUCH_GIT_DIR + + Default location of git repository. Overridden by :option:`--git-dir`. + +.. envvar:: NOTMUCH_GIT_PREFIX + + Default tag prefix (filter). Overridden by :option:`--tag-prefix`. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-insert.rst b/doc/man1/notmuch-insert.rst new file mode 100644 index 00000000..e05bd0b5 --- /dev/null +++ b/doc/man1/notmuch-insert.rst @@ -0,0 +1,133 @@ +.. _notmuch-insert(1): + +============== +notmuch-insert +============== + +SYNOPSIS +======== + +**notmuch** **insert** [option ...] [+<*tag*>|-<*tag*> ...] + +DESCRIPTION +=========== + +**notmuch insert** reads a message from standard input and delivers it +into the maildir directory given by configuration option +:nmconfig:`database.mail_root`, then incorporates the message into the notmuch +database. It is an alternative to using a separate tool to deliver the +message then running :any:`notmuch-new(1)` afterwards. + +The new message will be tagged with the tags specified by the +:nmconfig:`new.tags` configuration option, then by operations specified on the +command-line: tags prefixed by '+' are added while those prefixed by '-' +are removed. + +If the new message is a duplicate of an existing message in the database +(it has same Message-ID), it will be added to the maildir folder and +notmuch database, but the tags will not be changed. + +The **insert** command supports hooks. See :any:`notmuch-hooks(5)` for +more details on hooks. + +Option arguments must appear before any tag operation arguments. +Supported options for **insert** include + +.. program:: insert + +.. option:: --folder=<folder> + + Deliver the message to the specified folder, relative to the + top-level directory given by the value of :nmconfig:`database.mail_root`. The + default is the empty string, which means delivering to the + top-level directory. + +.. option:: --create-folder + + Try to create the folder named by the ``--folder`` option, if it + does not exist. Otherwise the folder must already exist for mail + delivery to succeed. + +.. option:: --keep + + Keep the message file if indexing fails, and keep the message + indexed if applying tags or maildir flag synchronization + fails. Ignore these errors and return exit status 0 to indicate + successful mail delivery. + +.. option:: --no-hooks + + Prevent hooks from being run. + +.. option:: --world-readable + + When writing mail to the mailbox, allow it to be read by users + other than the current user. Note that this does not override + umask. By default, delivered mail is only readable by the current + user. + +.. option:: --decrypt=(true|nostash|auto|false) + + If ``true`` and the message is encrypted, try to decrypt the + message while indexing, stashing any session keys discovered. If + ``auto``, and notmuch already knows about a session key for the + message, it will try decrypting using that session key but will + not try to access the user's secret keys. If decryption is + successful, index the cleartext itself. Either way, the message + is always stored to disk in its original form (ciphertext). + + ``nostash`` is the same as ``true`` except that it will not stash + newly-discovered session keys in the database. + + Be aware that the index is likely sufficient (and a stashed + session key is certainly sufficient) to reconstruct the cleartext + of the message itself, so please ensure that the notmuch message + index is adequately protected. DO NOT USE ``--decrypt=true`` or + ``--decrypt=nostash`` without considering the security of your + index. + + See also :nmconfig:`index.decrypt` in :any:`notmuch-config(1)`. + +CONFIGURATION +============= + +Indexing is influenced by the configuration options +:nmconfig:`index.decrypt` and :nmconfig:`index.header.\<prefix\>`. Tagging +is controlled by options :nmconfig:`new.tags` and +:nmconfig:`maildir.synchronize_flags`. See +:any:`notmuch-config(1)` for details. + +EXIT STATUS +=========== + +This command returns exit status 0 on successful mail delivery, +non-zero otherwise. The default is to indicate failed mail delivery on +any errors, including message file delivery to the filesystem, message +indexing to Notmuch database, changing tags, and synchronizing tags to +maildir flags. The ``--keep`` option may be used to settle for +successful message file delivery. + +This command supports the following special exit status code for +errors most likely to be temporary in nature, e.g. failure to get a +database write lock. + +``75 (EX_TEMPFAIL)`` + A temporary failure occurred; the user is invited to retry. + +The exit status of the **post-insert** hook does not affect the exit +status of the **insert** command. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-new.rst b/doc/man1/notmuch-new.rst new file mode 100644 index 00000000..f0ed8eb8 --- /dev/null +++ b/doc/man1/notmuch-new.rst @@ -0,0 +1,113 @@ +.. _notmuch-new(1): + +=========== +notmuch-new +=========== + +SYNOPSIS +======== + +**notmuch** **new** [options] + +DESCRIPTION +=========== + +Find and import any new messages to the database. + +The **new** command scans all sub-directories of the database, +performing full-text indexing on new messages that are found. Each new +message will automatically be tagged with both the **inbox** and +**unread** tags. + +You should run **notmuch new** once after first running +:any:`notmuch-setup(1)` to create the initial database. The first run +may take a long time if you have a significant amount of mail (several +hundred thousand messages or more). Subsequently, you should run +**notmuch new** whenever new mail is delivered and you wish to +incorporate it into the database. These subsequent runs will be much +quicker than the initial run. + +Invoking ``notmuch`` with no command argument will run **new** if +:any:`notmuch-setup(1)` has previously been completed, but **notmuch +new** has not previously been run. + +**notmuch new** updates tags according to maildir flag changes if the +**maildir.synchronize\_flags** configuration option is enabled. See +:any:`notmuch-config(1)` for details. + +The **new** command supports hooks. See :any:`notmuch-hooks(5)` for more +details on hooks. + +Supported options for **new** include + +.. program:: new + +.. option:: --no-hooks + + Prevents hooks from being run. + +.. option:: --quiet + + Do not print progress or results. + +.. option:: --verbose + + Print file names being processed. Ignored when combined with + ``--quiet``. + +.. option:: --decrypt=(true|nostash|auto|false) + + If ``true``, when encountering an encrypted message, try to + decrypt it while indexing, and stash any discovered session keys. + If ``auto``, try to use any session key already known to belong to + this message, but do not attempt to use the user's secret keys. + If decryption is successful, index the cleartext of the message. + + Be aware that the index is likely sufficient (and the session key + is certainly sufficient) to reconstruct the cleartext of the + message itself, so please ensure that the notmuch message index is + adequately protected. DO NOT USE ``--decrypt=true`` or + ``--decrypt=nostash`` without considering the security of your + index. + + See also ``index.decrypt`` in :any:`notmuch-config(1)`. + +.. option:: --full-scan + + By default notmuch-new uses directory modification times (mtimes) + to optimize the scanning of directories for new mail. This option turns + that optimization off. + +CONFIGURATION +============= + +Indexing is influenced by the configuration options +:nmconfig:`index.decrypt`, :nmconfig:`index.header.\<prefix\>` +and :nmconfig:`new.ignore`. Tagging +is controlled by :nmconfig:`new.tags` and +:nmconfig:`maildir.synchronize_flags`. See +:any:`notmuch-config(1)` for details. + +EXIT STATUS +=========== + +This command supports the following special exit status code + +``75 (EX_TEMPFAIL)`` + A temporary failure occurred; the user is invited to retry. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-reindex.rst b/doc/man1/notmuch-reindex.rst new file mode 100644 index 00000000..85dad249 --- /dev/null +++ b/doc/man1/notmuch-reindex.rst @@ -0,0 +1,105 @@ +.. _notmuch-reindex(1): + +=============== +notmuch-reindex +=============== + +SYNOPSIS +======== + +**notmuch** **reindex** [*option* ...] <*search-term*> ... + +DESCRIPTION +=========== + +Re-index all messages matching the search terms. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<*search-term*\ >. + +The **reindex** command searches for all messages matching the +supplied search terms, and re-creates the full-text index on these +messages using the supplied options. + +Supported options for **reindex** include + +.. program:: reindex + +.. option:: --decrypt=(true|nostash|auto|false) + + If ``true``, when encountering an encrypted message, try to + decrypt it while reindexing, stashing any session keys discovered. + If ``auto``, and notmuch already knows about a session key for the + message, it will try decrypting using that session key but will + not try to access the user's secret keys. If decryption is + successful, index the cleartext itself. + + ``nostash`` is the same as ``true`` except that it will not stash + newly-discovered session keys in the database. + + If ``false``, notmuch reindex will also delete any stashed session + keys for all messages matching the search terms. + + Be aware that the index is likely sufficient (and a stashed + session key is certainly sufficient) to reconstruct the cleartext + of the message itself, so please ensure that the notmuch message + index is adequately protected. DO NOT USE ``--decrypt=true`` or + ``--decrypt=nostash`` without considering the security of your + index. + + See also ``index.decrypt`` in :any:`notmuch-config(1)`. + +EXAMPLES +======== + +A user just received an encrypted message without indexing its +cleartext. After reading it (via ``notmuch show --decrypt=true``), +they decide that they want to index its cleartext so that they can +easily find it later and read it without having to have access to +their secret keys: + +:: + + notmuch reindex --decrypt=true id:1234567@example.com + +A user wants to change their policy going forward to start indexing +cleartext. But they also want indexed access to the cleartext of all +previously-received encrypted messages. Some messages might have +already been indexed in the clear (as in the example above). They can +ask notmuch to just reindex the not-yet-indexed messages: + +:: + + notmuch config set index.decrypt true + notmuch reindex tag:encrypted and not property:index.decryption=success + +Later, the user changes their mind, and wants to stop indexing +cleartext (perhaps their threat model has changed, or their trust in +their index store has been shaken). They also want to clear all of +their old cleartext from the index. Note that they compact the +database afterward as a workaround for +https://trac.xapian.org/ticket/742: + +:: + + notmuch config set index.decrypt false + notmuch reindex property:index.decryption=success + notmuch compact + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-compact(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-reply.rst b/doc/man1/notmuch-reply.rst new file mode 100644 index 00000000..4f39a959 --- /dev/null +++ b/doc/man1/notmuch-reply.rst @@ -0,0 +1,143 @@ +.. _notmuch-reply(1): + +============= +notmuch-reply +============= + +SYNOPSIS +======== + +**notmuch** **reply** [option ...] <*search-term*> ... + +DESCRIPTION +=========== + +Constructs a reply template for a set of messages. + +To make replying to email easier, **notmuch reply** takes an existing +set of messages and constructs a suitable mail template. Its To: +address is set according to the original email in this way: if the +Reply-to: header is present and different from any To:/Cc: address it +is used, otherwise From: header is used. Unless +``--reply-to=sender`` is specified, values from the To: and Cc: headers +are copied, but not including any of the current user's email addresses +(as configured in primary\_mail or other\_email in the .notmuch-config +file) in the recipient list. + +It also builds a suitable new subject, including Re: at the front (if +not already present), and adding the message IDs of the messages being +replied to to the References list and setting the In-Reply-To: field +correctly. + +Finally, the original contents of the emails are quoted by prefixing +each line with '> ' and included in the body. + +The resulting message template is output to stdout. + +Supported options for **reply** include + +.. program:: reply + +.. option:: --duplicate=N + + Reply to duplicate number N. The numbering starts from 1, and + matches the order used by :option:`show --duplicate` and + :option:`search --output=files <search --output>`. + +.. option:: --format=(default|json|sexp|headers-only) + + default + Includes subject and quoted message body as an RFC 2822 + message. + + json + Produces JSON output containing headers for a reply message + and the contents of the original message. This output can be + used by a client to create a reply message intelligently. + + sexp + Produces S-Expression output containing headers for a reply + message and the contents of the original message. This output + can be used by a client to create a reply message + intelligently. + + headers-only + Only produces In-Reply-To, References, To, Cc, and Bcc + headers. + +.. option:: --format-version=N + + Use the specified structured output format version. This is + intended for programs that invoke :any:`notmuch(1)` internally. If + omitted, the latest supported version will be used. + +.. option:: --reply-to=(all|sender) + + all (default) + Replies to all addresses. + + sender + Replies only to the sender. If replying to user's own message + (Reply-to: or From: header is one of the user's configured + email addresses), try To:, Cc:, and Bcc: headers in this + order, and copy values from the first that contains something + other than only the user's addresses. + +.. option:: --decrypt=(false|auto|true) + + If ``true``, decrypt any MIME encrypted parts found in the + selected content (i.e., "multipart/encrypted" parts). Status + of the decryption will be reported (currently only supported + with ``--format=json`` and ``--format=sexp``), and on successful + decryption the multipart/encrypted part will be replaced by + the decrypted content. + + If ``auto``, and a session key is already known for the + message, then it will be decrypted, but notmuch will not try + to access the user's secret keys. + + Use ``false`` to avoid even automatic decryption. + + Non-automatic decryption expects a functioning + :manpage:`gpg-agent(1)` to provide any needed credentials. Without + one, the decryption will likely fail. + + Default: ``auto`` + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<search-terms>. + +Note: It is most common to use **notmuch reply** with a search string +matching a single message, (such as id:<message-id>), but it can be +useful to reply to several messages at once. For example, when a series +of patches are sent in a single thread, replying to the entire thread +allows for the reply to comment on issues found in multiple patches. The +default format supports replying to multiple messages at once, but the +JSON and S-Expression formats do not. + +EXIT STATUS +=========== + +This command supports the following special exit status codes + +``20`` + The requested format version is too old. + +``21`` + The requested format version is too new. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-restore.rst b/doc/man1/notmuch-restore.rst new file mode 100644 index 00000000..ac6b4245 --- /dev/null +++ b/doc/man1/notmuch-restore.rst @@ -0,0 +1,107 @@ +.. _notmuch-restore(1): + +=============== +notmuch-restore +=============== + +SYNOPSIS +======== + +**notmuch** **restore** [--accumulate] [--format=(auto|batch-tag|sup)] [--input=<*filename*>] + +DESCRIPTION +=========== + +Restores the tags from the given file (see :any:`notmuch-dump(1)`). + +The input is read from the given filename, if any, or from stdin. + +Supported options for **restore** include + +.. program:: restore + +.. option:: --accumulate + + The union of the existing and new tags is applied, instead of + replacing each message's tags as they are read in from the dump + file. + +.. option:: --format=(sup|batch-tag|auto) + + Notmuch restore supports two plain text dump formats, with each + line specifying a message-id and a set of tags. For details of the + actual formats, see :any:`notmuch-dump(1)`. + + sup + The **sup** dump file format is specifically chosen to be + compatible with the format of files produced by sup-dump. So + if you've previously been using sup for mail, then the + **notmuch restore** command provides you a way to import all + of your tags (or labels as sup calls them). + + batch-tag + The **batch-tag** dump format is intended to more robust + against malformed message-ids and tags containing whitespace + or non-\ **ascii(7)** characters. See :any:`notmuch-dump(1)` for + details on this format. + + **notmuch restore** updates the maildir flags according to tag + changes if the **maildir.synchronize\_flags** configuration + option is enabled. See :any:`notmuch-config(1)` for details. + + auto + This option (the default) tries to guess the format from the + input. For correctly formed input in either supported format, + this heuristic, based the fact that batch-tag format contains + no parentheses, should be accurate. + +.. option:: --include=(config|properties|tags) + + Control what kind of metadata is restored. + + config + Restore configuration data to the database. Each configuration + line starts with "#@ ", followed by a space separated + key-value pair. Both key and value are hex encoded if needed. + + properties + Restore per-message (key,value) metadata. Each line starts + with "#= ", followed by a message id, and a space separated + list of key=value pairs. Ids, keys and values are hex encoded + if needed. See :any:`notmuch-properties(7)` for more details. + + tags + Restore per-message metadata, namely tags. See *format* above + for more details. + + The default is to restore all available types of data. The option + can be specified multiple times to select some subset. + +.. option:: --input=<filename> + + Read input from given file instead of stdin. + +GZIPPED INPUT +============= + +\ **notmuch restore** will detect if the input is compressed in +:manpage:`gzip(1)` format and automatically decompress it while +reading. This detection does not depend on file naming and in +particular works for standard input. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-properties(7)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst new file mode 100644 index 00000000..b87737ea --- /dev/null +++ b/doc/man1/notmuch-search.rst @@ -0,0 +1,191 @@ +.. _notmuch-search(1): + +============== +notmuch-search +============== + +SYNOPSIS +======== + +**notmuch** **search** [*option* ...] <*search-term*> ... + +DESCRIPTION +=========== + +Search for messages matching the given search terms, and display as +results the threads containing the matched messages. + +The output consists of one line per thread, giving a thread ID, the date +of the newest (or oldest, depending on the sort option) matched message +in the thread, the number of matched messages and total messages in the +thread, the names of all participants in the thread, and the subject of +the newest (or oldest) message. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<search-terms>. + +Supported options for **search** include + +.. program:: search + +.. option:: --format=(json|sexp|text|text0) + + Presents the results in either JSON, S-Expressions, newline + character separated plain-text (default), or null character + separated plain-text (compatible with :manpage:`xargs(1)` -0 + option where available). + +.. option:: --format-version=N + + Use the specified structured output format version. This is + intended for programs that invoke :any:`notmuch(1)` internally. If + omitted, the latest supported version will be used. + +.. option:: --output=(summary|threads|messages|files|tags) + + summary (default) + Output a summary of each thread with any message matching the + search terms. The summary includes the thread ID, date, the + number of messages in the thread (both the number matched and + the total number), the authors of the thread and the + subject. In the case where a thread contains multiple files + for some messages, the total number of files is printed in + parentheses (see below for an example). + + threads + Output the thread IDs of all threads with any message matching + the search terms, either one per line (``--format=text``), + separated by null characters (``--format=text0``), as a JSON array + (``--format=json``), or an S-Expression list (``--format=sexp``). + + messages + Output the message IDs of all messages matching the search + terms, either one per line (``--format=text``), separated by null + characters (``--format=text0``), as a JSON array (``--format=json``), + or as an S-Expression list (``--format=sexp``). + + files + Output the filenames of all messages matching the search + terms, either one per line (``--format=text``), separated by null + characters (``--format=text0``), as a JSON array (``--format=json``), + or as an S-Expression list (``--format=sexp``). + + Note that each message may have multiple filenames associated + with it. All of them are included in the output (unless + limited with the ``--duplicate=N`` option). This may be + particularly confusing for **folder:** or **path:** searches + in a specified directory, as the messages may have duplicates + in other directories that are included in the output, although + these files alone would not match the search. + + tags + Output all tags that appear on any message matching the search + terms, either one per line (``--format=text``), separated by null + characters (``--format=text0``), as a JSON array (``--format=json``), + or as an S-Expression list (``--format=sexp``). + +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + Note: The thread order will be distinct between these two options + (beyond being simply reversed). When sorting by **oldest-first** + the threads will be sorted by the oldest message in each thread, + but when sorting by **newest-first** the threads will be sorted by + the newest message in each thread. + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + +.. option:: --offset=[-]N + + Skip displaying the first N results. With the leading '-', start + at the Nth result from the end. + +.. option:: --limit=N + + Limit the number of displayed results to N. + +.. option:: --exclude=(true|false|all|flag) + + A message is called "excluded" if it matches at least one tag in + search.exclude\_tags that does not appear explicitly in the search + terms. This option specifies whether to omit excluded messages in + the search process. + + true (default) + Prevent excluded messages from matching the search terms. + + all + Additionally prevent excluded messages from appearing in + displayed results, in effect behaving as though the excluded + messages do not exist. + + false + Allow excluded messages to match search terms and appear in + displayed results. Excluded messages are still marked in the + relevant outputs. + + flag + Only has an effect when ``--output=summary``. The output is + almost identical to **false**, but the "match count" is the + number of matching non-excluded messages in the thread, rather + than the number of matching messages. + +.. option:: --duplicate=N + + For ``--output=files``, output the Nth filename associated with + each message matching the query (N is 1-based). If N is greater + than the number of files associated with the message, don't print + anything. + + For ``--output=messages``, only output message IDs of messages + matching the search terms that have at least N filenames + associated with them. + + Note that this option is orthogonal with the **folder:** search + prefix. The prefix matches messages based on filenames. This + option filters filenames of the matching messages. + +EXAMPLE +======= + +The following shows an example of the summary output format, with one +message having multiple filenames. + +:: + + % notmuch search date:today.. and tag:bad-news + thread:0000000000063c10 Today [1/1] Some Persun; To the bone (bad-news inbox unread) + thread:0000000000063c25 Today [1/1(2)] Ann Other; Bears (bad-news inbox unread) + thread:0000000000063c00 Today [1/1] A Thurd; Bites, stings, sad feelings (bad-news unread) + +EXIT STATUS +=========== + +This command supports the following special exit status codes + +``20`` + The requested format version is too old. + +``21`` + The requested format version is too new. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-address(1)` +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst new file mode 100644 index 00000000..c13d94de --- /dev/null +++ b/doc/man1/notmuch-show.rst @@ -0,0 +1,271 @@ +.. _notmuch-show(1): + +============ +notmuch-show +============ + +SYNOPSIS +======== + +**notmuch** **show** [*option* ...] <*search-term*> ... + +DESCRIPTION +=========== + +Shows all messages matching the search terms. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<search-terms>. + +The messages will be grouped and sorted based on the threading (all +replies to a particular message will appear immediately after that +message in date order). The output is not indented by default, but depth +tags are printed so that proper indentation can be performed by a +post-processor (such as the emacs interface to notmuch). + +Supported options for **show** include + +.. program:: show + +.. option:: --duplicate=N + + Output duplicate number N. The numbering starts from 1, and matches + the order used by :option:`search --duplicate` and + :option:`search --output=files <search --output>` + +.. option:: --entire-thread=(true|false) + + If true, **notmuch show** outputs all messages in the thread of + any message matching the search terms; if false, it outputs only + the matching messages. For ``--format=json`` and ``--format=sexp`` + this defaults to true. For other formats, this defaults to false. + +.. option:: --format=(text|json|sexp|mbox|raw) + + text (default for messages) + The default plain-text format has all text-content MIME parts + decoded. Various components in the output, (**message**, + **header**, **body**, **attachment**, and MIME **part**), will + be delimited by easily-parsed markers. Each marker consists of + a Control-L character (ASCII decimal 12), the name of the + marker, and then either an opening or closing brace, ('{' or + '}'), to either open or close the component. For a multipart + MIME message, these parts will be nested. + + json + The output is formatted with Javascript Object Notation + (JSON). This format is more robust than the text format for + automated processing. The nested structure of multipart MIME + messages is reflected in nested JSON output. By default JSON + output includes all messages in a matching thread; that is, by + default, ``--format=json`` sets ``--entire-thread``. The + caller can disable this behaviour by setting + ``--entire-thread=false``. The JSON output is always encoded + as UTF-8 and any message content included in the output will + be charset-converted to UTF-8. + + sexp + The output is formatted as the Lisp s-expression (sexp) + equivalent of the JSON format above. Objects are formatted as + property lists whose keys are keywords (symbols preceded by a + colon). True is formatted as ``t`` and both false and null are + formatted as ``nil``. As for JSON, the s-expression output is + always encoded as UTF-8. + + mbox + All matching messages are output in the traditional, Unix mbox + format with each message being prefixed by a line beginning + with "From " and a blank line separating each message. Lines + in the message content beginning with "From " (preceded by + zero or more '>' characters) have an additional '>' character + added. This reversible escaping is termed "mboxrd" format and + described in detail here: + + http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html + + raw (default if ``--part`` is given) + Write the raw bytes of the given MIME part of a message to + standard out. For this format, it is an error to specify a + query that matches more than one message. + + If the specified part is a leaf part, this outputs the body of + the part after performing content transfer decoding (but no + charset conversion). This is suitable for saving attachments, + for example. + + For a multipart or message part, the output includes the part + headers as well as the body (including all child parts). No + decoding is performed because multipart and message parts + cannot have non-trivial content transfer encoding. Consumers + of this may need to implement MIME decoding and similar + functions. + +.. option:: --format-version=N + + Use the specified structured output format version. This is + intended for programs that invoke :any:`notmuch(1)` internally. If + omitted, the latest supported version will be used. + +.. option:: --part=N + + Output the single decoded MIME part N of a single message. The + search terms must match only a single message. Message parts are + numbered in a depth-first walk of the message MIME structure, and + are identified in the 'json', 'sexp' or 'text' output formats. + + Note that even a message with no MIME structure or a single body + part still has two MIME parts: part 0 is the whole message + (headers and body) and part 1 is just the body. + +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + Only threads as a whole are reordered. Ordering of messages within + each thread will not be affected by this flag, since that order is + always determined by the thread's replies. + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + +.. option:: --offset=[-]N + + Skip displaying the first N results. With the leading '-', start + at the Nth result from the end. + +.. option:: --limit=N + + Limit the number of displayed results to N. + +.. option:: --verify + + Compute and report the validity of any MIME cryptographic + signatures found in the selected content (e.g., "multipart/signed" + parts). Status of the signature will be reported (currently only + supported with ``--format=json`` and ``--format=sexp``), and the + multipart/signed part will be replaced by the signed data. + +.. option:: --decrypt=(false|auto|true|stash) + + If ``true``, decrypt any MIME encrypted parts found in the + selected content (e.g., "multipart/encrypted" parts). Status of + the decryption will be reported (currently only supported + with ``--format=json`` and ``--format=sexp``) and on successful + decryption the multipart/encrypted part will be replaced by + the decrypted content. + + ``stash`` behaves like ``true``, but upon successful decryption it + will also stash the message's session key in the database, and + index the cleartext of the message, enabling automatic decryption + in the future. + + If ``auto``, and a session key is already known for the + message, then it will be decrypted, but notmuch will not try + to access the user's keys. + + Use ``false`` to avoid even automatic decryption. + + Non-automatic decryption (``stash`` or ``true``, in the absence of + a stashed session key) expects a functioning :manpage:`gpg-agent(1)` to + provide any needed credentials. Without one, the decryption will + fail. + + Note: setting either ``true`` or ``stash`` here implies + ``--verify``. + + Here is a table that summarizes each of these policies: + + +------------------------+-------+------+------+-------+ + | | false | auto | true | stash | + +========================+=======+======+======+=======+ + | Show cleartext if | | X | X | X | + | session key is | | | | | + | already known | | | | | + +------------------------+-------+------+------+-------+ + | Use secret keys to | | | X | X | + | show cleartext | | | | | + +------------------------+-------+------+------+-------+ + | Stash any newly | | | | X | + | recovered session keys,| | | | | + | reindexing message if | | | | | + | found | | | | | + +------------------------+-------+------+------+-------+ + + Note: ``--decrypt=stash`` requires write access to the database. + Otherwise, ``notmuch show`` operates entirely in read-only mode. + + Default: ``auto`` + +.. option:: --exclude=(true|false) + + Specify whether to omit threads only matching search.exclude\_tags + from the search results (the default) or not. In either case the + excluded message will be marked with the exclude flag (except when + output=mbox when there is nowhere to put the flag). + + If ``--entire-thread`` is specified then complete threads are returned + regardless (with the excluded flag being set when appropriate) but + threads that only match in an excluded message are not returned + when ``--exclude=true.`` + + The default is ``--exclude=true.`` + +.. option:: --body=(true|false) + + If true (the default) **notmuch show** includes the bodies of the + messages in the output; if false, bodies are omitted. + ``--body=false`` is only implemented for the text, json and sexp + formats and it is incompatible with ``--part > 0.`` + + This is useful if the caller only needs the headers as body-less + output is much faster and substantially smaller. + +.. option:: --include-html + + Include "text/html" parts as part of the output (currently + only supported with ``--format=text``, ``--format=json`` and + ``--format=sexp``). By default, unless ``--part=N`` is used to + select a specific part or ``--include-html`` is used to include all + "text/html" parts, no part with content type "text/html" is included + in the output. + +A common use of **notmuch show** is to display a single thread of +email messages. For this, use a search term of "thread:<thread-id>" as +can be seen in the first column of output from the +:any:`notmuch-search(1)` command. + +CONFIGURATION +============= + +Structured output (json / sexp) is influenced by the configuration +option :nmconfig:`show.extra_headers`. See +:any:`notmuch-config(1)` for details. + +EXIT STATUS +=========== + +This command supports the following special exit status codes + +``20`` + The requested format version is too old. + +``21`` + The requested format version is too new. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-tag(1)` diff --git a/doc/man1/notmuch-tag.rst b/doc/man1/notmuch-tag.rst new file mode 100644 index 00000000..ae311a23 --- /dev/null +++ b/doc/man1/notmuch-tag.rst @@ -0,0 +1,121 @@ +.. _notmuch-tag(1): + +=========== +notmuch-tag +=========== + +SYNOPSIS +======== + +**notmuch** **tag** [options ...] +<*tag*>|-<*tag*> [--] <*search-term*> ... + +**notmuch** **tag** **--batch** [--input=<*filename*>] + +DESCRIPTION +=========== + +Add/remove tags for all messages matching the search terms. + +See :any:`notmuch-search-terms(7)` for details of the supported syntax for +<*search-term*\ >. + +Tags prefixed by '+' are added while those prefixed by '-' are removed. +For each message, tag changes are applied in the order they appear on +the command line. + +The beginning of the search terms is recognized by the first argument +that begins with neither '+' nor '-'. Support for an initial search term +beginning with '+' or '-' is provided by allowing the user to specify a +"--" argument to separate the tags from the search terms. + +**notmuch tag** updates the maildir flags according to tag changes if +the **maildir.synchronize\_flags** configuration option is enabled. See +:any:`notmuch-config(1)` for details. + +Supported options for **tag** include + +.. program:: tag + +.. option:: --remove-all + + Remove all tags from each message matching the search terms before + applying the tag changes appearing on the command line. This + means setting the tags of each message to the tags to be added. If + there are no tags to be added, the messages will have no tags. + +.. option:: --batch + + Read batch tagging operations from a file (stdin by default). + This is more efficient than repeated **notmuch tag** + invocations. See `TAG FILE FORMAT <#tag_file_format>`__ below for + the input format. This option is not compatible with specifying + tagging on the command line. + +.. option:: --input=<filename> + + Read input from given file, instead of from stdin. Implies + ``--batch``. + +TAG FILE FORMAT +=============== + +The input must consist of lines of the format: + ++<*tag*\ >\|-<*tag*\ > [...] [--] <*query*\ > + +Each line is interpreted similarly to **notmuch tag** command line +arguments. The delimiter is one or more spaces ' '. Any characters in +<*tag*\ > **may** be hex-encoded with %NN where NN is the hexadecimal +value of the character. To hex-encode a character with a multi-byte +UTF-8 encoding, hex-encode each byte. Any spaces in <tag> **must** be +hex-encoded as %20. Any characters that are not part of <*tag*\ > **must +not** be hex-encoded. + +In the future tag:"tag with spaces" style quoting may be supported for +<*tag*\ > as well; for this reason all double quote characters in +<*tag*\ > **should** be hex-encoded. + +The <*query*\ > should be quoted using Xapian boolean term quoting +rules: if a term contains whitespace or a close paren or starts with a +double quote, it must be enclosed in double quotes (not including any +prefix) and double quotes inside the term must be doubled (see below for +examples). + +Leading and trailing space ' ' is ignored. Empty lines and lines +beginning with '#' are ignored. + +EXAMPLE +------- + +The following shows a valid input to batch tagging. Note that only the +isolated '\*' acts as a wildcard. Also note the two different quotings +of the tag **space in tags** + +:: + + +winner * + +foo::bar%25 -- (One and Two) or (One and tag:winner) + +found::it -- tag:foo::bar% + # ignore this line and the next + + +space%20in%20tags -- Two + # add tag '(tags)', among other stunts. + +crazy{ +(tags) +&are +#possible\ -- tag:"space in tags" + +match*crazy -- tag:crazy{ + +some_tag -- id:"this is ""nauty)""" + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst new file mode 100644 index 00000000..c488f12a --- /dev/null +++ b/doc/man1/notmuch.rst @@ -0,0 +1,237 @@ +.. _notmuch(1): +.. _notmuch-setup(1): + +======= +notmuch +======= + +SYNOPSIS +======== + +**notmuch** [option ...] **command** [arg ...] + +DESCRIPTION +=========== + +Notmuch is a command-line based program for indexing, searching, +reading, and tagging large collections of email messages. + +This page describes how to get started using notmuch from the command +line, and gives a brief overview of the commands available. For more +information on e.g. **notmuch show** consult the +:any:`notmuch-show(1)` man page, also accessible via **notmuch help +show** + +The quickest way to get started with Notmuch is to simply invoke the +``notmuch`` command with no arguments, which will interactively guide +you through the process of indexing your mail. + +NOTE +==== + +While the command-line program ``notmuch`` provides powerful +functionality, it does not provide the most convenient interface for +that functionality. More sophisticated interfaces are expected to be +built on top of either the command-line interface, or more likely, on +top of the notmuch library interface. See https://notmuchmail.org for +more about alternate interfaces to notmuch. The emacs-based interface to +notmuch (available under **emacs/** in the Notmuch source distribution) +is probably the most widely used at this time. + +OPTIONS +======= + +Supported global options for ``notmuch`` include + +.. program:: notmuch + +.. option:: --help [command-name] + + Print a synopsis of available commands and exit. With an optional + command name, show the man page for that subcommand. + +.. option:: --version + + Print the installed version of notmuch, and exit. + +.. option:: --config=FILE + + Specify the configuration file to use. This overrides any + configuration file specified by :envvar:`NOTMUCH_CONFIG`. The empty + string is a permitted and sometimes useful value of *FILE*, which + tells ``notmuch`` to use only configuration metadata from the database. + +.. option:: --uuid=HEX + + Enforce that the database UUID (a unique identifier which persists + until e.g. the database is compacted) is HEX; exit with an error + if it is not. This is useful to detect rollover in modification + counts on messages. You can find this UUID using e.g. ``notmuch + count --lastmod`` + +All global options except ``--config`` can also be specified after the +command. For example, ``notmuch subcommand --uuid=HEX`` is equivalent +to ``notmuch --uuid=HEX subcommand``. + +COMMANDS +======== + +SETUP +----- + +The **notmuch setup** command is used to configure Notmuch for first +use, (or to reconfigure it later). + +The setup command will prompt for your full name, your primary email +address, any alternate email addresses you use, and the directory +containing your email archives. Your answers will be written to a +configuration file in :envvar:`NOTMUCH_CONFIG` (if set) or +${HOME}/.notmuch-config . This configuration file will be created with +descriptive comments, making it easy to edit by hand later to change the +configuration. Or you can run **notmuch setup** again to change the +configuration. + +The mail directory you specify can contain any number of sub-directories +and should primarily contain only files with individual email messages +(eg. maildir or mh archives are perfect). If there are other, non-email +files (such as indexes maintained by other email programs) then notmuch +will do its best to detect those and ignore them. + +Mail storage that uses mbox format, (where one mbox file contains many +messages), will not work with notmuch. If that's how your mail is +currently stored, it is recommended you first convert it to maildir +format with a utility such as :manpage:`mb2md(1)` before running +**notmuch setup**. + +Invoking ``notmuch`` with no command argument will run **setup** if the +setup command has not previously been completed. + +OTHER COMMANDS +-------------- + +Several of the notmuch commands accept search terms with a common +syntax. See :any:`notmuch-search-terms(7)` for more details on the +supported syntax. + +The :any:`notmuch-search(1)`, :any:`notmuch-show(1)`, +:any:`notmuch-address(1)` and :any:`notmuch-count(1)` commands are +used to query the email database. + +The :any:`notmuch-reply(1)` command is useful for preparing a template +for an email reply. + +The :any:`notmuch-tag(1)` command is the only command available for +manipulating database contents. + +The :any:`notmuch-dump(1)` and :any:`notmuch-restore(1)` commands can +be used to create a textual dump of email tags for backup purposes, +and to restore from that dump. + +The :any:`notmuch-config(1)` command can be used to get or set +settings in the notmuch configuration file. + +EXTERNAL COMMANDS +----------------- + +If the given command is not known to notmuch, notmuch tries to execute +the external **notmuch-<subcommand>** in :envvar:`PATH` instead. This +allows users to have their own notmuch related tools to be run via the +notmuch command. By design, this does not allow notmuch's own commands +to be overridden using external commands. The environment variable +:envvar:`NOTMUCH_CONFIG` will be set according to :option:`--config`, +if the latter is present. + +OPTION SYNTAX +------------- + +All options accepting an argument can be used with '=' or ':' as a +separator. Except for boolean options (which would be ambiguous), a +space can also be used as a separator. The following are all +equivalent: + +:: + + notmuch --config=alt-config config get user.name + notmuch --config:alt-config config get user.name + notmuch --config alt-config config get user.name + +.. _duplicate-files: + +DUPLICATE MESSAGE FILES +======================= + +Notmuch considers the :mailheader:`Message-ID` to be the primary +identifier of message. Per :rfc:`5322` the :mailheader:`Message-ID` is +supposed to be globally unique, but this fails in two distinct +ways. When you receive copies of a message via a mechanism like +:mailheader:`Cc` or via a mailing list, the copies are typically +interchangeable. In the case of some broken mail sending software, the +same :mailheader:`Message-ID` is used for completely unrelated +messages. The options :option:`search --duplicate` and :option:`show +--duplicate` options provide the user with control over which message +file is displayed. Front ends will need to provide their own +interface, see e.g. the Emacs front-end :any:`emacs-show-duplicates`. + +ENVIRONMENT +=========== + +The following environment variables can be used to control the behavior +of notmuch. + +.. envvar:: NOTMUCH_CONFIG + + Specifies the location of the notmuch configuration file. See + :any:`notmuch-config(1)` for details. + +.. envvar:: NOTMUCH_DATABASE + + Specifies the location of the notmuch database. See + :any:`notmuch-config(1)` for details. + +.. envvar:: NOTMUCH_PROFILE + + Selects among notmuch configurations. See :any:`notmuch-config(1)` + for details. + +.. envvar:: NOTMUCH_TALLOC_REPORT + + Location to write a talloc memory usage report. See + **talloc\_enable\_leak\_report\_full** in :manpage:`talloc(3)` for more + information. + +.. envvar:: NOTMUCH_DEBUG_QUERY + + If set to a non-empty value, the notmuch library will print (to + stderr) Xapian queries it constructs. + +SEE ALSO +======== + +:any:`notmuch-address(1)`, +:any:`notmuch-compact(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-properties(7)`, +:any:`notmuch-reindex(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` + +The notmuch website: **https://notmuchmail.org** + +CONTACT +======= + +Feel free to send questions, comments, or kudos to the notmuch mailing +list <notmuch@notmuchmail.org> . Subscription is not required before +posting, but is available from the notmuchmail.org website. + +Real-time interaction with the Notmuch community is available via IRC +(server: irc.libera.chat, channel: #notmuch). diff --git a/doc/man5/notmuch-hooks.rst b/doc/man5/notmuch-hooks.rst new file mode 100644 index 00000000..d778bdb8 --- /dev/null +++ b/doc/man5/notmuch-hooks.rst @@ -0,0 +1,64 @@ +.. _notmuch-hooks(5): + +============= +notmuch-hooks +============= + +SYNOPSIS +======== + +<hook_dir>/{pre-new, post-new, post-insert} + +DESCRIPTION +=========== + +Hooks are scripts (or arbitrary executables or symlinks to such) that +notmuch invokes before and after certain actions. These scripts reside +in a directory defined as described in :any:`notmuch-config(1)`. They +must have executable permissions. + +The currently available hooks are described below. + +pre-new + This hook is invoked by the :any:`notmuch-new(1)` command before + scanning or importing new messages into the database. If this hook + exits with a non-zero status, notmuch will abort further + processing of the :any:`notmuch-new(1)` command. + + Typically this hook is used for fetching or delivering new mail to + be imported into the database. + +post-new + This hook is invoked by the :any:`notmuch-new(1)` command after + any new messages have been imported into the database and initial + tags have been applied. The hook will not be run if there have + been any errors during the scan or import. + + Typically this hook is used to perform additional query-based + tagging on the imported messages. + +post-insert + This hook is invoked by the :any:`notmuch-insert(1)` command after + the message has been delivered, added to the database, and initial + tags have been applied. The hook will not be run if there have + been any errors during the message delivery; what is regarded as + successful delivery depends on the ``--keep`` option. + + Typically this hook is used to perform additional query-based + tagging on the delivered messages. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man7/notmuch-properties.rst b/doc/man7/notmuch-properties.rst new file mode 100644 index 00000000..ff79f4c2 --- /dev/null +++ b/doc/man7/notmuch-properties.rst @@ -0,0 +1,148 @@ +.. _notmuch-properties(7): + +================== +notmuch-properties +================== + +SYNOPSIS +======== + +**notmuch** **count** **property:**\ <*key*>=<*value*> + +**notmuch** **search** **property:**\ <*key*>=<*value*> + +**notmuch** **show** **property:**\ <*key*>=<*value*> + +**notmuch** **reindex** **property:**\ <*key*>=<*value*> + +**notmuch** **tag** +<*tag*> **property:**\ <*key*>=<*value*> + + +**notmuch** **dump** **--include=properties** + +**notmuch** **restore** **--include=properties** + +DESCRIPTION +=========== + +Several notmuch commands can search for, modify, add or remove +properties associated with specific messages. Properties are +key/value pairs, and a message can have more than one key/value pair +for the same key. + +While users can select based on a specific property in their search +terms with the prefix **property:**, the notmuch command-line +interface does not provide mechanisms for modifying properties +directly to the user. + +Instead, message properties are expected to be set and used +programmatically, according to logic in notmuch itself, or in +extensions to it. + +Extensions to notmuch which make use of properties are encouraged to +report the specific properties used to the upstream notmuch project, +as a way of avoiding collisions in the property namespace. + +CONVENTIONS +=========== + +Any property with a key that starts with "index." will be removed (and +possibly re-set) upon reindexing (see :any:`notmuch-reindex(1)`). + +MESSAGE PROPERTIES +================== + +The following properties are set by notmuch internally in the course +of its normal activity. + +index.decryption + If a message contains encrypted content, and notmuch tries to + decrypt that content during indexing, it will add the property + ``index.decryption=success`` when the cleartext was successfully + indexed. If notmuch attempts to decrypt any part of a message + during indexing and that decryption attempt fails, it will add the + property ``index.decryption=failure`` to the message. + + Note that it's possible for a single message to have both + ``index.decryption=success`` and ``index.decryption=failure``. + Consider an encrypted e-mail message that contains another + encrypted e-mail message as an attachment -- if the outer message + can be decrypted, but the attached part cannot, then both + properties will be set on the message as a whole. + + If notmuch never tried to decrypt an encrypted message during + indexing (which is the default, see ``index.decrypt`` in + :any:`notmuch-config(1)`), then this property will not be set on that + message. + +session-key + When :any:`notmuch-show(1)` or :any:`notmuch-reply(1)` encounters + a message with an encrypted part, if notmuch finds a + ``session-key`` property associated with the message, it will try + that stashed session key for decryption. + + If you do not want to use any stashed session keys that might be + present, you should pass those programs ``--decrypt=false``. + + Using a stashed session key with "notmuch show" will speed up + rendering of long encrypted threads. It also allows the user to + destroy the secret part of any expired encryption-capable subkey + while still being able to read any retained messages for which + they have stashed the session key. This enables truly deletable + e-mail, since (once the session key and asymmetric subkey are both + destroyed) there are no keys left that can be used to decrypt any + copy of the original message previously stored by an adversary. + + However, access to the stashed session key for an encrypted message + permits full byte-for-byte reconstruction of the cleartext + message. This includes attachments, cryptographic signatures, and + other material that cannot be reconstructed from the index alone. + + See ``index.decrypt`` in :any:`notmuch-config(1)` for more + details about how to set notmuch's policy on when to store session + keys. + + The session key should be in the ASCII text form produced by + GnuPG. For OpenPGP, that consists of a decimal representation of + the hash algorithm used (identified by number from RFC 4880, + e.g. 9 means AES-256) followed by a colon, followed by a + hexadecimal representation of the algorithm-specific key. For + example, an AES-128 key might be stashed in a notmuch property as: + ``session-key=7:14B16AF65536C28AF209828DFE34C9E0``. + +index.repaired + Some messages arrive in forms that are confusing to view; they can + be mangled by mail transport agents, or the sending mail user + agent may structure them in a way that is confusing. If notmuch + knows how to both detect and repair such a problematic message, it + will do so during indexing. + + If it applies a message repair during indexing, it will use the + ``index.repaired`` property to note the type of repair(s) it + performed. + + ``index.repaired=skip-protected-headers-legacy-display`` indicates + that when indexing the cleartext of an encrypted message, notmuch + skipped over a "legacy-display" text/rfc822-headers part that it + found in that message, since it was able to index the built-in + protected headers directly. + + ``index.repaired=mixedup`` indicates the repair of a "Mixed Up" + encrypted PGP/MIME message, a mangling typically produced by + Microsoft's Exchange MTA. See + https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling + for more information. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-reindex(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search-terms(7)`, +:any:`notmuch-show(1)` diff --git a/doc/man7/notmuch-search-terms.rst b/doc/man7/notmuch-search-terms.rst new file mode 100644 index 00000000..acc1c967 --- /dev/null +++ b/doc/man7/notmuch-search-terms.rst @@ -0,0 +1,481 @@ +.. _notmuch-search-terms(7): + +==================== +notmuch-search-terms +==================== + +SYNOPSIS +======== + +**notmuch** **count** [option ...] <*search-term*> ... + +**notmuch** **dump** [--gzip] [--format=(batch-tag|sup)] [--output=<*file*>] [--] [<*search-term*> ...] + +**notmuch** **reindex** [option ...] <*search-term*> ... + +**notmuch** **search** [option ...] <*search-term*> ... + +**notmuch** **show** [option ...] <*search-term*> ... + +**notmuch** **tag** +<*tag*> ... -<*tag*> [--] <*search-term*> ... + +DESCRIPTION +=========== + +Several notmuch commands accept a common syntax for search terms. + +The search terms can consist of free-form text (and quoted phrases) +which will match all messages that contain all of the given +terms/phrases in the body, the subject, or any of the sender or +recipient headers. + +As a special case, a search string consisting of exactly a single +asterisk ("\*") will match all messages. + +Search prefixes +--------------- + +In addition to free text, the following prefixes can be used to force +terms to match against specific portions of an email, (where <brackets> +indicate user-supplied values). + +Some of the prefixes with <regex> forms can be also used to restrict +the results to those whose value matches a regular expression (see +:manpage:`regex(7)`) delimited with //, for example:: + + notmuch search 'from:"/bob@.*[.]example[.]com/"' + +body:<word-or-quoted-phrase> + Match terms in the body of messages. + +from:<name-or-address> or from:/<regex>/ + The **from:** prefix is used to match the name or address of + the sender of an email message. + +to:<name-or-address> + The **to:** prefix is used to match the names or addresses of any + recipient of an email message, (whether To, Cc, or Bcc). + +subject:<word-or-quoted-phrase> or subject:/<regex>/ + Any term prefixed with **subject:** will match only text from the + subject of an email. Searching for a phrase in the subject is + supported by including quotation marks around the phrase, + immediately following **subject:**. + +attachment:<word> + The **attachment:** prefix can be used to search for specific + filenames (or extensions) of attachments to email messages. + +mimetype:<word> + The **mimetype:** prefix will be used to match text from the + content-types of MIME parts within email messages (as specified by + the sender). + +tag:<tag> or tag:/<regex>/ or is:<tag> or is:/<regex>/ + For **tag:** and **is:** valid tag values include **inbox** and + **unread** by default for new messages added by + :any:`notmuch-new(1)` as well as any other tag values added + manually with :any:`notmuch-tag(1)`. + +id:<message-id> or mid:<message-id> or mid:/<regex>/ + For **id:** and **mid:**, message ID values are the literal + contents of the Message-ID: header of email messages, but without + the '<', '>' delimiters. + +thread:<thread-id> + The **thread:** prefix can be used with the thread ID values that + are generated internally by notmuch (and do not appear in email + messages). These thread ID values can be seen in the first column + of output from :any:`notmuch-search(1)` + +thread:{<notmuch query>} + Threads may be searched for indirectly by providing an arbitrary + notmuch query in **{}**. For example, the following returns + threads containing a message from mallory and one (not necessarily + the same message) with Subject containing the word "crypto". + + :: + + % notmuch search 'thread:"{from:mallory}" and thread:"{subject:crypto}"' + + The performance of such queries can vary wildly. To understand + this, the user should think of the query **thread:{<something>}** + as expanding to all of the thread IDs which match **<something>**; + notmuch then performs a second search using the expanded query. + +path:<directory-path> or path:<directory-path>/** or path:/<regex>/ + The **path:** prefix searches for email messages that are in + particular directories within the mail store. The directory must + be specified relative to the top-level maildir (and without the + leading slash). By default, **path:** matches messages in the + specified directory only. The "/\*\*" suffix can be used to match + messages in the specified directory and all its subdirectories + recursively. **path:""** matches messages in the root of the mail + store and, likewise, **path:\*\*** matches all messages. + + **path:** will find a message if *any* copy of that message is in + the specific directory. + +folder:<maildir-folder> or folder:/<regex>/ + The **folder:** prefix searches for email messages by maildir or + MH folder. For MH-style folders, this is equivalent to + **path:**. For maildir, this includes messages in the "new" and + "cur" subdirectories. The exact syntax for maildir folders depends + on your mail configuration. For maildir++, **folder:""** matches + the inbox folder (which is the root in maildir++), other folder + names always start with ".", and nested folders are separated by + "."s, such as **folder:.classes.topology**. For "file system" + maildir, the inbox is typically **folder:INBOX** and nested + folders are separated by slashes, such as + **folder:classes/topology**. + + **folder:** will find a message if *any* copy of that message is + in the specific folder. + +date:<since>..<until> or date:<date> + The **date:** prefix can be used to restrict the results to only + messages within a particular time range (based on the Date: + header). + + See **DATE AND TIME SEARCH** below for details on the range + expression, and supported syntax for <since> and <until> date and + time expressions. + + The time range can also be specified using timestamps without + including the date prefix using a syntax of: + + <initial-timestamp>..<final-timestamp> + + Each timestamp is a number representing the number of seconds + since 1970-01-01 00:00:00 UTC. Specifying a time range this way + is considered legacy and predates the date prefix. + +lastmod:<initial-revision>..<final-revision> + The **lastmod:** prefix can be used to restrict the result by the + database revision number of when messages were last modified (tags + were added/removed or filenames changed). Negative revisions are + interpreted relative to the most recent database revision (see + :option:`count --lastmod`). This is usually used in conjunction + with the ``--uuid`` argument to :any:`notmuch-search(1)` to find + messages that have changed since an earlier query. + +query:<name> + The **query:** prefix allows queries to refer to previously saved + queries added with :any:`notmuch-config(1)`. + +property:<key>=<value> + The **property:** prefix searches for messages with a particular + <key>=<value> property pair. Properties are used internally by + notmuch (and extensions) to add metadata to messages. A given key + can be present on a given message with several different values. + See :any:`notmuch-properties(7)` for more details. + +sexp:<subquery> + The **sexp:** prefix allows subqueries in the format + documented in :any:`notmuch-sexp-queries(7)`. Note that subqueries containing + spaces must be quoted, and any embedded double quotes must be escaped + (see :any:`quoting`). + +User defined prefixes are also supported, see :any:`notmuch-config(1)` for +details. + +Operators +--------- + +In addition to individual terms, multiple terms can be combined with +Boolean operators (**and**, **or**, **not**, and **xor**). Each term +in the query will be implicitly connected by a logical AND if no +explicit operator is provided (except that terms with a common prefix +will be implicitly combined with OR). The shorthand '-<term>' can be +used for 'not <term>' but unfortunately this does not work at the +start of an expression. Parentheses can also be used to control the +combination of the Boolean operators, but will have to be protected +from interpretation by the shell, (such as by putting quotation marks +around any parenthesized expression). + +In addition to the standard boolean operators, Xapian provides several +operators specific to text searching. + +:: + + notmuch search term1 NEAR term2 + +will return results where term1 is within 10 words of term2. The +threshold can be set like this: + +:: + + notmuch search term1 NEAR/2 term2 + +The search + +:: + + notmuch search term1 ADJ term2 + +will return results where term1 is within 10 words of term2, but in the +same order as in the query. The threshold can be set the same as with +NEAR: + +:: + + notmuch search term1 ADJ/7 term2 + + +Stemming +-------- + +**Stemming** in notmuch means that these searches + +:: + + notmuch search detailed + notmuch search details + notmuch search detail + +will all return identical results, because Xapian first "reduces" the +term to the common stem (here 'detail') and then performs the search. + +There are two ways to turn this off: a search for a capitalized word +will be performed unstemmed, so that one can search for "John" and not +get results for "Johnson"; phrase searches are also unstemmed (see +below for details). Stemming is currently only supported for +English. Searches for words in other languages will be performed unstemmed. + +Wildcards +--------- + +It is possible to use a trailing '\*' as a wildcard. A search for +'wildc\*' will match 'wildcard', 'wildcat', etc. + + +Boolean and Probabilistic Prefixes +---------------------------------- + +Xapian (and hence notmuch) prefixes are either **boolean**, supporting +exact matches like "tag:inbox" or **probabilistic**, supporting a more +flexible **term** based searching. Certain **special** prefixes are +processed by notmuch in a way not strictly fitting either of Xapian's +built in styles. The prefixes currently supported by notmuch are as +follows. + +Boolean + **tag:**, **id:**, **thread:**, **folder:**, **path:**, **property:** +Probabilistic + **body:**, **to:**, **attachment:**, **mimetype:** +Special + **from:**, **query:**, **subject:**, **sexp:** + +Terms and phrases +----------------- + +In general Xapian distinguishes between lists of terms and +**phrases**. Phrases are indicated by double quotes (but beware you +probably need to protect those from your shell) and insist that those +unstemmed words occur in that order. One useful, but initially +surprising feature is that the following are equivalent ways to write +the same phrase. + +- "a list of words" +- a-list-of-words +- a/list/of/words +- a.list.of.words + +Both parenthesised lists of terms and quoted phrases are ok with +probabilistic prefixes such as **to:**, **from:**, and **subject:**. +For prefixes supporting regex search, the parenthesised list should be +quoted. In particular + +:: + + subject:"(pizza free)" + +is equivalent to + +:: + + subject:pizza and subject:free + +Both of these will match a subject "Free Delicious Pizza" while + +:: + + subject:"pizza free" + +will not. + +.. _quoting: + +Quoting +------- + +Double quotes are also used by the notmuch query parser to protect +boolean terms, regular expressions, or subqueries containing spaces or +other special characters, e.g. + +:: + + tag:"a tag" + +:: + + folder:"/^.*/(Junk|Spam)$/" + +:: + + thread:"{from:mallory and date:2009}" + +As with phrases, you need to protect the double quotes from the shell +e.g. + +:: + + % notmuch search 'folder:"/^.*/(Junk|Spam)$/"' + % notmuch search 'thread:"{from:mallory and date:2009}" and thread:{to:mallory}' + +Double quotes within query strings need to be doubled to escape them. + +:: + + % notmuch search 'tag:"""quoted tag"""' + % notmuch search 'sexp:"(or ""wizard"" ""php"")"' + +DATE AND TIME SEARCH +==================== + +notmuch understands a variety of standard and natural ways of expressing +dates and times, both in absolute terms ("2012-10-24") and in relative +terms ("yesterday"). Any number of relative terms can be combined ("1 +hour 25 minutes") and an absolute date/time can be combined with +relative terms to further adjust it. A non-exhaustive description of the +syntax supported for absolute and relative terms is given below. + +The range expression +-------------------- + +date:<since>..<until> + +The above expression restricts the results to only messages from <since> +to <until>, based on the Date: header. + +<since> and <until> can describe imprecise times, such as "yesterday". +In this case, <since> is taken as the earliest time it could describe +(the beginning of yesterday) and <until> is taken as the latest time it +could describe (the end of yesterday). Similarly, date:january..february +matches from the beginning of January to the end of February. + +If specifying a time range using timestamps in conjunction with the +date prefix, each timestamp must be preceded by @ (ASCII hex 40). As +above, each timestamp is a number representing the number of seconds +since 1970-01-01 00:00:00 UTC. For example: + + date:@<initial-timestamp>..@<final-timestamp> + +Currently, spaces in range expressions are not supported. You can +replace the spaces with '\_', or (in most cases) '-', or (in some cases) +leave the spaces out altogether. Examples in this man page use spaces +for clarity. + +Open-ended ranges are supported. I.e. it's possible to specify +date:..<until> or date:<since>.. to not limit the start or +end time, respectively. + +Single expression +----------------- + +date:<expr> works as a shorthand for date:<expr>..<expr>. +For example, date:monday matches from the beginning of Monday until +the end of Monday. + +Relative date and time +---------------------- + +[N\|number] +(years\|months\|weeks\|days\|hours\|hrs\|minutes\|mins\|seconds\|secs) +[...] + +All refer to past, can be repeated and will be accumulated. + +Units can be abbreviated to any length, with the otherwise ambiguous +single m being m for minutes and M for months. + +Number can also be written out one, two, ..., ten, dozen, hundred. +Additionally, the unit may be preceded by "last" or "this" (e.g., "last +week" or "this month"). + +When combined with absolute date and time, the relative date and time +specification will be relative from the specified absolute date and +time. + +Examples: 5M2d, two weeks + +Supported absolute time formats +------------------------------- + +- H[H]:MM[:SS] [(am\|a.m.\|pm\|p.m.)] + +- H[H] (am\|a.m.\|pm\|p.m.) + +- HHMMSS + +- now + +- noon + +- midnight + +- Examples: 17:05, 5pm + +Supported absolute date formats +------------------------------- + +- YYYY-MM[-DD] + +- DD-MM[-[YY]YY] + +- MM-YYYY + +- M[M]/D[D][/[YY]YY] + +- M[M]/YYYY + +- D[D].M[M][.[YY]YY] + +- D[D][(st\|nd\|rd\|th)] Mon[thname] [YYYY] + +- Mon[thname] D[D][(st\|nd\|rd\|th)] [YYYY] + +- Wee[kday] + +Month names can be abbreviated at three or more characters. + +Weekday names can be abbreviated at three or more characters. + +Examples: 2012-07-31, 31-07-2012, 7/31/2012, August 3 + +Time zones +---------- + +- (+\|-)HH:MM + +- (+\|-)HH[MM] + +Some time zone codes, e.g. UTC, EET. + +SEE ALSO +======== + +:any:`notmuch(1)`, +:any:`notmuch-config(1)`, +:any:`notmuch-count(1)`, +:any:`notmuch-dump(1)`, +:any:`notmuch-hooks(5)`, +:any:`notmuch-insert(1)`, +:any:`notmuch-new(1)`, +:any:`notmuch-properties(7)`, +:any:`notmuch-reindex(1)`, +:any:`notmuch-reply(1)`, +:any:`notmuch-restore(1)`, +:any:`notmuch-search(1)`, +:any:`notmuch-show(1)`, +:any:`notmuch-tag(1)` diff --git a/doc/man7/notmuch-sexp-queries.rst b/doc/man7/notmuch-sexp-queries.rst new file mode 100644 index 00000000..858ff685 --- /dev/null +++ b/doc/man7/notmuch-sexp-queries.rst @@ -0,0 +1,366 @@ +.. _notmuch-sexp-queries(7): + +==================== +notmuch-sexp-queries +==================== + +SYNOPSIS +======== + +**notmuch** *subcommand* ``--query=sexp`` [option ...] ``--`` '(and (to santa) (date december))' + +DESCRIPTION +=========== + +Notmuch supports an alternative query syntax based on `S-expressions +<https://en.wikipedia.org/wiki/S-expression>`_ . It can be selected +with the command line ``--query=sexp`` or with the appropriate option +to the library function :c:func:`notmuch_query_create_with_syntax`. +Support for this syntax is currently optional, you can test if your +build of notmuch supports it with + +:: + + $ notmuch config get built_with.sexp_queries + + +S-EXPRESSIONS +------------- + +An *s-expression* is either an atom, or list of whitespace delimited +s-expressions inside parentheses. Atoms are either + +*basic value* + + A basic value is an unquoted string containing no whitespace, double quotes, or + parentheses. + +*quoted string* + + Double quotes (") delimit strings possibly containing whitespace + or parentheses. These can contain double quote characters by + escaping with backslash. E.g. ``"this is a quote \""``. + +S-EXPRESSION QUERIES +-------------------- + +An s-expression query is either an atom, the empty list, or a +*compound query* consisting of a prefix atom (first element) defining +a *field*, *logical operation*, or *modifier*, and 0 or more +subqueries. + +``*`` + + "*" matches any non-empty string in the current field. + +``()`` + + The empty list matches all messages + +*term* + + Match all messages containing *term*, possibly after stemming or + phrase splitting. For discussion of stemming in notmuch see + :any:`notmuch-search-terms(7)`. Stemming only applies to unquoted + terms (basic values) in s-expression queries. For information on + phrase splitting see :any:`fields`. + +``(`` *field* |q1| |q2| ... |qn| ``)`` + + Restrict the queries |q1| to |qn| to *field*, and combine with *and* + (for most fields) or *or*. See :any:`fields` for more information. + +``(`` *operator* |q1| |q2| ... |qn| ``)`` + + Combine queries |q1| to |qn|. Currently supported operators are + ``and``, ``or``, and ``not``. ``(not`` |q1| ... |qn| ``)`` is equivalent + to ``(and (not`` |q1| ``) ... (not`` |qn| ``))``. + +``(`` *modifier* |q1| |q2| ... |qn| ``)`` + + Combine queries |q1| to |qn|, and reinterpret the result (e.g. as a regular expression). + See :any:`modifiers` for more information. + +``(macro (`` |p1| ... |pn| ``) body)`` + + Define saved query with parameter substitution. The syntax is + recognized only in saved s-expression queries (see ``squery.*`` in + :any:`notmuch-config(1)`). Parameter names in ``body`` must be + prefixed with ``,`` to be expanded (see :any:`macro_examples`). + Macros may refer to other macros, but only to their own + parameters [#macro-details]_. + +.. _fields: + +FIELDS +`````` + +*Fields* [#aka-pref]_ +correspond to attributes of mail messages. Some are inherent (and +immutable) like ``subject``, while others ``tag`` and ``property`` are +settable by the user. Each concrete field in +:any:`the table below <field-table>` +is discussed further under "Search prefixes" in +:any:`notmuch-search-terms(7)`. The row *user* refers to user defined +fields, described in :any:`notmuch-config(1)`. + +Most fields are either *phrase fields* [#aka-prob]_ (which match +sequences of words), or *term fields* [#aka-bool]_ (which match exact +strings). *Phrase splitting* breaks the term (basic value or quoted +string) into words, ignore punctuation. Phrase splitting is applied to +terms in phrase (probabilistic) fields. Both phrase splitting and +stemming apply only in phrase fields. + +Each term or phrase field has an associated combining operator +(``and`` or ``or``) used to combine the queries from each element of +the tail of the list. This is generally ``or`` for those fields where +a message has one such attribute, and ``and`` otherwise. + +Term or phrase fields can contain arbitrarily complex queries made up +from terms, operators, and modifiers, but not other fields. + +Range fields take one or two arguments specifying lower and upper +bounds. One argument is interpreted as identical upper and lower +bounds. Either upper or lower bound may be specified as ``""`` or +``*`` to specify the lowest possible lower bound or highest possible +upper bound. + +``lastmod`` ranges support negative arguments, interpreted relative to +the most recent database revision (see :option:`count --lastmod`). + +.. _field-table: + +.. table:: Fields with supported modifiers + + +------------+-----------+-----------+-----------+-----------+----------+ + | field | combine | type | expand | wildcard | regex | + +============+===========+===========+===========+===========+==========+ + | *none* | and | | no | yes | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | *user* | and | phrase | no | yes | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | attachment | and | phrase | yes | yes | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | body | and | phrase | no | no | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | date | | range | no | no | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | folder | or | phrase | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | from | and | phrase | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | id | or | term | no | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | is | and | term | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | lastmod | | range | no | no | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | mid | or | term | no | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | mimetype | or | phrase | yes | yes | no | + +------------+-----------+-----------+-----------+-----------+----------+ + | path | or | term | no | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | property | and | term | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | subject | and | phrase | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | tag | and | term | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | thread | or | term | yes | yes | yes | + +------------+-----------+-----------+-----------+-----------+----------+ + | to | and | phrase | yes | yes | no | + +------------+-----------+-----------+-----------+-----------+----------+ + +.. _modifiers: + +MODIFIERS +````````` + +*Modifiers* refer to any prefixes (first elements of compound queries) +that are neither operators nor fields. + +``(infix`` *atom* ``)`` + + Interpret *atom* as an infix notmuch query (see + :any:`notmuch-search-terms(7)`). Not supported inside fields. + +``(matching`` |q1| |q2| ... |qn| ``)`` ``(of`` |q1| |q2| ... |qn| ``)`` + + Match all messages have the same values of the current field as + those matching all of |q1| ... |qn|. Supported in most term [#not-path]_ or + phrase fields. Most commonly used in the ``thread`` field. + +``(query`` *atom* ``)`` + + Expand to the saved query named by *atom*. See + :any:`notmuch-config(1)` for more. Note that the saved query must + be in infix syntax (:any:`notmuch-search-terms(7)`). Not supported + inside fields. + +``(regex`` *atom* ``)`` ``(rx`` *atom* ``)`` + + Interpret *atom* as a POSIX.2 regular expression (see + :manpage:`regex(7)`). This applies in term fields and a subset [#not-phrase]_ of + phrase fields (see :any:`field-table`). + +``(starts-with`` *subword* ``)`` + + Matches any term starting with *subword*. This applies in either + phrase or term :any:`fields <fields>`, or outside of fields [#not-body]_. Note that + a ``starts-with`` query cannot be part of a phrase. The + atom ``*`` is a synonym for ``(starts-with "")``. + +EXAMPLES +======== + +``Wizard`` + + Match all messages containing the word "wizard", ignoring case. + +``added`` + + Match all messages containing "added", but also those containing "add", "additional", + "Additional", "adds", etc... via stemming. + +``(and Bob Marley)`` + + Match messages containing words "Bob" and "Marley", or their stems + The words need not be adjacent. + +``(not Bob Marley)`` + + Match messages containing neither "Bob" nor "Marley", nor their stems. + +``"quick fox"`` ``quick-fox`` ``quick@fox`` + + Match the *phrase* "quick" followed by "fox" in phrase fields (or + outside a field). Match the literal string in a term field. + +``(folder (of (id 1234@invalid)))`` + + Match any message in the same folder as the one with Message-Id "1234\@invalid". + +``(id 1234@invalid blah@test)`` + + Matches Message-Id "1234\@invalid" *or* Message-Id "blah\@test". + +``(and (infix "date:2009-11-18..2009-11-18") (tag unread))`` + + Match messages in the given date range with tag unread. + +``(and (date 2009-11-18 2009-11-18) (tag unread))`` + + Match messages in the given date range with tag unread. + +``(and (date 2009-11-18 *) (tag unread))`` + + Match messages from 2009-11-18 or later with tag unread. + +``(and (date * 2009-11-18) (tag unread))`` + + Match messages from 2009-11-18 or earlier with tag unread. + +``(starts-with prelim)`` + + Match any words starting with "prelim". + +``(subject quick "brown fox")`` + + Match messages whose subject contains "quick" (anywhere, stemmed) and + the phrase "brown fox". + +``(subject (starts-with prelim))`` + + Matches any word starting with "prelim", inside a message subject. + +``(subject (starts-with quick) "brown fox")`` + + Match messages whose subject contains "quick brown fox", but also + "brown fox quicksand". + +``(thread (of (id 1234@invalid)))`` + + Match any message in the same thread as the one with Message-Id "1234\@invalid". + +``(thread (matching (from bob@example.com) (to bob@example.com)))`` + + Match any (messages in) a thread containing a message from + "bob\@example.com" and a (possibly distinct) message to + "bob\@example.com". + +``(to (or bob@example.com mallory@example.org))`` ``(or (to bob@example.com) (to mallory@example.org))`` + + Match in the "To" or "Cc" headers, "bob\@example.com", + "mallory\@example.org", and also "bob\@example.com.au" since it + contains the adjacent triple "bob", "example", "com". + +``(not (to *))`` + + Match messages with an empty or invalid 'To' and 'Cc' field. + +``(List *)`` + + Match messages with a non-empty List-Id header, assuming + configuration ``index.header.List=List-Id``. + +.. _macro_examples: + +MACRO EXAMPLES +-------------- + +A macro that takes two parameters and applies different fields to them. + +:: + + $ notmuch config set squery.TagSubject '(macro (tagname subj) (and (tag ,tagname) (subject ,subj)))' + $ notmuch search --query=sexp '(TagSubject inbox maildir)' + +Nested macros are allowed. + +:: + + $ notmuch config set squery.Inner '(macro (x) (subject ,x))' + $ notmuch config set squery.Outer '(macro (x y) (and (tag ,x) (Inner ,y)))' + $ notmuch search --query=sexp '(Outer inbox maildir)' + +Parameters can be re-used to reduce boilerplate. Any field, including +user defined fields is permitted within a macro. + +:: + + $ notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))' + $ notmuch search --query=sexp '(About notmuch)' + + +NOTES +===== + +.. [#macro-details] Technically macros implement lazy evaluation and + lexical scope. There is one top level scope + containing all macro definitions, but all + parameter definitions are local to a given macro. + +.. [#aka-pref] a.k.a. prefixes + +.. [#aka-prob] a.k.a. probabilistic prefixes + +.. [#aka-bool] a.k.a. boolean prefixes + +.. [#not-phrase] Due to the implementation of phrase fields in Xapian, + regex queries could only match individual words. + +.. [#not-body] Due to the way ``body`` is implemented in notmuch, + this modifier is not supported in the ``body`` field. + +.. [#not-path] Due to the way recursive ``path`` queries are implemented + in notmuch, this modifier is not supported in the + ``path`` field. + +.. |q1| replace:: `q`\ :sub:`1` +.. |q2| replace:: `q`\ :sub:`2` +.. |qn| replace:: `q`\ :sub:`n` + +.. |p1| replace:: `p`\ :sub:`1` +.. |p2| replace:: `p`\ :sub:`2` +.. |pn| replace:: `p`\ :sub:`n` diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst new file mode 100644 index 00000000..7dff7d64 --- /dev/null +++ b/doc/notmuch-emacs.rst @@ -0,0 +1,785 @@ +.. _notmuch-emacs: + +========================== +Emacs Frontend for Notmuch +========================== + +About this Manual +================= + +This manual covers only the Emacs interface to Notmuch. For information +on the command line interface, see section “Description” in the Notmuch +Manual Pages. To save typing, we will sometimes use *notmuch* in this +manual to refer to the Emacs interface to Notmuch. When this distinction +is important, we’ll refer to the Emacs interface as +*notmuch-emacs*. + +Notmuch-emacs is highly customizable via the Emacs customization +framework (or just by setting the appropriate variables). We try to +point out relevant variables in this manual, but in order to avoid +duplication of information, you can usually find the most detailed +description in the variables' docstring. + +notmuch-hello +============= + +.. index:: + single: notmuch-hello + single: notmuch + +``notmuch-hello`` is the main entry point for Notmuch. You can start it +with ``M-x notmuch`` or ``M-x notmuch-hello``. The startup screen looks +something like the following. There are some hints at the bottom of the +screen. There are three main parts to the notmuch-hello screen, +discussed below. The **bold** text indicates buttons you can click with +a mouse or by positioning the cursor and pressing ``<return>`` + +| Welcome to **notmuch** You have 52 messages. +| +| Saved searches: **[edit]** +| +| 52 **inbox** 52 **unread** +| +| Search: ____________________________________ +| +| All tags: **[show]** +| +| Hit \`?' for context-sensitive help in any Notmuch screen. +| Customize Notmuch or this page. + +You can change the overall appearance of the notmuch-hello screen by +customizing the variables + +.. el:defcustom:: notmuch-hello-sections + + |docstring::notmuch-hello-sections| + +.. el:defcustom:: notmuch-hello-thousands-separator + + |docstring::notmuch-hello-thousands-separator| + +.. el:defcustom:: notmuch-show-logo + + |docstring::notmuch-show-logo| + +.. el:defcustom:: notmuch-column-control + + Controls the number of columns for saved searches/tags in notmuch view. + + This variable has three potential types of values: + + .. describe:: t + + Automatically calculate the number of columns possible based + on the tags to be shown and the window width. + + .. describe:: integer <n> + + A lower bound on the number of characters that will + be used to display each column. + + .. describe:: float <f> + + A fraction of the window width that is the lower bound on the + number of characters that should be used for each column. + + So: + + - if you would like two columns of tags, set this to 0.5. + + - if you would like a single column of tags, set this to 1.0. + + - if you would like tags to be 30 characters wide, set this to 30. + + - if you don't want to worry about all of this nonsense, leave + this set to `t`. + +.. el:defcustom:: notmuch-show-empty-saved-searches + + |docstring::notmuch-show-empty-saved-searches| + +notmuch-hello key bindings +-------------------------- + +.. el:define-key:: <tab> + + Move to the next widget (button or text entry field) + +.. el:define-key:: <backtab> + + Move to the previous widget. + +.. el:define-key:: <return> + + Activate the current widget. + +.. el:define-key:: g + = + + Refresh the buffer; mainly update the counts of messages for various + saved searches. + +.. el:define-key:: G + + Import mail, See :ref:`importing` + +.. el:define-key:: m + + Compose a message + +.. el:define-key:: s + + Search the notmuch database using :ref:`notmuch-search` + +.. el:define-key:: v + + Print notmuch version + +.. el:define-key:: q + + Quit + +.. _saved-searches: + +Saved Searches +-------------- + +Since notmuch is entirely search-based, it's often useful to organize +mail around common searches. To facilitate this, the first section of +notmuch-hello presents a customizable set of saved searches. Saved +searches can also be accessed from anywhere in notmuch by pressing +``j`` to access :ref:`notmuch-jump`. + +The saved searches default to various common searches such as +``tag:inbox`` to access the inbox and ``tag:unread`` to access all +unread mail, but there are several options for customization: + +.. el:defcustom:: notmuch-saved-searches + + The list of saved searches, including names, queries, and + additional per-query options. + +.. el:defcustom:: notmuch-saved-search-sort-function + + This variable controls how saved searches should be sorted. A value + of ``nil`` displays the saved searches in the order they are stored + in ‘notmuch-saved-searches’. + +Search Box +---------- + +The search box lets the user enter a Notmuch query. See section +“Description” in Notmuch Query Syntax, for more info on Notmuch query +syntax. A history of recent searches is also displayed by default. The +latter is controlled by the variable `notmuch-hello-recent-searches-max`. + +.. el:defcustom:: notmuch-hello-recent-searches-max + + |docstring::notmuch-hello-recent-searches-max| + +Known Tags +---------- + +One special kind of saved search provided by default is for each +individual tag defined in the database. This can be controlled via the +following variables. + +.. el:defcustom:: notmuch-hello-tag-list-make-query + + Control how to construct a search (“virtual folder”) from a given + tag. + +.. el:defcustom:: notmuch-hello-hide-tags + + Which tags not to display at all. + +.. _notmuch-search: + +notmuch-search +============== + +``notmuch-search-mode`` is used to display the results from executing +a query via ``notmuch-search``. The syntax for these queries is the +the same as :ref:`saved-searches`. For details of this syntax see +info:notmuch-search-terms + +By default the output approximates that of the command line See section +“Description” in notmuch search command. + +The main purpose of the ``notmuch-search-mode`` buffer is to act as a +menu of results that the user can explore further by pressing +``<return>`` on the appropriate line. + +.. el:define-key:: n + C-n + <down> + + Move to next line + +.. el:define-key:: + p + C-p + <up> + + Move to previous line + +.. el:define-key:: <return> + + Open thread on current line in :ref:`notmuch-show` mode + +.. el:define-key:: g + = + + Refresh the buffer + +.. el:define-key:: ? + + Display full set of key bindings + +The presentation of results can be controlled by the following +variables. + +.. el:defcustom:: notmuch-search-result-format + + |docstring::notmuch-search-result-format| + + If the car of an element in notmuch-search-result-format is a + function, insert the result of calling the function into the buffer. + + This allows a user to generate custom fields in the output of a + search result. For example, with the following settings, the first + few characters on each line of the search result are used to show + information about some significant tags associated with the thread. + + .. code:: lisp + + (defun -notmuch-result-flags (format-string result) + (let ((tags-to-letters '(("flagged" . "!") + ("unread" . "u") + ("mine" . "m") + ("sent" . "s") + ("replied" . "r"))) + (tags (plist-get result :tags))) + (format format-string + (mapconcat (lambda (t2l) + (if (member (car t2l) tags) + (cdr t2l) + " ")) + tags-to-letters "")))) + + (setq notmuch-search-result-format '((-notmuch-result-flags . "%s ") + ("date" . "%12s ") + ("count" . "%9s ") + ("authors" . "%-30s ") + ("subject" . "%s ") + ("tags" . "(%s)"))) + + See also :el:defcustom:`notmuch-tree-result-format` and + :el:defcustom:`notmuch-unthreaded-result-format`. + +.. el:defcustom:: notmuch-search-oldest-first + + Display the oldest threads at the top of the buffer + +It is also possible to customize how the name of buffers containing +search results is formatted using the following variables: + +.. el:defcustom:: notmuch-search-buffer-name-format + + |docstring::notmuch-search-buffer-name-format| + +.. el:defcustom:: notmuch-saved-search-buffer-name-format + + |docstring::notmuch-saved-search-buffer-name-format| + + +.. _notmuch-show: + +notmuch-show +============ + +``notmuch-show-mode`` is used to display a single thread of email from +your email archives. + +By default, various components of email messages, (citations, +signatures, already-read messages), are hidden. You can make +these parts visible by clicking with the mouse button or by +pressing RET after positioning the cursor on a hidden part. + +.. el:define-key:: <space> + + Scroll the current message (if necessary), + advance to the next message, or advance to the next thread (if + already on the last message of a thread). + +.. el:define-key:: c + + :ref:`show-copy` + +.. el:define-key:: N + + Move to next message + +.. el:define-key:: P + + Move to previous message (or start of current message) + +.. el:define-key:: n + + Move to next matching message + +.. el:define-key:: p + + Move to previous matching message + +.. el:define-key:: + + - + + Add or remove arbitrary tags from the current message. + +.. el:define-key:: ! + + |docstring::notmuch-show-toggle-elide-non-matching| + +.. el:define-key:: ? + + Display full set of key bindings + +Display of messages can be controlled by the following variables; see also :ref:`show-large`. + +.. el:defcustom:: notmuch-message-headers + + |docstring::notmuch-message-headers| + +.. el:defcustom:: notmuch-message-headers-visible + + |docstring::notmuch-message-headers-visible| + +.. el:defcustom:: notmuch-show-header-line + + |docstring::notmuch-show-header-line| + +.. el:defcustom:: notmuch-multipart/alternative-discouraged + + Which mime types to hide by default for multipart messages. + + Can either be a list of mime types (as strings) or a function + mapping a plist representing the current message to such a list. + The following example function would discourage `text/html` and + `multipart/related` generally, but discourage `text/plain` should + the message be sent from `whatever@example.com`. + + .. code:: lisp + + (defun my--determine-discouraged (msg) + (let* ((headers (plist-get msg :headers)) + (from (or (plist-get headers :From) ""))) + (cond + ((string-match "whatever@example.com" from) + (list "text/plain")) + (t + (list "text/html" "multipart/related"))))) + +.. _show-large: + +Dealing with large messages and threads +--------------------------------------- + +If you are finding :ref:`notmuch-show` is annoyingly slow displaying +large messages, you can customize +:el:defcustom:`notmuch-show-max-text-part-size`. If you want to speed up the +display of large threads (with or without large messages), there are +several options. First, you can display the same query in one of the +other modes. :ref:`notmuch-unthreaded` is the most robust for +extremely large queries, but :ref:`notmuch-tree` is also be faster +than :ref:`notmuch-show` in general, since it only renders a single +message a time. If you prefer to stay with the rendered thread +("conversation") view of :ref:`notmuch-show`, you can customize the +variables :el:defcustom:`notmuch-show-depth-limit`, +:el:defcustom:`notmuch-show-height-limit` and +:el:defcustom:`notmuch-show-max-text-part-size` to limit the amount of +rendering done initially. Note that these limits are implicitly +*OR*-ed together, and combinations might have surprising effects. + +.. el:defcustom:: notmuch-show-depth-limit + + |docstring::notmuch-show-depth-limit| + +.. el:defcustom:: notmuch-show-height-limit + + |docstring::notmuch-show-height-limit| + +.. el:defcustom:: notmuch-show-max-text-part-size + + |docstring::notmuch-show-max-text-part-size| + +.. _show-copy: + +Copy to kill-ring +----------------- + +You can use the usually Emacs ways of copying text to the kill-ring, +but notmuch also provides some shortcuts. These keys are available in +:ref:`notmuch-show`, and :ref:`notmuch-tree`. A subset are available +in :ref:`notmuch-search`. + +.. el:define-key:: c F + M-x notmuch-show-stash-filename + + |docstring::notmuch-show-stash-filename| + +.. el:define-key:: c G + M-x notmuch-show-stash-git-send-email + + |docstring::notmuch-show-stash-git-send-email| + +.. el:define-key:: c I + M-x notmuch-show-stash-message-id-stripped + + |docstring::notmuch-show-stash-message-id-stripped| + +.. el:define-key:: c L + M-x notmuch-show-stash-mlarchive-link-and-go + + |docstring::notmuch-show-stash-mlarchive-link-and-go| + +.. el:define-key:: c T + M-x notmuch-show-stash-tags + + |docstring::notmuch-show-stash-tags| + +.. el:define-key:: c c + M-x notmuch-show-stash-cc + + |docstring::notmuch-show-stash-cc| + +.. el:define-key:: c d + M-x notmuch-show-stash-date + + |docstring::notmuch-show-stash-date| + +.. el:define-key:: c f + M-x notmuch-show-stash-from + + |docstring::notmuch-show-stash-from| + +.. el:define-key:: c i + M-x notmuch-show-stash-message-id + + |docstring::notmuch-show-stash-message-id| + +.. el:define-key:: c l + M-x notmuch-show-stash-mlarchive-link + + |docstring::notmuch-show-stash-mlarchive-link| + +.. el:define-key:: c s + M-x notmuch-show-stash-subject + + |docstring::notmuch-show-stash-subject| + +.. el:define-key:: c t + M-x notmuch-show-stash-to + + |docstring::notmuch-show-stash-to| + +.. el:define-key:: c ? + M-x notmuch-subkeymap-help + + Show all available copying commands + +.. _emacs-show-duplicates: + +Dealing with duplicates +----------------------- + +If there are multiple files with the same :mailheader:`Message-ID` +(see :any:`duplicate-files`), then :any:`notmuch-show` displays the +number of duplicates and identifies the current duplicate. In the +following example duplicate 3 of 5 is displayed. + +.. code-block:: + :emphasize-lines: 1 + + M. Mustermann <max@example.com> (Sat, 30 Jul 2022 10:33:10 -0300) (inbox signed) 3/5 + Subject: Re: Multiple files per message in emacs + To: notmuch@notmuchmail.org + +.. el:define-key:: % + M-x notmuch-show-choose-duplicate + + |docstring::notmuch-show-choose-duplicate| + +.. _notmuch-tree: + +notmuch-tree +============ + +``notmuch-tree-mode`` displays the results of a "notmuch tree" of your +email archives. Each line in the buffer represents a single +message giving the relative date, the author, subject, and any +tags. + +.. el:define-key:: c + + :ref:`show-copy` + +.. el:define-key:: <return> + + Displays that message. + +.. el:define-key:: N + + Move to next message + +.. el:define-key:: P + + Move to previous message + +.. el:define-key:: n + + Move to next matching message + +.. el:define-key:: p + + Move to previous matching message + +.. el:define-key:: o + M-x notmuch-tree-toggle-order + + |docstring::notmuch-tree-toggle-order| + +.. el:define-key:: l + M-x notmuch-tree-filter + + Filter or LIMIT the current search results based on an additional query string + +.. el:define-key:: t + M-x notmuch-tree-filter-by-tag + + Filter the current search results based on an additional tag + + +.. el:define-key:: g + = + + Refresh the buffer + +.. el:define-key:: ? + + Display full set of key bindings + +As is the case with :ref:`notmuch-search`, the presentation of results +can be controlled by the variable ``notmuch-search-oldest-first``. + +.. el:defcustom:: notmuch-tree-result-format + + |docstring::notmuch-tree-result-format| + + The following example shows how to optionally display recipients instead + of authors for sent mail (assuming the user is named Mustermann). + + .. code:: lisp + + (defun -notmuch-authors-or-to (format-string result) + (let* ((headers (plist-get result :headers)) + (to (plist-get headers :To)) + (author (plist-get headers :From)) + (face (if (plist-get result :match) + 'notmuch-tree-match-author-face + 'notmuch-tree-no-match-author-face))) + (propertize + (format format-string + (if (string-match "Mustermann" author) + (concat "To:" (notmuch-tree-clean-address to)) + author)) + 'face face))) + + (setq notmuch-tree-result-format + '(("date" . "%12s ") + (-notmuch-authors-or-to . "%-20.20s") + ((("tree" . "%s") + ("subject" . "%s")) + . " %-54s ") + ("tags" . "(%s)"))) + + See also :el:defcustom:`notmuch-search-result-format` and + :el:defcustom:`notmuch-unthreaded-result-format`. + +.. _notmuch-tree-outline: + +notmuch-tree-outline +-------------------- + +When this mode is set, each thread and subthread in the results +list is treated as a foldable section, with its first message as +its header. + +The mode just makes available in the tree buffer all the +keybindings in info:emacs#Outline_Mode, and binds the following +additional keys: + +.. el:define-key:: <tab> + + Cycle visibility state of the current message's tree. + +.. el:define-key:: <M-tab> + + Cycle visibility state of all trees in the buffer. + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + +.. el:defcustom:: notmuch-tree-outline-open-on-next + + |docstring::notmuch-tree-outline-open-on-next| + +.. _notmuch-unthreaded: + +notmuch-unthreaded +------------------ + +``notmuch-unthreaded-mode`` is similar to :any:`notmuch-tree` in that +each line corresponds to a single message, but no thread information +is presented. + +Keybindings are the same as :any:`notmuch-tree`. + +.. el:defcustom:: notmuch-unthreaded-result-format + + |docstring::notmuch-unthreaded-result-format| + + See also :el:defcustom:`notmuch-search-result-format` and + :el:defcustom:`notmuch-tree-result-format`. + +Global key bindings +=================== + +Several features are accessible from most places in notmuch through the +following key bindings: + +.. el:define-key:: j + + Jump to saved searches using :ref:`notmuch-jump`. + +.. el:define-key:: k + + Tagging operations using :ref:`notmuch-tag-jump` + +.. el:define-key:: C-_ + C-/ + C-x u + + Undo previous tagging operation using :any:`notmuch-tag-undo` + +.. _notmuch-jump: + +notmuch-jump +------------ + +Saved searches configured through :ref:`saved-searches` can +include a "shortcut key" that's accessible through notmuch-jump. +Pressing ``j`` anywhere in notmuch followed by the configured shortcut +key of a saved search will immediately jump to that saved search. For +example, in the default configuration ``j i`` jumps immediately to the +inbox search. When you press ``j``, notmuch-jump shows the saved +searches and their shortcut keys in the mini-buffer. + +.. _notmuch-tag-jump: + +notmuch-tag-jump +---------------- + +Tagging operations configured through ``notmuch-tagging-keys`` can +be accessed via :kbd:`k` in :ref:`notmuch-show`, +:ref:`notmuch-search` and :ref:`notmuch-tree`. With a +prefix (:kbd:`C-u k`), notmuch displays a menu of the reverses of the +operations specified in ``notmuch-tagging-keys``; i.e. each +``+tag`` is replaced by ``-tag`` and vice versa. + +.. el:defcustom:: notmuch-tagging-keys + + |docstring::notmuch-tagging-keys| + + +notmuch-tag-undo +---------------- + +Each notmuch buffer supporting tagging operations (i.e. buffers in +:any:`notmuch-show`, :any:`notmuch-search`, :any:`notmuch-tree`, and +:any:`notmuch-unthreaded` mode) keeps a local stack of tagging +operations. These can be undone via :any:`notmuch-tag-undo`. By default +this is bound to the usual Emacs keys for undo. + +.. el:define-key:: C-_ + C-/ + C-x u + M-x notmuch-tag-undo + + |docstring::notmuch-tag-undo| + +Buffer navigation +================= + +.. el:define-key:: M-x notmuch-cycle-notmuch-buffers + + |docstring::notmuch-cycle-notmuch-buffers| + +Configuration +============= + +.. _importing: + +Importing Mail +-------------- + +.. el:define-key:: M-x notmuch-poll + + |docstring::notmuch-poll| + +.. el:defcustom:: notmuch-poll-script + + |docstring::notmuch-poll-script| + +Sending Mail +------------ + +.. el:defcustom:: mail-user-agent + + Emacs consults the variable :code:`mail-user-agent` to choose a mail + sending package for commands like :code:`report-emacs-bug` and + :code:`compose-mail`. To use ``notmuch`` for this, customize this + variable to the symbol :code:`notmuch-user-agent`. + +.. el:defcustom:: message-dont-reply-to-names + + When composing mail replies, Emacs's message mode uses the + variable :code:`message-dont-reply-to-names` to exclude + recipients matching a given collection of regular expressions + or satisfying an arbitrary predicate. Notmuch's MUA inherits + this standard mechanism and will honour your customization of + this variable. + +Init File +--------- + +When Notmuch is loaded, it will read the ``notmuch-init-file`` +(``~/.emacs.d/notmuch-config`` by default) file. This is normal Emacs Lisp +file and can be used to avoid cluttering your ``~/.emacs`` with Notmuch +stuff. If the file with ``.elc``, ``.elc.gz``, ``.el`` or ``.el.gz`` +suffix exist it will be read instead (just one of these, chosen in this +order). Most often users create ``~/.emacs.d/notmuch-config.el`` and just +work with it. If Emacs was invoked with the ``-q`` or ``--no-init-file`` +options, ``notmuch-init-file`` is not read. diff --git a/doc/python-bindings.rst b/doc/python-bindings.rst new file mode 100644 index 00000000..e1ad26ad --- /dev/null +++ b/doc/python-bindings.rst @@ -0,0 +1,5 @@ +Python Bindings +=============== + +.. automodule:: notmuch2 + :members: diff --git a/doc/queries.rst b/doc/queries.rst new file mode 100644 index 00000000..b76e71e0 --- /dev/null +++ b/doc/queries.rst @@ -0,0 +1,9 @@ +Notmuch Queries +=============== + +.. toctree:: + :titlesonly: + + man7/notmuch-search-terms + man7/notmuch-sexp-queries + man7/notmuch-properties |
