[PATCH v5 4/4] emacs: show: set default show-all-multipart/alternatives to nil
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. --- emacs/notmuch-show.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index f9366d0..5751d98 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -94,7 +94,7 @@ visible for any given message." :group 'notmuch-hooks) ;; Mostly useful for debugging. -(defcustom notmuch-show-all-multipart/alternative-parts t +(defcustom notmuch-show-all-multipart/alternative-parts nil "Should all parts of multipart/alternative parts be shown?" :type 'boolean :group 'notmuch-show) -- 1.7.9.1
[PATCH v5 3/4] emacs: show: add invisibility button action
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). --- emacs/notmuch-show.el | 31 +-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index dc86b43..f9366d0 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -554,6 +554,25 @@ message at DEPTH in the current thread." (let ((handle (mm-make-handle (current-buffer) (list content-type (mm-pipe-part handle +;; This is taken from notmuch-wash: maybe it should be unified? +(defun notmuch-show-toggle-part-invisibility ( button) + (interactive) + (let* ((button (or button (button-at (point +(overlay (button-get button 'overlay))) +(when overlay + (let* ((show (overlay-get overlay 'invisible)) +(new-start (button-start button)) +(button-label (button-get button :base-label)) +(old-point (point)) +(inhibit-read-only t)) + (overlay-put overlay 'invisible (not show)) + (goto-char new-start) + (insert "[ " button-label (if show " ]" " (hidden) ]")) + (let ((old-end (button-end button))) + (move-overlay button new-start (point)) + (delete-region (point) old-end)) + (goto-char (min old-point (1- (button-end button + (defun notmuch-show-multipart/*-to-list (part) (mapcar (lambda (inner-part) (plist-get inner-part :content-type)) (plist-get part :content))) @@ -847,7 +866,12 @@ message at DEPTH in the current thread." ;; also need to check that the button is a genuine part button not ;; a notmuch-wash button. (when (and button (/= part-beg end) (button-get button :base-label)) - (button-put button 'overlay (make-overlay part-beg end) + (button-put button 'overlay (make-overlay part-beg end)) + ;; We toggle the button for hidden parts as that gets the + ;; button label right. + (save-excursion + (when hide + (notmuch-show-toggle-part-invisibility button)) (defun notmuch-show-insert-bodypart (msg part depth hide) "Insert the body part PART at depth DEPTH in the current thread. @@ -1953,7 +1977,10 @@ the user (see `notmuch-show-stash-mlarchive-link-alist')." (defun notmuch-show-part-button-default ( button) (interactive) - (notmuch-show-part-button-internal button notmuch-show-part-button-default-action)) + (let ((button (or button (button-at (point) +(if (button-get button 'overlay) + (notmuch-show-toggle-part-invisibility button) + (notmuch-show-part-button-internal button notmuch-show-part-button-default-action (defun notmuch-show-part-button-save ( button) (interactive) -- 1.7.9.1
[PATCH v5 2/4] emacs: show: add overlays for each part
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. --- emacs/notmuch-show.el | 45 ++--- 1 files changed, 30 insertions(+), 15 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 5248fba..dc86b43 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -567,11 +567,10 @@ message at DEPTH in the current thread." ;; but it's not clear that this is the wrong thing to do - which ;; should be chosen if there are more than one that match? (mapc (lambda (inner-part) - (let ((inner-type (plist-get inner-part :content-type))) - (if (or notmuch-show-all-multipart/alternative-parts - (string= chosen-type inner-type)) - (notmuch-show-insert-bodypart msg inner-part depth) - (notmuch-show-insert-part-header (plist-get inner-part :id) inner-type inner-type nil " (not shown)" + (let* ((inner-type (plist-get inner-part :content-type)) + (hide (not (or notmuch-show-all-multipart/alternative-parts + (string= chosen-type inner-type) + (notmuch-show-insert-bodypart msg inner-part depth hide))) inner-parts) (when notmuch-show-indent-multipart @@ -839,17 +838,33 @@ message at DEPTH in the current thread." (setq handlers (cdr handlers t) -(defun notmuch-show-insert-bodypart (msg part depth) - "Insert the body part PART at depth DEPTH in the current thread." +(defun notmuch-show-create-part-overlays (msg beg end hide) + "Add an overlay to the part between BEG and END" + (let* ((button (button-at beg)) +(part-beg (and button (1+ (button-end button) + +;; If the part contains no text we do not make it toggleable. We +;; also need to check that the button is a genuine part button not +;; a notmuch-wash button. +(when (and button (/= part-beg end) (button-get button :base-label)) + (button-put button 'overlay (make-overlay part-beg end) + +(defun notmuch-show-insert-bodypart (msg part depth hide) + "Insert the body part PART at depth DEPTH in the current thread. + +If HIDE is non-nil then initially hide this part." (let ((content-type (downcase (plist-get part :content-type))) - (nth (plist-get part :id))) -(notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type)) - ;; Some of the body part handlers leave point somewhere up in the - ;; part, so we make sure that we're down at the end. - (goto-char (point-max)) - ;; Ensure that the part ends with a carriage return. - (unless (bolp) -(insert "\n"))) + (nth (plist-get part :id)) + (beg (point))) + +(notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type) +;; Some of the body part handlers leave point somewhere up in the +;; part, so we make sure that we're down at the end. +(goto-char (point-max)) +;; Ensure that the part ends with a carriage return. +(unless (bolp) + (insert "\n")) +(notmuch-show-create-part-overlays msg beg (point) hide))) (defun notmuch-show-insert-body (msg body depth) "Insert the body BODY at depth DEPTH in the current thread." -- 1.7.9.1
[PATCH v5 1/4] emacs: show: modify insert-part-header to save the button text
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). --- emacs/notmuch-show.el | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4bdd5af..5248fba 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -483,17 +483,17 @@ message at DEPTH in the current thread." (fset 'notmuch-show-part-button-map notmuch-show-part-button-map) (defun notmuch-show-insert-part-header (nth content-type declared-type name comment) - (let ((button)) + (let ((button) + (base-label (concat (when name (concat name ": ")) + declared-type + (unless (string-equal declared-type content-type) + (concat " (as " content-type ")")) + comment))) + (setq button (insert-button - (concat "[ " - (if name (concat name ": ") "") - declared-type - (if (not (string-equal declared-type content-type)) - (concat " (as " content-type ")") -"") - (or comment "") - " ]") + (concat "[ " base-label " ]") + :base-label base-label :type 'notmuch-show-part-button-type :notmuch-part nth :notmuch-filename name -- 1.7.9.1
[PATCH v5 0/4] Use invisibility to toggle display of all parts including multipart
This is an alternative version of id:1355781287-6010-1-git-send-email-markwalters1009 at gmail.com based on top of Austin's patch at id:1355812810-32747-1-git-send-email-amdragon at mit.edu Austin's patch significantly simplifies the invisibility handling taking this series down from 90/27 to 68/26 in diffstat terms. In general terms Austin's approach has to be the right thing to do: what we want to do just before the freeze is less clear. My view is that we should go with Austin's approach now so that at least any bugs we get from it and (more likely) from this series apply to master as well. I am posting this series to make it easier for people to judge the two approaches when finished (ie with part invisibility too). I attach a trimmed diff from v4 below the diffstat (note this was a diff with -U10 which I have trimmed so it is purely for information) Note we no longer need patch 4/5 because in this approach the overlays do not need to know about other overlays. Best wishes Mark Mark Walters (4): emacs: show: modify insert-part-header to save the button text emacs: show: add overlays for each part emacs: show: add invisibility button action emacs: show: set default show-all-multipart/alternatives to nil emacs/notmuch-show.el | 94 +++- 1 files changed, 68 insertions(+), 26 deletions(-) Diff from v4 emacs/notmuch-show.el | 33 ++--- emacs/notmuch-wash.el |2 +- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index ee67fec..5751d98 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -551,31 +551,28 @@ message at DEPTH in the current thread." ;; This is taken from notmuch-wash: maybe it should be unified? (defun notmuch-show-toggle-part-invisibility ( button) (interactive) (let* ((button (or button (button-at (point -(overlay (button-get button 'overlay)) -(invis-spec (button-get button 'invisibility-spec)) -(show (invisible-p invis-spec))) +(overlay (button-get button 'overlay))) (when overlay - (if show - (remove-from-invisibility-spec invis-spec) - (add-to-invisibility-spec invis-spec)) - (let* ((new-start (button-start button)) + (let* ((show (overlay-get overlay 'invisible)) +(new-start (button-start button)) (button-label (button-get button :base-label)) (old-point (point)) (inhibit-read-only t)) + (overlay-put overlay 'invisible (not show)) (goto-char new-start) (insert "[ " button-label (if show " ]" " (hidden) ]")) (let ((old-end (button-end button))) (move-overlay button new-start (point)) (delete-region (point) old-end)) (goto-char (min old-point (1- (button-end button @@ -862,39 +859,21 @@ message at DEPTH in the current thread." (defun notmuch-show-create-part-overlays (msg beg end hide) "Add an overlay to the part between BEG and END" (let* ((button (button-at beg)) (part-beg (and button (1+ (button-end button) ;; If the part contains no text we do not make it toggleable. We ;; also need to check that the button is a genuine part button not ;; a notmuch-wash button. (when (and button (/= part-beg end) (button-get button :base-label)) - (let ((base-label (button-get button :base-label)) - (overlay (make-overlay part-beg end)) - (message-invis-spec (plist-get msg :message-invis-spec)) - (invis-spec (make-symbol "notmuch-part-region"))) - - (overlay-put overlay 'invisible (list invis-spec message-invis-spec)) - (overlay-put overlay 'priority 10) - ;; Now we have to add invis-spec to every overlay this - ;; overlay contains, otherwise these inner overlays will - ;; override this one. - (dolist (inner (overlays-in part-beg end)) - (when (and (>= (overlay-start inner) part-beg) - (<= (overlay-end inner) end)) - (overlay-put inner 'invisible - (cons invis-spec (overlay-get inner 'invisible) - - (button-put button 'invisibility-spec invis-spec) - (button-put button 'overlay overlay)) - + (button-put button 'overlay (make-overlay part-beg end)) ;; We toggle the button for hidden parts as that gets the ;; button label right. (save-excursion (when hide (notmuch-show-toggle-part-invisibility button)) @@ -1992,21 +1971,21 @@ If optional argument MLA is non-nil, use the provided key instead of prompting (defun notmuch-show-part-button-default ( button) (interactive) (let ((button (or button (button-at (point) -(if (button-get button 'invisibility-spec) +(if (button-get button 'overlay) (notmuch-show-toggle-part-invisibility button)
[PATCH v4 0/5] add --format=text0 to notmuch search
Jani Nikula writes: > Hi all, a quick rebase of id:cover.1355691124.git.jani at nikula.org to fix > a tiny conflict in patch context of 3/5. > pushed, d
[PATCH 2/2] news: Promote some things to a general section
Date range search may be implemented as a library change, but it's an important user-facing change that affects all notmuch usage. Tag name restrictions aren't as important, but they affect both the CLI interface and the Emacs interface. --- NEWS | 40 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 8865ef9..3e48501 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,26 @@ Notmuch 0.15 (-MM-DD) = +General +--- + +Date range search support + + The `date:` prefix can now be used in queries to restrict the results + to only messages within a particular time range (based on the Date: + header) with a range syntax of `date:..`. Notmuch + supports a wide variety of expressions in `` and + ``. Please refer to the `notmuch-search-terms(7)` manual page + for details. + +Empty tag names and tags beginning with "-" are deprecated + + Such tags have been a frequent source of confusion and cause + (sometimes unresolvable) conflicts with other syntax. notmuch tag + no longer allows such tags to be added to messages. Removing such + tags continues to be supported to allow cleanup of existing tags, + but may be removed in a future release. + Command-Line Interface -- @@ -15,14 +35,6 @@ Support for single message mboxes is deprecated containing a single message; however, this behavior is now officially deprecated. -Empty tag names and tags beginning with "-" are deprecated - - Such tags have been a frequent source of confusion and cause - (sometimes unresolvable) conflicts with other syntax. notmuch tag - no longer allows such tags to be added to messages. Removing such - tags continues to be supported to allow cleanup of existing tags, - but may be removed in a future release. - Fixed `notmuch new` to skip ignored broken symlinks `notmuch new` now correctly skips symlinks if they are in the @@ -98,18 +110,6 @@ Fixed buttonization of id: links without quote characters Emacs now correctly buttonizes id: links where the message ID is not quoted. -Library changes - -Date range search support - - The `date:` prefix can now be used in queries to restrict the results - to only messages within a particular time range (based on the Date: - header) with a range syntax of `date:..`. Notmuch - supports a wide variety of expressions in `` and - ``. Please refer to the `notmuch-search-terms(7)` manual page - for details. - New add-on tool: notmuch-pick - -- 1.7.10.4
[PATCH 1/2] News for changes from Austin Clements
I fear I've fallen behind on my NEWS duties. --- NEWS | 64 1 file changed, 64 insertions(+) diff --git a/NEWS b/NEWS index 2e1c054..8865ef9 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,17 @@ Notmuch 0.15 (-MM-DD) Command-Line Interface -- +`notmuch new` no longer chokes on mboxes + + `notmuch new` now rejects mbox files containing more than one + message, rather than treating the file as one giant message. + +Support for single message mboxes is deprecated + + For historical reasons, `notmuch new` will index mbox files + containing a single message; however, this behavior is now + officially deprecated. + Empty tag names and tags beginning with "-" are deprecated Such tags have been a frequent source of confusion and cause @@ -12,12 +23,24 @@ Empty tag names and tags beginning with "-" are deprecated tags continues to be supported to allow cleanup of existing tags, but may be removed in a future release. +Fixed `notmuch new` to skip ignored broken symlinks + + `notmuch new` now correctly skips symlinks if they are in the + ignored files list. Previously, it would abort when encountering + broken symlink, even if it was ignored. + Bcc and Reply-To headers are now available in notmuch show json output The `notmuch show --format=json` now includes "Bcc" and "Reply-To" headers. For example notmuch Emacs client can now have these headers visible when the headers are added to the `notmuch-message-headers` variable. +CLI callers can now request a specific output format version + + `notmuch` subcommands that support structured output now support a + `--format-version` argument for requesting a specific version of the + structured output, enabling better compatibility and error handling. + Emacs Interface --- @@ -28,6 +51,12 @@ Removal of the deprecated `notmuch-folders` variable has now been removed. Any remaining users should migrate to `notmuch-saved-searches`. +Emacs now buttonizes mid: links + + mid: links are a standardized way to link to messages by message ID + (see RFC 2392). Emacs now hyperlinks mid: links to the appropriate + notmuch search. + Handle errors from bodypart insertions If displaying the text of a message in show mode causes an error (in @@ -35,6 +64,11 @@ Handle errors from bodypart insertions off thread display at the offending message. The error is now simply displayed in place of the message. +Emacs now detects version mismatches with the notmuch CLI + + Emacs now detects and reports when the Emacs interface version and + the notmuch CLI version are incompatible. + Improved text/calendar content handling Carriage returns in embedded text/calendar content caused insertion @@ -49,6 +83,21 @@ Disabled coding conversions when reading in `with-current-notmuch-show-message` corrupting the saved attachment. This has been fixed by making `with-current-notmuch-show-message` disable coding conversion. +Fixed errors with HTML email containing images in Emacs 24 + + Emacs 24 ships with a new HTML renderer that produces better output, + but is slightly buggy. We work around a bug that caused it to fail + for HTML email containing images. + +Fixed handling of tags with unusual characters in them + + Emacs now handles tags containing spaces, quotes, and parenthesis. + +Fixed buttonization of id: links without quote characters + + Emacs now correctly buttonizes id: links where the message ID is not + quoted. + Library changes --- @@ -72,6 +121,21 @@ terms of amount of output and can be useful for viewing both single threads and multiple threads. See the notmuch-pick README file for further details and installation. +Portability +--- + +notmuch now builds on OpenBSD. + +Internal test framework changes +--- + +The emacsclient binary is now user-configurable + + The test framework now accepts TEST_EMACSCLIENT in addition to + TEST_EMACS for configuring the emacsclient to use. This is + necessary to avoid using an old emacsclient with a new emacs, which + can result in buggy behavior. + Notmuch 0.14 (2012-08-20) = -- 1.7.10.4
[DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
On Tue, 18 Dec 2012, Austin Clements wrote: > 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 looks really good: the diffstat is great (even if we ignore the loss of the isearch-workaround it is still 17 insertions for 55 deletions!) and the new code works as one would expect with none of this nasty adding outer overlay invisbility properties to all inner overlay lists stuff. > Mark's part toggling code got me thinking about how needlessly > complicated our other show-mode invisibility code was. This patch is > a shot at fixing that. It will require a bit of reworking after part > toggling goes in (owning to the aforementioned non-composability, part > toggling needs to be intimately aware of wash and message hiding). > However, I think this patch should wait until after the release > freeze; this code is fragile (though much less so after this patch), > so I'd rather it soak for a release than cause user-visible bugs for > no user-visible gain. I have modified the part invisibility stuff to apply on top of this patch and it loses 20 lines, and those are the 20 lines which are `non-obvious' (the create-part-overlays function becomes almost trivial). It is not clear to me that putting this in is more dangerous than not: with the current code the part-invisibility is inherently fragile and with this it feels much less so. One example of this is the bug Jani found (with fake x-diff parts): it is not a bug when applied on top of the series because we do not have to do strange things with the invisibility specs. Incidentally, the invisibility specs approach seems to date back to very early notmuch (2009): I can't find any comments on why this approach was chosen instead of Austin's. Best wishes Mark > > emacs/notmuch-show.el | 42 +++-- > emacs/notmuch-wash.el | 97 > ++--- > 2 files changed, 17 insertions(+), 122 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 7d9f8a9..4bdd5af 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -872,27 +872,8 @@ message at DEPTH in the current thread." >message-start message-end >content-start content-end >headers-start headers-end > - body-start body-end > - (headers-invis-spec (notmuch-show-make-symbol "header")) > - (message-invis-spec (notmuch-show-make-symbol "message")) >(bare-subject (notmuch-show-strip-re (plist-get headers :Subject > > -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise > -;; removing items from `buffer-invisibility-spec' (which is what > -;; `notmuch-show-headers-visible' and > -;; `notmuch-show-message-visible' do) is a no-op and has no > -;; effect. This caused threads with only matching messages to have > -;; those messages hidden initially
[DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
Quoth Mark Walters on Dec 18 at 6:14 pm: > On Tue, 18 Dec 2012, Austin Clements wrote: > > 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. > > --- > > > > Mark's part toggling code got me thinking about how needlessly > > complicated our other show-mode invisibility code was. This patch is > > a shot at fixing that. It will require a bit of reworking after part > > toggling goes in (owning to the aforementioned non-composability, part > > toggling needs to be intimately aware of wash and message hiding). > > However, I think this patch should wait until after the release > > freeze; this code is fragile (though much less so after this patch), > > so I'd rather it soak for a release than cause user-visible bugs for > > no user-visible gain. > > > > emacs/notmuch-show.el | 42 +++-- > > emacs/notmuch-wash.el | 97 > > ++--- > > 2 files changed, 17 insertions(+), 122 deletions(-) > > > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > > index 7d9f8a9..4bdd5af 100644 > > --- a/emacs/notmuch-show.el > > +++ b/emacs/notmuch-show.el > > @@ -872,27 +872,8 @@ message at DEPTH in the current thread." > > message-start message-end > > content-start content-end > > headers-start headers-end > > -body-start body-end > > -(headers-invis-spec (notmuch-show-make-symbol "header")) > > -(message-invis-spec (notmuch-show-make-symbol "message")) > > (bare-subject (notmuch-show-strip-re (plist-get headers :Subject > > > > -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise > > -;; removing items from `buffer-invisibility-spec' (which is what > > -;; `notmuch-show-headers-visible' and > > -;; `notmuch-show-message-visible' do) is a no-op and has no > > -;; effect. This caused threads with only matching messages to have > > -;; those messages hidden initially because > > -;; `buffer-invisibility-spec' stayed `t'. > > -;; > > -;; This needs to be set here (rather than just above the call to > > -;; `notmuch-show-headers-visible') because some of the part > > -;; rendering or body washing functions > > -;; (e.g. `notmuch-wash-text/plain-citations') manipulate > > -;; `buffer-invisibility-spec'). > > -(when (eq buffer-invisibility-spec t) > > - (setq buffer-invisibility-spec nil)) > > - > > (setq message-start (point-marker)) > > > > (notmuch-show-insert-headerline headers > > @@ -904,9 +885,6 @@ message at DEPTH in the current thread." > > > > (setq content-start (point-marker)) > > > > -(plist-put msg :headers-invis-spec headers-invis-spec) > > -(plist-put msg :message-invis-spec message-invis-spec) > > - > > ;; Set `headers-start' to point after the 'Subject:' header to
[PATCH v4 0/5] Use invisibility to toggle display of all parts including multipart
Quoth Mark Walters on Dec 18 at 8:54 am: > On Mon, 17 Dec 2012, Mark Walters wrote: > > This is version 4 of this series (previous version at > > id:139338-14313-1-git-send-email-markwalters1009 at gmail.com). > > > > The only change should be a bugfix which, for reasons I don't > > understand, only causes a problem on emacs 24. The problem is that the > > part invisibility code looks for a part button at the start of the > > region. This gets confused if there is a part with no part button > > (this is the case for the first part if it is text/plain) and the part > > starts with a button (as can happen if the message starts with the > > reply as in the first test in test/emacs-show). > > > > This checks that the button is a part button before creating the part > > overlay. > > I don't think the above is very clear so I will try to explain it more > fully. > > The invisibility overlay for a part needs to be `linked' to the part > header button so that the part header button can toggle the overlay > visibility. The overlay is created and linked to this button after the > whole part has been inserted (including any notmuch-wash stuff). > > I could have made insert-part-header return the button it made and pass > it back up the call chain to the the create-overlays function but > instead I chose to make create-overlays just take the button at the > start of the part. > > Now if the first part is text/plain then notmuch does not insert a > [text/plain] button so the code checks for this case by making sure the > part does start with a button, and if not it does not create the part > overlay (there is no button to toggle it so no point in an overlay). > > However, if the first part is text/plain and notmuch wash happens to > make a button at the very start of the part then the create-overlays > function did still create an overlay *and* link it to the button. This > linking overwrote some of the things notmuch wash had attached to its > button (eg the button :overlay property) and that caused things to > break. > > I still do not know why emacs 23 and emacs 24 behave differently, but > regardless the change from v3 is a clear bugfix: we just make sure it is > a notmuch-show-insert-part-header button not a notmuch-wash button > before we do the overlay creation/linking to the button. This version > does that by looking for a :base-label property of the button which > insert-part-header buttons have but notmuch-wash buttons do > not. (Obviously there are other ways this check could be done) Now I understand. LGTM. Do you want to go ahead and push this or would you rather get my wash/show cleanup in and push your reworked version of the series?
[PATCH v4 0/5] Use invisibility to toggle display of all parts including multipart
On Mon, 17 Dec 2012, Mark Walters wrote: > This is version 4 of this series (previous version at > id:139338-14313-1-git-send-email-markwalters1009 at gmail.com). > > The only change should be a bugfix which, for reasons I don't > understand, only causes a problem on emacs 24. The problem is that the > part invisibility code looks for a part button at the start of the > region. This gets confused if there is a part with no part button > (this is the case for the first part if it is text/plain) and the part > starts with a button (as can happen if the message starts with the > reply as in the first test in test/emacs-show). > > This checks that the button is a part button before creating the part > overlay. I don't think the above is very clear so I will try to explain it more fully. The invisibility overlay for a part needs to be `linked' to the part header button so that the part header button can toggle the overlay visibility. The overlay is created and linked to this button after the whole part has been inserted (including any notmuch-wash stuff). I could have made insert-part-header return the button it made and pass it back up the call chain to the the create-overlays function but instead I chose to make create-overlays just take the button at the start of the part. Now if the first part is text/plain then notmuch does not insert a [text/plain] button so the code checks for this case by making sure the part does start with a button, and if not it does not create the part overlay (there is no button to toggle it so no point in an overlay). However, if the first part is text/plain and notmuch wash happens to make a button at the very start of the part then the create-overlays function did still create an overlay *and* link it to the button. This linking overwrote some of the things notmuch wash had attached to its button (eg the button :overlay property) and that caused things to break. I still do not know why emacs 23 and emacs 24 behave differently, but regardless the change from v3 is a clear bugfix: we just make sure it is a notmuch-show-insert-part-header button not a notmuch-wash button before we do the overlay creation/linking to the button. This version does that by looking for a :base-label property of the button which insert-part-header buttons have but notmuch-wash buttons do not. (Obviously there are other ways this check could be done) Best wishes Mark > The diff is below the diffstat. > > Best wishes > > Mark > > > > Mark Walters (5): > emacs: show: modify insert-part-header to save the button text > emacs: show: add overlays for each part > emacs: show: add invisibility button action > emacs: wash: fix fake-diff part to include msg parameter > emacs: show: set default show-all-multipart/alternatives to nil > > emacs/notmuch-show.el | 115 > ++--- > emacs/notmuch-wash.el |2 +- > 2 files changed, 90 insertions(+), 27 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 5ca6fe2..3816e32 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -865,8 +865,10 @@ message at DEPTH in the current thread." >(let* ((button (button-at beg)) >(part-beg (and button (1+ (button-end button) > > -;; If the part contains no text we do not make it toggleable. > -(when (and button (/= part-beg end)) > +;; If the part contains no text we do not make it toggleable. We > +;; also need to check that the button is a genuine part button not > +;; a notmuch-wash button. > +(when (and button (/= part-beg end) (button-get button :base-label)) >(let ((base-label (button-get button :base-label)) > (overlay (make-overlay part-beg end)) > (message-invis-spec (plist-get msg :message-invis-spec)) > -- > 1.7.9.1
[DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
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. --- Mark's part toggling code got me thinking about how needlessly complicated our other show-mode invisibility code was. This patch is a shot at fixing that. It will require a bit of reworking after part toggling goes in (owning to the aforementioned non-composability, part toggling needs to be intimately aware of wash and message hiding). However, I think this patch should wait until after the release freeze; this code is fragile (though much less so after this patch), so I'd rather it soak for a release than cause user-visible bugs for no user-visible gain. emacs/notmuch-show.el | 42 +++-- emacs/notmuch-wash.el | 97 ++--- 2 files changed, 17 insertions(+), 122 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7d9f8a9..4bdd5af 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -872,27 +872,8 @@ message at DEPTH in the current thread." message-start message-end content-start content-end headers-start headers-end -body-start body-end -(headers-invis-spec (notmuch-show-make-symbol "header")) -(message-invis-spec (notmuch-show-make-symbol "message")) (bare-subject (notmuch-show-strip-re (plist-get headers :Subject -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise -;; removing items from `buffer-invisibility-spec' (which is what -;; `notmuch-show-headers-visible' and -;; `notmuch-show-message-visible' do) is a no-op and has no -;; effect. This caused threads with only matching messages to have -;; those messages hidden initially because -;; `buffer-invisibility-spec' stayed `t'. -;; -;; This needs to be set here (rather than just above the call to -;; `notmuch-show-headers-visible') because some of the part -;; rendering or body washing functions -;; (e.g. `notmuch-wash-text/plain-citations') manipulate -;; `buffer-invisibility-spec'). -(when (eq buffer-invisibility-spec t) - (setq buffer-invisibility-spec nil)) - (setq message-start (point-marker)) (notmuch-show-insert-headerline headers @@ -904,9 +885,6 @@ message at DEPTH in the current thread." (setq content-start (point-marker)) -(plist-put msg :headers-invis-spec headers-invis-spec) -(plist-put msg :message-invis-spec message-invis-spec) - ;; Set `headers-start' to point after the 'Subject:' header to be ;; compatible with the existing implementation. This just sets it ;; to after the first header. @@ -924,7 +902,6 @@ message at DEPTH in the current thread." (setq notmuch-show-previous-subject bare-subject) -(setq body-start (point-marker)) ;; A blank line between the headers and the body. (insert "\n") (notmuch-show-insert-body msg (plist-get msg :body) @@ -932,7 +909,6 @@ message at DEPTH
Re: [PATCH v4 0/5] Use invisibility to toggle display of all parts including multipart
On Mon, 17 Dec 2012, Mark Walters markwalters1...@gmail.com wrote: This is version 4 of this series (previous version at id:139338-14313-1-git-send-email-markwalters1...@gmail.com). The only change should be a bugfix which, for reasons I don't understand, only causes a problem on emacs 24. The problem is that the part invisibility code looks for a part button at the start of the region. This gets confused if there is a part with no part button (this is the case for the first part if it is text/plain) and the part starts with a button (as can happen if the message starts with the reply as in the first test in test/emacs-show). This checks that the button is a part button before creating the part overlay. I don't think the above is very clear so I will try to explain it more fully. The invisibility overlay for a part needs to be `linked' to the part header button so that the part header button can toggle the overlay visibility. The overlay is created and linked to this button after the whole part has been inserted (including any notmuch-wash stuff). I could have made insert-part-header return the button it made and pass it back up the call chain to the the create-overlays function but instead I chose to make create-overlays just take the button at the start of the part. Now if the first part is text/plain then notmuch does not insert a [text/plain] button so the code checks for this case by making sure the part does start with a button, and if not it does not create the part overlay (there is no button to toggle it so no point in an overlay). However, if the first part is text/plain and notmuch wash happens to make a button at the very start of the part then the create-overlays function did still create an overlay *and* link it to the button. This linking overwrote some of the things notmuch wash had attached to its button (eg the button :overlay property) and that caused things to break. I still do not know why emacs 23 and emacs 24 behave differently, but regardless the change from v3 is a clear bugfix: we just make sure it is a notmuch-show-insert-part-header button not a notmuch-wash button before we do the overlay creation/linking to the button. This version does that by looking for a :base-label property of the button which insert-part-header buttons have but notmuch-wash buttons do not. (Obviously there are other ways this check could be done) Best wishes Mark The diff is below the diffstat. Best wishes Mark Mark Walters (5): emacs: show: modify insert-part-header to save the button text emacs: show: add overlays for each part emacs: show: add invisibility button action emacs: wash: fix fake-diff part to include msg parameter emacs: show: set default show-all-multipart/alternatives to nil emacs/notmuch-show.el | 115 ++--- emacs/notmuch-wash.el |2 +- 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 5ca6fe2..3816e32 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -865,8 +865,10 @@ message at DEPTH in the current thread. (let* ((button (button-at beg)) (part-beg (and button (1+ (button-end button) -;; If the part contains no text we do not make it toggleable. -(when (and button (/= part-beg end)) +;; If the part contains no text we do not make it toggleable. We +;; also need to check that the button is a genuine part button not +;; a notmuch-wash button. +(when (and button (/= part-beg end) (button-get button :base-label)) (let ((base-label (button-get button :base-label)) (overlay (make-overlay part-beg end)) (message-invis-spec (plist-get msg :message-invis-spec)) -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
On Tue, 18 Dec 2012, Austin Clements amdra...@mit.edu wrote: 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 looks really good: the diffstat is great (even if we ignore the loss of the isearch-workaround it is still 17 insertions for 55 deletions!) and the new code works as one would expect with none of this nasty adding outer overlay invisbility properties to all inner overlay lists stuff. Mark's part toggling code got me thinking about how needlessly complicated our other show-mode invisibility code was. This patch is a shot at fixing that. It will require a bit of reworking after part toggling goes in (owning to the aforementioned non-composability, part toggling needs to be intimately aware of wash and message hiding). However, I think this patch should wait until after the release freeze; this code is fragile (though much less so after this patch), so I'd rather it soak for a release than cause user-visible bugs for no user-visible gain. I have modified the part invisibility stuff to apply on top of this patch and it loses 20 lines, and those are the 20 lines which are `non-obvious' (the create-part-overlays function becomes almost trivial). It is not clear to me that putting this in is more dangerous than not: with the current code the part-invisibility is inherently fragile and with this it feels much less so. One example of this is the bug Jani found (with fake x-diff parts): it is not a bug when applied on top of the series because we do not have to do strange things with the invisibility specs. Incidentally, the invisibility specs approach seems to date back to very early notmuch (2009): I can't find any comments on why this approach was chosen instead of Austin's. Best wishes Mark emacs/notmuch-show.el | 42 +++-- emacs/notmuch-wash.el | 97 ++--- 2 files changed, 17 insertions(+), 122 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7d9f8a9..4bdd5af 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -872,27 +872,8 @@ message at DEPTH in the current thread. message-start message-end content-start content-end headers-start headers-end - body-start body-end - (headers-invis-spec (notmuch-show-make-symbol header)) - (message-invis-spec (notmuch-show-make-symbol message)) (bare-subject (notmuch-show-strip-re (plist-get headers :Subject -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise -;; removing items from `buffer-invisibility-spec' (which is what -;; `notmuch-show-headers-visible' and -;; `notmuch-show-message-visible' do) is a no-op and has no -;; effect. This caused threads with only matching messages to have -;; those messages hidden initially because -;; `buffer-invisibility-spec' stayed `t'. -;; -
Re: [PATCH v4 0/5] Use invisibility to toggle display of all parts including multipart
Quoth Mark Walters on Dec 18 at 8:54 am: On Mon, 17 Dec 2012, Mark Walters markwalters1...@gmail.com wrote: This is version 4 of this series (previous version at id:139338-14313-1-git-send-email-markwalters1...@gmail.com). The only change should be a bugfix which, for reasons I don't understand, only causes a problem on emacs 24. The problem is that the part invisibility code looks for a part button at the start of the region. This gets confused if there is a part with no part button (this is the case for the first part if it is text/plain) and the part starts with a button (as can happen if the message starts with the reply as in the first test in test/emacs-show). This checks that the button is a part button before creating the part overlay. I don't think the above is very clear so I will try to explain it more fully. The invisibility overlay for a part needs to be `linked' to the part header button so that the part header button can toggle the overlay visibility. The overlay is created and linked to this button after the whole part has been inserted (including any notmuch-wash stuff). I could have made insert-part-header return the button it made and pass it back up the call chain to the the create-overlays function but instead I chose to make create-overlays just take the button at the start of the part. Now if the first part is text/plain then notmuch does not insert a [text/plain] button so the code checks for this case by making sure the part does start with a button, and if not it does not create the part overlay (there is no button to toggle it so no point in an overlay). However, if the first part is text/plain and notmuch wash happens to make a button at the very start of the part then the create-overlays function did still create an overlay *and* link it to the button. This linking overwrote some of the things notmuch wash had attached to its button (eg the button :overlay property) and that caused things to break. I still do not know why emacs 23 and emacs 24 behave differently, but regardless the change from v3 is a clear bugfix: we just make sure it is a notmuch-show-insert-part-header button not a notmuch-wash button before we do the overlay creation/linking to the button. This version does that by looking for a :base-label property of the button which insert-part-header buttons have but notmuch-wash buttons do not. (Obviously there are other ways this check could be done) Now I understand. LGTM. Do you want to go ahead and push this or would you rather get my wash/show cleanup in and push your reworked version of the series? ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
On Tue, 18 Dec 2012, Austin Clements amdra...@mit.edu wrote: 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. --- Mark's part toggling code got me thinking about how needlessly complicated our other show-mode invisibility code was. This patch is a shot at fixing that. It will require a bit of reworking after part toggling goes in (owning to the aforementioned non-composability, part toggling needs to be intimately aware of wash and message hiding). However, I think this patch should wait until after the release freeze; this code is fragile (though much less so after this patch), so I'd rather it soak for a release than cause user-visible bugs for no user-visible gain. emacs/notmuch-show.el | 42 +++-- emacs/notmuch-wash.el | 97 ++--- 2 files changed, 17 insertions(+), 122 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7d9f8a9..4bdd5af 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -872,27 +872,8 @@ message at DEPTH in the current thread. message-start message-end content-start content-end headers-start headers-end - body-start body-end - (headers-invis-spec (notmuch-show-make-symbol header)) - (message-invis-spec (notmuch-show-make-symbol message)) (bare-subject (notmuch-show-strip-re (plist-get headers :Subject -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise -;; removing items from `buffer-invisibility-spec' (which is what -;; `notmuch-show-headers-visible' and -;; `notmuch-show-message-visible' do) is a no-op and has no -;; effect. This caused threads with only matching messages to have -;; those messages hidden initially because -;; `buffer-invisibility-spec' stayed `t'. -;; -;; This needs to be set here (rather than just above the call to -;; `notmuch-show-headers-visible') because some of the part -;; rendering or body washing functions -;; (e.g. `notmuch-wash-text/plain-citations') manipulate -;; `buffer-invisibility-spec'). -(when (eq buffer-invisibility-spec t) - (setq buffer-invisibility-spec nil)) - (setq message-start (point-marker)) (notmuch-show-insert-headerline headers @@ -904,9 +885,6 @@ message at DEPTH in the current thread. (setq content-start (point-marker)) -(plist-put msg :headers-invis-spec headers-invis-spec) -(plist-put msg :message-invis-spec message-invis-spec) - ;; Set `headers-start' to point after the 'Subject:' header to be ;; compatible with the existing implementation. This just sets it ;; to after the first header. @@ -924,7 +902,6 @@ message at DEPTH in the current thread. (setq notmuch-show-previous-subject bare-subject) -(setq body-start (point-marker)) ;; A blank line
Re: [DRAFT PATCH] emacs: Eliminate buffer invisibility specs from show and wash
Quoth Mark Walters on Dec 18 at 6:14 pm: On Tue, 18 Dec 2012, Austin Clements amdra...@mit.edu wrote: 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. --- Mark's part toggling code got me thinking about how needlessly complicated our other show-mode invisibility code was. This patch is a shot at fixing that. It will require a bit of reworking after part toggling goes in (owning to the aforementioned non-composability, part toggling needs to be intimately aware of wash and message hiding). However, I think this patch should wait until after the release freeze; this code is fragile (though much less so after this patch), so I'd rather it soak for a release than cause user-visible bugs for no user-visible gain. emacs/notmuch-show.el | 42 +++-- emacs/notmuch-wash.el | 97 ++--- 2 files changed, 17 insertions(+), 122 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7d9f8a9..4bdd5af 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -872,27 +872,8 @@ message at DEPTH in the current thread. message-start message-end content-start content-end headers-start headers-end -body-start body-end -(headers-invis-spec (notmuch-show-make-symbol header)) -(message-invis-spec (notmuch-show-make-symbol message)) (bare-subject (notmuch-show-strip-re (plist-get headers :Subject -;; Set `buffer-invisibility-spec' to `nil' (a list), otherwise -;; removing items from `buffer-invisibility-spec' (which is what -;; `notmuch-show-headers-visible' and -;; `notmuch-show-message-visible' do) is a no-op and has no -;; effect. This caused threads with only matching messages to have -;; those messages hidden initially because -;; `buffer-invisibility-spec' stayed `t'. -;; -;; This needs to be set here (rather than just above the call to -;; `notmuch-show-headers-visible') because some of the part -;; rendering or body washing functions -;; (e.g. `notmuch-wash-text/plain-citations') manipulate -;; `buffer-invisibility-spec'). -(when (eq buffer-invisibility-spec t) - (setq buffer-invisibility-spec nil)) - (setq message-start (point-marker)) (notmuch-show-insert-headerline headers @@ -904,9 +885,6 @@ message at DEPTH in the current thread. (setq content-start (point-marker)) -(plist-put msg :headers-invis-spec headers-invis-spec) -(plist-put msg :message-invis-spec message-invis-spec) - ;; Set `headers-start' to point after the 'Subject:' header to be ;; compatible with the existing implementation. This just sets it ;; to after the first header. @@ -924,7 +902,6 @@ message at DEPTH in the current thread.
[PATCH v5 0/4] Use invisibility to toggle display of all parts including multipart
This is an alternative version of id:1355781287-6010-1-git-send-email-markwalters1...@gmail.com based on top of Austin's patch at id:1355812810-32747-1-git-send-email-amdra...@mit.edu Austin's patch significantly simplifies the invisibility handling taking this series down from 90/27 to 68/26 in diffstat terms. In general terms Austin's approach has to be the right thing to do: what we want to do just before the freeze is less clear. My view is that we should go with Austin's approach now so that at least any bugs we get from it and (more likely) from this series apply to master as well. I am posting this series to make it easier for people to judge the two approaches when finished (ie with part invisibility too). I attach a trimmed diff from v4 below the diffstat (note this was a diff with -U10 which I have trimmed so it is purely for information) Note we no longer need patch 4/5 because in this approach the overlays do not need to know about other overlays. Best wishes Mark Mark Walters (4): emacs: show: modify insert-part-header to save the button text emacs: show: add overlays for each part emacs: show: add invisibility button action emacs: show: set default show-all-multipart/alternatives to nil emacs/notmuch-show.el | 94 +++- 1 files changed, 68 insertions(+), 26 deletions(-) Diff from v4 emacs/notmuch-show.el | 33 ++--- emacs/notmuch-wash.el |2 +- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index ee67fec..5751d98 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -551,31 +551,28 @@ message at DEPTH in the current thread. ;; This is taken from notmuch-wash: maybe it should be unified? (defun notmuch-show-toggle-part-invisibility (optional button) (interactive) (let* ((button (or button (button-at (point -(overlay (button-get button 'overlay)) -(invis-spec (button-get button 'invisibility-spec)) -(show (invisible-p invis-spec))) +(overlay (button-get button 'overlay))) (when overlay - (if show - (remove-from-invisibility-spec invis-spec) - (add-to-invisibility-spec invis-spec)) - (let* ((new-start (button-start button)) + (let* ((show (overlay-get overlay 'invisible)) +(new-start (button-start button)) (button-label (button-get button :base-label)) (old-point (point)) (inhibit-read-only t)) + (overlay-put overlay 'invisible (not show)) (goto-char new-start) (insert [ button-label (if show ] (hidden) ])) (let ((old-end (button-end button))) (move-overlay button new-start (point)) (delete-region (point) old-end)) (goto-char (min old-point (1- (button-end button @@ -862,39 +859,21 @@ message at DEPTH in the current thread. (defun notmuch-show-create-part-overlays (msg beg end hide) Add an overlay to the part between BEG and END (let* ((button (button-at beg)) (part-beg (and button (1+ (button-end button) ;; If the part contains no text we do not make it toggleable. We ;; also need to check that the button is a genuine part button not ;; a notmuch-wash button. (when (and button (/= part-beg end) (button-get button :base-label)) - (let ((base-label (button-get button :base-label)) - (overlay (make-overlay part-beg end)) - (message-invis-spec (plist-get msg :message-invis-spec)) - (invis-spec (make-symbol notmuch-part-region))) - - (overlay-put overlay 'invisible (list invis-spec message-invis-spec)) - (overlay-put overlay 'priority 10) - ;; Now we have to add invis-spec to every overlay this - ;; overlay contains, otherwise these inner overlays will - ;; override this one. - (dolist (inner (overlays-in part-beg end)) - (when (and (= (overlay-start inner) part-beg) - (= (overlay-end inner) end)) - (overlay-put inner 'invisible - (cons invis-spec (overlay-get inner 'invisible) - - (button-put button 'invisibility-spec invis-spec) - (button-put button 'overlay overlay)) - + (button-put button 'overlay (make-overlay part-beg end)) ;; We toggle the button for hidden parts as that gets the ;; button label right. (save-excursion (when hide (notmuch-show-toggle-part-invisibility button)) @@ -1992,21 +1971,21 @@ If optional argument MLA is non-nil, use the provided key instead of prompting (defun notmuch-show-part-button-default (optional button) (interactive) (let ((button (or button (button-at (point) -(if (button-get button 'invisibility-spec) +(if (button-get button 'overlay) (notmuch-show-toggle-part-invisibility button)
[PATCH v5 1/4] emacs: show: modify insert-part-header to save the button text
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). --- emacs/notmuch-show.el | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4bdd5af..5248fba 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -483,17 +483,17 @@ message at DEPTH in the current thread. (fset 'notmuch-show-part-button-map notmuch-show-part-button-map) (defun notmuch-show-insert-part-header (nth content-type declared-type optional name comment) - (let ((button)) + (let ((button) + (base-label (concat (when name (concat name : )) + declared-type + (unless (string-equal declared-type content-type) + (concat (as content-type ))) + comment))) + (setq button (insert-button - (concat [ - (if name (concat name : ) ) - declared-type - (if (not (string-equal declared-type content-type)) - (concat (as content-type )) -) - (or comment ) - ]) + (concat [ base-label ]) + :base-label base-label :type 'notmuch-show-part-button-type :notmuch-part nth :notmuch-filename name -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v5 3/4] emacs: show: add invisibility button action
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). --- emacs/notmuch-show.el | 31 +-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index dc86b43..f9366d0 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -554,6 +554,25 @@ message at DEPTH in the current thread. (let ((handle (mm-make-handle (current-buffer) (list content-type (mm-pipe-part handle +;; This is taken from notmuch-wash: maybe it should be unified? +(defun notmuch-show-toggle-part-invisibility (optional button) + (interactive) + (let* ((button (or button (button-at (point +(overlay (button-get button 'overlay))) +(when overlay + (let* ((show (overlay-get overlay 'invisible)) +(new-start (button-start button)) +(button-label (button-get button :base-label)) +(old-point (point)) +(inhibit-read-only t)) + (overlay-put overlay 'invisible (not show)) + (goto-char new-start) + (insert [ button-label (if show ] (hidden) ])) + (let ((old-end (button-end button))) + (move-overlay button new-start (point)) + (delete-region (point) old-end)) + (goto-char (min old-point (1- (button-end button + (defun notmuch-show-multipart/*-to-list (part) (mapcar (lambda (inner-part) (plist-get inner-part :content-type)) (plist-get part :content))) @@ -847,7 +866,12 @@ message at DEPTH in the current thread. ;; also need to check that the button is a genuine part button not ;; a notmuch-wash button. (when (and button (/= part-beg end) (button-get button :base-label)) - (button-put button 'overlay (make-overlay part-beg end) + (button-put button 'overlay (make-overlay part-beg end)) + ;; We toggle the button for hidden parts as that gets the + ;; button label right. + (save-excursion + (when hide + (notmuch-show-toggle-part-invisibility button)) (defun notmuch-show-insert-bodypart (msg part depth optional hide) Insert the body part PART at depth DEPTH in the current thread. @@ -1953,7 +1977,10 @@ the user (see `notmuch-show-stash-mlarchive-link-alist'). (defun notmuch-show-part-button-default (optional button) (interactive) - (notmuch-show-part-button-internal button notmuch-show-part-button-default-action)) + (let ((button (or button (button-at (point) +(if (button-get button 'overlay) + (notmuch-show-toggle-part-invisibility button) + (notmuch-show-part-button-internal button notmuch-show-part-button-default-action (defun notmuch-show-part-button-save (optional button) (interactive) -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v5 2/4] emacs: show: add overlays for each part
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. --- emacs/notmuch-show.el | 45 ++--- 1 files changed, 30 insertions(+), 15 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 5248fba..dc86b43 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -567,11 +567,10 @@ message at DEPTH in the current thread. ;; but it's not clear that this is the wrong thing to do - which ;; should be chosen if there are more than one that match? (mapc (lambda (inner-part) - (let ((inner-type (plist-get inner-part :content-type))) - (if (or notmuch-show-all-multipart/alternative-parts - (string= chosen-type inner-type)) - (notmuch-show-insert-bodypart msg inner-part depth) - (notmuch-show-insert-part-header (plist-get inner-part :id) inner-type inner-type nil (not shown) + (let* ((inner-type (plist-get inner-part :content-type)) + (hide (not (or notmuch-show-all-multipart/alternative-parts + (string= chosen-type inner-type) + (notmuch-show-insert-bodypart msg inner-part depth hide))) inner-parts) (when notmuch-show-indent-multipart @@ -839,17 +838,33 @@ message at DEPTH in the current thread. (setq handlers (cdr handlers t) -(defun notmuch-show-insert-bodypart (msg part depth) - Insert the body part PART at depth DEPTH in the current thread. +(defun notmuch-show-create-part-overlays (msg beg end hide) + Add an overlay to the part between BEG and END + (let* ((button (button-at beg)) +(part-beg (and button (1+ (button-end button) + +;; If the part contains no text we do not make it toggleable. We +;; also need to check that the button is a genuine part button not +;; a notmuch-wash button. +(when (and button (/= part-beg end) (button-get button :base-label)) + (button-put button 'overlay (make-overlay part-beg end) + +(defun notmuch-show-insert-bodypart (msg part depth optional hide) + Insert the body part PART at depth DEPTH in the current thread. + +If HIDE is non-nil then initially hide this part. (let ((content-type (downcase (plist-get part :content-type))) - (nth (plist-get part :id))) -(notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type)) - ;; Some of the body part handlers leave point somewhere up in the - ;; part, so we make sure that we're down at the end. - (goto-char (point-max)) - ;; Ensure that the part ends with a carriage return. - (unless (bolp) -(insert \n))) + (nth (plist-get part :id)) + (beg (point))) + +(notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type) +;; Some of the body part handlers leave point somewhere up in the +;; part, so we make sure that we're down at the end. +(goto-char (point-max)) +;; Ensure that the part ends with a carriage return. +(unless (bolp) + (insert \n)) +(notmuch-show-create-part-overlays msg beg (point) hide))) (defun notmuch-show-insert-body (msg body depth) Insert the body BODY at depth DEPTH in the current thread. -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v5 4/4] emacs: show: set default show-all-multipart/alternatives to nil
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. --- emacs/notmuch-show.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index f9366d0..5751d98 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -94,7 +94,7 @@ visible for any given message. :group 'notmuch-hooks) ;; Mostly useful for debugging. -(defcustom notmuch-show-all-multipart/alternative-parts t +(defcustom notmuch-show-all-multipart/alternative-parts nil Should all parts of multipart/alternative parts be shown? :type 'boolean :group 'notmuch-show) -- 1.7.9.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] News for changes from Austin Clements
I fear I've fallen behind on my NEWS duties. --- NEWS | 64 1 file changed, 64 insertions(+) diff --git a/NEWS b/NEWS index 2e1c054..8865ef9 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,17 @@ Notmuch 0.15 (-MM-DD) Command-Line Interface -- +`notmuch new` no longer chokes on mboxes + + `notmuch new` now rejects mbox files containing more than one + message, rather than treating the file as one giant message. + +Support for single message mboxes is deprecated + + For historical reasons, `notmuch new` will index mbox files + containing a single message; however, this behavior is now + officially deprecated. + Empty tag names and tags beginning with - are deprecated Such tags have been a frequent source of confusion and cause @@ -12,12 +23,24 @@ Empty tag names and tags beginning with - are deprecated tags continues to be supported to allow cleanup of existing tags, but may be removed in a future release. +Fixed `notmuch new` to skip ignored broken symlinks + + `notmuch new` now correctly skips symlinks if they are in the + ignored files list. Previously, it would abort when encountering + broken symlink, even if it was ignored. + Bcc and Reply-To headers are now available in notmuch show json output The `notmuch show --format=json` now includes Bcc and Reply-To headers. For example notmuch Emacs client can now have these headers visible when the headers are added to the `notmuch-message-headers` variable. +CLI callers can now request a specific output format version + + `notmuch` subcommands that support structured output now support a + `--format-version` argument for requesting a specific version of the + structured output, enabling better compatibility and error handling. + Emacs Interface --- @@ -28,6 +51,12 @@ Removal of the deprecated `notmuch-folders` variable has now been removed. Any remaining users should migrate to `notmuch-saved-searches`. +Emacs now buttonizes mid: links + + mid: links are a standardized way to link to messages by message ID + (see RFC 2392). Emacs now hyperlinks mid: links to the appropriate + notmuch search. + Handle errors from bodypart insertions If displaying the text of a message in show mode causes an error (in @@ -35,6 +64,11 @@ Handle errors from bodypart insertions off thread display at the offending message. The error is now simply displayed in place of the message. +Emacs now detects version mismatches with the notmuch CLI + + Emacs now detects and reports when the Emacs interface version and + the notmuch CLI version are incompatible. + Improved text/calendar content handling Carriage returns in embedded text/calendar content caused insertion @@ -49,6 +83,21 @@ Disabled coding conversions when reading in `with-current-notmuch-show-message` corrupting the saved attachment. This has been fixed by making `with-current-notmuch-show-message` disable coding conversion. +Fixed errors with HTML email containing images in Emacs 24 + + Emacs 24 ships with a new HTML renderer that produces better output, + but is slightly buggy. We work around a bug that caused it to fail + for HTML email containing images. + +Fixed handling of tags with unusual characters in them + + Emacs now handles tags containing spaces, quotes, and parenthesis. + +Fixed buttonization of id: links without quote characters + + Emacs now correctly buttonizes id: links where the message ID is not + quoted. + Library changes --- @@ -72,6 +121,21 @@ terms of amount of output and can be useful for viewing both single threads and multiple threads. See the notmuch-pick README file for further details and installation. +Portability +--- + +notmuch now builds on OpenBSD. + +Internal test framework changes +--- + +The emacsclient binary is now user-configurable + + The test framework now accepts TEST_EMACSCLIENT in addition to + TEST_EMACS for configuring the emacsclient to use. This is + necessary to avoid using an old emacsclient with a new emacs, which + can result in buggy behavior. + Notmuch 0.14 (2012-08-20) = -- 1.7.10.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] news: Promote some things to a general section
Date range search may be implemented as a library change, but it's an important user-facing change that affects all notmuch usage. Tag name restrictions aren't as important, but they affect both the CLI interface and the Emacs interface. --- NEWS | 40 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 8865ef9..3e48501 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,26 @@ Notmuch 0.15 (-MM-DD) = +General +--- + +Date range search support + + The `date:` prefix can now be used in queries to restrict the results + to only messages within a particular time range (based on the Date: + header) with a range syntax of `date:since..until`. Notmuch + supports a wide variety of expressions in `since` and + `until`. Please refer to the `notmuch-search-terms(7)` manual page + for details. + +Empty tag names and tags beginning with - are deprecated + + Such tags have been a frequent source of confusion and cause + (sometimes unresolvable) conflicts with other syntax. notmuch tag + no longer allows such tags to be added to messages. Removing such + tags continues to be supported to allow cleanup of existing tags, + but may be removed in a future release. + Command-Line Interface -- @@ -15,14 +35,6 @@ Support for single message mboxes is deprecated containing a single message; however, this behavior is now officially deprecated. -Empty tag names and tags beginning with - are deprecated - - Such tags have been a frequent source of confusion and cause - (sometimes unresolvable) conflicts with other syntax. notmuch tag - no longer allows such tags to be added to messages. Removing such - tags continues to be supported to allow cleanup of existing tags, - but may be removed in a future release. - Fixed `notmuch new` to skip ignored broken symlinks `notmuch new` now correctly skips symlinks if they are in the @@ -98,18 +110,6 @@ Fixed buttonization of id: links without quote characters Emacs now correctly buttonizes id: links where the message ID is not quoted. -Library changes - -Date range search support - - The `date:` prefix can now be used in queries to restrict the results - to only messages within a particular time range (based on the Date: - header) with a range syntax of `date:since..until`. Notmuch - supports a wide variety of expressions in `since` and - `until`. Please refer to the `notmuch-search-terms(7)` manual page - for details. - New add-on tool: notmuch-pick - -- 1.7.10.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v4 0/5] add --format=text0 to notmuch search
Jani Nikula j...@nikula.org writes: Hi all, a quick rebase of id:cover.1355691124.git.j...@nikula.org to fix a tiny conflict in patch context of 3/5. pushed, d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v5 0/4] Use invisibility to toggle display of all parts including multipart
Quoth Mark Walters on Dec 18 at 7:27 pm: This is an alternative version of id:1355781287-6010-1-git-send-email-markwalters1...@gmail.com based on top of Austin's patch at id:1355812810-32747-1-git-send-email-amdra...@mit.edu Austin's patch significantly simplifies the invisibility handling taking this series down from 90/27 to 68/26 in diffstat terms. In general terms Austin's approach has to be the right thing to do: what we want to do just before the freeze is less clear. My view is that we should go with Austin's approach now so that at least any bugs we get from it and (more likely) from this series apply to master as well. I am posting this series to make it easier for people to judge the two approaches when finished (ie with part invisibility too). I attach a trimmed diff from v4 below the diffstat (note this was a diff with -U10 which I have trimmed so it is purely for information) Note we no longer need patch 4/5 because in this approach the overlays do not need to know about other overlays. Best wishes Mark LGTM. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch