This seems to fix a problem with emacs 25 creating partial buttons by
calling n-s-b-l with a region that does not include the whole button.
I'm not 100% sure it's legit to act outside the region passed by
jit-lock, but goto-address-fontify-region (where I borrowed the code
from) already does this, so this patch to not make things worse.
Emacs message-send seems to ignore a secure mml tag anywhere except at
the start of the body, and it must be followed by a newline. Since
this is almost certainly not desired we check for it, and require user
confirmation before sending.
As the setup before message-send or message-send-and-exit is getting
more complicated it is convenient to unify the two correspoinding
notmuch functions.
This commit adds a common message-send function for message-send and
message-send-and-exit. At the moment the overlap is small, but the
message-send function will get more complex.
The current code for address completion takes the list of possible
completions (whether generated internally or externally), makes the
first match the initial value for the completion, and puts all the
others (but not the first match) into the possible completions.
This has the nice effect that the <down> key takes you immediately to
the next completion (whereas if the first match were included in the
possible completions it would take you to the first match
again).
However, it has two side effects. First, once you have completed to
the full match you find it says and try completing again you get told
"no match" not "sole completion". Secondly, if you delete some of the
text and try completing you don't get the first match as an option.
This tries to get round most of these problems by including the full
list of possible completions, but with the first match moved to the
very end of the list.
Currently, by default k invokes the tag-jump menu, and following it by
r invokes the reverse tag change jump menu. This is awkward to type
(e.g. k r u for undoing a -unread change). This changes it so that k
followed by k invokes the reverse menu. We make the key for the
reverse map a variable as that makes it possible for a user to
change it by editing their .emacs file.
This tweaks the keybindings in tree-mode. It make b do bounce/resend
matching show-mode. Since b was already bound to scroll message pane
back, we now use backspace for that.
This means space/backspace scroll the message pane forwards/backwards,
and page-up/page-down scrolls the tree pane forwards/backwards.
Commit d25d33ff cleaned up some of the tag face code. However, for the
face notmuch-tag-deleted it used the test
((class color) (supports :strike-through))
to decide whether to use red strikethrough or inverse-video (emacs in
a terminal typically doesn't support red strikethrough, but in X it does).
However, it seems that test often returns true even though red
strikethrough is not supported. This breaks the tag update code -- the
wrong thing is displayed to the user.
Thus we make the test explicitly more specific, changing the test to
((class color) (supports :strike-through "red"))
j is in the global notmuch keymap bound to notmuch jump. In tree-mode
it makes sense to close the message pane first (otherwise the new
search runs in the small top pane of tree-mode).
This stops the (usually incorrect) sigstatus and encstatus buttons
appearing when replying in emacs, and updates the test suite to match.
Overriding the status button functions is a little unusual but much
less intrusive than passing an argument all the way down the call
chain. It also makes it clear exactly what it does.
We also hide the application/pgp-encrypted part as it can only contain
"Version: 1". We do this in notmuch show, which means it also happens
when replying.
Previously if notmuch-wash-wrap-lines-length was set then all messages
would be wrapped at this value (or window-width if that is
smaller). This was done regardless of the message's depth in a thread --
for example, if the n.w.w.l.l is 80 and the messages depth is 20
(so indented 20 by default) the messages text only got 60 characters
of space.
This commit changes that so a message always gets the full n.w.w.l.l
of width regardless of its indentation (unless that goes over
window-width of course).
This allows the user to override the mime-type of a part in the show
buffer. This takes the simple option of displaying the part with the
specified mime-type in its own buffer (in view mode). This avoids
further complicating the part handling code.
Bound to ". m" (i.e., m in the part map). Then the user can either
enter a mime-type (with completion to all mime types that mailcap (and
thus notmuch) knows about, or press return for the default choice of
text/plain.
With all the preparation it is now simple to add the actual insert
code. Since insert can fail for many reasons we let the user decide
interactively deal with it.
We modify test-lib.el to set file fcc, so that all the old tests and
emacs_fcc_message from test-lib.sh still work
We will need our own local copy of message-do-fcc so this commit just
copies the code straight from message.el so that it is easier to see
our local changes coming in the next commit.
We move some code around in preparation for the use of notmuch
insert. In particular, we move the check for a valid maildir for the
fcc to when the message is sent rather than when the fcc header is
inserted. The main motivation is consistency with the insert version
(coming later) where we cannot check the validity until send.
We allow the user some chance to correct the header; the choice here
is intended to be consistent with the insert version to come.
This function prints diagnostic information in the event of an
error. However, one of the callers has an optional :stdin-string
keyword argument. This causes the error printing routine to error
itself.
Rather than reach notmuch-check-exit-status about the possible keyword
arguments (currently only one but could be more in the future) this
commit just tells notmuch-check-exit-status how to print non-string arguments.
This commit makes two changes. The first allows the user to override
an external completion method with the internal notmuch address based
completion for an individual buffer.
Secondly, if the user has company-mode enabled then it sets up company
mode (based on internal completion) but disables the automatic timeout
completion -- the user can still activate it in when desired with
standard company commands such as company-complete.
This commit lets the user customize the address completion. It makes
two changes.
The first change controls whether to build the address completion list
based on messages you have sent or you have received (the latter is
much faster).
The second change add a possible filter query to limit the messages
used -- for example, setting this to date:1y.. would limit the
address completions to addresses used in the last year. This speeds up
the address harvest and may also make the search less cluttered as old
addresses may well no longer be valid.
The User-Agent: header can be fun and interesting, but it also leaks
quite a bit of information about the user and their software stack.
This represents a potential security risk (attackers can target the
particular stack) and also an anonymity risk (a user trying to
preserve their anonymity by sending mail from a non-associated account
might reveal quite a lot of information if their choice of mail user
agent is exposed).
This change also avoids hiding the User-Agent header by default, so
that people who decide they want to send it will at least see it (and
can edit it if they want to) before sending.
It makes sense to have safer defaults.
Previously notmuch-wash made the width of the text (approximately) the
window-width minus the depth in thread. This is correct for the
default indentation of 1 per message depth, but is incorrect for any
other setting of notmuch-show-indent-messages-width.
As notmuch-show-indent-messages-width is customisable, and notmuch-tree
sets it to zero to avoid indenting messages in the message pane, this
bug can show up in real use.
Two of the tests had to be updated: when
notmuch-show-indent-messages-width is 0, then the new (correct) word
wrapping happens later, when notmuch-show-indent-messages-width is 4,
then the new word wrapping happens sooner.
The two new faces (notmuch-search-flagged-face and
notmuch-search-unread-face) make it easier to find the relevant face by
customizing notmuch-faces. I plan to do the same to the other alists of
faces found elsewhere.
Previously if a marking read tag change (i.e., removing the unread
tag) failed for some reason, such as a locked database, then no more
mark read tag changes would be attempted in that buffer.
This handles the error more gracefully. There is not much we can do
yet about dealing with the error itself, and marking read is probably
not important enough to warrant keeping a queue of pending changes or
anything.
However this commit changes it so that
- we do try and make future mark read tag changes.
- we display the tag state correctly: i.e. we don't display the tag as
deleted (no strike through)
- and since we know the tag change failed we can try to mark this
message read in the future. Indeed, since the code uses the
post-command hook we will try again on the next keypress (unless the
user has left the message).
We indicate to the user that these mark read tag changes may have
failed in the header-line.
Many of the external links found in the notmuch source can be resolved
using https instead of http. This changeset addresses as many as i
could find, without touching the e-mail corpus or expected outputs
found in tests.
This binding is similar to mutt's, which is
bind {mode} b "bounce-message" # remail a message to another user
where {mode} is 'index', 'pager' or 'attach'.
The new function notmuch-show-message-resend re-sends
message to new recipients using #'message-resend.
Recipients are read from minibuffer as a comma-separated
string (with some keyboard support including tab completion).
Final confirmation before sending is asked.
When composing messages (including replies, etc.), indicate to
`message-mode' definitively that the message is email (as opposed to
Usenet news) rather than having it attempt to determine this for itself.
This causes `message-mode' to observe such variables as
`message-default-mail-headers', which previously happened haphazardly.
`notmuch--get-bodypart-raw' previously assumed that all non-binary MIME
parts could be successfully read by assuming that they were UTF-8
encoded. This was demonstrated to be wrong, specifically when a part was
marked as ISO8859-1 and included accented characters (which were
incorrectly rendered as a result).
Rather than assuming UTF-8, attempt to use the part's declared charset
when reading it, falling back to US-ASCII if the declared charset is
unknown, unsupported or invalid.
Please put my address in CC when replying. Thanks!
From 4b9ab261a0ea8a31065e310c5150f522be86d37b Mon Sep 17 00:00:00 2001
From: stefan <aeuii@posteo.de>
Date: Fri, 8 Apr 2016 22:47:06 +0200
Subject: [PATCH] emacs: make use of `message-make-from'
Will respect `mail-from-style'.
When no decryption or signature examination is
happening (i.e. `notmuch-crypto-process-mime' is `nil') insert buttons
that indicate this, rather than remaining silent.
Currently the preference for which sub-part of a multipart/alternative
part is shown is global. Allow to the user to override the settings on a
per-message basis by providing the ability to call a function that has
access to the message to return the discouraged type list.
The original approach is retained as the default.
`notmuch-get-bodypart-text' assumed that it is always possible to
acquire text/* parts via the sexp output format. This is not true if the
part in question has a content type of application/octet-stream but is
being interpreted as text/* based on the extension of the part filename.
Rework `notmuch-get-bodypart-text' to use the raw output format to
address this and make the implementation common with that of
`notmuch-get-bodypart-binary'.
Move the brief help text at the bottom of the hello screen to the
notmuch-hello-mode help, and promote '?' as the universal help key
across Notmuch. This unclutters the hello screen, and allows for a
more verbose description in the mode help. Hopefully, this change is
useful for both experienced and new users alike.
While at it, improve the links to Notmuch and hello screen
customization.
Add a customizable function specifying which parts get a header when
replying, and give some sensible possiblities. These are,
1) all parts except multipart/*. (Subparts of a multipart part do
receive a header button.)
2) only included text/* parts.
3) Exactly as in the show buffer.
4) None at all. This means the reply contains a mish-mash of all the
original message's parts.
In the test suite we set the choice to option 4 to match the
previous behaviour.
Use the message display code to generate message text to cite in
replies.
For now we set insert-headers-p function to
notmuch-show-reply-insert-header-p-never so that, as before, we don't
insert part buttons.
With that choice of insert-headers-p function there is only one
failing test: this test has a text part (an email message) listed as
application/octet-stream. Notmuch show displays this part, but the
reply code omitted it as it had type application/octet-stream. The new
code correctly includes it. Thus update the expected output to match.
This allows callers of notmuch-show-insert-bodypart to use a `let'
binding to override the default function for specifying when part
headers should be inserted.
We also add an option to never show part buttons which will be used by
the test suites for the reply tests.
If the basic query passed to `notmuch-show' generates no results, ring
the bell and inform the user that no messages matched the query rather
than displaying an empty buffer and showing an obscure error.
Similarly when refreshing a `notmuch-show' buffer and no messages match.
Change the key binding for filter (or "limit") in search-mode. This
gives consistency with the new filter in show-mode, and frees 'f' for
forward-thread in the future.
As pointed out by David Bremner, Elisp manual says "A common pitfall
is to use a quoted constant list as a non-last argument to ‘nconc’."
Since this was the case in recently added code, we fix it here.
notmuch-mua-mail ignored the switch-function argument and always used
the function returned by notmuch-mua-get-switch-function instead. In
order to support standard emacs interfaces (compose-mail in this
case), this commit changes notmuch-mua-mail to use the switch-function
argument if it is non-nil and notmuch-mua-get-switch-function
otherwise.
Commit 570c0aeb40 reworked
notmuch-mua-mail function in a way that worked only under Emacs 24.
The reason was that message-setup-1 took one argument less in Emacs
23.
We fix this by only supplying the return-action argument when it is
actually set by the caller.
Recent addition of notmuch-message-mode introduced several problems:
1. When message-setup-hook is used to set buffer local variables,
these settings are not effective, because all buffer local
variables are immediately erased by notmuch-message-mode
initialization.
2. message-mode-hook gets invoked twice - first when message-mail
invokes message-mode and second when notmuch-mua-mail invokes
notmuch-message-mode.
This commit fixes these problems by replacing a call to message-mail
with notmuch-specific code that is (hopefully) equivalent to
message-mail functionality before introduction of
notmuch-message-mode.
We first initialize notmuch-message-mode with
notmuch-mua-pop-to-buffer, which is a modified version of
message-pop-to-buffer and then call message-setup-1, which is the only
functionality of message-mail that is needed for notmuch.
Previously poll called from emacs would fail silently. This makes it
return a useful error message.
In the non-deprecated case of notmuch new and appropriate hooks, it
uses notmuch-call-notmuch-process which gives an error and
additionally puts the stdout/stderr etc in the *Notmuch errors*
buffer.
In the deprecated case of a custom poll script it only returns an
error message.
Commit based on a bug report, and a potential fix, by Ketil Malde.
In emacs24 we use make-composed-keymap. It seems that if only a single
map is specified then emacs just resuses it rather than creating a
copy of it. Thus use make-sparse-keymap to force a copy.
emacs/make-depend.el will compute all other related dependencies
except this one:
notmuch-version is not top-level `require' expression in
notmuc-lib.el[c] but conditional based on the existence of
notmuch-version.el[c].
emacs/make-depend.el does not know now notmuch-version.el[c] becomes
into existence but emacs/Makefile.local does know.
notmuch-show-view-raw-message() re-uses buffer created with same
name (same Message-Id:) but it did not erase it before filling.
If this ever happened, there were duplicated (potentially overlapping)
content in the buffer. Now this is fixed.
Apparently since emacs 24.5 the (view-buffer) makes the buffer read-only;
so this problem would not have happened there, just that
notmuch-show-view-raw-message() failed. This is fixed by setting
inhibit-read-only t before erasing and filling the buffer. The emacs 24.5
feature having raw message buffer read-only is also now explicitly set to
the buffer so the same experience is available with emaces < 24.5.
Flyspell mode uses a special setting for message-mode to not
spell-check message headers except Subject. Apply this setting also to
notmuch-message-mode.
Commit e26d767897 changed the
fontification of the body associated with the From header to
message-header-from. However, that face is non-existent, and in
message.el (message-font-lock-keywords) the From-header falls through
and is attributed the message-header-other face.
This commit removes the fontification of the [Ff]rom header in
notmuch-show-mode in order to fontify it using the message-header-other
face.
This only affects non-default configurations where
notmuch-message-headers is set to display From.
When company-mode is available (Emacs >= 24), address completion
candidates are shown in a nice popup box. This is triggered either by
pressing TAB or by waiting a while during typing an address. The
completion is based entirely on the asynchronous address harvesting
from notmuch-address.el so the GUI is theoretically not blocked for
long time.
The completion works similarly as the TAB-initiated completion from
notmuch-address.el, i.e. quick harvest based on user input is executed
first and only after full harvesting is finished, in-memory cached data
is used.
[Improved by David Bremner]
Currently, notmuch has an address completion mechanism that requires
external command to provide completion candidates. This commit adds a
completion mechanism inspired by https://github.com/tjim/nevermore,
which is implemented in Emacs lisp only.
The preexisting address completion mechanism, activated by pressing
TAB on To/Cc lines, is extended to use the new mechanism when
notmuch-address-command to 'internal, which is the new default.
The core of the new mechanism is the function notmuch-address-harvest,
which collects the completion candidates from the notmuch database and
stores them in notmuch-address-completions variable. The address
harvesting can run either synchronously (same as with the previous
mechanism) or asynchronously. When the user presses TAB for the first
time, synchronous harvesting limited to user entered text is performed.
If the entered text is reasonably long, this operation is relatively
fast. Then, asynchronous harvesting over the full database is triggered.
This operation may take long time (minutes on rotating disk). After it
finishes, no harvesting is normally performed again and subsequent
completion requests use the harvested data cached in memory. Completion
cache is updated after 24 hours.
Note that this commit restores (different) completion functionality for
users when the user used external command named "notmuch-addresses",
i.e. the old default. The result will be that the user will use
the new mechanism instead of this command. I believe that many users may
not even recognize this because the new mechanism works the same as
http://commonmeasure.org/~jkr/git/notmuch_addresses.git and perhaps also
as other commands suggested at
http://notmuchmail.org/emacstips/#address_completion.
[This feature was significantly improved by David Bremner and Mark Walters]
This allows e.g. Gnus users to load this file without changing
message-mode behaviour.
This will disable completion for those that did not customize the
variable but relied on the existence of a file named "notmuch-addresses"
in their path. In the next commit the default behaviour will change to
use a "workalike" internal completion mechanism.
This patch allows the user to customize a saved search to choose tree
view rather than the default search view. It also updates notmuch-jump
so that it respects this choice.
Currently notmuch-show-max-text-part-size is 10000 which means some
relatively normal messages have all parts hidden by default. Increase
this to 100000 by default.
The setting was introduced to alleviate problems with notmuch being
very slow on large threads. Users hitting these problems may wish to
customize this variable to something smaller (like 10000).
Formerly replying to an encrypted message in tree-view did not work:
the message was not decrypted. This commit makes notmuch-tree respect
the setting of notmuch-crypto-process-mime. In particular, if
notmuch-crypto-process-mime is set to t, then replying to encrypted
messages in tree mode will now decrypt the reply (as it already did in
show mode).
When filtering the current search further with notmuch-search-filter,
wrap the current search in parens (if necessary).
This fixes unexpected behavior when the current search is
complex (like "(tag:this and date:one_week_ago..) or tag:that").
Previously we globally modified these variables, which tended to cause
problems for people using message-mode, but not notmuch-mua-mail, to
send mail.
User visible changes:
- Calling notmuch-fcc-header-setup is no longer optional. OTOH, it
seems to do the right thing if notmuch-fcc-dirs is set to nil.
- The Fcc header is visible during message composition
- The name in the mode line is changed, and no longer matches exactly
the menu label.
- Previously notmuch-mua-send-and-exit was never called. Either we
misunderstood define-mail-user-agent, or it had a bug. So there was
no difference if the user called message-send-and-exit directly. Now
there will be.
- User bindings to C-c C-c and C-c C-s in message-mode-map are
overridden. The user can override them in notmuch-message-mode-map,
but then they're on their own for Fcc handling.
This is to provide a clean way of overriding e.g. keybindings when
sending mail from notmuch.
This is needed in particular to allow somewhere to dynamically bind
certain message-mode variables which are not respected when buffer-local. See e.g.
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=21174
Now that we have `notmuch-emacs-version' defined in notmuch emacs MUA
use that as a part of User-Agent: header to provide more accurate
version information when sending emails.
In case some incomplete installation of notmuch emacs MUA is used and
`notmuch-emacs-version' is defined as "unknown" then fall back to ask
version info from cli (as it used to be before this commit).
Requiring notmuch-version[.elc] and if that is missing setting
"fallback" notmuch-emacs-version (to "unknown") was moved from
notmuch.el to notmuch-lib.el as notmuch-mua.el (which provides
User-Agent: information) require's the latter.
Show the current thread with a different filter (i.e., open messages
in the thread matching the new query).
Bound to 'l' for "limit".
Note that it is not the same as filter in search mode as it replaces
the existing query rather than ANDing with it (but it does keep the
thread-id part of the query).
Separate out a notmuch-show-goto-msg-id sub-function from
notmuch-show-apply-state. There should be no functional change but the
next patch will call the new function.
The second argument to notmuch-tag is now called tag-changes, but the
documentation for notmuch-before-tag-hook and notmuch-after-tag-hook
still used the old argument name `tags'. This resulted in broken hooks
when following the documentation.
The mark read code for tree mode did not get updated in the recent
changes. This updates it to match. Since the user can customize the
mark read logic we just call the show logic in the message pane.
The notmuch-search-terms man page states that "tag:<tag>" is equivalent
to "is:<tag>". Completion for "is:<tag>" style searches is now supported
in the Emacs interface.
Amended by David Bremner: combine lexical-let and let into
lexical-let*
notmuch-show can be slow displaying large attachments so hide them by
default. The default maximum size is 10000 bytes/characters but it is
customizable.
Note that notmuch-show-insert-bodypart is also called from the reply
code so we need to be a little careful.
Besides generally cleaning up the code and separating the general
content ID handling from the w3m-specific code, this fixes several
problems.
Foremost is that, previously, the code roughly assumed that referenced
parts would be in the same multipart/related as the reference.
According to RFC 2392, nothing could be further from the truth:
content IDs are supposed to be globally unique and globally
addressable. This is nonsense, but this patch at least fixes things
so content IDs can be anywhere in the same message.
As a side-effect of the above, this handles multipart/alternate
content-IDs more in line with RFC 2046 section 5.1.2 (not that I've
ever seen this in the wild). This also properly URL-decodes cid:
URLs, as per RFC 2392 (the previous code did not), and applies crypto
settings from the show buffer (the previous code used the global
crypto settings).
Unibyte strings are meant for representing binary data. In practice,
using unibyte versus multibyte strings affects *almost* nothing. It
does happen to matter if we use the binary data in an image descriptor
(which is, helpfully, not documented anywhere and getting it wrong
results in opaque errors like "Not a PNG image: <giant binary spew
that is, in fact, a PNG image>").
`notmuch-get-bodypart-content' could do two very different things,
depending on conditions: for text/* parts other than text/html, it
would return the part content as a multibyte Lisp string *after*
charset conversion, while for other parts (including text/html), it
would return binary part content without charset conversion.
This commit completes the split of `notmuch-get-bodypart-content' into
two different and explicit APIs: `notmuch-get-bodypart-binary' and
`notmuch-get-bodypart-text'. It updates all callers to use one or the
other depending on what's appropriate.
The new function, `notmuch-get-bodypart-binary', replaces
`notmuch-get-bodypart-internal'. Whereas the old function was really
meant for internal use in `notmuch-get-bodypart-content', it was used
in a few other places. Since the difference between
`notmuch-get-bodypart-content' and `notmuch-get-bodypart-internal' was
unclear, these other uses were always confusing and potentially
inconsistent. The new call clearly requests the part as undecoded
binary.
This is step 1 of 2 in separating `notmuch-get-bodypart-content' into
two APIs for retrieving either undecoded binary or decoded text.
We set header-line-format to the message subject, but if the subject
contains percents, the next character is interpreted as a formatting
control, which is not desired.
The TAB-initiated address completion generates completion candidates
synchronously, blocking the UI. Since this can take long time, it is
better to let the use know what's happening.
Make a new customizable variable instead of relying on
message-cite-function because the default for the latter changed
between emacs releases.
The defcustom is borrowed from the message.el source, with minor
modifications.
The faces used when washing messages should be notmuch specific and
inherit from the underlying emacs face rather than using it
directly. This allows the washed face to be modified without requiring
the modification of the underlying face.
`with-current-notmuch-show-message' applies a `no-conversion' coding
system when reading a raw message from notmuch. That coding system
should _not_ be applied when the body of the macro is evaluated, as it
can cause file operations used during that evaluation to incorrectly
apply the `no-conversion' coding system.
This was discovered when a user's .signature file contained non-ASCII
characters. When a message is forwarded, the `no-conversion' coding
system was applied to the reading of the .signature file, resulting in
raw rather than UTF-8 interpretation of the data.
notmuch-jump uses window-body-width which is not defined in emacs
23. To get around this it does
(unless (fboundp 'window-body-width)
;; Compatibility for Emacs pre-24
(defalias 'window-body-width 'window-width))
This makes sure window-body-width is defined and all should be
well. But it seems that the byte compiler does not realise that this
guarantees that window-body-width will be defined and so, when
compiling with emacs 23, it gives an error
In end of data:
notmuch-jump.el:172:1:Warning: the function `window-body-width' is not known to be defined.
Domo and I came to following on irc: wrap the (unless (fboundp ...))
inside eval-and-compile which ensures that both the test and the
defalias (if needed) happen at both compile and load time. This fixes
the warning.
default-value needs its argument to be quoted.
Slightly strangely default-value of 't or nil is 't or nil
respectively so the code
(default-value notmuch-search-oldest-first)
just gives the current value of notmuch-search-oldest-first rather
than intended default-value of this variable.
The symptom is that if you are in a search buffer and use notmuch jump
to run a saved search which does not have an explicitly set sort order
then the sort order of the saved-search is inherited from the current
search buffer rather than being the default search order.
Thanks to Jani for finding the bug.
Fix byte compiler warning "Warning: the function `window-body-width'
is not known to be defined." by moving our compatibility wrapper
before its use and simplify the definition to a defalias for the old
name of the function.
This should help new users off to a better start with the addition of
more sensible saved searches and default shortcut keys. Most existing
users have probably customized this variable and won't be affected.
This introduces notmuch-jump, which is like a user-friendly,
user-configurable global prefix map for saved searches. This provides
a non-modal and much faster way to access saved searches than
notmuch-hello.
A user configures shortcut keys in notmuch-saved-searches, which are
immediately accessible from anywhere in Notmuch under the "j" key (for
"jump"). When the user hits "j", the minibuffer immediately shows a
helpful table of bindings reminiscent of a completions buffer.
This code is a combination of work from myself (originally,
"notmuch-go"), David Edmondson, and modifications from Mark Walters.
notmuch-poll-script has long since been deprecated in favor of
post-new hooks, but this wasn't obvious from the documentation.
Update the documentation to make this clear. Since
notmuch-poll-script could, to some extend, be used to control the path
of the notmuch binary and that use is now clearly discouraged, promote
notmuch-command to a real defcustom instead of just a variable.
tree overrides notmuch-show-get-prop so that it can use many of the
utility function directly. Now that tree is in mainline the version
from tree can be moved to show and the original overridden show
version dropped.
This adds the current query as a "default value" to
notmuch-read-qeury. The default value is available via a down-arrow as
opposed to history which is available from the up arrow.
Note if a user presses return in the minibuffer this value is not
returned.
The implementation is simple but notmuch-read-query could be called
via notmuch-search/notmuch-tree etc from any buffer so it makes sense
to put the decision of how to extract the current query in
notmuch-read-query rather than in each of the callers.
notmuch-search-archive-thread moves to the next line after tagging. In
the normal case this makes sense, but if the region is active, it tags
the whole region and then it doesn't really. Thus only move to the
next line if region is not active.
Add a function for updating seen messages to the
post-command-hook. This function calls a customizable (by eg
defcustom) function with parameters the start and end of the current
window and that function can decide what to mark read based on that
and the current point.
Since this is in the post-command-hook it should get called after most
user actions (exceptions include user resizing the window) so it
should be possible to make sure the seen status gets updated whether
the user uses notmuch commands like next-message or normal emacs
commands like scroll-up.
It removes all of the old mark read/seen points but introduces a
simple example function that just marks the current message read if it
is open. This function has one small subtlety: it makes sure it
doesn't mark the same message read twice (in the same instance of the
same buffer); otherwise the post-command-hook makes it impossible for
a user to manually mark a message unread.
This fixes the current bugs (imo) that closed messages can be marked
read, and that opening a closed message does not mark it read.
Another advantage of using the post-command-hook any programmatic use
with point passing through a message will not mark it read.
When the user begins forwarding a message, the resulting composition
buffer should not be marked as modified, in order that it can
immediately be killed without prompting.
`make install-emacs` will copy $(emacs_sources), $(emacs_images) and
$(emacs_bytecode) to their target directories. $(emacs_bytecode) was
already a prerequisite of make install-emacs as these obviously needed
to be build. Until a while ago all of $(emacs_sources) was available
in the repository, but now it includes `notmuch-version.el` which
is generated. In the future we may have generated emacs images too.
Currently notmuch-tag throws a "wrong-type-argument stringp nil" if
passed a nil query-string. Catch this and provide a more useful error
message. This fixes a case in notmuch-tree (if you try to tag when at
the end of the buffer).
Secondly, as pointed out by David (dme)
`notmuch-search-find-stable-query-region' can return the query string
() if there are no messages in the region. This gets passed to notmuch
tag, and due to interactions in the optimize_query code in
notmuch-tag.c becomes, in the case tag-change is -inbox, "( () ) and
(tag:inbox)". This query matches some strange collection of messages
which then get archived. This should probably be fixed, but in any
case make `notmuch-search-find-stable-query-region' return a nil
query-string in this case.
This avoids data-loss (random tag removal) in this case.
The implementation and documentation for `notmuch-search-line-faces'
disagreed in how elements in the list were merged. Correct the
documentation to match the implementation (that is, the earlier
elements in the list have precedence over later elements).
Some archives may use a more complicated scheme for referring to
messages than just concatenated url and message-id. In particular,
patchwork requires a query to translate message-id to a patchwork
patch id. Allow functions in notmuch-show-stash-mlarchive-link-alist
to facilitate this.
For example, one could use something like this for patchwork.
(lambda (message-id)
(concat
"http://patchwork.example.com/patch/"
(nth 0
(split-string
(car (last (process-lines "pwclient" "search" "-n" "1"
"-m" (concat "<" message-id ">"))))))))
The recent changes for saved searches introduced a bug when notmuch
was loaded after the saved search was defined. This was caused by a
utility function not being defined when the defcustom was loaded.
Fix this by moving some code around: the defcustom is moved into
notmuch-hello (which is a more natural place anyway), and the utility
functions are moved before the defcustom in notmuch-hello. We are
rather constrained as the defcustom for saved searches is the first
variable in the notmuch-hello customize window; to avoid moving this
customize the defcustom needs to be the first defcustom in
notmuch-hello, and the utility functions come before that.
This patch also renames one of the utility functions from
notmuch--saved-searches-to-plist to
notmuch-hello--saved-searches-to-plist (as it is purely local to
notmuch-hello) and corrects a couple of typo/spelling mistakes pointed
out by Tomi.
Previously, even if debug-on-error was non-nil, the debugger would not
trap on part renderer errors. This made debugging part renderer bugs
frustrating, so let the debugger trap these errors.
My recent changes to the saved search format broke the alphabetically
sorted saved sort option. This makes it work again.
Also update docs for saved-search sort defcustom to match the new
format.
Finally, since the saved-search list is no longer an alist change the
names in the sort function to avoid confusion.
It was decided that auto-signing is potentially too troublesome for the
apparently common case of users who enable crypto processing for the
purpose of checking signature validity but who are not in a position to
sign out-going messages. Users can still manually invoke signing as needed.
Encrypting replies to encrypted messages is more of a security issue
so we leave it in place.
This is a simple approach to improving security when replying to
signed or encrypted messages. If the message being replied to was
signed, add mml tag to sign the reply. If the message being replied to
was encrypted, add mml tag to sign and encrypt the reply.
This may need configuration; I for one might want to encrypt replies
to encrypted messages, but not always sign replies to signed messages.
This still includes a slight bug: if any mml tags are added, they are
included in the region containing the quoted parts. Killing the region
will kill the mml tags too.
This adds a sort-order option to saved-searches, stores it in the
saved-search buttons (widgets), and uses the stored value when the
button is pressed.
Storing the sort-order in the widget was suggested by Jani in
id:4c3876274126985683e888641b29cf18142a5eb8.1391771337.git.jani@nikula.org.
Make the defcustom for notmuch-saved-searches use the new plist
format. It should still work with oldstyle saved-searches but will
write the newstyle form.
Add helper functions to for saved searches to ease the transition to
the new plist form while maintaining backwards compatibility. They
will be used in the next patch.
The notmuch cli program and emacs lisp versions may differ (especially
in remote usage). It helps to resolve problems if we can determine
the versions of notmuch cli and notmuch emacs mua separately.
The build process now creates notmuch-version.el from template file
by filling the version info to notmuch-emacs-version variable.
We push mark on reply so user can cut the quote. Push the mark before
signature, if any, instead of end of buffer so the signature is
preserved.
This is consistent with message-kill-to-signature.
So that users can easily organize their notmuch-specific configurations
to separate file and they don't have to have notmuch configurations in
*every* emacs installation they launch, especially if those need to
'(require notmuch) to make the configurations possible.
When (require 'notmuch) is added to ~/.emacs notmuch is loaded to every
instance of emacs although it may not be used in majority of
those instances.
When (autoload 'notmuch "notmuch" ...) is added to ~/.emacs notmuch
is loaded (only) when user invokes the notmuch function.
User may want to add other entrypoints to notmuch by adding more
autoloads -- the autoload instruction given should offer them clue how
to do so.
Previously, the term escaper used a blacklist of characters that
needed escaping. This blacklist turned out to be somewhat incomplete;
for example, it did not contain non-whitespace ASCII control
characters or Unicode "fancy quotes", both of which do require the
term to be escaped.
Switch to a whitelist of characters that are definitely safe to leave
unquoted. This fixes the broken test introduced by the previous
patch.
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.
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.
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.
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.
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.
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.
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.
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.
`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.
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.
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.
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 "").
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.
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>
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.
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.
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.
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.
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.
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.
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).
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.
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.]
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.
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.
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.
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"
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.
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.
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.
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.
(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!)
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.
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.
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.
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.
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.
Authors and subjects can contain embedded, encoded control characters
like "\n" and "\t" that mess up display. Transform control characters
into spaces everywhere we display them in search and show.
We no longer use this, since we've lifted all interactive behavior to
the appropriate interactive entry points. Because of this,
`notmuch-tag' also no longer needs to return the tag changes list,
since the caller always passes it in.
This is similar to the previous commit, but applies to search.
Search is somewhat more complicated because its tagging operations can
also apply to a region. Hence, this lifts interactive prompting into
a helper function. This also takes advantage of the new ability to
provide a prompt to distinguish tagging a single thread from tagging a
region of threads.
This modifies all tagging operations in show to call
`notmuch-read-tag-changes' in their interactive specification to input
tag changes, rather than depending on lower-level functions to prompt
for tag changes regardless of their calling context.
Besides being more Elispy and providing a more consistent programmatic
API, this enables callers to provide two call site-specific pieces of
information: an appropriate prompt, and the set of visible tags. The
prompt lets us differentiate * from +/-. Providing visible tags
enables a more consistent user experience than retrieving the
(potentially different) tags from the database, and avoids a
round-trip to the CLI and database.
This modifies the interface of `notmuch-read-tag-changes' to take an
optional prompt string as well as a list of existing tags instead of a
query. This list of tags is used to populate the tag removal
completions and lets the caller compute these in a more
efficient/consistent manner than performing a potentially large or
complex query. This patch also updates the sole current caller of
`notmuch-read-tag-changes'.
The calling convention for `notmuch-tag' changed in commit 97aa3c06 to
take a list of tag changes instead of a &rest argument, but the call
from `notmuch-search-tag-all' still passed a &rest argument. This
happened to work for interactive calls because tag-changes would be
nil, so the `apply' call would pass only the query string to
`notmuch-tag' and simply omit the &optional tag-changes argument.
Currently notmuch-show looks at the prefix-arg directly via
current-prefix-arg. This changes it to use the interactive
specification.
One test (for elide-toggle functionality) set the prefix arg
directly. Update this test to set the new argument directly.
Change foreground color to `blue' like lines representing threads
with flagged messages in notmuch-search. Before tag `flagged' was
shown in notmuch-show buffers as image star on graphical frames while
there was no visible distinction to other flags on terminal frames.
This improves the function documentation for many interactive
commands, either by improving their documentation string where the
improvement also makes sense for programmatic use or by adding a
'notmuch-doc property where it doesn't.
For nearly all commands that support a prefix argument, this adds a
'notmuch-prefix-doc property to document their prefixed behavior This
omits prefix documentation for a few commands where I thought the
prefixed behavior was too obscure (or too complex to fit in one line).
Traditionally, function documentation strings are intended primarily
for programmers, rather than users. They're written from the
perspective of calling the function, not interactively invoking it.
They're only ever displayed along with the function prototype (and
often refer to argument names). And built-in help commands like
`describe-bindings' show the name of the command, not its
documentation.
The notmuch help system is like `describe-bindings', but tries to be
more user-friendly by displaying documentation strings, rather than
Elisp command names. For most commands, this is fine, but for some
the "programmer description" is inappropriate for interactive use.
This is particularly noticeable for commands that take an optional
prefix argument.
This patch adds support for two symbol properties: notmuch-doc and
notmuch-prefix-doc, which let a command override its interactive
documentation and provide separate documentation for its prefixed
invocation. If notmuch-prefix-doc is present, we add an extra line to
the help giving the prefixed key sequence along with the documentation
for the prefixed command.
Like `notmuch-mua-new-forward-message', this is meant to be invoked
programmatically by something that can provide a reasonable query
string.
In fact, `notmuch-mua-new-reply's interactive specification didn't
match its arguments, so it wouldn't have worked interactively.
`notmuch-mua-new-forward-message' must be called from a buffer
containing a raw RFC2822-formatted message to forward. Hence, it's
intended to be invoked programmatically through something else that
sets up this buffer (like `notmuch-show-forward-message'), not
interactively.
Remove its interactive specification and update the documentation
string to mention the requirements on the current buffer.
In the recent changes for search order handling the default-value of
notmuch-search-oldest-first was used. However, default-value needs a
symbol so the symbol-name needs to be quoted.
This missing quote was causing strange sort-orders in some cases.
The only user-visible effect of this should be that "G" now works in
show mode (previously it was unbound for no apparent reason).
This shared keymap gives us one place to put global commands, which
both forces us to think about what commands should be global, and
ensures their bindings can't diverge (like the missing "G" in show).
This converts notmuch-help to use map-keymap for all keymap traversal.
This generally cleans up and simplifies construction of keymap
documentation, and also makes notmuch-help support anything that can
be in a keymap, including more esoteric stuff like multiple
inheritance.
This unifies the various refresh and poll-and-refresh functions we
have for different modes. Now all modes bind "=" and "G" (except
show, which doesn't bind "G" for some reason) to
`notmuch-refresh-this-buffer' and
`notmuch-poll-and-refresh-this-buffer', respectively.
Since notmuch-hello doesn't need this any more, we can remove this
hack. This also eliminates `notmuch-search-quit', so now all modes
bind "q" to `notmuch-kill-this-buffer'.
Since there is now no difference between notmuch-hello-search and
notmuch-search when called interactively, bind "s" to notmuch-search
in notmuch-hello-mode-map. Now all modes bind "s" this way.
Previously, we refreshed hello when the user quit a search that was
started from hello. This is fine assuming purely stack-oriented
buffer use, but is quite fragile and requires hacks to search.
This replaces that logic with a new approach that refreshes hello
whenever the user switches to the hello buffer, regardless of how this
happens.
Previously, if `notmuch-search' was called interactively (bound to "s"
in search and show, but not hello), it would always use newest-first.
However, `notmuch-hello-search' (bound to "s" in hello) and
`notmuch-hello-widget-search` would call it with the user-configured
sort order. This inconsistency seems unintentional, so change
`notmuch-search' to use the user-configured sort order when called
interactively.
When text/html parts include images as multipart/related and the
text/plain alternative is used these images can be completely hidden
with no easy way to access them or even find out that they are there.
Make notmuch-show-insert-part-multipart/related add buttons for all
parts, the first one visible the rest hidden.
The lazy part handler had a bug that it allowed the button to be
toggled to be specified. During toggling it needs to save and restore
the text-properties for the button but it actually saved the text
properties at point rather than from the button.
In almost all cases this didn't matter as as point had the same text
properties as the button. However, it is a bug and did cause incorrect
behaviour in some cases: see id:87txhz14z6.fsf@qmul.ac.uk for details.
When composing a reply, notmuch-mua-reply attempts to cite the
the original message by inserting it before the user signature, if
one is present. The existing method used to search the signature
separator backward from the end of the buffer and then move one
line up. In case of variable `message-signature-insert-empty-line'
being nil this caused point to go to the beginning of
'--text follows this line--'
separator line, and citation was inserted there.
This change checks the value of `message-signature-insert-empty-line'
and doesn't move point if that is nil. Additional narrowing to
the body region ensures that point never goes to the separator line
(or beyond).
`message-signature-setup-hook' or `message-setup-hook' may already have
added some other content to the message body, therefore using simply
(message-goto-body) to move point to the beginning of body might lead
to unexpected results.
Original patch from "Geoffrey H. Ferrari", continued with iterations
from Jani and Mark.
In reply, insert quotable parts using notmuch-show-insert-bodypart
instead of calling notmuch-mm-display-part-inline directly to render
the quoted parts as they are rendered in show view.
We use a temp buffer to not leak text properties from the show
renderer into the reply. This way we also don't need to worry about
narrowing or point placement. Credits to Mark Walters
<markwalters1009@gmail.com> and Austin Clements <amdragon@MIT.EDU> for
getting this part straight.
The notable change is that replies to text/calendar parts quote the
pretty printed output of icalendar-import-buffer rather than the ugly
raw vcalendar.
notmuch-show.el and notmuch.el had 3 duplicate, identical functions:
notmuch-foreach-mime-part, notmuch-count-attachments and
notmuch-save-attachments. Now these functions in notmuch-show.el
are replaced with declare-functions pointing to "notmuch"(.el).
Notmuch puts attachments in as declared content-type except when the
content-type is application/octet-stream it tries to guess the type
from the filename/extension. This means that viewing a pdf (for
example) which is sent as application/octet-strem invokes the pdf
viewer rather than just offering to save the part.
Recent changes to the attachment handling (commit 1546387d) changed
(broke) this. This patch stores the calculated mime-type with the part
and changes the attachment part handlers can use it instead.
Recently notmuch-hello was converted to use batch count. However, it
seems that several people run different versions of notmuch-emacs and
notmuch-cli so this batch makes emacs fail with an error message if
--batch is not available in the CLI.
Amended by: db
Notmuch cli provides all structured data previously provided
in json format now in s-expression format, rendering all current
json functionality obsolete.
This switches `notmuch-mua-reply' and `notmuch-query-get-threads' to
the S-exp format. These were the last two uses of the JSON format in
the Emacs frontend.
This is just like `notmuch-call-notmuch-json', but parses S-expression
output. Note that, also like `notmuch-call-notmuch-json', this
doesn't consider trailing data to be an error, which may or may not be
what we want in the long run.
This removes the v command, since we now have much nicer part commands,
and deprecates the underlying notmuch-show-view-all-mime-parts. This
also means that people who try using the old unprefixed 'v' command on
a part button will no longer be greeted by ALL of their parts popping
up.
Previously the query string for piping a message to a command was
"Pipe message to command: " regardless of whether the function was
called with a prefix argument (which pipes all open messages to the
command). This patch modifies the `interactive' command to reflect
this.
This adds the actual code to do the lazy insertion of hidden parts.
We use a memory inefficient but simple method: when we come to insert
the part if it is hidden we just store all of the arguments to the
part insertion function as a button property. This means when we want
to show the part we can just resume where we left off.
One thing is that we can't tell if a lazy part will produce text until
we try to render it so when unhiding a part we check to see if it
rendered; if not we invoke the default part handler (e.g. an external
viewer).
Also, we would like to insert the lazy part at the start of the line
after the part button. But if this line has some text properties
(e.g. the colours for a following message header) then the lazy part
gets these properties. Thus we start at the end of the part button
line, insert a newline, insert the lazy part, and then delete the
extra newline at the end of the part.
Previously, whether a part was hidden or shown was recorded in the
invisibility/visibility of the part overlay. Since we are going to
have lazily rendered parts with no overlay store the hidden/shown
state in the part button itself.
Additionally, in preparation for the invisible part handling move the
actual hiding of the hidden parts to insert-bodypart from
create-part-overlays.
Finally, we will need to know whether a part-insertion has done
anything (it won't if the invisible part cannot be displayed by emacs)
so we slightly rejig the code order in
notmuch-show-toggle-part-invisibility to make it easier for the
function to set an appropriate return value.
Previously each of the part insertion handlers inserted the part
button themselves. Move this up into
notmuch-show-insert-bodypart. Since a small number of the handlers
modify the button (the encryption/signature ones) we need to pass the
header button as an argument into the individual part insertion
handlers. However, the declared-type argument was only used for the
text for the part buttons we can now omit it.
The patch is large but mostly simple. The only things of note are that
we let the text/plain handler applies notmuch-wash to the whole part
including the part button. In particular, notmuch-wash removes leading
blank lines from a text/plain part, but since the button is counted as
part of the part this does not happen with text/plain buttons that
have a button. This is probably a bug in notmuch-wash but changing it
does make several tests fail (that rely on this blank line) so, for
the moment, keep the old behaviour.
Earlier patches have moved the handling of wash fake inline patch
parts to insert-bodypart so we can drop the function
notmuch-show-insert-part-inline-patch-fake-part
Occasionally, when the user killed the search buffer when the CLI
process was still running, Emacs would run the
notmuch-start-notmuch-sentinel sentinel twice. The first call would
process and delete the error output file and the second would fail
with an "Opening input file: no such file or directory, ..." error
when attempting to access the error file.
Emacs isn't supposed to run the sentinel twice. The reason it does is
rather subtle (and probably a bug in Emacs):
1) When the user kills the search buffer, Emacs invokes
kill_buffer_processes, which sends a SIGHUP to notmuch, but doesn't do
anything else. Meanwhile, suppose the notmuch search process has
printed some more output, but Emacs hasn't consumed it yet (this is
critical and is why this error only happens sometimes).
2) Emacs gets a SIGCHLD from the dying notmuch process, which invokes
handle_child_signal, which sets the new process status, but can't do
anything else because it's a signal handler.
3) Emacs returns to its idle loop, which calls status_notify, which
sees that the notmuch process has a new status. This is where things
get interesting.
3.1) Emacs guarantees that it will run process filters on any
unconsumed output before running the process sentinel, so
status_notify calls read_process_output, which consumes the final
output and calls notmuch-search-process-filter.
3.1.1) notmuch-search-process-filter checks if the search buffer is
still alive and, since it's not, it calls delete-process.
3.1.1.1) delete-process correctly sees that the process is already
dead and doesn't try to send another signal, *but* it still modifies
the status to "killed". To deal with the new status, it calls
status_notify. Dun dun dun. We've seen this function before.
3.1.1.1.1) The *recursive* status_notify invocation sees that the
process has a new status and doesn't have any more output to consume,
so it invokes our sentinel and returns.
3.2) The outer status_notify call (which we're still in) is now done
flushing pending process output, so it *also* invokes our sentinel.
This patch addresses this problem at step 3.1.1, where the filter
calls delete-process, since this is a strange and redundant thing to
do anyway.
Previously, when the user killed the search buffer before the CLI
search process had completed, we would report the signal sent by Emacs
to kill the CLI to the user as an error. Fix this by only reporting
error exits if the process buffer is still live. We still report
stderr output regardless in case stderr output was relevant to why the
user killed the search buffer (such as a wrapper script being stuck).
This commit adds an extra button at the end of the search entries that
allows deleting that individual search from the history. A short
confirmation («y» or «n») is made before taking action.
The button to clear the recent searches in notmuch-hello is easy to
press accidentally while moving around the, clearing potentially
useful searches with no way of recovering them.
Previously, we simply called pushnew to add :notmuch-part to the
front-sticky and rear-nonsticky text property lists. This works if
these are nil or lists, but they can also have the value t, meaning
that all properties are front-sticky/rear-nonsticky. In this case,
pushnew will signal an error because t is not a list. We never set
these properties to t ourselves, but since we apply these property
changes over arbitrary renderer output, we have to deal with this
possibility.
Several function docstrings refer to behaviour in docstrings that is
really controlled by notmuch-archive-tags. Add cross references, and
replace hardcoding.
These functions refer to default values of variables, but it seems
less confusing and less likely to get out of date to just allow the
user to follow the help cross-reference links.
I found several places where a setq is immediately followed by a let
or a let*. This seems to be the pessimal combination, with the
implicit scope of the setq combined with the extra indentation of the let.
I combined these cases into a single let* which I think is easier to read.
I can't see any benefit to the funcall, and it looks like the result
of cut-and-paste from some code that actually used a variable for the
function to call.
In addition to being the Right Thing to do, this noticeably improves
the time taken to display the first page of search results, since it's
roughly an order of magnitude faster than the JSON parser.
Interestingly, it does *not* significantly improve the time to
completely fill a large search buffer because for large search
buffers, the cost of creating author invisibility overlays and
inserting text (which slows down with more overlays) dominates.
However, the time required to display the first page of results is
generally more important to the user experience.
This provides the same interface as the streaming JSON parser, but
reads S-expressions incrementally. The only difference is that the
`notmuch-sexp-parse-partial-list' helper does not handle interleaved
error messages (since we now have the ability to separate these out at
the invocation level), so it no longer takes an error function and
does not need to do the horrible resynchronization that the JSON
parser had to.
Some implementation improvements have been made over the JSON parser.
This uses a vector instead of a list for the parser data structure,
since this allows faster access to elements (and modern versions of
Emacs handle storage of small vectors efficiently). Private functions
follow the "prefix--name" convention. And the implementation is much
simpler overall because S-expressions are much easier to parse.
Previously, search started the async notmuch process directly. Now,
it uses `notmuch-start-notmuch'. This simplifies the process sentinel
a bit and means that we no longer have to worry about errors
interleaved with the JSON output.
We also update the tests of Emacs error handling, since the error
output is now separated from the search results buffer.
This provides a new notmuch-lib utility to start an asynchronous
notmuch process that handles redirecting of stderr and checking of the
exit status. This is similar to `notmuch-call-notmuch-json', but for
asynchronous processes (and it leaves output processing to the
caller).
Since the part commands are no longer tied to a button, but can be
applied with point anywhere within a part, bind the part commands
keymap to "." everywhere in the show buffer. This lets you save or
view parts without having to navigate to the part button, and is
particularly useful for parts that have no button.
This removes the un-prefixed MIME part commands from the part button
keymap, but that's okay because those clashed in annoying ways with
show buffer bindings like "s" for search. RET on part buttons is
unaffected, which is the most important part button binding.
This unifies the part button actions and the underlying part action
functions into single interactive command that simply applies to the
part containing point using the just-added part p-list text property
instead of button properties. Since all part actions can be performed
by applying the appropriate mm function to an mm-handle, this patch
abstracts out the creation of mm handles, making the implementations
of the part commands trivial. This also eliminates our special
handling for part save in favor of using the appropriate mm function.
This necessarily modifies the way we handle the default part button
action, but in a way that does not change the meaning of the
notmuch-show-part-button-default-action defcustom.
Since these commands are no longer specific to buttons, this patch
eliminates the extra metadata stored with each button. This also
eliminates one rather special-purpose macro for a collection of
general purpose part handling utilities.
This is similar to what we already do with the message p-list, though
we apply the part's text property to the whole part's text, in
contrast with the message p-list, which is (rather obscurely) only
applied to the first character.
Previously, we lost any text properties applied to part buttons or
wash buttons when they were toggled because `insert' directly copies
the text properties of the string being inserted. Fix this by
capturing the properties applied to the button beforehand and
re-applying them after inserting the new text.
For such a simple regexp, this was broken in a very complicated way.
The intent was to strip the newline (and potentially other whitespace)
off the end of the error string so there wasn't an extra newline in
the error signal. However, the regexp was deeply dependent on the
active syntax table and the subtleties of $. We didn't notice this
because all notmuch major modes put ?\n in the whitespace class, which
makes this behaved as intended: the "\\s " matches all newlines, but
by matching the newline character, causes the $ *not* to match
*except* where it matched the empty string at the very end of the
string, which was not followed by a newline.
However, if the syntax table declares ?\n to be non-whitespace
(lisp-mode declares it as endcomment, and is likely to be the mode
you're in when testing functions), then this regexp behaves completely
differently, matching trailing spaces at the end of every line within
the string.
The solution is to say what we mean for whitespace *and* to switch
from $ to \', which matches only the end of the string, rather than
the end of each line. Both are necessary or this will strip away
interior newlines, which is not what we want.
Previously, notmuch-show-view-part overrode the function binding of
mm-show-part to redirect it to notmuch-show-save-part to get notmuch's
default file name handling in case mm-display-part decided to fall
back to saving the part. In addition to being messy, this depended on
the now-deprecated dynamic binding behavior of flet.
This patch removes the mm-show-part override in favor of passing the
file name in to mm-show-part the way it expects, so we get its default
file name handling. It's not clear why we didn't do this before;
mm-show-part has supported default file names since at least Emacs
23.1.
Previously, we simply byte compiled each Elisp source file
independently. This is actually the wrong thing to do and can lead to
issues with macros and performance issues with substitutions because
1) when the byte compiler encounters a (require 'x) form, it will load
x.elc in preference to x.el, even if x.el is newer, and as a result
may load old macro and substitution definitions and 2) if we update a
macro or substitution definition in one file, we currently won't
re-compile other files that depend on the file containing the
definition.
This patch addresses these problems by computing make dependency rules
from the (require 'x) forms in the Elisp source files, which we inject
into make's dependency database.
Currently mime parts are basically handled based on their mime-type
with the exception of application/octet-stream parts. Deal with these
parts at the top level (notmuch-show-insert-bodypart).
This is needed later in the series as we need to put in a part button
for each part (which means knowing its mime type) while deferring the
actual insertion of the part.
Apparently Emacs provides a function to stringify errors properly.
Use this in the search sentinel where we have to do our own error
messaging, rather than assuming the first error argument will be the
descriptive string.
When compiling notmuch-tag.el there is a compile warning:
notmuch-tag.el:27:1:Warning: cl package required at runtime
Since we have decided to allow runtime use of cl we suppress this
warning by adding a tail comment to the file.
The support for emacs version 22 has not worked at least since
September 2011 when I attempted to use it. I expanded the support in
id:yf6ippgtbn0.fsf@taco2.nixu.fi but that was not enough and then I
found it easier to switch to emacs 23.
In case one wants to resurrect emacs 22 (or earlier!) support, pick
the changes from the patch email referenced above.
Added a customizable variable notmuch-address-selection-function
and the function with the same name to provide a way for user to
change the function called to do address selection.
By default the functionality is exactly the same as it has been so
far; completing-read is called with the same parameters as before.
Setting equivalent lambda expression in place of using
notmuch-address-selection-function function is done as follows:
(setq notmuch-address-selection-function
(lambda (prompt collection initial-input)
(completing-read prompt collection nil nil initial-input)))
For example drop-in replacement with ido-completing-read can be done
easily as an one alternative to the default.
Some (declare-function ...) definitions were drifted away from the
actual (defun ...)'s. To find the drifts and to verify changes
the following command line was used:
$ emacs --batch -L emacs --eval '(check-declare-directory "emacs")'
From a show buffer, notmuch-bbdb/snarf-from imports the sender into
bbdb. notmuch-bbdb/snarf-to imports all recipients. Newly imported
contacts are reported in the minibuffer / Messages buffer.
Both functions use the BBDB parser to recognize email address formats.
This modifies notmuch hello to use the new count --batch
functionality. It should give exactly the same results as before but
under many conditions it should be much faster. In particular it is
much faster for remote use.
The code is a little ugly as it has to do some working out of the
query when asking the query and some when dealing with the result.
However, the code path is exactly the same in both local and remote
use.
This has two benefits: unified error handling, and avoiding tramp's
hooking into shell-command-string.
This seems to be a fix for id:874nguxbvq.fsf@tu-dortmund.de
This patch extracts the rendering of tags in notmuch-show to
the notmuch-tag file.
This file introduces a `notmuch-tag-formats' variable that associates
each tag to a particular format. This variable can be customized
thanks to the work of Austin Clements. For example,
'(("unread" (propertize tag 'face '(:foreground "red")))
("flagged" (notmuch-tag-format-image tag "star.svg")))
associates a red foreground to the "unread" tag and a star picture to
the "flagged" tag.
Signed-off-by: Damien Cassou <damien.cassou@gmail.com>
This improves notmuch-combine-face-text-property to support both
applying faces to strings and to support combining the given face
under existing faces, rather than over.
Previously, notmuch-combine-face-text-property assumed that any
existing face properties of the modified text were already in face
list form. This was true as long as it was the only function
manipulating faces (since it always produced a list form face), but if
anything else has manipulated the face, it was more likely to be
either a face name or a face plist. It also didn't correctly handle
face lists as arguments, even though the doc string claimed it did.
This patch fixes notmuch-combine-face-text-property to handle all face
forms correctly by canonicalizing both the argument face and the
existing faces into list form. This also means we can set the face to
a simpler non-list form if there's no existing face.
Emacs has two button type objects: widgets (as used for saved searches
in notmuch-hello) and buttons as used by parts/citations and id links
in notmuch-show. These two behave subtly differently when clicked with
the mouse: widgets select the window clicked before running the
action, buttons do not.
This patch makes all of these behave the same: clicking always selects
the clicked window. It does this by defining a notmuch-button-type
supertype that the other notmuch buttons can inherit from. This
supertype binds the mouse-action to select the window and then
activate the button.
There is a bug in the current notmuch code with w3m and invisible
parts. w3m sets a keymap, and if we have a hidden [text/html] point
at the start of the following line still gets this w3m keymap which
causes some strange effects. For example, RET gives an error "No URL
at Point" rather than hiding the message, <down> goes to the next link
rather than just down a line.
These keybinding are also inconvenient when the text/html part is
displayed so we ask w3m not to install a keymap.
This is only likely to be a problem for emacs 23 as shr is preferred
as html renderer on emacs 24 (although the user can set the renderer
to w3m even on emacs 24).
This solution was suggested by Tomi Ollila <tomi.ollila@iki.fi>
We recently switched to popping up a buffer to report CLI errors, but
this was too intrusive, especially for transient errors and especially
since we made fewer things ignore errors. This patch changes this to
display a basic error message in the minibuffer (using Emacs' usual
error handling path) and, if there are additional details, to log
these to a separate error buffer and reference the error buffer from
the minibuffer message. This is more in line with how Emacs typically
handles errors, but makes the details available to the user without
flooding them with the details.
Given this split, we pare down the basic message and make it more
user-friendly, and also make the verbose message even more detailed
(and more debugging-oriented).
Now that the invisibility display of parts is present we no longer
need to force the display of all multipart/alternatives: users can
toggle them for themselves when needed.
This adds a button action to show hidden parts. In this version "RET"
toggles the visibility of any part which puts content in the buffer
(as opposed to attachments such as application/pdf).
The button is used to hide parts when appropriate (eg text/html in
multipart/alternative).
This makes notmuch-show-insert-bodypart add an overlay for any
non-trivial part with a button header (currently the first text/plain
part does not have a button). At this point the overlay is available
to the button but there is no action using it yet.
In addition the argument HIDE is passed down to
notmuch-show-insert-part-overlays to request that the part be hidden
by default but this is not acted on yet.
This just make notmuch-show-insert-part-header save the basic button
text for parts as an attribute. This makes it simpler for the button
action (added in a later patch) to reword the label as appropriate (eg
append "(not shown)" or not as appropriate).
Previously, all visibility in show buffers for headers, message
bodies, and washed text was specified by generating one or more
symbols for each region and creating overlays with their 'invisible
property set to carefully crafted combinations of these symbols.
Visibility was controlled not by modifying the overlays directly, but
by adding and removing the generated symbols from a gigantic buffer
invisibilty spec.
This has myriad negative consequences. It's slow because Emacs'
display engine has to traverse the buffer invisibility list for every
overlay and, since every overlay has its own symbol, this makes
rendering O(N^2) in the number of overlays. It composes poorly
because symbol-type 'invisible properties are taken from the highest
priority overlay over a given character (which is often ambiguous!),
rather than being gathered from all overlays over a character. As a
result, we have to include symbols related to message hiding in the
wash code lest the wash overlays un-hide parts of hidden messages. It
also requires various workarounds for isearch to properly open
overlays, to set up buffer-invisibility-spec for
remove-from-invisibility-spec to work right, and to explicitly refresh
the display after updating the buffer invisibility spec.
None of this is necessary.
This patch converts show and wash to use simple boolean 'invisible
properties and to not use the buffer invisibility spec. Rather than
adding and removing generated symbols from the invisibility spec, the
code now directly toggles the 'invisible property of the appropriate
overlay. This speeds up rendering because the display engine only has
to check the boolean values of the overlays over a character. It
composes nicely because text will be invisible if *any* overlay over
it has 'invisible t, which means we can overlap invisibility overlays
with abandon. We no longer need any of the workarounds mentioned
above. And it fixes a minor bug for free: now, when isearch opens a
washed region, the button text will update to say "Click/Enter to
hide" rather than remaining unchanged.
This slightly changes the output of an existing test since we now
report non-zero exits with a pop-up buffer instead of at the end of
the search results.
This checks for non-zero exit status from JSON CLI calls and pops up
an error buffer with stderr and stdout. A consequence of this is that
show and reply now handle errors, rather than ignoring them.
This provides library functions for unified handling of errors from
the notmuch CLI. Follow-up patches will convert some scattered error
handling to use this and add error handling where we currently ignore
errors.
Previously, if the input stream consisted only of an error message,
notmuch-json-begin-compound would signal a (wrong-type-argument
number-or-marker-p nil) error when reaching the end of the error
message. This happened because notmuch-json-scan-to-value would think
that it reached a value and put the parser into the 'value state.
Even after notmuch-json-begin-compound signaled the syntax error, the
parser would remain in this state and when the resynchronization logic
reached the end of the buffer, the parser would fail because the
'value state indicates that characters are available.
This fixes this problem by restoring the parser's previous state if it
encounters a syntax error.
Previously refreshing the notmuch show buffer did not remove overlays
which meant that if the user refreshed a message with images the
images would remain and then the new text was added after.
One might have guessed that erase-buffer would have removed them but
it seems not. Thus force the removal of overlays with remove-overlays.
Remove notmuch-folders which has been deprecated since
commit a466921760
Author: Carl Worth <cworth@cworth.org>
Date: Mon Apr 26 22:42:07 2010 -0700
emacs: Rip out all of the notmuch-folder code.
This lets us simplify the notmuch-saved-searches code slightly.
This function is also used by pick so split it out in preperation for
moving to lib. In fact, pick and show want a slightly different
combination of name and email on return so make the separated function
return them as a pair, and let show or pick extract the combination
they want from that.
The macro with-current-notmuch-show-message executes command
`notmuch show --format=raw id:...` which just outputs the contents
of the mail file verbatim (into temporary buffer). In case e.g. utf-8
locale is used the temporary buffer has buffer-file-coding-system as
utf-8. In this case Emacs converts the data to multibyte format, guessing
that input is in utf-8.
However, the "raw" (MIME) message may contain octet data in any other
8bit format, and as no (MIME-)content spesific handling to the message
is done at this point, conversion to other formats may lose information.
By setting coding-system-for-read 'no-conversion drops the conversion part
and makes this handle input as notmuch-get-bodypart-internal() does.
This marks the broken test in previous change fixed.
icalendar-import-buffer can fail by an error signal (which have been
witnessed) but according to its docstring it can also return nil
when failing (it returns t when succeeding).
Now that the error is caught by the caller of notmuch-show-inset-part-*
functions in case icalendar-import-buffer returns nil an explicit
error is signaled and unwind-protect takes care of deleting the
temporary file (just in case, it is usually not written to the fs yet).
notmuch-get-bodypart-content provides raw data to its caller so
that it can be stored verbatim whenever needed. icalendar functions
expect Emacs to do EOL conversion for the data given to these. Therefore
it the CRLF -> LF conversion is now done explicitly.
The calls to private functions icalendar--convert-ical-to-diary and
icalendar--read-element are replaced with call to public function
icalendar-import-buffer.
This regexp agrees with Xapian query syntax much more closely, though
we specifically disallow various cases that would be confusing in the
context of an email body (e.g., punctuation at the end of an id: link
is not considered part of the id: link because it's probably part of
the surrounding text).
In particular, this handles id: links that are not surrounded by
quotes much better, which stash is much more likely to generate now
that we don't quote id's that don't need to be quoted. It also
handles quoted id: links better.
We update the buttonization test to reflect the new pattern.
When inserting of email bodypart failes, insert a failure message
to the buffer (and continue) instead of halting the insertion of
the rest of that email thread in question.
This patch just renames the internal variables for the JSON parser now
it is no longer specific to search mode. It also fixes up the white
space after the previous patch. There should be no functional changes.
This patch splits out the incremental json parser into its own
function.
It moves the main logic of the parser to happen inside the parse
buffer rather than inside the results buffer, but makes sure all
results and all errors are displayed in the results buffer.
It also changes the local parser variables from being buffer
local to the results buffer to being buffer local to the parse buffer,
and sets them up automatically so the caller does not need to.
Finally to keep the diff small this patch does not fix the whitespace,
nor complete the code movement (these are done in subsequent patches)
but it should contain all the functional changes.
Currently, we only properly escape stashed id queries, but there are
other places where the Emacs UI constructs queries for boolean terms.
Since this escaping function is meant to be used in other places, it
avoids escaping strings that don't need escaping.
Emacs 24's mm-shr HTML email renderer fails to load gnus-art before
referencing gnus-inhibit-images, resulting in a void-variable error
when notmuch attempts to render an HTML email with inline images.
This works around this bug by advising mm-shr to load gnus-art.
mm-shr is the only function outside of gnus-art itself that references
gnus-inhibit-images, so this workaround should be correct. If this
ever changes, hopefully they will have fixed this bug upstream first.
This fixes the "Rendering HTML mail with images" test for Emacs 24.
notmuch-hello (called also through notmuch-hello-update, bound to '='
by default) tries to find the widget under or following point before
refresh, and put the point back to the widget afterwards. The code has
grown quite complicated, and has at least the following issues:
1) All the individual section functions have to include code to
support point placement. If there is no such support, point is
dropped to the search box. Only saved searches and all tags
sections support point placement.
2) Point placement is based on widget-value. If there are two widgets
with the same widget-value (for example a saved search with the
same name as a tag) the point is moved to the earlier one, even if
point was on the later one.
3) When first entering notmuch-hello notmuch-hello-target is nil, and
point is dropped to the search box.
Moving the point to the search box is annoying because the user is
required to move the point before being able to enter key bindings.
Simplify the code by removing all point placement based on widgets, as
it does not work properly, and trying to fix that would unnecessarily
complicate the code.
Save current line and column before refresh, and restore them
afterwards. Sometimes, if notmuch-show-empty-saved-searches is nil,
and the refresh adds or removes saved searches from the list, this has
the appearance of moving the point relative to the nearest
widgets. This is a much smaller and less frequent problem than the
ones listed above.
Since marking a message as read can now be a user customized set of
tag changes, make reversing this easier. Allow a prefix argument to
notmuch-show-mark-read to reverse the marking as read, similar to the
unarchiving in notmuch-show-archive-message.
While at it, update the relevant documentation to match that of other
automatic tagging (i.e. archive and reply).
Since archiving a thread can now be a user customized set of tag
changes, make reversing this easier. Allow a prefix argument to
notmuch-search-archive-thread to reverse the archiving, similar to the
unarchiving in notmuch-show-archive-message.
Add support for customization of the tag changes that are applied when
a message or a thread is archived. Instead of hard-coded removal of
the "inbox" tag, the user can now specify a list of tag changes to
perform.
* emacs/notmuch.el (notmuch-search-mode):
`notmuch-search-tag-all' currently uses the current query string
instead of `notmuch-search-find-thread-id-region-search', which
might cause a race condition.
The `notmuch-show-mark-read-tags' lists tags that are to be applied when
message is read. By default, the only value is "-unread" which will remove
the unread tag. Among other uses, this variable can be used to stop
notmuch-show from modifying tags when message is shown (by setting the
variable to an empty list).
Previously, notmuch-show-previous-message would move to the beginning
of the message before the message containing point. This patch makes
it instead move to the previous message *boundary*. That is, if point
isn't already at the beginning of the message, it moves to the
beginning of the current message. This is consistent with
notmuch-show-next-message, which can be thought of as moving to the
next message boundary. Several people have expressed a preference for
this.
The recent change to use json for notmuch-search.el introduced a bug
in the code for keeping position on refresh. The problem is a
comparison between (plist-get result :thread) and a thread-id returned
by notmuch-search-find-thread-id: the latter is prefixed with
"thread:"
We fix this by adding an option to notmuch-search-find-thread-id to
return the bare thread-id. It appears that notmuch-search-refresh-view
is the only caller of notmuch-search that supplies a thread-id so this
change should be safe (but could theoretically break users .emacs
functions).
Previously, the Emacs byte compiler produced the warning
the function `remove-if-not' might not be defined at runtime.
because we only required cl at compile-time (not runtime). This fixes
this warning by requiring cl at runtime, ensuring that the definition
of remove-if-not is available.
The pipe message function (when used with a prefix) uses a search of
the form "id:<id1> or id:<id2>" etc. Since the user says precisely
which messages are wanted by opening them it should not use excludes.
In commit 5d0883e the function notmuch-search-next-thread was changed.
In particular it only goes to the next message if there is a next
message. This breaks notmuch-show-archive-thread-then-next. Fix this
by going to the "next" message whenever we are on a current message.
At this point, the only remaining functions that don't support
multi-line search result formats are the thread navigation functions.
This patch fixes that by rewriting them in terms of
notmuch-search-result-{beginning,end}.
This changes the behavior of notmuch-search-previous-thread slightly
so that if point isn't at the beginning of a result, it first moves
point to the beginning of the result.
Previously we ignored any notmuch-search-result-format customizations
for tag formatting because we needed to be able to parse back in the
result line and update the tags in place. We no longer do either of
these things, so we can allow customization of this format.
(Coincidentally, previously we still allowed too much customization of
the tags format, since moving it earlier on the line or removing it
from the line would interfere with the tagging mechanism. There is
now no problem with doing such things.)
Since the result object contains everything that the other text
properties recorded, we can remove the other text properties and
simply look in the plist of the appropriate result object.
This simplifies the traversal of regions of results and eliminates the
need for save-excursions (which tend to get in the way of maintaining
point when we make changes to the buffer). It also fixes some strange
corner cases in the old line-based code where results that bordered
the region but were not included in it could be affected by region
commands. Coincidentally, this also essentially enables multi-line
search result formats; the only remaining non-multi-line-capable
functions are notmuch-search-{next,previous}-thread, which are only
used for interactive navigation.
Now that we keep the full thread result object, we can refresh a
result after any changes by simply deleting and reconstructing the
result line from scratch.
A convenient side-effect of this wholesale replacement is that search
now re-applies notmuch-search-line-faces when tags change.
Previously, tag-based search result highlighting was done by creating
an overlay over each search result. However, overlays have annoying
front- and rear-advancement semantics that make it difficult to
manipulate text at their boundaries, which the next patch will do.
They also have performance problems (creating an overlay is linear in
the number of overlays between point and the new overlay, making
highlighting a search buffer quadratic in the number of results).
Text properties have neither problem. However, text properties make
it more difficult to apply multiple faces since, unlike with overlays,
a given character can only have a single 'face text property. Hence,
we introduce a utility function that combines faces into any existing
'face text properties.
Using this utility function, it's straightforward to apply all of the
appropriate tag faces in notmuch-search-color-line.
notmuch-message-mark-replied used "apply" to change message tags
according to notmuch-message-replied-tags after sending a reply. This
works if the latter is a single-element list. But with the recently
changed format of tag changes, it breaks for multiple-element lists.
Use "funcall" to properly pass the list of tag changes as a single
argument.
The JSON format eliminates the complex escaping issues that have
plagued the text search format. This uses the incremental JSON parser
so that, like the text parser, it can output search results
incrementally.
This slows down the parser by about ~4X, but puts us in a good
position to optimize either by improving the JSON parser (evidence
suggests this can reduce the overhead to ~40% over the text format) or
by switching to S-expressions (evidence suggests this will more than
double performance over the text parser). [1]
This also fixes the incremental search parsing test.
This has one minor side-effect on search result formatting.
Previously, the date field was always padded to a fixed width of 12
characters because of how the text parser's regexp was written. The
JSON format doesn't do this. We could pad it out in Emacs before
formatting it, but, since all of the other fields are variable width,
we instead fix notmuch-search-result-format to take the variable-width
field and pad it out. For users who have customized this variable,
we'll mention in the NEWS how to fix this slight format change.
[1] id:"20110720205007.GB21316@mit.edu"
This parser is designed to read streaming JSON whose structure is
known to the caller. Like a typical JSON parsing interface, it
provides a function to read a complete JSON value from the input.
However, it extends this with an additional function that
requires the next value in the input to be a compound value and
descends into it, allowing its elements to be read one at a time
or further descended into. Both functions can return 'retry to
indicate that not enough input is available.
The parser supports efficient partial parsing, so there's no need to
frame the input for correctness or performance.
The bulk of the parsing is still done by Emacs' json.el, so any
improvements or optimizations to that will benefit the incremental
parser as well.
Currently only descending into JSON lists is supported because that's
all we need, but support for descending into JSON objects can be added
in the future.
Rather than passing lots of arguments and then further passing those
to `notmuch-search-insert-field', pass a plist containing all of the
search result information. This plist is compatible with the JSON
format search results.
This is a simpler place to do this, since we can avoid any point
motion and hence any save-excursions in
`notmuch-search-process-filter', which in turn lets us put all of the
search-target logic outside of any save-excursions.
`notmuch-search-show-{result,error}' are now responsible for their own
point motion.
`notmuch-search-process-filter' could use some reindentation after
this, but we're about to rewrite it entirely, so we won't bother.
This removes the last bit of direct output from the parsing function.
With the parser now responsible solely for parsing, we can swap it out
for another parser.
Previously, much of the display of search lines was done in the same
function that parsed the CLI's output. Now the parsing function only
parses, and notmuch-search-show-result fully inserts the search result
in the search buffer.
This introduces a variable to control after how many characters a line
is wrapped by notmuch-wash-wrap-long-lines (still wrapping at the
window width if it is lower).