* [PATCH 01/13] emacs: Usability improvements for `notmuch-hello'.
2010-05-19 7:03 patches for 0.4 David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 02/13] notmuch: Fix off-by-one errors if a header is >200 characters long David Edmondson
` (12 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
- If no saved searches exist or are displayed, don't signal an error,
- If no saved searches exist or are displayed, leave the cursor in the
search bar,
- Minor layout improvements.
---
emacs/notmuch-hello.el | 36 +++++++++++++++++++-----------------
1 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 6a1c56e..1358387 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -273,7 +273,7 @@ diagonal."
(notmuch-hello-update))
:help-echo "Refresh"
(car (process-lines notmuch-command "count")))
- (widget-insert " messages (that's not much mail).\n\n"))
+ (widget-insert " messages (that's not much mail).\n"))
(let ((found-target-pos nil)
(final-target-pos nil))
@@ -292,7 +292,7 @@ diagonal."
(widest (max saved-widest alltags-widest)))
(when saved-alist
- (widget-insert "Saved searches: ")
+ (widget-insert "\nSaved searches: ")
(widget-create 'push-button
:notify (lambda (&rest ignore)
(customize-variable 'notmuch-saved-searches))
@@ -305,18 +305,16 @@ diagonal."
(setq final-target-pos found-target-pos))
(indent-rigidly start (point) notmuch-hello-indent)))
- (let ((start (point)))
- (widget-insert "\nSearch: ")
- (setq notmuch-hello-search-bar-marker (point-marker))
- (widget-create 'editable-field
- ;; Leave some space at the start and end of the
- ;; search boxes.
- :size (max 8 (- (window-width) (* 2 notmuch-hello-indent)
- (length "Search: ")))
- :action (lambda (widget &rest ignore)
- (notmuch-hello-search (widget-value widget))))
- (widget-insert "\n")
- (indent-rigidly start (point) notmuch-hello-indent))
+ (widget-insert "\nSearch: ")
+ (setq notmuch-hello-search-bar-marker (point-marker))
+ (widget-create 'editable-field
+ ;; Leave some space at the start and end of the
+ ;; search boxes.
+ :size (max 8 (- (window-width) notmuch-hello-indent
+ (length "Search: ")))
+ :action (lambda (widget &rest ignore)
+ (notmuch-hello-search (widget-value widget))))
+ (widget-insert "\n")
(when notmuch-hello-recent-searches
(widget-insert "\nRecent searches: ")
@@ -408,9 +406,13 @@ diagonal."
(widget-setup)
- (goto-char final-target-pos)
- (if (not (widget-at))
- (widget-forward 1)))))
+ (when final-target-pos
+ (goto-char final-target-pos)
+ (unless (widget-at)
+ (widget-forward 1)))
+
+ (unless (widget-at)
+ (notmuch-hello-goto-search)))))
;;;###autoload
(defun notmuch-folder ()
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/13] notmuch: Fix off-by-one errors if a header is >200 characters long.
2010-05-19 7:03 patches for 0.4 David Edmondson
2010-05-19 7:03 ` [PATCH 01/13] emacs: Usability improvements for `notmuch-hello' David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 03/13] emacs: Adjust comment to avoid confusing font-lock David Edmondson
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
If a single header is more than 200 characters long a set of 'off by
one' errors cause memory corruption.
When allocating memory with:
a = malloc (len);
the last usable byte of the memory is 'a + len - 1' rather than 'a +
len'.
Fix the same bug when calculating the current offset should the buffer
used for collecting the output header need to be reallocated.
---
| 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
--git a/gmime-filter-headers.c b/gmime-filter-headers.c
index 2f3df80..7db3779 100644
--- a/gmime-filter-headers.c
+++ b/gmime-filter-headers.c
@@ -169,7 +169,7 @@ filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
headers->lineptr = headers->line = malloc (headers->line_size);
}
lineptr = headers->lineptr;
- lineend = headers->line + headers->line_size;
+ lineend = headers->line + headers->line_size - 1;
if (lineptr == NULL)
return;
outptr = filter->outbuf;
@@ -185,8 +185,8 @@ filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
if (lineptr == lineend) {
headers->line_size *= 2;
headers->line = xrealloc (headers->line, headers->line_size);
- lineptr = headers->line + headers->line_size / 2;
- lineend = headers->line + headers->line_size;
+ lineptr = headers->line + (headers->line_size / 2) - 1;
+ lineend = headers->line + headers->line_size - 1;
}
if (headers->saw_nl && *inptr != ' ' && *inptr != '\t') {
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/13] emacs: Adjust comment to avoid confusing font-lock.
2010-05-19 7:03 patches for 0.4 David Edmondson
2010-05-19 7:03 ` [PATCH 01/13] emacs: Usability improvements for `notmuch-hello' David Edmondson
2010-05-19 7:03 ` [PATCH 02/13] notmuch: Fix off-by-one errors if a header is >200 characters long David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 04/13] emacs: Display non-matching authors with a different face David Edmondson
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Comments with an open bracket in the first column confuse `font-lock'
mode, so avoid them.
---
emacs/notmuch.el | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 57e1140..7457da9 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -551,10 +551,10 @@ This function advances the next thread when finished."
"Tag/face mapping for line highlighting in notmuch-search.
Here is an example of how to color search results based on tags.
-(the following text would be placed in your ~/.emacs file):
+ (the following text would be placed in your ~/.emacs file):
-(setq notmuch-search-line-faces '((\"delete\" . '(:foreground \"red\"))
- (\"unread\" . '(:foreground \"green\"))))
+ (setq notmuch-search-line-faces '((\"delete\" . '(:foreground \"red\"))
+ (\"unread\" . '(:foreground \"green\"))))
Order matters: for lines with multiple tags, the the first
matching will be applied."
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/13] emacs: Display non-matching authors with a different face.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (2 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 03/13] emacs: Adjust comment to avoid confusing font-lock David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 05/13] emacs: Set the `face' property rather than `font-lock-face' David Edmondson
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
In search mode some messages don't match the search criteria. Show
their authors names with a different face - generally darker than
those that do match.
---
emacs/notmuch.el | 36 +++++++++++++++++++++++++++++-------
1 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 7457da9..60c0ee5 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -297,6 +297,17 @@ For a mouse binding, return nil."
"Notmuch search mode face used to highligh tags."
:group 'notmuch)
+(defface notmuch-search-non-matching-authors
+ '((((class color)
+ (background dark))
+ (:foreground "grey30"))
+ (((class color)
+ (background light))
+ (:foreground "grey60"))
+ (t (:italic t)))
+ "Face used in search mode for authors not matching the query."
+ :group 'notmuch)
+
;;;###autoload
(defun notmuch-search-mode ()
"Major mode displaying results of a notmuch search.
@@ -576,6 +587,23 @@ matching will be applied."
(t
(setq tags-faces (cdr tags-faces)))))))))
+(defun notmuch-search-insert-authors (format-string authors)
+ (insert (let* ((formatted-sample (format format-string ""))
+ (formatted-authors (format format-string authors))
+ (truncated-string
+ (if (> (length formatted-authors)
+ (length formatted-sample))
+ (concat (substring authors 0 (- (length formatted-sample) 4)) "... ")
+ formatted-authors)))
+ ;; Need to save the match data to avoid interfering with
+ ;; `notmuch-search-process-filter'.
+ (save-match-data
+ (if (string-match "\\(.*\\)|\\(..*\\)" truncated-string)
+ (concat (match-string 1 truncated-string) ","
+ (propertize (match-string 2 truncated-string)
+ 'face 'notmuch-search-non-matching-authors))
+ truncated-string)))))
+
(defun notmuch-search-insert-field (field date count authors subject tags)
(cond
((string-equal field "date")
@@ -583,13 +611,7 @@ matching will be applied."
((string-equal field "count")
(insert (format (cdr (assoc field notmuch-search-result-format)) count)))
((string-equal field "authors")
- (insert (let* ((format-string (cdr (assoc field notmuch-search-result-format)))
- (formatted-sample (format format-string ""))
- (formatted-authors (format format-string authors)))
- (if (> (length formatted-authors)
- (length formatted-sample))
- (concat (substring authors 0 (- (length formatted-sample) 4)) "... ")
- formatted-authors))))
+ (notmuch-search-insert-authors (cdr (assoc field notmuch-search-result-format)) authors))
((string-equal field "subject")
(insert (format (cdr (assoc field notmuch-search-result-format)) subject)))
((string-equal field "tags")
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/13] emacs: Set the `face' property rather than `font-lock-face'.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (3 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 04/13] emacs: Display non-matching authors with a different face David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 06/13] emacs: Allow control over faces for search mode columns David Edmondson
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Avoid using face properties reserved for the font-lock package.
---
emacs/notmuch.el | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 60c0ee5..d36a92d 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -438,7 +438,7 @@ and will also appear in a buffer named \"*Notmuch errors*\"."
(let ((end (point)))
(delete-region beg end)
(insert (propertize (mapconcat 'identity tags " ")
- 'font-lock-face 'notmuch-tag-face))))))
+ 'face 'notmuch-tag-face))))))
(defun notmuch-search-get-tags ()
(save-excursion
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/13] emacs: Allow control over faces for search mode columns.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (4 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 05/13] emacs: Set the `face' property rather than `font-lock-face' David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 07/13] emacs: Allow tuning of the tag/saved search layout David Edmondson
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Add face declarations for the date, count, matching author and subject
columns in search mode and apply those faces when building the search
mode display.
---
emacs/notmuch.el | 59 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index d36a92d..7c9c028 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -285,27 +285,48 @@ For a mouse binding, return nil."
"Face for the single-line message summary in notmuch-show-mode."
:group 'notmuch)
-(defface notmuch-tag-face
+(defface notmuch-search-date
+ '((t :inherit default))
+ "Face used in search mode for dates."
+ :group 'notmuch)
+
+(defface notmuch-search-count
+ '((t :inherit default))
+ "Face used in search mode for the count matching the query."
+ :group 'notmuch)
+
+(defface notmuch-search-subject
+ '((t :inherit default))
+ "Face used in search mode for subjects."
+ :group 'notmuch)
+
+(defface notmuch-search-matching-authors
+ '((t :inherit default))
+ "Face used in search mode for authors matching the query."
+ :group 'notmuch)
+
+(defface notmuch-search-non-matching-authors
'((((class color)
(background dark))
- (:foreground "OliveDrab1"))
+ (:foreground "grey30"))
(((class color)
(background light))
- (:foreground "navy blue" :bold t))
+ (:foreground "grey60"))
(t
- (:bold t)))
- "Notmuch search mode face used to highligh tags."
+ (:italic t)))
+ "Face used in search mode for authors not matching the query."
:group 'notmuch)
-(defface notmuch-search-non-matching-authors
+(defface notmuch-tag-face
'((((class color)
(background dark))
- (:foreground "grey30"))
+ (:foreground "OliveDrab1"))
(((class color)
(background light))
- (:foreground "grey60"))
- (t (:italic t)))
- "Face used in search mode for authors not matching the query."
+ (:foreground "navy blue" :bold t))
+ (t
+ (:bold t)))
+ "Face used in search mode face for tags."
:group 'notmuch)
;;;###autoload
@@ -599,21 +620,27 @@ matching will be applied."
;; `notmuch-search-process-filter'.
(save-match-data
(if (string-match "\\(.*\\)|\\(..*\\)" truncated-string)
- (concat (match-string 1 truncated-string) ","
+ (concat (propertize (concat (match-string 1 truncated-string) ",")
+ 'face 'notmuch-search-matching-authors)
(propertize (match-string 2 truncated-string)
'face 'notmuch-search-non-matching-authors))
- truncated-string)))))
+ (propertize truncated-string 'face 'notmuch-search-matching-authors))))))
(defun notmuch-search-insert-field (field date count authors subject tags)
(cond
((string-equal field "date")
- (insert (format (cdr (assoc field notmuch-search-result-format)) date)))
+ (insert (propertize (format (cdr (assoc field notmuch-search-result-format)) date)
+ 'face 'notmuch-search-date)))
((string-equal field "count")
- (insert (format (cdr (assoc field notmuch-search-result-format)) count)))
+ (insert (propertize (format (cdr (assoc field notmuch-search-result-format)) count)
+ 'face 'notmuch-search-count)))
+ ((string-equal field "subject")
+ (insert (propertize (format (cdr (assoc field notmuch-search-result-format)) subject)
+ 'face 'notmuch-search-subject)))
+
((string-equal field "authors")
(notmuch-search-insert-authors (cdr (assoc field notmuch-search-result-format)) authors))
- ((string-equal field "subject")
- (insert (format (cdr (assoc field notmuch-search-result-format)) subject)))
+
((string-equal field "tags")
(insert (concat "(" (propertize tags 'font-lock-face 'notmuch-tag-face) ")")))))
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/13] emacs: Allow tuning of the tag/saved search layout.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (5 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 06/13] emacs: Allow control over faces for search mode columns David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 08/13] emacs: Reuse rather than reinvent message header filtering David Edmondson
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Add `notmuch-column-control', which has three potential sets of
values:
- t: automatically calculate the number of columns per line based on
the tags to be shown and the window width,
- an integer: a lower bound on the number of characters that will be
used to display each column,
- a float: a fraction of the window width that is the lower bound on
the number of characters that should be used for each column.
So:
- if you would like two columns of tags, set this to 0.5.
- if you would like a single column of tags, set this to 1.0.
- if you would like tags to be 30 characters wide, set this to
30.
- if you don't want to worry about all of this nonsense, leave
this set to `t'.
---
emacs/notmuch-hello.el | 63 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 1358387..acf40bc 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -65,6 +65,32 @@
"Background colour for the notmuch logo."
:group 'notmuch)
+(defcustom notmuch-column-control t
+ "Controls the number of columns for saved searches/tags in notmuch view.
+
+This variable has three potential sets of values:
+
+- t: automatically calculate the number of columns possible based
+ on the tags to be shown and the window width,
+- an integer: a lower bound on the number of characters that will
+ be used to display each column,
+- a float: a fraction of the window width that is the lower bound
+ on the number of characters that should be used for each
+ column.
+
+So:
+- if you would like two columns of tags, set this to 0.5.
+- if you would like a single column of tags, set this to 1.0.
+- if you would like tags to be 30 characters wide, set this to
+ 30.
+- if you don't want to worry about all of this nonsense, leave
+ this set to `t'."
+ :group 'notmuch
+ :type '(choice
+ (const :tag "Automatically calculated" t)
+ (integer :tag "Number of characters")
+ (float :tag "Fraction of window")))
+
(defvar notmuch-hello-url "http://notmuchmail.org"
"The `notmuch' web site.")
@@ -146,13 +172,38 @@ diagonal."
(defun notmuch-saved-search-count (search)
(car (process-lines notmuch-command "count" search)))
+(defun notmuch-hello-tags-per-line (widest)
+ "Determine how many tags to show per line and how wide they
+should be. Returns a cons cell `(tags-per-line width)'."
+ (let ((tags-per-line
+ (cond
+ ((integerp notmuch-column-control)
+ (max 1
+ (/ (- (window-width) notmuch-hello-indent)
+ ;; Count is 7 wide (6 digits plus space), 1 for the space
+ ;; after the name.
+ (+ 7 1 (max notmuch-column-control widest)))))
+
+ ((floatp notmuch-column-control)
+ (let* ((available-width (- (window-width) notmuch-hello-indent))
+ (proposed-width (max (* available-width notmuch-column-control) widest)))
+ (floor available-width proposed-width)))
+
+ (t
+ (max 1
+ (/ (- (window-width) notmuch-hello-indent)
+ ;; Count is 7 wide (6 digits plus space), 1 for the space
+ ;; after the name.
+ (+ 7 1 widest)))))))
+
+ (cons tags-per-line (/ (- (window-width) notmuch-hello-indent
+ (* tags-per-line (+ 7 1)))
+ tags-per-line))))
+
(defun notmuch-hello-insert-tags (tag-alist widest target)
- (let* ((tags-per-line (max 1
- (/ (- (window-width) notmuch-hello-indent)
- ;; Count is 7 wide (6 digits plus
- ;; space), 1 for the space after the
- ;; name.
- (+ 7 1 widest))))
+ (let* ((tags-and-width (notmuch-hello-tags-per-line widest))
+ (tags-per-line (car tags-and-width))
+ (widest (cdr tags-and-width))
(count 0)
(reordered-list (notmuch-hello-reflect tag-alist tags-per-line))
;; Hack the display of the buttons used.
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/13] emacs: Reuse rather than reinvent message header filtering
2010-05-19 7:03 patches for 0.4 David Edmondson
` (6 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 07/13] emacs: Allow tuning of the tag/saved search layout David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 09/13] emacs: Avoid runtime use of `cl' David Edmondson
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
From: Sebastian Spaeth <Sebastian@SSpaeth.de>
In notmuch-mua-reply we were filtering out the Subject and To headers
manually in a loop, but message mode offers a nice function for
exactly that. Simplify the code by using that. Also, as
notmuch-mua-mail already sorts and hides headers that we want sorted
and hidden, we can safely remove those 2 functions from here as well.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
emacs/notmuch-mua.el | 7 +------
1 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index bd06e3c..6318c15 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -92,12 +92,7 @@ list."
((same-window-regexps '("\\*mail .*")))
(notmuch-mua-mail (mail-header 'to headers)
(mail-header 'subject headers)
- (loop for header in headers
- if (not (or (eq 'to (car header))
- (eq 'subject (car header))))
- collect header)))
- (message-sort-headers)
- (message-hide-headers)
+ (message-headers-to-generate headers t '(to subject))))
;; insert the message body - but put it in front of the signature
;; if one is present
(goto-char (point-max))
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/13] emacs: Avoid runtime use of `cl'.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (7 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 08/13] emacs: Reuse rather than reinvent message header filtering David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 10/13] emacs: In search mode, truncate authors using invisible text David Edmondson
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
The GNU Emacs Lisp Reference Manual section D.1 says:
> * Please don't require the cl package of Common Lisp extensions at
> run time. Use of this package is optional, and it is not part of
> the standard Emacs namespace. If your package loads cl at run time,
> that could cause name clashes for users who don't use that package.
>
> However, there is no problem with using the cl package at compile
> time, with (eval-when-compile (require 'cl)). That's sufficient for
> using the macros in the cl package, because the compiler expands
> them before generating the byte-code.
Follow this advice, requiring the following changes where `cl' was
used at runtime:
- replace `rassoc-if' in `notmuch-search-buffer-title' with the `loop'
macro and inline code. At the same time find the longest prefix
which matches the query rather than simply the last,
- replace `union', `intersection' and `set-difference' in
`notmuch-show-add-tag' and `notmuch-show-remove-tag' with local code
to calculate the result of adding and removing a list of tags from
another list of tags.
---
emacs/notmuch-hello.el | 2 +-
emacs/notmuch-show.el | 54 +++++++++++++++++++++++++++++++++++------------
emacs/notmuch.el | 16 +++++++++----
3 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index acf40bc..538785f 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -19,9 +19,9 @@
;;
;; Authors: David Edmondson <dme@dme.org>
+(eval-when-compile (require 'cl))
(require 'widget)
(require 'wid-edit) ; For `widget-forward'.
-(require 'cl)
(require 'notmuch-lib)
(require 'notmuch-mua)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 4b1baf3..ff1a7a7 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -21,7 +21,7 @@
;; Authors: Carl Worth <cworth@cworth.org>
;; David Edmondson <dme@dme.org>
-(require 'cl)
+(eval-when-compile (require 'cl))
(require 'mm-view)
(require 'message)
(require 'mm-decode)
@@ -908,29 +908,55 @@ to stdout or stderr will appear in the *Messages* buffer."
(list command " < "
(shell-quote-argument (notmuch-show-get-filename)))))
+(defun notmuch-show-add-tags-worker (current-tags add-tags)
+ "Add to `current-tags' with any tags from `add-tags' not
+currently present and return the result."
+ (let ((result-tags (copy-seq current-tags)))
+ (mapc (lambda (add-tag)
+ (unless (member add-tag current-tags)
+ (setq result-tags (push add-tag result-tags))))
+ add-tags)
+ (sort result-tags 'string<)))
+
+(defun notmuch-show-del-tags-worker (current-tags del-tags)
+ "Remove any tags in `del-tags' from `current-tags' and return
+the result."
+ (let ((result-tags (copy-seq current-tags)))
+ (mapc (lambda (del-tag)
+ (setq result-tags (delete del-tag result-tags)))
+ del-tags)
+ result-tags))
+
(defun notmuch-show-add-tag (&rest toadd)
"Add a tag to the current message."
(interactive
(list (notmuch-select-tag-with-completion "Tag to add: ")))
- (apply 'notmuch-call-notmuch-process
- (append (cons "tag"
- (mapcar (lambda (s) (concat "+" s)) toadd))
- (cons (notmuch-show-get-message-id) nil)))
- (notmuch-show-set-tags (sort (union toadd (notmuch-show-get-tags) :test 'string=) 'string<)))
+
+ (let* ((current-tags (notmuch-show-get-tags))
+ (new-tags (notmuch-show-add-tags-worker current-tags toadd)))
+
+ (unless (equal current-tags new-tags)
+ (apply 'notmuch-call-notmuch-process
+ (append (cons "tag"
+ (mapcar (lambda (s) (concat "+" s)) toadd))
+ (cons (notmuch-show-get-message-id) nil)))
+ (notmuch-show-set-tags new-tags))))
(defun notmuch-show-remove-tag (&rest toremove)
"Remove a tag from the current message."
(interactive
(list (notmuch-select-tag-with-completion
"Tag to remove: " (notmuch-show-get-message-id))))
- (let ((tags (notmuch-show-get-tags)))
- (if (intersection tags toremove :test 'string=)
- (progn
- (apply 'notmuch-call-notmuch-process
- (append (cons "tag"
- (mapcar (lambda (s) (concat "-" s)) toremove))
- (cons (notmuch-show-get-message-id) nil)))
- (notmuch-show-set-tags (sort (set-difference tags toremove :test 'string=) 'string<))))))
+
+ (let* ((current-tags (notmuch-show-get-tags))
+ (new-tags (notmuch-show-del-tags-worker current-tags toremove)))
+
+ (unless (equal current-tags new-tags)
+ (apply 'notmuch-call-notmuch-process
+ (append (cons "tag"
+ (mapcar (lambda (s) (concat "-" s)) toremove))
+ (cons (notmuch-show-get-message-id) nil)))
+ (notmuch-show-set-tags new-tags))))
(defun notmuch-show-toggle-headers ()
"Toggle the visibility of the current message headers."
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 7c9c028..c2fefe5 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -47,7 +47,7 @@
; kudos: Notmuch list <notmuch@notmuchmail.org> (subscription is not
; required, but is available from http://notmuchmail.org).
-(require 'cl)
+(eval-when-compile (require 'cl))
(require 'mm-view)
(require 'message)
@@ -712,10 +712,16 @@ characters as well as `_.+-'.
(defun notmuch-search-buffer-title (query)
"Returns the title for a buffer with notmuch search results."
- (let* ((saved-search (rassoc-if (lambda (key)
- (string-match (concat "^" (regexp-quote key))
- query))
- (reverse (notmuch-saved-searches))))
+ (let* ((saved-search
+ (let (longest
+ (longest-length 0))
+ (loop for tuple in notmuch-saved-searches
+ if (let ((quoted-query (regexp-quote (cdr tuple))))
+ (and (string-match (concat "^" quoted-query) query)
+ (> (length (match-string 0 query))
+ longest-length)))
+ do (setq longest tuple))
+ longest))
(saved-search-name (car saved-search))
(saved-search-query (cdr saved-search)))
(cond ((and saved-search (equal saved-search-query query))
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/13] emacs: In search mode, truncate authors using invisible text.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (8 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 09/13] emacs: Avoid runtime use of `cl' David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-06-04 2:13 ` Carl Worth
2010-05-19 7:03 ` [PATCH 11/13] emacs: Pretty print the numbers of matching messages David Edmondson
` (3 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Rather than discarding authors when truncated to fit the defined
column width, mark the text beyond the end of the column as invisible
and allow `isearch' to be used over the text so hidden.
This allows us to retain the compact display whilst enabling a user to
find the elided text.
---
emacs/notmuch.el | 61 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index c2fefe5..10babe4 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -608,23 +608,52 @@ matching will be applied."
(t
(setq tags-faces (cdr tags-faces)))))))))
+(defun notmuch-search-isearch-authors-show (overlay)
+ (remove-from-invisibility-spec (cons (overlay-get overlay 'invisible) t)))
+
(defun notmuch-search-insert-authors (format-string authors)
- (insert (let* ((formatted-sample (format format-string ""))
- (formatted-authors (format format-string authors))
- (truncated-string
- (if (> (length formatted-authors)
- (length formatted-sample))
- (concat (substring authors 0 (- (length formatted-sample) 4)) "... ")
- formatted-authors)))
- ;; Need to save the match data to avoid interfering with
- ;; `notmuch-search-process-filter'.
- (save-match-data
- (if (string-match "\\(.*\\)|\\(..*\\)" truncated-string)
- (concat (propertize (concat (match-string 1 truncated-string) ",")
- 'face 'notmuch-search-matching-authors)
- (propertize (match-string 2 truncated-string)
- 'face 'notmuch-search-non-matching-authors))
- (propertize truncated-string 'face 'notmuch-search-matching-authors))))))
+ (let* ((propertized-authors
+ ;; Need to save the match data to avoid interfering with
+ ;; `notmuch-search-process-filter'.
+ (save-match-data
+ ;; Authors that don't match the search query are shown in a
+ ;; different font.
+ (if (string-match "\\(.*\\)|\\(..*\\)" authors)
+ (concat (propertize (concat (match-string 1 authors) ",")
+ 'face 'notmuch-search-matching-authors)
+ (propertize (match-string 2 authors)
+ 'face 'notmuch-search-non-matching-authors))
+ (propertize authors 'face 'notmuch-search-matching-authors))))
+
+ (formatted-sample (format format-string ""))
+ (formatted-authors (format format-string propertized-authors))
+ visible-string invisible-string)
+
+ ;; Determine the part of the authors that will be visible by
+ ;; default.
+ (if (> (length formatted-authors)
+ (length formatted-sample))
+ ;; 4 is `(length "... ")'.
+ (let ((visible-length (- (length formatted-sample) 4)))
+ (setq visible-string (substring propertized-authors 0 visible-length)
+ invisible-string (substring propertized-authors visible-length)))
+ (setq visible-string formatted-authors
+ invisible-string nil))
+
+ ;; Insert both the visible and invisible author strings.
+ (insert visible-string)
+ (when invisible-string
+ (let ((start (point))
+ (invis-spec (make-symbol "notmuch-search-authors"))
+ overlay)
+ (insert invisible-string)
+ ;; Using a cons-cell here causes an ellipsis to be inserted
+ ;; instead of the invisible text.
+ (add-to-invisibility-spec (cons invis-spec t))
+ (setq overlay (make-overlay start (point)))
+ (overlay-put overlay 'invisible invis-spec)
+ (overlay-put overlay 'isearch-open-invisible #'notmuch-search-isearch-authors-show)
+ (insert " ")))))
(defun notmuch-search-insert-field (field date count authors subject tags)
(cond
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/13] emacs: Pretty print the numbers of matching messages.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (9 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 10/13] emacs: In search mode, truncate authors using invisible text David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 12/13] emacs: Tags should be shown with `notmuch-tag-face' David Edmondson
` (2 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Insert a separator every three digits when outputting numbers. Allow
the user to choose the separator by customizing
`notmuch-decimal-separator'. Widen the space allocated for message
counts accordingly.
---
emacs/notmuch-hello.el | 38 +++++++++++++++++++++++++++++++-------
1 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 538785f..7ade0eb 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -91,6 +91,13 @@ So:
(integer :tag "Number of characters")
(float :tag "Fraction of window")))
+(defcustom notmuch-decimal-separator ","
+ "The string used as a decimal separator.
+
+Typically \",\" in the US and UK and \".\" in Europe."
+ :group 'notmuch
+ :type 'string)
+
(defvar notmuch-hello-url "http://notmuchmail.org"
"The `notmuch' web site.")
@@ -103,6 +110,17 @@ So:
notmuch-recent-searches-max)
(setq notmuch-hello-recent-searches (butlast notmuch-hello-recent-searches))))
+(defun notmuch-hello-nice-number (n)
+ (let (result)
+ (while (> n 0)
+ (push (% n 1000) result)
+ (setq n (/ n 1000)))
+ (apply #'concat
+ (number-to-string (car result))
+ (mapcar (lambda (elem)
+ (format "%s%03d" notmuch-decimal-separator elem))
+ (cdr result)))))
+
(defun notmuch-hello-trim (search)
"Trim whitespace."
(if (string-match "^[[:space:]]*\\(.*[^[:space:]]\\)[[:space:]]*$" search)
@@ -180,9 +198,9 @@ should be. Returns a cons cell `(tags-per-line width)'."
((integerp notmuch-column-control)
(max 1
(/ (- (window-width) notmuch-hello-indent)
- ;; Count is 7 wide (6 digits plus space), 1 for the space
+ ;; Count is 9 wide (8 digits plus space), 1 for the space
;; after the name.
- (+ 7 1 (max notmuch-column-control widest)))))
+ (+ 9 1 (max notmuch-column-control widest)))))
((floatp notmuch-column-control)
(let* ((available-width (- (window-width) notmuch-hello-indent))
@@ -192,12 +210,15 @@ should be. Returns a cons cell `(tags-per-line width)'."
(t
(max 1
(/ (- (window-width) notmuch-hello-indent)
- ;; Count is 7 wide (6 digits plus space), 1 for the space
+ ;; Count is 9 wide (8 digits plus space), 1 for the space
;; after the name.
- (+ 7 1 widest)))))))
+ (+ 9 1 widest)))))))
(cons tags-per-line (/ (- (window-width) notmuch-hello-indent
- (* tags-per-line (+ 7 1)))
+ ;; Count is 9 wide (8 digits plus
+ ;; space), 1 for the space after the
+ ;; name.
+ (* tags-per-line (+ 9 1)))
tags-per-line))))
(defun notmuch-hello-insert-tags (tag-alist widest target)
@@ -218,7 +239,9 @@ should be. Returns a cons cell `(tags-per-line width)'."
(let* ((name (car elem))
(query (cdr elem))
(formatted-name (format "%s " name)))
- (widget-insert (format "%6s " (notmuch-saved-search-count query)))
+ (widget-insert (format "%8s "
+ (notmuch-hello-nice-number
+ (string-to-number (notmuch-saved-search-count query)))))
(if (string= formatted-name target)
(setq found-target-pos (point-marker)))
(widget-create 'push-button
@@ -323,7 +346,8 @@ should be. Returns a cons cell `(tags-per-line width)'."
:notify (lambda (&rest ignore)
(notmuch-hello-update))
:help-echo "Refresh"
- (car (process-lines notmuch-command "count")))
+ (notmuch-hello-nice-number
+ (string-to-number (car (process-lines notmuch-command "count")))))
(widget-insert " messages (that's not much mail).\n"))
(let ((found-target-pos nil)
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/13] emacs: Tags should be shown with `notmuch-tag-face'.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (10 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 11/13] emacs: Pretty print the numbers of matching messages David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-05-19 7:03 ` [PATCH 13/13] emacs: Allow the display of absolute dates in the header line David Edmondson
2010-06-04 2:20 ` patches for 0.4 Carl Worth
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Use the same face for tags in `notmuch-show' mode as that used in
`notmuch-search' mode.
---
emacs/notmuch-show.el | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index ff1a7a7..7601857 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -189,7 +189,8 @@ any given message."
(if (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
(let ((inhibit-read-only t))
(replace-match (concat "("
- (mapconcat 'identity tags " ")
+ (propertize (mapconcat 'identity tags " ")
+ 'face 'notmuch-tag-face)
")"))))))
(defun notmuch-show-insert-headerline (headers date tags depth)
@@ -201,7 +202,8 @@ message at DEPTH in the current thread."
" ("
date
") ("
- (mapconcat 'identity tags " ")
+ (propertize (mapconcat 'identity tags " ")
+ 'face 'notmuch-tag-face)
")\n")
(overlay-put (make-overlay start (point)) 'face 'notmuch-message-summary-face)))
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 13/13] emacs: Allow the display of absolute dates in the header line.
2010-05-19 7:03 patches for 0.4 David Edmondson
` (11 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 12/13] emacs: Tags should be shown with `notmuch-tag-face' David Edmondson
@ 2010-05-19 7:03 ` David Edmondson
2010-06-04 2:20 ` patches for 0.4 Carl Worth
13 siblings, 0 replies; 17+ messages in thread
From: David Edmondson @ 2010-05-19 7:03 UTC (permalink / raw)
To: notmuch
Add `notmuch-show-relative-dates' to control whether the summary line
in `notmuch-show' mode displays relative dates (e.g. '26 mins ago') or
the full date string from the message. Default to `t' for
compatibility with the previous behaviour.
---
emacs/notmuch-show.el | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 7601857..cbc3012 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -58,6 +58,11 @@ any given message."
:group 'notmuch
:type 'boolean)
+(defcustom notmuch-show-relative-dates t
+ "Display relative dates in the message summary line."
+ :group 'notmuch
+ :type 'boolean)
+
(defvar notmuch-show-markup-headers-hook '(notmuch-show-colour-headers)
"A list of functions called to decorate the headers listed in
`notmuch-message-headers'.")
@@ -407,7 +412,9 @@ current buffer, if possible."
(setq message-start (point-marker))
(notmuch-show-insert-headerline headers
- (or (plist-get msg :date_relative)
+ (or (if notmuch-show-relative-dates
+ (plist-get msg :date_relative)
+ nil)
(plist-get headers :Date))
(plist-get msg :tags) depth)
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: patches for 0.4
2010-05-19 7:03 patches for 0.4 David Edmondson
` (12 preceding siblings ...)
2010-05-19 7:03 ` [PATCH 13/13] emacs: Allow the display of absolute dates in the header line David Edmondson
@ 2010-06-04 2:20 ` Carl Worth
2010-06-07 13:51 ` David Edmondson
13 siblings, 1 reply; 17+ messages in thread
From: Carl Worth @ 2010-06-04 2:20 UTC (permalink / raw)
To: David Edmondson, notmuch
[-- Attachment #1: Type: text/plain, Size: 1740 bytes --]
On Wed, 19 May 2010 08:03:27 +0100, David Edmondson <dme@dme.org> wrote:
> This is a set of small feature and cleanup patches. The only
> particularly significant one is patch 2, as it fixes a memory
> corruption bug in notmuch.
Thanks, David.
Most of these I had already picked up in my recent scan of my
queue. Specifically:
> [PATCH 01/13] emacs: Usability improvements for `notmuch-hello'.
> [PATCH 02/13] notmuch: Fix off-by-one errors if a header is >200 characters long.
> [PATCH 04/13] emacs: Display non-matching authors with a different face.
> [PATCH 05/13] emacs: Set the `face' property rather than `font-lock-face'.
> [PATCH 06/13] emacs: Allow control over faces for search mode columns.
> [PATCH 07/13] emacs: Allow tuning of the tag/saved search layout.
> [PATCH 08/13] emacs: Reuse rather than reinvent message header filtering
> [PATCH 11/13] emacs: Pretty print the numbers of matching messages.
> [PATCH 13/13] emacs: Allow the display of absolute dates in the header line.
I did find three new patches here, which I've now committed:
> [PATCH 03/13] emacs: Adjust comment to avoid confusing font-lock.
> [PATCH 10/13] emacs: In search mode, truncate authors using invisible text.
> [PATCH 12/13] emacs: Tags should be shown with `notmuch-tag-face'.
Finally, there is this one patch in the series that I have tagged for a
closer review:
> [PATCH 09/13] emacs: Avoid runtime use of `cl'.
Perhaps it's just fine now that you've been testing it a while, but at
least in your original email you said you wanted some additional review,
so I planned to do that.
Thanks for sending this list, (and for all of your work on these
features!).
-Carl
--
carl.d.worth@intel.com
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread