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).
Previously the elide messages code got the entire-thread from
notmuch-show.c and then threw away all non-matching messages. This
version calls notmuch-show.c without the --entire-thread flag so
it never receives the non-matching messages in the first place.
This makes it substantially faster.
Allow the user to pipe the attachment somewhere. Bound to '|' on the
attachment button.
Signed-off-by: Jameson Graef Rollins <jrollins@finestructure.net>
Previously, the timestamp at the beginning of the FCC unique maildir
name was derived incorrectly, thanks to an integer overflow. This
changes the derivation of timestamp to use a float, and so will get
the number correct at least until 2038. (It is still formatted with
"%d" so it will show up as an integer.) Should we need to change it in
the next 26 years to take the unix millenium into account, it will be
invisible to users.
This change is mostly a question of consistency, since the unique name
is arbitrary anyway. But since most people use timestamps, and that was
the original intention here as well, we might as well.
Signed-off-by: Jesse Rosenthal <jrosenthal@jhu.edu>
It was decided in the thread starting at [0] that it is okay for
notmuch to use 'cl runtime functions. However, by default, these
produce byte compiler warnings. This suppresses those using
file-local variables.
[0] id:"m262g864dz.fsf@wal122.wireless-pennnet.upenn.edu"
When mail message is read from emacs, the message structure
obtained may contain parts which have content included
(`text/plain` for example) and other parts where content is not
included (`text/html` for example).
In case content is included, the string is already available in
emacs' internal format and therefore mm-... functions should not
attempt to do further decoding for the data in temp buffer
provided for it.
Currently when reply buffer is created,
notmuch-mm-display-part-inline () is used to provided quoted reply
content. This change makes the mm-... functions called by it use
'gnus-decoded as charset whenever the content is already available.
File .../emacs-23.3/lisp/gnus/mm-uu.el mentions:
"`gnus-decoded' is a fake charset, which means no further decoding."
The customization widget referred to a non-existing function
`notmuch-hello-insert-query-list'. The patch changes it to the
correct one - `notmuch-hello-insert-searches'. The relevant test is
fixed now.
Sometimes, notmuch reply outputs something to stderr, for example:
"Failed to verify signed part: Cannot verify multipart/signed part:
unsupported signature protocol". When this happens, replying in emacs
fails, because emacs cannot parse the error message as JSON.
This patch causes emacs to ignore stderr when reading reply from
notmuch.
Introduce a new defcustom notmuch-mua-compose-in that allows users to
specify where new mails are composed, either in the current window or
in a new window or frame.
Signed-off-by: Jameson Rollins <jrollins@finestructure.net>
Quote non-text parts nicely by displaying them with mm-display-part
before calling message-cite-original to quote them. HTML-only emails
can now be quoted correctly. We re-use some code from notmuch-show
(notmuch-show-mm-display-part-inline), which has been moved to
notmuch-lib.el.
Mark the test for this feature as not broken.
The main change here is to modify argument parsing so as to not force
tag-changes to be a list, and to let notmuch-tag handle prompting the
user when required. doc strings are also updated and cleaned up.
The main change here is to modify argument parsing so as to not force
tag-changes to be a list, and to let notmuch-tag handle prompting the
user when required. doc strings are also updated and cleaned up.
notmuch-tag is extended to accept various formats of the tag changes.
In particular, user prompting for tag changes is now incorporated
here, so it is common for modes.
The tag binary and the notmuch-{before,after}-tag-hooks are only
called if tag changes is non-nil.
In all cases tag-changes is returned as a list.
Tagging functions are used in notmuch.el, notmuch-show.el, and
notmuch-message.el. There are enough common functions for tagging
that it makes sense to put them all in their own library.
No code is modified, just moved around.
When using the spacebar to scroll through a thread, hitting 'space'
when the bottom of the last message is visible should take the cursor
to the end of the buffer rather than immediately archiving the thread
and moving to the next thread.
Currently emacs show does not open matching but excluded
messages. This is normally the desired behaviour but is probably not
ideal if only excluded messages match. This patch opens all the
matching (necessarily excluded) messages in this case and goes to the
first one.
A previous patch [0] replaced blank subject lines with '[No Subject]'
in search and show mode. Apparently this was needed to circumvent
some bug in the printing code, but there was no need for it search or
show, and it is definitely not desirable, so we undo it here (a revert
is no longer feasible). We should not be modifying strings in the
original message without good reason, or without a clear indication
that we are doing so, neither of which apply in this case. For
further discussion see [0].
[0] id:"1327918561-16245-3-git-send-email-dme@dme.org"
No functional change here. The help message previously referred to
the "delete" tag, but "deleted" is now preferred, so hopefully this
will reduce any potential confusion.
The new message exclude functionality will hide tags that only exist
on excluded messages. However, one might very well want to manually
modify excluded tags. This makes sure tags from excluded messages are
always available in tab completion.
This patch removes trailing spaces in notmuch-hello view.
A side effect of this change is that tag/query buttons no longer
include a space at the end. This means that pressing RET when the
point is at the first character after the tag/query button no longer
works (note that this is the standard behavior for buttons). We may
change this behavior in the future (without adding trailing spaces
back) if people would find this change inconvenient.
Show has to set --exclude=false to deal with cases where it is asked
to show a single excluded message. It uses JSON so it can easily pass
the exclude information to the user.
In the new reply code, the References header gets inserted by
message.el using a function called message-shorten-references. Unlike
all the other header-inserting functions, it doesn't put a newline
after the header, causing the next header to end up on the same
line. In our case, this header happened to be User-Agent, so it's hard
to notice. This is probably a bug in message.el, but we need to work
around it.
This fixes the problem by wrapping message-shorten-references in a
function that inserts a newline after if necessary. This should
protect against the message.el bug being fixed in the future.
Bug 1: Replying from alternate addresses
----------------------------------------
The reply code was inconsistent in its use of symbols and strings for
header names being passed to message.el functions. This caused the
From header to be lookup up incorrectly, causing an additional From
header to be added with the user's primary address instead of the
correct alternate address.
This is fixed by using symbols everywhere, i.e. never using strings
for header names when interacting with message.el.
This change also removes our use of `mail-header`, since we don't use
it anywhere else, and using assq makes it clear how the header lists
are expected to work.
Bug 2: Duplicate headers in emacs 23.2
--------------------------------------
The message.el code in emacs 23.2 assumes that header names will
always be passed as symbols, so our use of strings caused
problems. The symptom was that on 23.2 (and presumably on earlier
versions) the reply message would end up with two of some headers.
Converting everything to symbols also fixes this issue.
Previously, this function took an argument called "message-id", even
though it was a general query, rather than a message ID. This changes
it to "query".
This adds a lib function to turn a message ID into a properly escaped
message ID query and uses this function wherever we previously
hand-constructed ID queries. Wherever this new function is used,
documentation has been clarified to refer to "id: queries" instead of
"message IDs".
This fixes the broken test introduced by the previous patch.
The function notmuch-match-content-type was comparing content types
case sensitively. Fix it so it tests case insensitively.
This fixes a bug where emacs would not include any body when replying
to a message with content-type TEXT/PLAIN.
Use the new JSON reply format to create replies in emacs. Quote HTML
parts nicely by using mm-display-part to turn them into displayable
text, then quoting them with message-cite-original. This is very
useful for users who regularly receive HTML-only email.
Use message-mode's message-cite-original function to create the
quoted body for reply messages. In order to make this act like the
existing notmuch defaults, you will need to set the following in
your emacs configuration:
message-citation-line-format "On %a, %d %b %Y, %f wrote:"
message-citation-line-function 'message-insert-formatted-citation-line
The tests have been updated to reflect the (ugly) emacs default.
In X, Emacs distinguishes the tab key, which produces a 'tab event;
from C-i, which produces a ?\t event. However, in a terminal, these
are indistinguishable and only produce a ?\t event. In order to
simplify things, Emacs automatically translates from 'tab to ?\t (see
"Function key translations" in M-x describe-bindings), so functions
only need to be bound to ?\t to work in all situations.
Previously, the search tab completion code usedq (kbd "<tab>"), which
produced the event sequence [tab], which only matched the 'tab event
and hence only worked in X. This patch changes it to (kbd "TAB"),
which matches the general ?\t event and works in all situations.
The reply MML quoting added in commit ae438cc unintentionally MML
quotes also the signature/encryption MML tags added via
message-setup-hook, causing the reply not to be signed/encrypted.
MML quote just the original message in the temp buffer before
inserting it to the message buffer, to not interfere with message mode
hooks or message construction in general.
See [1] and [2] for bug reports.
Thanks to Tim Bielawa <tbielawa@redhat.com> for testing.
[1] id:"87hay78x6l.fsf@wyzanski.jamesvasile.com"
[2] id:"1330812262-28272-1-git-send-email-tbielawa@redhat.com".
Signed-off-by: Jani Nikula <jani@nikula.org>
This is a small change to make notmuch.el ignore excluded matches. In
the future it could do something better like add a button for
rerunning the search with the excludes (particularly if nothing
matches with the excludes) or having them invisible and allowing the
visibility to be toggled.
Show mode will recognize the exclude flag by not opening excluding
messages by default, and will start at the first matching non-excluded
message. If there are no matching non-excluded messages it will go to
the first matching (necessarily excluded) message.
After retrieving gpg key retain show buffer state like in
all other operations (i.e. no other calls to notmuch-show-refresh-view
provides optional reset-state argument).
Emacs MUA keeps current message under cursor instead of going first
open message(possibly marking it read).
This patch makes the notmuch-hello screen fully customizable
by allowing the user to add and remove arbitrary sections. It
also provides some convenience functions for constructing sections,
e.g. showing the unread message count for each tag.
This is done by specifying a list of functions that will be run
when notmuch-hello is invoked.
It is not clear whether the term "thread" refers to the thread in the
database or to the thread currently shown in a buffer. Those two
meanings may refer to different sets of messages, e.g. when a new email
is added to the database while the buffer shows the state before the new
email arrived.
This patch replaces the term thread with the term current buffer, which
is hopefully less ambiguous.
The behavior of the header line in show-mode changed from showing the
subject of the first open message to showing the subject of the first
message in 4d77f18b. Update a comment to reflect this.
Consensus seems to be that people prefer that refreshing show buffers
retains state by default, rather than resetting it by default. This
turns out to be the case in the code, as well. In fact, there's even
a test for this that's been marked broken for several months, which
this patch finally gets to mark as fixed.
If we retain state while refreshing a show buffer, it should not mark
any messages read since it's not a navigation operation (it especially
shouldn't mark the first message matching the query read, which is
what it did previously). If the user or caller requests that refresh
reset the state of the buffer, then we consider that a navigation
operation, so we do mark the message under point after the refresh
read.
This is implemented by moving responsibility for initial positioning
and read-marking out of notmuch-show-worker and into its caller.
Since notmuch-show-worker is now exclusively about building the show
buffer, we rename it to notmuch-show-build-buffer.
* emacs/notmuch-show.el
(notmuch-show-stash-mlarchive-link-alist):
New defcustom of type `alist' (key = name, value = URI),
containing Mailing List Archive URI's for searching by Message-Id.
(notmuch-show-stash-mlarchive-link-default):
New defcustom, default MLA to use when `notmuch-show-stash-mlarchive-link'
received no user input whatsoever. Available choices are generated using
the contents of `notmuch-show-stash-mlarchive-link-alist'.
(notmuch-show-stash-map):
Added keybinds "l" and "L" for `notmuch-show-stash-mlarchive-link'
respectively `notmuch-show-stash-mlarchive-link-and-go'.
(notmuch-show-stash-mlarchive-link):
New function, stashes a URI pointing to the current message at one
of the MLAs configured in `notmuch-show-stash-mlarchive-link-alist'.
Prompts user with `completing-read' if not provided with an MLA key.
(notmuch-show-stash-mlarchive-link-and-go):
New function, uses `notmuch-show-stash-mlarchive-link' to
stash a URI, and then visits it using the browser configured
in `browse-url-browser-function'.
Based on original work [1] by David Edmondson <dme@dme.org>.
[1] id:"1327397873-20596-1-git-send-email-dme@dme.org"
* emacs/notmuch-show.el
(notmuch-show-get-message-id):
Add optional arg BARE. When non-nil, return a Message-Id without
quotes and prefix, thus obviating the need to strip them off again
in various places.
(notmuch-show-stash-message-id-stripped):
Update wrt changes in `notmuch-show-get-message-id'.
Replace text/x-vcalendar with text/calendar, while maintaining support
and backwards compatibility for text/x-vcalendar.
Code by David Edmondson <dme@dme.org>
When notmuch-search-line-faces is used to set background color in search
results, the highlight of the current line is not always displayed
correctly. This patch fixes that by increasing the priority property of
the highlight overlay.
The notmuch-show view refresh function (`notmuch-show-refresh-view',
bound to "=") accepts an optional RETAIN-STATE argument. The patch
allows to set this argument interactively by using "C-u =".
Recent changes in notmuch-show tagging introduced some code
duplication. The patch cleanups and simplifies
`notmuch-show-archive-thread' function by using
`notmuch-show-tag-all', no longer used function are removed. After
the change, `notmuch-show-archive-thread' function becomes symmetric
with `notmuch-show-archive-message'.
A side effect of these changes is that `notmuch-show-archive-thread'
no longer calls "notmuch tag" for each message in the thread.
With an argument, record and reply the state of the buffer during
`notmuch-show-refresh-view'.
In this context, "state" is defined as:
- the open/closed state of each message,
- the current message.
Traditional use of refresh with the = key does not retain the
state. The recently introduced toggle commands ($, !, < and >) do
retain the state.
Very deeply indented content is sometimes difficult to
read (particular for something like patches). Allow the indentation of
the content to be toggled with '<'.
Indentation of the header lines is not affected, so it remains
possible to see the structure of the thread.
The current behaviour (all messages shown, non-matching collapsed)
is retained as the default. Type '!' to switch to showing only
the matching messages - non-matching messages are not available.
'!' will switch back to showing everything.
Re-work the existing crypto switch toggle to be based on a persistant
buffer-local variable.
To allow this, modify `notmuch-show-refresh-view' to erase and re-draw
in the current buffer rather than killing the current buffer and
creating a new one. (This will also allow more per-buffer behaviour in
future patches.)
Add a binding ('$') to toggle crypto processing of the current buffer
and remove the prefix argument approach that achieves a similar
result.
When showing the user some details of gnupg output, ensure that those
details are shown at the end of the gnupg status buffer
("*notmuch-crypto-gpg-out*"), otherwise it can end up mixed up with
earlier output.
Add default value to notmuch-search-line-faces to show "unread"
messages in bold, and "flagged" messages in blue, to have some visual
indication of important messages in search results. This should be
helpful for new users.
"unread" tag is quite obvious, and handled specially both in the lib
and emacs ui. "flagged" is synced to maildir F flag in the lib. If one
syncs the maildir to IMAP, this also translates to corresponding IMAP
flag. (This is "starred" in GMail and Android.)
Signed-off-by: Jani Nikula <jani@nikula.org>
Modify the show view key bindings as follows to make them more
consistent:
'a' = Archive current message, then move to next message, or show next
thread from search if at the last message in thread.
'A' = Archive each message in thread, then show next thread from
search.
'x' = Archive current message, then move to next message, or exit back
to search results if at the last message in thread.
'X' = Archive each message in thread, then exit back to search
results.
The changes make the key bindings more consistent in two ways:
1) 'a'/'A' both advance to the next thread like 'a' used to.
2) 'x' operates on messages and 'X' on threads like 'a'/'A'.
This makes the argument names more consistent and clear. The
following functions changed: `notmuch-tag',
`notmuch-search-tag-thread', `notmuch-search-tag-region' and
`notmuch-search-tag-all'.
Since `notmuch-tag' is a non-interactive function and hence is meant
to be invoked programmatically, it should accept zero tags. Also, the
tagging operations (bound to "*", "+", "-") would accept empty input
without an error.
The tag syntax check in `notmuch-tag' function was too strict and did
not allow nmbug tags with "::". Since the check is done for all
tagging operations in Emacs UI, this basically means that no nmbug
tags can be changed. The patch relaxes the tag syntax check to allow
any tag names that do not include whitespace characters.
Some tag-related operations accept a single tag without prefix
(`notmuch-select-tag-with-completion'), others accept multiple tags
prefixed with '+' or '-' (`notmuch-read-tag-changes'). Before the
change, both functions used a single default minibuffer history. This
is inconvenient because you have to skip options with incompatible
format when going through the history. The patch adds separate
history lists for the two functions. Note that functions that accept
the same input format (e.g. "+", "-", "*") share the history list as
before.
The patch adds `notmuch-show-tag-all' function bound to "*" in
notmuch-show view. The function is similar to the
`notmuch-search-tag-all' function for the notmuch-search view: it
changes tags for all messages in the current thread.
Before the change, "+" and "-" tagging operations in notmuch-show view
accepted only a single tag. The patch makes them use the recently
added `notmuch-read-tag-changes' function, which allows to enter
multiple tags with "+" and "-" prefixes. So after the change, "+" and
"-" bindings in notmuch-show view allow to both add and remove
multiple tags. The only difference between "+" and "-" is the
minibuffer initial input ("+" and "-" respectively).
Before the change, "+" and "-" tagging operations in notmuch-search
view accepted only a single tag. The patch makes them use the
recently added `notmuch-read-tag-changes' function (renamed
`notmuch-select-tags-with-completion'), which allows to enter multiple
tags with "+" and "-" prefixes. So after the change, "+" and "-"
bindings in notmuch-search view allow to both add and remove multiple
tags. The only difference between "+" and "-" is the minibuffer
initial input ("+" and "-" respectively).
Before the change, tag format validation was done in
`notmuch-search-operate-all' function only. The patch moves it down
to `notmuch-tag', so that all users of that function get input
validation.
As Aaron explains in id:"m2vco72tf3.fsf@wal122.wireless-pennnet.upenn.edu"
Using point-max would include the signature in the quoting as well.
It would probably be fairly odd to want to put an MML tag in one’s
signature, but that doesn’t mean that we should break that usage.
We had to use point-max in the 0.11.1 bug-fix release, because the
mark functionality was added post 0.11.
`Notmuch-wash-region-to-button' is the function that creates hidden
regions with buttons for signatures, citations and original messages.
Before the change, it did not work correctly if the to-be-hidden
region started at the beginning of a message: the visibility toggle
button was hidden as well. The patch fixes this. There are two parts
in the fix:
* Use `insert-before-markers' instead of `insert' for creating the
button, so that it does not get added to the hidden overlay.
* Stop using PREFIX argument for adding a newline before the button.
The newline should not be added before a button at the beginning of
buffer.
The corresponding test is fixed now.
The blank line doesn't really change position, but is now considered
to be part of the body rather than part of the headers. This means
that it is visible when the body is visible rather than when the
headers are visible.
Emacs message-mode uses certain text strings to indicate how to attach
files to outgoing mail. If these are present in the text of an email,
and a user is tricked into replying to the message, the user’s files
could be exposed.
Edited-by: Pieter Praet <pieter@praet.org>: Rebased to release branch.
This changes the default key bindings for the 'a' key in notmuch-show
mode. Instead of archiving the entire thread, it now just archives
the current message, and then advance to the next open message
(archive-message-then-next). 'A' is now bound to the previous
archive-thread-then-next function.
This will allow for keybindings that achieve a smoother message
processing flow by reducing the number of key presses needed for most
common operations.
This adds two new message archiving functions that parallel the thread
archiving functions: notmuch-show-archive-message{,-then-next}. The
former also takes a prefix argument to unarchive the message (ie. put
back in inbox).
This function is now just for archiving the current thread. A new
function is created to archive-then-next. The 'a' key binding is
updated accordingly.
This will allow people to bind to the simple thread archiving function
without the extra navigation. The archive-thread function now also
takes a prefix to unarchive the current thread (ie. put the whole
thread back in the inbox).
Break up notmuch-show-archive-thread-internal into two new functions:
notmuch-show-tag-thread-internal: applies a tag to all messages in
thread. If option remove flag is t, tags will be removed instead of
added.
notmuch-show-next-thread: moves to the next thread in the search
result. If given a prefix, will show the next result, otherwise will
just move to it in the search view.
Two new interactive functions, notmuch-show-{add,remove}-tag-thread,
are also added. Together, these provide a better suit of thread
tagging and navigation tools.
The higher level thread archiving functions are modified to use these
new function.