* [WIP Patch 1/7] Make keys of notmuch-tag-formats regexps and use caching
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 2/7] emacs: tag split customise option for format-tags into a widget Mark Walters
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
From: Austin Clements <amdragon@MIT.EDU>
This was a little hack to test the feasibility of switching
notmuch-tag-formats to use regexps with caching for performance. In
the end it works fine and isn't particularly complex, though there
were a few gotchas:
1) We have to clear the cache somehow on changes to
notmuch-tag-formats. I opted to use a defcustom :set plus some
documentation telling people what to do if they change it directly
from Elisp. This is less automatic than I would like, but I doubt
people are changing this very often and I concluded that any machinery
to automatically detect changes to notmuch-tag-formats would probably
outweigh the benefits of caching. Alternatively, we could require
search/show/tree buffers to "opt in" to caching when they start
building.
2) I spent way too long trying to use assoc-default before realizing
this it just wouldn't work, since there's no way to distinguish a
missing key from a present key with a null cdr. assoc* from cl works
fine.
Performance-wise, the caching of regexp lookup makes this just as fast
as assoc for unformatted tags (it would probably be faster if someone
had a really big `notmuch-tag-formats') and the caching of eval
results makes this much *faster* than the current code for formatted
tags.
inbox (usec) unread (usec)
assoc: 0.4 2.8
regexp: 3.2 7.2
regexp+caching: 0.4 0.4
That said, even at 7.2 usec, tag formatting is still *very* fast
(though regexp matching may get noticeably slower with larger
`notmuch-tag-formats'). Tag formatting is nowhere near our top
bottleneck.
---
emacs/notmuch-tag.el | 75 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 53 insertions(+), 22 deletions(-)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 908e7ad..cb88fd5 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -28,35 +28,56 @@
(require 'crm)
(require 'notmuch-lib)
+;; (notmuch-tag-clear-cache will be called by the defcustom
+;; notmuch-tag-formats, so it has to be defined first.)
+
+(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
+ "Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
+
+(defun notmuch-tag-clear-cache ()
+ "Clear the internal cache of tag formats.
+
+This must be called after changes to `notmuch-tag-formats'."
+ (clrhash notmuch-tag--format-cache))
+
(defcustom notmuch-tag-formats
'(("unread" (propertize tag 'face '(:foreground "red")))
("flagged" (propertize tag 'face '(:foreground "blue"))
(notmuch-tag-format-image-data tag (notmuch-tag-star-icon))))
"Custom formats for individual tags.
-This gives a list that maps from tag names to lists of formatting
-expressions. The car of each element gives a tag name and the
-cdr gives a list of Elisp expressions that modify the tag. If
-the list is empty, the tag will simply be hidden. Otherwise,
-each expression will be evaluated in order: for the first
-expression, the variable `tag' will be bound to the tag name; for
-each later expression, the variable `tag' will be bound to the
-result of the previous expression. In this way, each expression
-can build on the formatting performed by the previous expression.
-The result of the last expression will displayed in place of the
-tag.
+This is an association list that maps from tag name regexps to
+lists of formatting expressions. The first entry whose car
+regexp-matches a tag will be used to format that tag. The regexp
+is implicitly anchored, so to match a literal tag name, just use
+that tag name (if it contains special regexp characters like
+\".\" or \"*\", these have to be escaped). The cdr of the
+matching entry gives a list of Elisp expressions that modify the
+tag. If the list is empty, the tag will simply be hidden.
+Otherwise, each expression will be evaluated in order: for the
+first expression, the variable `tag' will be bound to the tag
+name; for each later expression, the variable `tag' will be bound
+to the result of the previous expression. In this way, each
+expression can build on the formatting performed by the previous
+expression. The result of the last expression will displayed in
+place of the tag.
For example, to replace a tag with another string, simply use
that string as a formatting expression. To change the foreground
of a tag to red, use the expression
(propertize tag 'face '(:foreground \"red\"))
+After modifying this variable in Elisp, be sure to call
+`notmuch-tag-clear-cache'. Modifying this via customize does
+this automatically.
+
See also `notmuch-tag-format-image', which can help replace tags
with images."
:group 'notmuch-search
:group 'notmuch-show
- :type '(alist :key-type (string :tag "Tag")
+ :set (lambda (var val) (set-default var val) (notmuch-tag-clear-cache))
+ :type '(alist :key-type (regexp :tag "Tag")
:extra-offset -3
:value-type
(radio :format "%v"
@@ -137,16 +158,26 @@ This can be used with `notmuch-tag-format-image-data'."
(defun notmuch-tag-format-tag (tag)
"Format TAG by looking into `notmuch-tag-formats'."
- (let ((formats (assoc tag notmuch-tag-formats)))
- (cond
- ((null formats) ;; - Tag not in `notmuch-tag-formats',
- tag) ;; the format is the tag itself.
- ((null (cdr formats)) ;; - Tag was deliberately hidden,
- nil) ;; no format must be returned
- (t ;; - Tag was found and has formats,
- (let ((tag tag)) ;; we must apply all the formats.
- (dolist (format (cdr formats) tag)
- (setq tag (eval format))))))))
+ (let ((formatted (gethash tag notmuch-tag--format-cache 'missing)))
+ (when (eq formatted 'missing)
+ (let* ((formats
+ (save-match-data
+ (assoc* tag notmuch-tag-formats
+ :test (lambda (tag key)
+ (and (eq (string-match key tag) 0)
+ (= (match-end 0) (length tag))))))))
+ (setq formatted
+ (cond
+ ((null formats) ;; - Tag not in `notmuch-tag-formats',
+ tag) ;; the format is the tag itself.
+ ((null (cdr formats)) ;; - Tag was deliberately hidden,
+ nil) ;; no format must be returned
+ (t ;; - Tag was found and has formats,
+ (let ((tag tag)) ;; we must apply all the formats.
+ (dolist (format (cdr formats) tag)
+ (setq tag (eval format)))))))
+ (puthash tag formatted notmuch-tag--format-cache)))
+ formatted))
(defun notmuch-tag-format-tags (tags &optional face)
"Return a string representing formatted TAGS."
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 2/7] emacs: tag split customise option for format-tags into a widget
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
2014-02-14 9:15 ` [WIP Patch 1/7] Make keys of notmuch-tag-formats regexps and use caching Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 3/7] emacs: tag: add customize for deleted/added tag formats Mark Walters
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
We will re-use the customize option for format-tags for formattting
deleted tags to added tags in the next patch so split it into a
widget. There should be no functional change.
---
emacs/notmuch-tag.el | 55 ++++++++++++++++++++++++++-----------------------
1 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index cb88fd5..f987291 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -40,6 +40,34 @@
This must be called after changes to `notmuch-tag-formats'."
(clrhash notmuch-tag--format-cache))
+(define-widget 'notmuch-tag-format-type 'lazy
+ "Customize widget for notmuch-tag-format and friends"
+ :type '(alist :key-type (regexp :tag "Tag")
+ :extra-offset -3
+ :value-type
+ (radio :format "%v"
+ (const :tag "Hidden" nil)
+ (set :tag "Modified"
+ (string :tag "Display as")
+ (list :tag "Face" :extra-offset -4
+ (const :format "" :inline t
+ (propertize tag 'face))
+ (list :format "%v"
+ (const :format "" quote)
+ custom-face-edit))
+ (list :format "%v" :extra-offset -4
+ (const :format "" :inline t
+ (notmuch-tag-format-image-data tag))
+ (choice :tag "Image"
+ (const :tag "Star"
+ (notmuch-tag-star-icon))
+ (const :tag "Empty star"
+ (notmuch-tag-star-empty-icon))
+ (const :tag "Tag"
+ (notmuch-tag-tag-icon))
+ (string :tag "Custom")))
+ (sexp :tag "Custom")))))
+
(defcustom notmuch-tag-formats
'(("unread" (propertize tag 'face '(:foreground "red")))
("flagged" (propertize tag 'face '(:foreground "blue"))
@@ -73,35 +101,10 @@ this automatically.
See also `notmuch-tag-format-image', which can help replace tags
with images."
-
:group 'notmuch-search
:group 'notmuch-show
:set (lambda (var val) (set-default var val) (notmuch-tag-clear-cache))
- :type '(alist :key-type (regexp :tag "Tag")
- :extra-offset -3
- :value-type
- (radio :format "%v"
- (const :tag "Hidden" nil)
- (set :tag "Modified"
- (string :tag "Display as")
- (list :tag "Face" :extra-offset -4
- (const :format "" :inline t
- (propertize tag 'face))
- (list :format "%v"
- (const :format "" quote)
- custom-face-edit))
- (list :format "%v" :extra-offset -4
- (const :format "" :inline t
- (notmuch-tag-format-image-data tag))
- (choice :tag "Image"
- (const :tag "Star"
- (notmuch-tag-star-icon))
- (const :tag "Empty star"
- (notmuch-tag-star-empty-icon))
- (const :tag "Tag"
- (notmuch-tag-tag-icon))
- (string :tag "Custom")))
- (sexp :tag "Custom")))))
+ :type 'notmuch-tag-format-type)
(defun notmuch-tag-format-image-data (tag data)
"Replace TAG with image DATA, if available.
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 3/7] emacs: tag: add customize for deleted/added tag formats
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
2014-02-14 9:15 ` [WIP Patch 1/7] Make keys of notmuch-tag-formats regexps and use caching Mark Walters
2014-02-14 9:15 ` [WIP Patch 2/7] emacs: tag split customise option for format-tags into a widget Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 4/7] emacs: show: mark tags changed since buffer loaded Mark Walters
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
Add customize options for deleted/added tag formats. These are not
used yet but will be later in the series.
---
emacs/notmuch-tag.el | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index f987291..add60a3 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -106,6 +106,39 @@ with images."
:set (lambda (var val) (set-default var val) (notmuch-tag-clear-cache))
:type 'notmuch-tag-format-type)
+(defcustom notmuch-tag-deleted-formats
+ '((".*" (propertize tag 'face
+ (if (display-supports-face-attributes-p '(:strike-through "red"))
+ '(:strike-through "red")
+ '(:inverse-video t)))))
+ "Custom formats for tags when deleted.
+
+For deleted tags the formats in `notmuch-tag-formats` are applied
+first and then these formats are applied on top.
+
+By default this shows deleted tags with strike-through in red,
+unless strike-through is not available (e.g., emacs is running in
+a terminal) in which case it uses inverse video. To hide deleted
+tags completely set this to
+ '((\"\" nil))
+
+See `notmuch-tag-formats' for full documentation."
+ :group 'notmuch-show
+ :set (lambda (var val) (set-default var val) (notmuch-tag-clear-cache))
+ :type 'notmuch-tag-format-type)
+
+(defcustom notmuch-tag-added-formats
+ '((".*" (propertize tag 'face '(:underline "green"))))
+ "Custom formats for tags when added.
+
+For added tags the formats in `notmuch-tag-formats` are applied
+first and then these formats are applied on top.
+
+See `notmuch-tag-formats' for full documentation."
+ :group 'notmuch-show
+ :set (lambda (var val) (set-default var val) (notmuch-tag-clear-cache))
+ :type 'notmuch-tag-format-type)
+
(defun notmuch-tag-format-image-data (tag data)
"Replace TAG with image DATA, if available.
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 4/7] emacs: show: mark tags changed since buffer loaded
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
` (2 preceding siblings ...)
2014-02-14 9:15 ` [WIP Patch 3/7] emacs: tag: add customize for deleted/added tag formats Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 5/7] emacs: show: use orig-tags for tag display Mark Walters
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
This allows (and requires) the original-tags to be passed along with
the current-tags to be passed to notmuch-tag-format-tags. This allows
the tag formatting to show added and deleted tags.By default a removed
tag is displayed with strike-through in red (if strike-through is not
available, eg on a terminal, inverse video is used instead) and an
added tag is displayed underlined in green.
If the caller does not wish to use the new feature it can pass
current-tags for both arguments and, at this point, we do exactly that
in the three callers of this function.
Note, we cannot tidily allow original-tags to be optional because we would
need to distinguish nil meaning "we are not specifying original-tags"
from nil meaning there were no original-tags (an empty list).
We use this in subsequent patches to make it clear when a message was
unread when you first loaded a show buffer (previously the unread tag
could be removed before a user realised that it had been unread).
The code adds into the existing tag formatting code. The user can
specify exactly how a tag should be displayed normally, when deleted,
or when added. For convenience an entry for the empty string in the
notmuch-tag-formats (and the corresponding notmuch-tag-deleted-formats
notmuch-tag-added-formats) is applied to all tags which do not have an
explicit match.
This means that a user can tell notmuch not to show deleted tags at
all by setting notmuch-tag-deleted-formats to
'(("" nil))
or not to show any deleted tags except "unread" by setting it to
'(("" nil)
("unread" (propertize tag 'face '(strike-through "red"))))
All the variables are customizable; however, more complicated cases
like changing the face depending on the type of display will require
custom lisp.
Currently this overrides notmuch-tag-deleted-formats for the tests
setting it to '(("" nil)) so that they get removed from the display
and, thus, all tests still pass.
---
emacs/notmuch-show.el | 4 +-
emacs/notmuch-tag.el | 65 ++++++++++++++++++++++++++++++++++++++----------
emacs/notmuch-tree.el | 2 +-
emacs/notmuch.el | 2 +-
test/test-lib.el | 5 ++++
5 files changed, 60 insertions(+), 18 deletions(-)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 1ac80ca..1ce56f9 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -344,7 +344,7 @@ operation on the contents of the current buffer."
(if (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
(let ((inhibit-read-only t))
(replace-match (concat "("
- (notmuch-tag-format-tags tags)
+ (notmuch-tag-format-tags tags tags)
")"))))))
(defun notmuch-clean-address (address)
@@ -423,7 +423,7 @@ message at DEPTH in the current thread."
" ("
date
") ("
- (notmuch-tag-format-tags tags)
+ (notmuch-tag-format-tags tags tags)
")\n")
(overlay-put (make-overlay start (point)) 'face 'notmuch-message-summary-face)))
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index add60a3..812a0f4 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -192,36 +192,73 @@ This can be used with `notmuch-tag-format-image-data'."
</g>
</svg>")
-(defun notmuch-tag-format-tag (tag)
- "Format TAG by looking into `notmuch-tag-formats'."
- (let ((formatted (gethash tag notmuch-tag--format-cache 'missing)))
+(defun notmuch-tag-format-tag-by-state (tag formatted-tag tag-state)
+ "Format TAG by looking into the appropriate `notmuch-tag-formats`.
+
+Applies formats for TAG from the appropriate one of
+`notmuch-tag-formats`, `notmuch-tag-deleted-formats` and
+`notmuch-tag-added-formats` based on TAG-STATE to the partially
+formatted tag FORMATTED-TAG."
+ (let ((formatted (gethash (cons tag tag-state) notmuch-tag--format-cache 'missing)))
(when (eq formatted 'missing)
- (let* ((formats
+ (let* ((tag-formats (cond ((null tag-state) notmuch-tag-formats)
+ ((eq 'deleted tag-state) notmuch-tag-deleted-formats)
+ ((eq 'added tag-state) notmuch-tag-added-formats)))
+ (formats
(save-match-data
- (assoc* tag notmuch-tag-formats
+ (assoc* tag tag-formats
:test (lambda (tag key)
(and (eq (string-match key tag) 0)
(= (match-end 0) (length tag))))))))
(setq formatted
(cond
- ((null formats) ;; - Tag not in `notmuch-tag-formats',
- tag) ;; the format is the tag itself.
+ ((null formats) ;; - Tag not in `tag-formats',
+ formatted-tag) ;; the format is the tag itself.
((null (cdr formats)) ;; - Tag was deliberately hidden,
nil) ;; no format must be returned
- (t ;; - Tag was found and has formats,
- (let ((tag tag)) ;; we must apply all the formats.
+ (t
+ ;; Tag was found and has formats, we must apply all
+ ;; the formats. FORMATTED-TAG may be null so treat
+ ;; that as a special case.
+ (let ((tag (or formatted-tag "")))
(dolist (format (cdr formats) tag)
- (setq tag (eval format)))))))
- (puthash tag formatted notmuch-tag--format-cache)))
+ (setq tag (eval format)))
+ (if (and (null formatted-tag)
+ (equal tag ""))
+ nil
+ tag)))))
+ (puthash (cons tag tag-state) formatted notmuch-tag--format-cache)))
formatted))
-(defun notmuch-tag-format-tags (tags &optional face)
+(defun notmuch-tag-format-tag (tags orig-tags tag)
+ "Format TAG by looking into `notmuch-tag-formats'.
+
+TAGS and ORIG-TAGS are lists of the current tags and the original
+tags; tags which have been deleted (i.e., are in ORIG-TAGS but
+are not in TAGS) are shown using formats from
+`notmuch-tag-deleted-formats'; tags which have been added (i.e.,
+are in TAGS but are not in ORIG-TAGS) are shown using formats
+from `notmuch-tag-added-formats' and tags which have not been
+changed (the normal case) are shown using formats from
+`notmuch-tag-formats'"
+ (let* ((formatted-tag (notmuch-tag-format-tag-by-state tag tag nil)))
+ (cond ((not (member tag tags))
+ (notmuch-tag-format-tag-by-state tag formatted-tag 'deleted))
+ ((not (member tag orig-tags))
+ (notmuch-tag-format-tag-by-state tag formatted-tag 'added))
+ (t
+ formatted-tag))))
+
+(defun notmuch-tag-format-tags (tags orig-tags &optional face)
"Return a string representing formatted TAGS."
- (let ((face (or face 'notmuch-tag-face)))
+ (let ((face (or face 'notmuch-tag-face))
+ (all-tags (sort (delete-dups (append tags orig-tags nil)) #'string<)))
(notmuch-combine-face-text-property-string
(mapconcat #'identity
;; nil indicated that the tag was deliberately hidden
- (delq nil (mapcar #'notmuch-tag-format-tag tags))
+ (delq nil (mapcar
+ (apply-partially #'notmuch-tag-format-tag tags orig-tags)
+ all-tags))
" ")
face
t)))
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 4f2ac02..b37e2cd 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -704,7 +704,7 @@ unchanged ADDRESS if parsing fails."
(face (if match
'notmuch-tree-match-tag-face
'notmuch-tree-no-match-tag-face)))
- (format format-string (notmuch-tag-format-tags tags face)))))))
+ (format format-string (notmuch-tag-format-tags tags tags face)))))))
(defun notmuch-tree-format-field-list (field-list msg)
"Format fields of MSG according to FIELD-LIST and return string"
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 0471750..1436e5a 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -754,7 +754,7 @@ non-authors is found, assume that all of the authors match."
((string-equal field "tags")
(let ((tags (plist-get result :tags)))
- (insert (format format-string (notmuch-tag-format-tags tags)))))))
+ (insert (format format-string (notmuch-tag-format-tags tags tags)))))))
(defun notmuch-search-show-result (result &optional pos)
"Insert RESULT at POS or the end of the buffer if POS is null."
diff --git a/test/test-lib.el b/test/test-lib.el
index 37fcb3d..437f83f 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -165,3 +165,8 @@ nothing."
(t
(notmuch-test-report-unexpected output expected)))))
+
+;; For historical reasons, we hide deleted tags by default in the test
+;; suite
+(setq notmuch-tag-deleted-formats
+ '((".*" nil)))
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 5/7] emacs: show: use orig-tags for tag display
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
` (3 preceding siblings ...)
2014-02-14 9:15 ` [WIP Patch 4/7] emacs: show: mark tags changed since buffer loaded Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 6/7] emacs: search: use orig-tags in search Mark Walters
2014-02-14 9:15 ` [WIP Patch 7/7] emacs: tree: " Mark Walters
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
This uses the previous patch to show the tag changes that have occured
in the show buffer since it was last loaded/refreshed.
---
emacs/notmuch-show.el | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 1ce56f9..97243dc 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -344,7 +344,7 @@ operation on the contents of the current buffer."
(if (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
(let ((inhibit-read-only t))
(replace-match (concat "("
- (notmuch-tag-format-tags tags tags)
+ (notmuch-tag-format-tags tags (notmuch-show-get-prop :orig-tags))
")"))))))
(defun notmuch-clean-address (address)
@@ -1167,6 +1167,8 @@ function is used."
(jit-lock-register #'notmuch-show-buttonise-links)
+ (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags))))
+
;; Set the header line to the subject of the first message.
(setq header-line-format (notmuch-sanitize (notmuch-show-strip-re (notmuch-show-get-subject))))
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 6/7] emacs: search: use orig-tags in search
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
` (4 preceding siblings ...)
2014-02-14 9:15 ` [WIP Patch 5/7] emacs: show: use orig-tags for tag display Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
2014-02-14 9:15 ` [WIP Patch 7/7] emacs: tree: " Mark Walters
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
This uses the recent functionality to show the tag changes in the
search buffer. Currently this is only used to show changes the search
buffer makes itself: i.e., it does not make display any changes
reflecting tagging done by other notmuch-buffers.
---
emacs/notmuch.el | 40 ++++++++++++++++++++++++----------------
1 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 1436e5a..f07b216 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -753,24 +753,32 @@ non-authors is found, assume that all of the authors match."
format-string (notmuch-sanitize (plist-get result :authors))))
((string-equal field "tags")
- (let ((tags (plist-get result :tags)))
- (insert (format format-string (notmuch-tag-format-tags tags tags)))))))
+ (let ((tags (plist-get result :tags))
+ (orig-tags (plist-get result :orig-tags)))
+ (insert (format format-string (notmuch-tag-format-tags tags orig-tags)))))))
-(defun notmuch-search-show-result (result &optional pos)
- "Insert RESULT at POS or the end of the buffer if POS is null."
+(defun notmuch-search-show-result (result beg)
+ "Insert RESULT at BEG."
;; Ignore excluded matches
(unless (= (plist-get result :matched) 0)
- (let ((beg (or pos (point-max))))
- (save-excursion
- (goto-char beg)
- (dolist (spec notmuch-search-result-format)
- (notmuch-search-insert-field (car spec) (cdr spec) result))
- (insert "\n")
- (notmuch-search-color-line beg (point) (plist-get result :tags))
- (put-text-property beg (point) 'notmuch-search-result result))
- (when (string= (plist-get result :thread) notmuch-search-target-thread)
- (setq notmuch-search-target-thread "found")
- (goto-char beg)))))
+ (save-excursion
+ (goto-char beg)
+ (dolist (spec notmuch-search-result-format)
+ (notmuch-search-insert-field (car spec) (cdr spec) result))
+ (insert "\n")
+ (notmuch-search-color-line beg (point) (plist-get result :tags))
+ (put-text-property beg (point) 'notmuch-search-result result))
+ (when (string= (plist-get result :thread) notmuch-search-target-thread)
+ (setq notmuch-search-target-thread "found")
+ (goto-char beg))))
+
+(defun notmuch-search-append-result (result)
+ "Insert RESULT at the end of the buffer.
+
+This is only called when a result is first inserted so it also
+sets the :orig-tag property."
+ (plist-put result :orig-tags (plist-get result :tags))
+ (notmuch-search-show-result result (point-max)))
(defun notmuch-search-process-filter (proc string)
"Process and filter the output of \"notmuch search\""
@@ -784,7 +792,7 @@ non-authors is found, assume that all of the authors match."
(save-excursion
(goto-char (point-max))
(insert string))
- (notmuch-sexp-parse-partial-list 'notmuch-search-show-result
+ (notmuch-sexp-parse-partial-list 'notmuch-search-append-result
results-buf)))))
(defun notmuch-search-tag-all (tag-changes)
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [WIP Patch 7/7] emacs: tree: use orig-tags in search
2014-02-14 9:15 [WIP Patch 0/7] emacs: show tag changes in buffer Mark Walters
` (5 preceding siblings ...)
2014-02-14 9:15 ` [WIP Patch 6/7] emacs: search: use orig-tags in search Mark Walters
@ 2014-02-14 9:15 ` Mark Walters
6 siblings, 0 replies; 8+ messages in thread
From: Mark Walters @ 2014-02-14 9:15 UTC (permalink / raw)
To: notmuch, Austin Clements
This uses the recent functionality to show the tag changes in the tree
buffer. Currently this is only used to show changes the tree buffer
makes itself: i.e., it does not make display any changes reflecting
tagging done by other notmuch-buffers.
---
emacs/notmuch-tree.el | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index b37e2cd..0f4cd47 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -701,10 +701,11 @@ unchanged ADDRESS if parsing fails."
((string-equal field "tags")
(let ((tags (plist-get msg :tags))
+ (orig-tags (plist-get msg :orig-tags))
(face (if match
'notmuch-tree-match-tag-face
'notmuch-tree-no-match-tag-face)))
- (format format-string (notmuch-tag-format-tags tags tags face)))))))
+ (format format-string (notmuch-tag-format-tags tags orig-tags face)))))))
(defun notmuch-tree-format-field-list (field-list msg)
"Format fields of MSG according to FIELD-LIST and return string"
@@ -766,8 +767,10 @@ message together with all its descendents."
(push "├" tree-status)))
(push (concat (if replies "┬" "─") "►") tree-status)
- (plist-put msg :first (and first (eq 0 depth)))
- (notmuch-tree-goto-and-insert-msg (plist-put msg :tree-status tree-status))
+ (setq msg (plist-put msg :first (and first (eq 0 depth))))
+ (setq msg (plist-put msg :tree-status tree-status))
+ (setq msg (plist-put msg :orig-tags (plist-get msg :tags)))
+ (notmuch-tree-goto-and-insert-msg msg)
(pop tree-status)
(pop tree-status)
--
1.7.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread