From 7b47345b7c9a06033c51cdd6ed5a966de9e37c7c Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 5 Jan 2010 21:37:43 +0100 Subject: [PATCH] Fix gnus-summary-recenter to properly handle invisible lines * gnus-sum.el (gnus-forward-line-ignore-invisible): New function. (gnus-summary-recenter): Use it instead of forward-line. (Bug#5257) --- lisp/gnus/ChangeLog | 7 ++++++- lisp/gnus/gnus-sum.el | 35 +++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index c127239b164..1b418e3275a 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,8 @@ +2010-01-05 Andreas Schwab + + * gnus-sum.el (gnus-forward-line-ignore-invisible): New function. + (gnus-summary-recenter): Use it instead of forward-line. (Bug#5257) + 2010-01-02 Chong Yidong * message.el (message-exchange-point-and-mark): Rework last change to @@ -13788,7 +13793,7 @@ See ChangeLog.2 for earlier changes. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 658193bd508..cd56cd1f4bb 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -6727,6 +6727,26 @@ Also do horizontal recentering." (put 'gnus-recenter 'isearch-scroll t) +(defun gnus-forward-line-ignore-invisible (n) + "Move N lines forward (backward if N is negative). +Like forward-line, but skip over (and don't count) invisible lines." + (let (done) + (while (and (> n 0) (not done)) + ;; If the following character is currently invisible, + ;; skip all characters with that same `invisible' property value. + (while (invisible-p (point)) + (goto-char (next-char-property-change (point)))) + (forward-line 1) + (if (eobp) + (setq done t) + (setq n (1- n)))) + (while (and (< n 0) (not done)) + (forward-line -1) + (if (bobp) (setq done t) + (setq n (1+ n)) + (while (and (not (bobp)) (invisible-p (1- (point)))) + (goto-char (previous-char-property-change (point)))))))) + (defun gnus-summary-recenter () "Center point in the summary window. If `gnus-auto-center-summary' is nil, or the article buffer isn't @@ -6742,16 +6762,19 @@ displayed, no centering will be performed." gnus-auto-center-summary (/ (1- (window-height)) 2))))) (height (1- (window-height))) - (bottom (save-excursion (goto-char (point-max)) - (forward-line (- height)) - (point))) + (bottom (save-excursion + (goto-char (point-max)) + (gnus-forward-line-ignore-invisible (- height)) + (point))) (window (get-buffer-window (current-buffer)))) (when (get-buffer-window gnus-article-buffer) ;; Only do recentering when the article buffer is displayed, ;; Set the window start to either `bottom', which is the biggest ;; possible valid number, or the second line from the top, ;; whichever is the least. - (let ((top-pos (save-excursion (forward-line (- top)) (point)))) + (let ((top-pos (save-excursion + (gnus-forward-line-ignore-invisible (- top)) + (point)))) (if (> bottom top-pos) ;; Keep the second line from the top visible (set-window-start window top-pos) @@ -6760,12 +6783,12 @@ displayed, no centering will be performed." ;; visible, or revert to using TOP-POS. (save-excursion (goto-char (point-max)) - (forward-line -1) + (gnus-forward-line-ignore-invisible -1) (let ((last-line-start (point))) (goto-char bottom) (set-window-start window (point) t) (when (not (pos-visible-in-window-p last-line-start window)) - (forward-line 1) + (gnus-forward-line-ignore-invisible 1) (set-window-start window (min (point) top-pos) t))))))) ;; Do horizontal recentering while we're at it. (when (and (get-buffer-window (current-buffer) t)