Commit graph

618 commits

Author SHA1 Message Date
Mark Walters
274355776b emacs: tree: use orig-tags in search
This uses the recent functionality to show the tag changes in the tree
buffer. Currently this is only used to show changes the tree buffer
makes itself: i.e., it does not make display any changes reflecting
tagging done by other notmuch-buffers.
2014-03-24 19:48:55 -03:00
Mark Walters
af8c8c2b46 emacs: search: use orig-tags in search
This uses the recent functionality to show the tag changes in the
search buffer. Currently this is only used to show changes the search
buffer makes itself: i.e., it does not make display any changes
reflecting tagging done by other notmuch-buffers.
2014-03-24 19:48:40 -03:00
Mark Walters
a673d618d1 emacs: show: use orig-tags for tag display
This uses the previous patch to show the tag changes that have occured
in the show buffer since it was last loaded/refreshed.
2014-03-24 19:48:22 -03:00
Mark Walters
941e172724 emacs: show: mark tags changed since buffer loaded
This allows (and requires) the original-tags to be passed along with
the current-tags to be passed to notmuch-tag-format-tags. This allows
the tag formatting to show added and deleted tags.By default a removed
tag is displayed with strike-through in red (if strike-through is not
available, eg on a terminal, inverse video is used instead) and an
added tag is displayed underlined in green.

If the caller does not wish to use the new feature it can pass
current-tags for both arguments and, at this point, we do exactly that
in the three callers of this function.

Note, we cannot tidily allow original-tags to be optional because we would
need to distinguish nil meaning "we are not specifying original-tags"
from nil meaning there were no original-tags (an empty list).

We use this in subsequent patches to make it clear when a message was
unread when you first loaded a show buffer (previously the unread tag
could be removed before a user realised that it had been unread).

The code adds into the existing tag formatting code. The user can
specify exactly how a tag should be displayed normally, when deleted,
or when added.

Since the formatting code matches regexps a user can match all deleted
tags with a ".*" in notmuch-tag-deleted-formats.  For example setting
notmuch-tag-deleted-formats to '((".*" nil)) tells notmuch not to show
deleted tags at all.

All the variables are customizable; however, more complicated cases
like changing the face depending on the type of display will require
custom lisp.

Currently this overrides notmuch-tag-deleted-formats for the tests
setting it to '((".*" nil)) so that they get removed from the display
and, thus, all tests still pass.
2014-03-24 19:48:04 -03:00
Mark Walters
d5acfdda5f emacs: tag: add customize for deleted/added tag formats
Add customize options for deleted/added tag formats.  These are not
used yet but will be later in the series.

We switch to using `notmuch-apply-face' rather than `propertize' in
the defcustom for faces so that the faces for deleted/added tags add
to the default face attributes for the tag.

We special case deleting the unread tag as that tag is a strong visual
cue and we don't need that cue when we are just saying it used to be
unread. Thus, we revert to the normal tag face with strikethough for
deleted unread tags.
2014-03-24 19:47:49 -03:00
Mark Walters
b9a777e0a3 emacs: tag split customise option for format-tags into a widget
We will re-use the customize option for format-tags for formattting
deleted tags to added tags in the next patch so split it into a
widget. There should be no functional change.
2014-03-24 19:47:35 -03:00
Austin Clements
7023466ece Make keys of notmuch-tag-formats regexps and use caching
This modifies `notmuch-tag-format-tag' to treat the keys of
`notmuch-tag-formats' as (anchored) regexps, rather than literal
strings.  This is clearly more flexible, as it allows for prefix
matching, defining a fallback format, etc.  This may cause compatibility
problems if people have customized `notmuch-tag-formats' to match tags
that contain regexp specials, but this seems unlikely.

Regular expression matching has quite a performance hit over string
lookup, so this also introduces a simple cache from exact tags to
formatted strings.  The number of unique tags is likely to be quite
small, so this cache should have a high hit rate.  In addition to
eliminating the regexp lookup in the common case, this cache stores
fully formatted tags, eliminating the repeated evaluation of potentially
expensive, user-specified formatting code.  This makes regexp lookup at
least as fast as assoc for unformatted tags (e.g., inbox) and *faster*
than the current code for formatted tags (e.g., unread):

                    inbox (usec)   unread (usec)
    assoc:              0.4            2.8
    regexp:             3.2            7.2
    regexp+caching:     0.4            0.4

(Though even at 7.2 usec, tag formatting is not our top bottleneck.)

This cache must be explicitly cleared to keep it coherent, so this adds
the appropriate clearing calls.
2014-03-24 19:43:00 -03:00
Austin Clements
dfab8e5e49 emacs: Combine notmuch-combine-face-text-property{, -string}
This combines our two face combining functions into one, easy to use
function with a much shorter name: `notmuch-apply-face'.  This
function takes the full set of arguments that
`notmuch-combine-face-text-property' took, but takes them in a more
convenient order and provides smarter defaults that make the function
easy to use on both strings and buffers.
2014-03-24 19:42:33 -03:00
Jani Nikula
14d3251b9c emacs: add path: prefix to query completion
Complete to the new path: prefix.
2014-03-23 07:49:50 -03:00
Jani Nikula
ec13bd12e3 emacs: use the originating buffer's working directory for pipe
Currently notmuch-show-pipe-message runs the command in the working
directory of the *notmuch-pipe* buffer if it exists, and the current
buffer's working directory (which is inherited to the new
*notmuch-pipe* buffer) otherwise. This is all very surprising to the
user, and it's difficult to know or change where the command will be
run.

Always use the current show buffer's working directory for piping. The
user can check that with M-x pwd and change it with M-x cd. This is
consistent with notmuch-show-pipe-part.
2014-03-04 20:00:50 -04:00
Austin Clements
ed720f4e6d emacs: Simplify and fix `notmuch-mua-prompt-for-sender'
`notmuch-mua-prompt-for-sender' is over-engineered and often wrong.
It attempts to detect when all identities have the same name and
specialize the prompt to just the email address part.  However, to do
this it uses `mail-extract-address-components', which is meant for
displaying email addresses, not general-purpose parsing, and hence
performs many canonicalizations that can interfere with this use.  For
example, configuring notmuch-identities to ("Austin
<austin@example.com>"), will cause `notmuch-mua-prompt-for-sender' to
lose the name part entirely and return " <austin@example.com>".

This patch rewrites `notmuch-mua-prompt-for-sender' to simply prompt
for a full identity when notmuch-identities is configured, or to
prompt for a sender address when it isn't.

The original code also did several strange things, like using `eval'
and specifying that this function was interactive.  As a side-effect,
this patch fixes these problems.  And it adds a docstring.
2014-03-04 19:59:35 -04:00
David Bremner
75d84dfd84 emacs: remove newlines from input to notmuch count --batch
Since a newline starts a new query in batch mode, this causes
mysterious crashes in the emacs interface if saved searches contain
newlines.  See the discussion at

      id:87wqhcxb5j.fsf@maritornes.cs.unb.ca

In general newlines seem to be just whitespace to the xapian query
parser, so this should be mainly harmless.
2014-02-25 20:53:19 -04:00
Austin Clements
4b2ec627eb emacs: Fix `notmuch-user-other-email' when no other emails are configured
Thanks to the previous patch, this no longer crashes in this
situation, but now would return ("").  Fix it to return () when no
emails are configured.
2014-02-22 19:51:13 -04:00
Austin Clements
4b734374fb emacs: Fix exception when fetching empty or unconfigured settings
When "notmuch config" is called with the name of an empty or
unconfigured setting, it prints nothing (not even a new line).
Previously, `notmuch-config-get' assumed it would always print a
newline.  As a result, when `notmuch-config-get' was called with the
name of an empty of unconfigured setting, it would attempt to
(substring "" 0 -1) to strip the newline, which would fail with a
(args-out-of-range "" 0 -1) exception.

Fix this by only stripping the newline if there actually is one.
2014-02-22 19:51:03 -04:00
Austin Clements
1326ec09ee emacs: Build forwarded message buffer more directly
Previously, we used `message-forward' to build forwarded messages, but
this function is simply too high-level to be a good fit for some of
what we do.

First, since `message-forward' builds a full forward message buffer
given the message to forward, we have to duplicate much of the logic
in `notmuch-mua-mail' to patch the notmuch-y things into the built
buffer.

Second, `message-forward' constructs the From header from
user-full-name and user-mail-address.  As a result, if we prompt the
user for an identity, we have to parse it into name and address
components, just to have it put back together by `message-forward'.
This process is not entirely loss-less because
`mail-extract-address-components' does a lot of canonicalization
(since it's intended for displaying addresses, not for parsing them).

To fix these problems, don't use `message-forward' at all.
`message-forward' itself is basically just a call to `message-mail'
and `message-forward-make-body'.  Do this ourselves, but call
`notmuch-mua-mail' instead of `message-mail' so we can directly build
a notmuch-y message and control the From header.

This also fixes a bug that was a direct consequence of our use of
`mail-extract-address-components': if the user chose an identity that
had no name part (or the name part matched the mailbox), we would bind
user-full-name to nil, which would cause an exception in the bowels of
message-mode because user-full-name is expected to always be a string
(even if it's just "").
2014-02-22 19:50:55 -04:00
Austin Clements
7c0a1b4d60 emacs: Avoid rebuilding .eldeps even when there's nothing to do
Previously, we updated .eldeps only if the file contents actually
needed to change.  This was done to avoid unnecessary make restarts
(if the .eldeps rule changes the mtime of .eldeps, make has to restart
to collect the new dependencies).  However, this meant that, after a
modification to any .el file that did not change dependencies, .eldeps
would always be out of date, so every make invocation would run the
.eldeps rule, which is both expensive because it starts up Emacs and
noisy.  This was true even when there was nothing to do.  E.g.,

$ make clean && make
...
$ touch emacs/notmuch-lib.el && make
...
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.

Fix this by replacing .eldeps with two files with identical content.
One tracks the mtime of the dependency information and triggers the
Emacs call to rebuild dependencies only when it may be necessary.  The
other tracks the content only; this rule over-triggers in the same way
the old rule did, but this rule is cheap and quiet.
2014-02-21 21:07:23 -04:00
Jed Brown
718d58ade0 emacs: update alist for mail-archive.com API change
Searching by Message-Id no longer works via the old mail-archive.com
API, though I have contacted them in hopes that they restore it to
prevent dead links.  Anyway, the new API is cleaner.

Acked-by: Austin Clements <amdragon@MIT.EDU>
2014-02-16 18:55:24 -04:00
Tomi Ollila
9c1bc977d7 emacs: initialize ido(-completing-read) in emacs 23.[123]
Otherwise `ido-completing-read' will freeze after PROMPT is displayed.
2014-02-03 16:20:39 -04:00
Tomi Ollila
9ac863c549 emacs: ad-activate 'mm-shr after ad-disable-advice 'mm-shr
Imitated from "Enabling advice" in Emacs lisp manual...

ad-disable-advice by itself only changes the enable flag for a
piece of advice. To make the change take effect in the
advised definition, the advice needs to be activated again.
2014-01-30 12:21:25 -04:00
David Bremner
1c2f2c960c emacs: add notmuch-assert-cli-sane to notmuch-hello
This is meant to be the friendly entrypoint, so let's do something
better than the mangled output described in

       id:5228989D.8030607@fifthhorseman.net
2014-01-26 15:10:30 -04:00
David Bremner
71d809ac9a emacs: add function notmuch-assert-cli-sane
If the CLI seems borked, signal an error, and log a suggestion for the
user about how to recover.
2014-01-26 15:10:30 -04:00
David Bremner
71d6a40581 emacs: add a function to heuristically test if the CLI is configured OK.
We cache the result so that we can call the function many places
without worrying about the cost.
2014-01-26 15:10:29 -04:00
Mark Walters
17e44cd584 emacs: tree: use tag-format-tags
Previously tree did not use tag-format-tags: since tree wants to
distinguish matching messages from non-matching messages it is not a
perfect fit.

However, in preparation for allowing tag-changes to be shown (i.e.,
added or deleted tags to be indicated) it is convenient to make all
places displaying tags call the same routines.

We modify notmuch-tag-format-tags slightly so that it can take and
argument for the default characteristics of the face before the
special tag features are applied.

This also means that things like the star symbol for flagged messages
all work in tree.
2014-01-18 14:41:50 -04:00
Mark Walters
3c231e7e49 emacs: tree: default face for matching/non-matching messages
This adds default faces for matching and non-matching messages. This
makes it easier for a user to do broad customization without having to
customize every field. It also fits more neatly with the next patch
which switches to using notmuch-tag-format-tags for tag formatting.

We set the field specific face customization to nil for all the fields
which use the message default face to make it clear to a user which
fields customizations are being used.
2014-01-18 14:41:19 -04:00
Mark Walters
719391f09a emacs: tree remove comma separator tags
Previously the tags on each line in tree view were separarted by ", "
not just " ". This is different from show and search views.

This patch removes this comma. This is a large patch as essentially
every line of each of the expected outputs in the tree tests needs
updating.

Apart from aesthetic reasons this simplifies the switch to
notmuch-tag-format-tags in the next patch.
2014-01-13 14:12:29 -04:00
Tomi Ollila
f2a3d9799d emacs: Makefile.local: HAVE_EMACS usage fixes
If we don't have emacs, disable targets that used EMACS while doing
the recipes of that target.

If we do have emacs, make install-emacs depend on *.elc files,
as making the target will attempt to install those.
2014-01-13 14:12:05 -04:00
Mark Walters
e36284d72d emacs: tree: bare-id in tree
Previously notmuch-tree-get-message-id always returned the id
including the prefix "id:". Modify the function to take an optional
`bare' argument saying to return the raw string.

This will be useful later and brings the function in line with
notmuch-show-get-message-id.
2014-01-03 07:12:28 -04:00
Mark Walters
6d6006bea9 emacs: add '?' to some prefix keymaps to describe its bindings
Added function notmuch-subkeymap-help to describe keybindings of a
subkeymap (eg after . or c in notmuch-search and notmuch-show).
2013-12-10 03:52:54 +08:00
Mark Walters
9c25d4bbf0 emacs: show: stop stderr appearing in buffer
In emacs 24.3+ the stdout/stderr from externally displaying an
attachment gets inserted into the show buffer. This is caused by
changes in mm-display-external in mm-decode.el.

Ideally, we would put this output in the notmuch errors buffer but the
handler is called asynchronously so we don't know when the output will
appear. Thus if we put it straight into the errors buffer it could get
interleaved with other errors. Also we can't easily tell when we
have got all the error output so can't wait until the process is complete.

One solution would be to create a new buffer for the stderr of each
attachment viewed. Again, since we can't tell when the process has
finished, we can't close these buffers automatically so this will
leave lots of buffers around.

Thus we add a debug variable notmuch-show-attachment-debug: it this is
non-nil we create a new buffer for each viewer; if this variable is
nil we just use a temp buffer which means all error output is
discarded (this is the same behaviour as with emacs pre 24.3).
2013-11-20 18:14:35 -04:00
Mark Walters
4eb151e26c emacs: do not put quoted reply in primary selection
In current emacs (24.3) select-active-regions is set to t by
default. The reply insertion code sets the region to the quoted
message to make it easy to delete (kill-region or C-w). These two
things combine to put the quoted message in the primary selection.

This is not what the user wanted and is a privacy risk (accidental
pasting of the quoted message). We can avoid some of the problems
by let-binding select-active-regions to nil. This fixes if the
primary selection was previously in a non-emacs window but not if
it was in an emacs window. To avoid the problem in the latter case
we deactivate mark.

One key test (which fails under many simpler "fixes") is: open emacs
24.3 with notmuch, open 2 windows (viewing different notmuch buffers),
highlight some text in one, and then reply to a message in the
other. In many of my earlier attempts to fix this big this test fails.
2013-11-19 20:18:17 -04:00
Mark Walters
9838fe8e16 emacs: tree: use remap for the over-ridden global bindings
Following a suggestion by Austin in id:20130915153642.GY1426@mit.edu
we use remap for the over-riding bindings in pick. This means that if
the user modifies the global keymap these modifications will happen in
the tree-view versions of them too.

[tree-view overrides these to do things like close the message pane
before doing the action, so the functionality is very close to the
original common keymap function.]
2013-11-13 21:47:00 -04:00
Mark Walters
b5f93cc0db emacs: help: add a special function to deal with remaps
remaps are a rather unusual keymap consisting of "first key" 'remap
and then "second-key" the remapped-function. Thus we do the
documentation for it separately.
2013-11-13 21:46:50 -04:00
Mark Walters
8141555d25 emacs: help: add base-keymap
To support key remapping in emacs help we need to know the base keymap
when looking at the remapping. keep track of this while we recurse
down the sub-keymaps in help.
2013-11-13 21:46:39 -04:00
Mark Walters
141f3813d8 emacs: help: split out notmuch-describe-key as a function
The actual documentation function notmuch-describe-keymap was getting
rather complicated so split out the code for a single key into its own
function notmuch-describe-key.
2013-11-13 21:46:32 -04:00
Mark Walters
9d0174b11c emacs: help: remove duplicate bindings
If the user (or a mode) overrides a keybinding from the common keymap
in one of the modes then both help lines appear in the help screen
even though only one of them is applicable.

Fix this by checking if we already have that key binding. We do this
by constructing an list of (key . docstring) pairs so it is easy to
check if we have already had that binding. Then the actual print help
routine changes these pairs into strings "key \t docstring"
2013-11-13 21:33:28 -04:00
Mark Walters
6f616bd733 emacs: help: save-match-data
The routines that construct the help page in notmuch-lib rely on
match-data being preserved across some fairly complicated code. This
is currently valid but will not be when this series is finished. Thus
place everything between the string-match and replace-match inside a
save-match-data.
2013-11-13 21:33:14 -04:00
Mark Walters
a5ecdf390e emacs: help: check for nil key binding
A standard way to unset a key binding is local-unset-key which is equivalent to
  (define-key (current-local-map) key nil)

Currently notmuch-help gives an error and fails if a user has done this.

To fix this we only add a help line if the binding is non-nil.
2013-11-13 21:33:05 -04:00
Austin Clements
9ecfc1c426 emacs: Correct documentation of `notmuch-poll-script'
The functions referred to in the documentation for this variable were
replaced by the unified `notmuch-poll-and-refresh-this-buffer' in
21474f0e.  Update the documentation to reflect the new function.
2013-11-13 21:27:51 -04:00
Austin Clements
96c0ce28f8 emacs: Fix search tagging races
This fixes races in thread-local and global tagging in notmuch-search
(e.g., "+", "-", "a", "*", etc.).  Previously, these would modify tags
of new messages that arrived after the search.  Now they only operate
on the messages that were in the threads when the search was
performed.  This prevents surprises like archiving messages that
arrived in a thread after the search results were shown.

This eliminates `notmuch-search-find-thread-id-region(-search)'
because these functions strongly encouraged racy usage.

This fixes the two broken tests added by the previous patch.
2013-11-08 20:52:00 -04:00
Austin Clements
730b8f61e0 emacs: Use notmuch tag --batch for large tag queries
(Unfortunately, it's difficult to first demonstrate this problem with
a known-broken test because modern Linux kernels have argument length
limits in the megabytes, which makes Emacs really slow!)
2013-11-08 20:35:13 -04:00
Austin Clements
662e097984 emacs: Support passing input via `notmuch-call-notmuch-*'
This adds support for passing a string to write to notmuch's stdin to
`notmuch-call-notmuch-process' and `notmuch-call-notmuch-sexp'.  Since
this makes both interfaces a little more complicated, it also unifies
their documentation better.
2013-11-08 20:28:44 -04:00
Austin Clements
ddc44ae0d0 emacs: Move `notmuch-call-notmuch-process' to notmuch-lib
Previously, this was in notmuch.el, but all of the other notmuch call
wrappers were in notmuch-lib.el.  Move `notmuch-call-notmuch-process'
to live with its friends.  This happens to fix a missing dependency
from notmuch-tag.el, which required notmuch-lib, but not notmuch.
2013-11-08 20:23:03 -04:00
Mark Walters
3cf926463e emacs: move the show entry to tree into show.el
Move the keybinding and show specific helper from tree.el to show.el
2013-11-07 08:01:22 -04:00
Mark Walters
31d81f7fdd emacs: add z to common keymap
Add the main entry "z" to notmuch-tree to the common keymap.
2013-11-07 08:01:07 -04:00
Mark Walters
00b3ee4f82 emacs: move search based tree functions to notmuch.el
Move a couple of the search mode specifc caller helpers for tree from
tree into notmuch.el.
2013-11-07 07:52:43 -04:00
Mark Walters
6661206381 emacs: minimal change to load notmuch-tree by default
We want to load notmuch-tree when notmuch is loaded, so include it as
a require in notmuch.el. To avoid circular dependency we need to move
one keybinding from notmuch-tree.el to notmuch.el: it makes sense for
it to be defined there anyway.

Since tree is now loaded by default there is no need to print a
message when it is loaded.
2013-11-07 07:47:25 -04:00
Mark Walters
6e56912d13 emacs: add tree to the makefile 2013-11-07 07:39:52 -04:00
Mark Walters
bb5fb8ea25 emacs: move notmuch-tree from contrib to mainline 2013-11-07 07:31:55 -04:00
Mark Walters
52faf1f993 emacs: move notmuch-help to lib
notmuch-help is in notmuch.el not notmuch-lib.el and this is
incovenient for the way pick/tree uses it. I think lib makes more
sense anyway so move it there.
2013-11-07 07:16:47 -04:00
Austin Clements
9f9a63c863 emacs: Add a space after completed tag operations
Previously, when a user fully completed a tag operation, they had to
press space to begin entering another tag operation.  This is
different from, say, shell file name completion, which typically
inserts a space after an unambiguous completion under the assumption
that the user will want to enter more input.

This patch tweaks `notmuch-read-tag-changes' to act more like shell
file name completion: after an unambiguous tag completion, it now
inserts a space, ready and waiting for another tagging operation from
the user.  This is backwards-compatible with old habits, since there's
no harm in putting an extra space.
2013-10-27 17:35:58 -03:00