Commit graph

152 commits

Author SHA1 Message Date
Austin Clements
69c52c56f2 emacs: Make notmuch-help work with arbitrary keymaps
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.
2013-09-10 08:07:19 -03:00
Austin Clements
21474f0e09 emacs: Add unified refresh-this-buffer function
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.
2013-09-10 08:07:06 -03:00
Austin Clements
ebd8a2e344 emacs: Move `notmuch-poll' to notmuch-lib 2013-09-10 08:06:52 -03:00
Austin Clements
ecdfa9a6b0 emacs: Remove notmuch-search quit continuation
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'.
2013-09-10 08:06:42 -03:00
Austin Clements
8a111b58d8 emacs: Consistently use configured sort order
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.
2013-09-10 08:05:50 -03:00
Jani Nikula
c1a42652a1 emacs: update search sort order help to match code 2013-06-24 22:51:37 -07:00
Austin Clements
88cce8c6a4 emacs: Fix "no such file or directory" error
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.
2013-06-12 23:53:27 +09:00
David Bremner
915a707ae4 emacs: add `notmuch-archive-tags' cross references in docstrings
Several function docstrings refer to behaviour in docstrings that is
really controlled by notmuch-archive-tags. Add cross references, and
replace hardcoding.
2013-06-02 20:43:14 -03:00
David Bremner
63782f4023 emacs: replace setq + let with let*
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.
2013-06-02 20:38:17 -03:00
David Bremner
9de0639126 emacs: replace (funcall 'foo ...) with (foo ...)
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.
2013-06-02 11:37:22 -03:00
Austin Clements
89efd5717a emacs: Use streaming S-expr parser for search
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.
2013-06-01 09:00:40 -03:00
Austin Clements
08fde50bf3 emacs: Use async process helper for search
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.
2013-06-01 08:56:16 -03:00
Austin Clements
e63aa66de8 emacs: Proper error string handling in search sentinel
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.
2013-05-18 07:50:11 -03:00
Damien Cassou
b714a808a6 emacs: possibility to customize the rendering of tags
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>
2013-03-25 11:38:49 -04:00
Austin Clements
401dbebd48 emacs: Use the minibuffer for CLI error reporting
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).
2013-01-06 22:47:35 -04:00
Austin Clements
2cdb3f54f7 emacs: Use --format-version for search, show, and reply 2012-12-16 17:22:26 -04:00
Austin Clements
19e5b2d912 emacs: Use unified error handling in search
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.
2012-12-16 17:17:41 -04:00
Austin Clements
0844af35eb emacs: Use unified error handling in notmuch-call-notmuch-process
This makes notmuch-call-notmuch-process use the unified CLI error
handling, which basically refines the error handling this function
already did.
2012-12-16 17:00:00 -04:00
Mark Walters
42391b4056 emacs: Move the incremental JSON parser to notmuch-lib.el
This just moves the newly split out incremental json parser (together
with its state variables) to lib.

There should be no functional change.
2012-10-28 09:42:18 -03:00
Mark Walters
294667871a emacs: Rename incremental JSON internal variables
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.
2012-10-28 09:42:09 -03:00
Mark Walters
1dd76ab9b6 emacs: Split out the incremental json parser into its own function
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.
2012-10-28 09:41:54 -03:00
Austin Clements
0a4663ff43 emacs: Escape tag queries suggested by tab completion 2012-10-27 09:34:34 -03:00
Jani Nikula
1548751041 emacs: add support for reversing notmuch-search-archive-thread tag changes
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.
2012-09-19 08:05:59 -03:00
Jani Nikula
d5dcfc714e emacs: add support for custom tag changes on message/thread archive
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.
2012-09-19 08:04:10 -03:00
Pieter Praet
c62126238b emacs: correct notmuch-search-mode's docstring wrt notmuch-search-tag-all'
* 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.
2012-09-01 23:08:52 -03:00
Mark Walters
5811550cdd emacs: notmuch search bugfix
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).
2012-08-12 21:27:45 +02:00
Mark Walters
3fa00020ea emacs: fix a bug introduced by the recent search cleanups.
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.
2012-08-02 21:11:53 -03:00
Austin Clements
5d0883ea1b emacs: Fix navigation of multi-line search result formats
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.
2012-07-24 09:23:53 -03:00
Austin Clements
90e741ef81 emacs: Allow custom tags formatting
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.)
2012-07-24 09:23:13 -03:00
Austin Clements
e94b45112e emacs: Replace other search text properties with result property
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.
2012-07-24 09:21:48 -03:00
Austin Clements
7ba5c86399 emacs: Use result text properties for search result iteration
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.
2012-07-24 09:21:38 -03:00
Austin Clements
2a91f636d8 emacs: Update tags by rewriting the search result line in place
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.
2012-07-24 09:04:50 -03:00
Austin Clements
60ebc84945 emacs: Use text properties instead of overlays for tag coloring
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.
2012-07-24 09:04:38 -03:00
Austin Clements
ae30f33093 emacs: Record thread search result object in a text property
This also provides utility functions for working with this text
property that get its value, find its start, and find its end.
2012-07-24 09:04:27 -03:00
Austin Clements
9c5ea07cc6 emacs: Switch from text to JSON format for search results
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"
2012-07-12 17:39:36 -06:00
Austin Clements
1a5bcdf6c1 emacs: Pass plist to `notmuch-search-show-result'
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.
2012-07-12 17:39:12 -06:00
Austin Clements
17525340a2 emacs: Move search-target logic to `notmuch-search-show-result'
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.
2012-07-12 17:39:04 -06:00
Austin Clements
9b4361d0fe emacs: Helper for reporting search parsing errors
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.
2012-07-12 17:38:54 -06:00
Austin Clements
e4818cc9c5 emacs: Separate search line parsing and display
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.
2012-07-12 17:38:43 -06:00
Austin Clements
bbc74d98f5 emacs: Clean up notmuch-search-show-result
This simplifies the code and makes it no longer cubic in the number of
result fields.
2012-07-12 17:38:34 -06:00
Jameson Graef Rollins
904a807088 emacs: eliminate search-tag-thread in favor of just search-tag
notmuch-search-tag-thread is now completely redundant with
notmuch-search-tag so we eliminate it to simplify the interface.
2012-04-29 17:43:03 -03:00
Jameson Graef Rollins
dba0e53ea8 emacs: modify search tag functions to use new notmuch-tag interface
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.
2012-04-29 17:41:57 -03:00
Jameson Graef Rollins
eb8feb1666 emacs: create notmuch-tag.el, and move appropriate functions from notmuch.el
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.
2012-04-29 17:39:37 -03:00
Jameson Graef Rollins
cbba1d1ba9 emacs: do not modify subject in search or show
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"
2012-04-28 23:30:59 -03:00
Jameson Graef Rollins
5073de34b4 emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name.
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.
2012-04-24 23:25:51 -03:00
Jameson Graef Rollins
6c84116091 emacs: have tag-completion return all tags for nil input
Previously the function would fail if the initial input was nil.  Now
it will return a list of all tags, which obviously makes much more
sense.
2012-04-12 15:34:49 -03:00
Jameson Graef Rollins
8225ff21ec emacs: include tags from excluded messages in tag tab completion
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.
2012-04-12 08:43:22 -03:00
Jameson Graef Rollins
1d4758e21f emacs: update call in tag-completion function
"search-tags" is deprecated, so use the more modern and supported
"search --output=tags".
2012-04-12 08:42:55 -03:00
Austin Clements
0eaf4a21dd emacs: Fix search tab completion in terminals
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.
2012-03-18 09:14:23 -03:00
Mark Walters
1aa4abe7a1 emacs: notmuch.el ignore excluded matches
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.
2012-03-02 08:38:27 -04:00