Changes committed gnus/lisp (ChangeLog gnus-sum.el gnus-util.el)

"Katsumi Yamaoka" <[email protected]> Wed, 06 Jan 2010 01:09:50 +0100
Newsgroups gmane.emacs.gnus.commits
Message-ID <[email protected]>
Modified: ChangeLog gnus-sum.el gnus-util.el

2010-01-06  Katsumi Yamaoka  <[email protected]>

	* gnus-util.el (gnus-invisible-p, gnus-next-char-property-change)
	(gnus-previous-char-property-change): New functions.

	* gnus-sum.el (gnus-forward-line-ignore-invisible): Use them.

2010-01-05  Andreas Schwab  <[email protected]>

	* gnus-sum.el (gnus-forward-line-ignore-invisible): New function.
	(gnus-summary-recenter): Use it instead of forward-line.  (Bug#5257)


Index: ChangeLog
diff -u gnus/lisp/ChangeLog:7.2048 gnus/lisp/ChangeLog:7.2049
--- ChangeLog:7.2048	Tue Jan  5 03:22:52 2010
+++ ChangeLog	Wed Jan  6 01:09:49 2010
@@ -1,3 +1,15 @@
+2010-01-06  Katsumi Yamaoka  <[email protected]>
+
+	* gnus-util.el (gnus-invisible-p, gnus-next-char-property-change)
+	(gnus-previous-char-property-change): New functions.
+
+	* gnus-sum.el (gnus-forward-line-ignore-invisible): Use them.
+
+2010-01-05  Andreas Schwab  <[email protected]>
+
+	* 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  <[email protected]>
 
 	* message.el (message-exchange-point-and-mark): Rework last change to
Index: gnus-sum.el
diff -u gnus/lisp/gnus-sum.el:7.245 gnus/lisp/gnus-sum.el:7.246
--- gnus-sum.el:7.245	Mon Nov 30 10:36:17 2009
+++ gnus-sum.el	Wed Jan  6 01:09:49 2010
@@ -6727,6 +6727,26 @@
 
 (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 (gnus-invisible-p (point))
+	(goto-char (gnus-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)) (gnus-invisible-p (1- (point))))
+	  (goto-char (gnus-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 @@
 			     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 @@
 	    ;; 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)
Index: gnus-util.el
diff -u gnus/lisp/gnus-util.el:7.89 gnus/lisp/gnus-util.el:7.90
--- gnus-util.el:7.89	Wed Sep  9 12:42:27 2009
+++ gnus-util.el	Wed Jan  6 01:09:49 2010
@@ -969,6 +969,29 @@
 			  (overlay-get overlay 'face))
 			(overlays-at pos)))))))
 
+(if (fboundp 'invisible-p)
+    (defalias 'gnus-invisible-p 'invisible-p)
+  ;; for Emacs < 22.2, and XEmacs.
+  (defun gnus-invisible-p (pos)
+    "Return non-nil if the character after POS is currently invisible."
+    (let ((prop (get-char-property pos 'invisible)))
+      (if (eq buffer-invisibility-spec t)
+	  prop
+	(or (memq prop buffer-invisibility-spec)
+	    (assq prop buffer-invisibility-spec))))))
+
+;; Note: the optional 2nd argument has a different meaning between
+;; Emacs and XEmacs.
+;; (next-char-property-change POSITION &optional LIMIT)
+;; (next-extent-change        POS      &optional OBJECT)
+(defalias 'gnus-next-char-property-change
+  (if (fboundp 'next-extent-change)
+      'next-extent-change 'next-char-property-change))
+
+(defalias 'gnus-previous-char-property-change
+  (if (fboundp 'previous-extent-change)
+      'previous-extent-change 'previous-char-property-change))
+
 ;;; Protected and atomic operations.  [email protected] 21.11.1996
 ;; The primary idea here is to try to protect internal datastructures
 ;; from becoming corrupted when the user hits C-g, or if a hook or