[PATCH] emacs: In hello mode, bind `C-tab' to move backwards through widgets.

2010-04-29 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

`C-tab' is now the inverse operation to `tab'.
---
 emacs/notmuch-hello.el |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 538785f..bf49bb1 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -448,6 +448,7 @@ should be. Returns a cons cell `(tags-per-line width)'."

   (use-local-map widget-keymap)
   (local-set-key "=" 'notmuch-hello-update)
+  (local-set-key (kbd "") 'widget-backward)
   (local-set-key "G" 'notmuch-hello-poll-and-update)
   (local-set-key "m" 'notmuch-mua-mail)
   (local-set-key "q" '(lambda () (interactive) (kill-buffer 
(current-buffer
-- 
1.7.0



[PATCH] notmuch: Fix off-by-one errors if a header is >200 characters long.

2010-04-28 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

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.
---

This is the cause of my segmentation fault (or bus error) during
`notmuch reply'. The patch is for the 0.3.1 branch, but I'd expect
that it will apply cleanly to master.

 gmime-filter-headers.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --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.0



[PATCH] emacs: Allow tuning of the tag/saved search layout.

2010-04-27 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

Add `notmuch-hello-tag-width', which has three potential sets of
values:

- t: automatically calculate the number of tags per line 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 tag,
- a float: a fraction of the window width that is the lower bound
  on the number of characters that should be used for each tag.

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'.
---

Carl, for 0.4. You mentioned that you might like to have a single
column of tags/saved searches, but others appear to like multiple
columns. So, make it configurable.

 emacs/notmuch-hello.el |   62 +++
 1 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 378d41c..f7703d9 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -141,13 +141,63 @@ diagonal."
 (defun notmuch-saved-search-count (search)
   (car (process-lines notmuch-command "count" search)))

+(defcustom notmuch-hello-tag-width t
+  "How wide should a tag be?
+
+This variable has three potential sets of values:
+
+- t: automatically calculate the number of tags per line 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 tag,
+- a float: a fraction of the window width that is the lower bound
+  on the number of characters that should be used for each tag.
+
+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")))
+
+(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-hello-tag-width)
+  (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-hello-tag-width widest)
+
+ ((floatp notmuch-hello-tag-width)
+  (let* ((available-width (- (window-width) notmuch-hello-indent))
+ (proposed-width (max (* available-width 
notmuch-hello-tag-width) 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.0



[PATCH] emacs/notmuch-wash.el: Add `notmuch-wash-convert-inline-patch-to-part'.

2010-04-27 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

Detect inline patches and convert them to fake attachments, in order
that `diff-mode' highlighting can be applied to the patch. This can be
enabled by customising `notmuch-show-insert-text/plain-hook'.
---
 emacs/notmuch-show.el |3 ++-
 emacs/notmuch-wash.el |   38 ++
 2 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index eb5335f..4b1baf3 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -71,7 +71,8 @@ any given message."
   "Functions used to improve the display of text/plain parts."
   :group 'notmuch
   :type 'hook
-  :options '(notmuch-wash-wrap-long-lines
+  :options '(notmuch-wash-convert-inline-patch-to-part
+notmuch-wash-wrap-long-lines
 notmuch-wash-tidy-citations
 notmuch-wash-elide-blank-lines
 notmuch-wash-excerpt-citations))
diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 57f0cc5..bf0a354 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -23,6 +23,8 @@

 (require 'coolj)

+(declare-function notmuch-show-insert-bodypart "notmuch-show" (msg part depth)
+
 ;;

 (defvar notmuch-wash-signature-regexp
@@ -231,4 +233,40 @@ When doing so, maintaining citation leaders in the wrapped 
text."

 ;;

+(require 'diff-mode)
+
+(defvar diff-file-header-re) ; From `diff-mode.el'.
+
+(defun notmuch-wash-convert-inline-patch-to-part (depth)
+  "Convert an inline patch into a fake 'text/x-diff' attachment.
+
+Given that this function guesses whether a buffer includes a
+patch and then guesses the extent of the patch, there is scope
+for error."
+
+  (goto-char (point-min))
+  (if (re-search-forward diff-file-header-re nil t)
+  (progn
+   (beginning-of-line -1)
+   (let ((patch-start (point))
+ (patch-end (point-max))
+ part)
+ (goto-char patch-start)
+ (if (or
+  ;; Patch ends with signature.
+  (re-search-forward notmuch-wash-signature-regexp nil t)
+  ;; Patch ends with bugtraq comment.
+  (re-search-forward "^\\*\\*\\* " nil t))
+ (setq patch-end (match-beginning 0)))
+ (save-restriction
+   (narrow-to-region patch-start patch-end)
+   (setq part (plist-put part :content-type "text/x-diff"))
+   (setq part (plist-put part :content (buffer-string)))
+   (setq part (plist-put part :id -1))
+   (setq part (plist-put part :filename "inline patch"))
+   (delete-region (point-min) (point-max))
+   (notmuch-show-insert-bodypart nil part depth))
+
+;;
+
 (provide 'notmuch-wash)
-- 
1.7.0



[PATCH 2/2] emacs: Fix `notmuch-hello-insert-tags' to correctly draw the tags.

2010-04-27 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

The fix in 1e1871154341cdd3413fe3f32e3aae477826d815 broke end-of-row
wrapping when drawing the table of tags/saved searches. Fix that and
improve the readability of the matrix reflection code to hasten future
debugging.
---

Carl, this is a fix for a regression that I caused this morning when
fixing the line wrapping. Serves me right for doing more than was
really necessary in the previous patch. Sorry :-(

 emacs/notmuch-hello.el |   37 +++--
 1 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 1b59ef1..6a1c56e 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -118,23 +118,24 @@
   (+ (/ dividend divisor)
  (if (> (% dividend divisor) 0) 1 0)))

-(defun notmuch-hello-reflect (list width)
-  "Reflect a `width' wide matrix represented by `list' along the
+(defun notmuch-hello-reflect-generate-row (ncols nrows row list)
+  (let ((len (length list)))
+(loop for col from 0 to (- ncols 1)
+ collect (let ((offset (+ (* nrows col) row)))
+   (if (< offset len)
+   (nth offset list)
+ ;; Don't forget to insert an empty slot in the
+ ;; output matrix if there is no corresponding
+ ;; value in the input matrix.
+ nil)
+
+(defun notmuch-hello-reflect (list ncols)
+  "Reflect a `ncols' wide matrix represented by `list' along the
 diagonal."
   ;; Not very lispy...
-  (let* ((len (length list))
-(nrows (notmuch-hello-roundup len width)))
+  (let ((nrows (notmuch-hello-roundup (length list) ncols)))
 (loop for row from 0 to (- nrows 1)
- append (loop for col from 0 to (- width 1)
-  ;; How could we calculate the offset just once
-  ;; per inner-loop?
-  if (< (+ (* nrows col) row) len)
-  collect (nth (+ (* nrows col) row) list)
-  else
-  ;; Don't forget to insert an empty slot in the
-  ;; output matrix if there is no corresponding
-  ;; value in the input matrix.
-  collect nil
+ append (notmuch-hello-reflect-generate-row ncols nrows row list

 (defun notmuch-hello-widget-search (widget  ignore)
   (notmuch-search (widget-get widget
@@ -179,10 +180,10 @@ diagonal."
;; can just insert `(- widest (length name))' spaces -
;; the column separator is included in the button if
;; `(equal widest (length name)'.
-   (widget-insert (make-string (- widest (length name)) ? )))
- (setq count (1+ count))
- (if (eq (% count tags-per-line) 0)
- (widget-insert "\n"
+   (widget-insert (make-string (- widest (length name)) ? 
+   (setq count (1+ count))
+   (if (eq (% count tags-per-line) 0)
+   (widget-insert "\n")))
  reordered-list)

 ;; If the last line was not full (and hence did not include a
-- 
1.7.0



[PATCH 1/2] emacs: If 'all tags' is not shown, don't use it when calculating widths.

2010-04-27 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

If the 'all tags' section of the hello buffer will not be shown, don't
consider those tags when determining the number of saved searches that
can be displayed on a single line.
---
 emacs/notmuch-hello.el |   38 --
 1 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 50d8911..1b59ef1 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -284,8 +284,9 @@ diagonal."
  if (> (string-to-number (notmuch-saved-search-count (cdr 
elem))) 0)
  collect elem)))
 (saved-widest (notmuch-hello-longest-label saved-alist))
-(alltags-alist (mapcar '(lambda (tag) (cons tag (concat "tag:" 
tag)))
-   (process-lines notmuch-command 
"search-tags")))
+(alltags-alist (if notmuch-show-all-tags-list
+   (mapcar '(lambda (tag) (cons tag (concat "tag:" 
tag)))
+   (process-lines notmuch-command 
"search-tags"
 (alltags-widest (notmuch-hello-longest-label alltags-alist))
 (widest (max saved-widest alltags-widest)))

@@ -360,26 +361,27 @@ diagonal."
(indent-rigidly start (point) notmuch-hello-indent)))

(when alltags-alist
- (if notmuch-show-all-tags-list
- (progn
-   (widget-insert "\nAll tags: ")
-   (widget-create 'push-button
-  :notify (lambda (widget  ignore)
-(setq notmuch-show-all-tags-list nil)
-(notmuch-hello-update))
-  "hide")
-   (widget-insert "\n\n")
-   (let ((start (point)))
- (setq found-target-pos (notmuch-hello-insert-tags 
alltags-alist widest target))
- (if (not final-target-pos)
- (setq final-target-pos found-target-pos))
- (indent-rigidly start (point) notmuch-hello-indent)))
-   (widget-insert "\n")
+ (widget-insert "\nAll tags: ")
+ (widget-create 'push-button
+:notify (lambda (widget  ignore)
+  (setq notmuch-show-all-tags-list nil)
+  (notmuch-hello-update))
+"hide")
+ (widget-insert "\n\n")
+ (let ((start (point)))
+   (setq found-target-pos (notmuch-hello-insert-tags alltags-alist 
widest target))
+   (if (not final-target-pos)
+   (setq final-target-pos found-target-pos))
+   (indent-rigidly start (point) notmuch-hello-indent)))
+
+   (widget-insert "\n")
+
+   (if (not notmuch-show-all-tags-list)
(widget-create 'push-button
   :notify (lambda (widget  ignore)
 (setq notmuch-show-all-tags-list t)
 (notmuch-hello-update))
-  "Show all tags"
+  "Show all tags")))

   (let ((start (point)))
(widget-insert "\n\n")
-- 
1.7.0



[PATCH] emacs: Fix column alignment in `notmuch-hello-insert-tags'

2010-04-27 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

Re-working the saved search/tag insertion to buttonize only the name
of the saved search/tag plus one space broke the calculation of how
much filler is required to complete the column, resulting in lines
wider than the window.
---
 emacs/notmuch-hello.el |   44 +++-
 1 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index cbe414f..50d8911 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -148,8 +148,9 @@ diagonal."
 (defun notmuch-hello-insert-tags (tag-alist widest target)
   (let* ((tags-per-line (max 1
 (/ (- (window-width) notmuch-hello-indent)
-   ;; Count is 7 wide, 1 for the space
-   ;; after the name.
+   ;; Count is 7 wide (6 digits plus
+   ;; space), 1 for the space after the
+   ;; name.
(+ 7 1 widest
 (count 0)
 (reordered-list (notmuch-hello-reflect tag-alist tags-per-line))
@@ -159,21 +160,30 @@ diagonal."
 (found-target-pos nil))
 ;; dme: It feels as though there should be a better way to
 ;; implement this loop than using an incrementing counter.
-(loop for elem in reordered-list
- do (progn
-  ;; (not elem) indicates an empty slot in the matrix.
-  (when elem
-(widget-insert (format "%6s " (notmuch-saved-search-count (cdr 
elem
-(if (string= (format "%s " (car elem)) target)
-(setq found-target-pos (point-marker)))
-(widget-create 'push-button
-   :notify #'notmuch-hello-widget-search
-   :notmuch-search-terms (cdr elem)
-   (format "%s " (car elem)))
-(insert (make-string (1+ (- widest (length (car elem ? )))
-  (setq count (1+ count))
-  (if (eq (% count tags-per-line) 0)
-  (widget-insert "\n"
+(mapc (lambda (elem)
+   ;; (not elem) indicates an empty slot in the matrix.
+   (when elem
+ (let* ((name (car elem))
+(query (cdr elem))
+(formatted-name (format "%s " name)))
+   (widget-insert (format "%6s " (notmuch-saved-search-count 
query)))
+   (if (string= formatted-name target)
+   (setq found-target-pos (point-marker)))
+   (widget-create 'push-button
+  :notify #'notmuch-hello-widget-search
+  :notmuch-search-terms query
+  formatted-name)
+   ;; Insert enough space to consume the rest of the
+   ;; column.  Because the button for the name is `(1+
+   ;; (length name))' long (due to the trailing space) we
+   ;; can just insert `(- widest (length name))' spaces -
+   ;; the column separator is included in the button if
+   ;; `(equal widest (length name)'.
+   (widget-insert (make-string (- widest (length name)) ? )))
+ (setq count (1+ count))
+ (if (eq (% count tags-per-line) 0)
+ (widget-insert "\n"
+ reordered-list)

 ;; If the last line was not full (and hence did not include a
 ;; carriage return), insert one now.
-- 
1.7.0



[PATCH] emacs: Tell the user how many addresses matched when completing

2010-04-26 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

When completing an address, tell the user how many addresses in the
database matched the query.
---
 emacs/notmuch-address.el |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 69a52a2..a295204 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -53,9 +53,11 @@ line."
 (orig (buffer-substring-no-properties beg end))
 (completion-ignore-case t)
 (options (notmuch-address-options orig))
-(chosen (if (eq (length options) 1)
+(num-options (length options))
+(chosen (if (eq num-options 1)
 (car options)
-  (completing-read "Address: " (cdr options) nil nil (car 
options)
+  (completing-read (format "Address (%s matches): " 
num-options 1)
+   (cdr options) nil nil (car options)
'notmuch-address-history
 (when chosen
   (push chosen notmuch-address-history)
-- 
1.7.0



[PATCH] emacs: Remove duplicate declaration of `notmuch-folders'

2010-04-26 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

---
 emacs/notmuch.el |5 -
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 428ae6c..e207180 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -659,11 +659,6 @@ characters as well as `_.+-'.
 (apply 'notmuch-call-notmuch-process "tag"
   (append action-split (list notmuch-search-query-string) nil

-(defcustom notmuch-folders (quote (("inbox" . "tag:inbox") ("unread" . 
"tag:unread")))
-  "List of searches for the notmuch folder view"
-  :type '(alist :key-type (string) :value-type (string))
-  :group 'notmuch)
-
 (defun notmuch-search-buffer-title (query)
   "Returns the title for a buffer with notmuch search results."
   (let* ((folder (rassoc-if (lambda (key)
-- 
1.7.0



[PATCH] emacs: `notmuch' should display the `notmuch-hello' interface

2010-04-26 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

---
 emacs/notmuch-hello.el |1 -
 emacs/notmuch-lib.el   |5 +
 emacs/notmuch.el   |7 +++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 30b3a5e..bd882b8 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -24,7 +24,6 @@
 (require 'cl)

 (require 'notmuch-lib)
-(require 'notmuch)
 (require 'notmuch-mua)

 (declare-function notmuch-search "notmuch" (query  oldest-first 
target-thread target-line continuation))
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 47c74b9..b64aeab 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -33,6 +33,11 @@
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch)

+(defcustom notmuch-search-oldest-first t
+  "Show the oldest mail first when searching."
+  :type 'boolean
+  :group 'notmuch)
+
 ;;

 (defun notmuch-version ()
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index eecff23..428ae6c 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -54,6 +54,7 @@
 (require 'notmuch-lib)
 (require 'notmuch-show)
 (require 'notmuch-mua)
+(require 'notmuch-hello)

 (defcustom notmuch-search-result-format
   `(("date" . "%s ")
@@ -221,8 +222,6 @@ For a mouse binding, return nil."
 (defvar notmuch-search-query-string)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
-(defvar notmuch-search-oldest-first t
-  "Show the oldest mail first in the search-mode")
 (defvar notmuch-search-continuation)

 (defvar notmuch-search-disjunctive-regexp  "\\<[oO][rR]\\>")
@@ -811,9 +810,9 @@ current search results AND that are tagged with the given 
tag."

 ;;;###autoload
 (defun notmuch ()
-  "Run notmuch to display all mail with tag of 'inbox'"
+  "Run notmuch and display saved searches, known tags, etc."
   (interactive)
-  (notmuch-search "tag:inbox" notmuch-search-oldest-first))
+  (notmuch-hello))

 (setq mail-user-agent 'notmuch-user-agent)

-- 
1.7.0



[PATCH] emacs: Fix `notmuch-show-rewind' in the presence of invisible text

2010-04-26 Thread d...@dme.org
From: David Edmondson <d...@dme.org>

When determining whether or not to re-align the head of the current
message with the top of the window, use `count-screen-lines' rather
than `count-lines' to allow for invisible text in the preceding
message. When comparing that number of lines against
`next-screen-context-lines', realign if the number of lines of the
previous message visible is 'smaller than or equal to' rather than
just 'smaller than' to improve usability.
---
 emacs/notmuch-show.el |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index f5de8ae..eb5335f 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -833,8 +833,8 @@ any effects from previous calls to
   ;; If a small number of lines from the previous message are
   ;; visible, realign so that the top of the current message is at
   ;; the top of the screen.
-  (if (< (count-lines (window-start) (notmuch-show-message-top))
-next-screen-context-lines)
+  (if (<= (count-screen-lines (window-start) start-of-message)
+ next-screen-context-lines)
  (progn
(goto-char (notmuch-show-message-top))
(notmuch-show-message-adjust)))
-- 
1.7.0