Subject: Re: bug#18847: 24.4; Inconsistent behaviour of M-h with negative arguments

From: [email-masked] (H. Dieter Wilhelm)
Date: Sat, 15 Nov 2014 20:13:03 +0100

The following patches

1) solve bug#18847 (when applying M-h with negative arguments and
   repeating this command)

2) solve another - not reported - bug.  When, e.g. at the end of the
   buffer, the numbers of paragraphs left in the buffer is less than
   ARG, then paragraphs are also marked *before* the current paragraph
   (contradicting the function's documentation)

3) (hopefully) clarifying a bit the documentation of mark-paragraph

4) aligning the behaviour of a zero argument to other marking commands
   (doing nothing, no error signal)

It still remains one anomaly - in my opinon - but only for a fringe
case, at the moment C-h and forward/backward-paragraph consider empty
lines at the end or the beginning of the buffer as an additional
paragraph...

Anyway, could some good soul apply the patches to emacs-24?

Thank you

      Dieter

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index a6ab3b8..463753c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-15  H. Dieter Wilhelm <[email-masked]>
+	* textmodes/paragraph.el (mark-paragraph): Handling of
+	negative arguments (bug#18847)
+
 2014-11-14  Ivan Andrus  <[email-masked]>
 
 	* progmodes/python.el (python-ffap-module-path): Use

diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el
index 3e77d37..d17cf09 100644
--- a/lisp/textmodes/paragraphs.el
+++ b/lisp/textmodes/paragraphs.el
@@ -371,33 +371,47 @@ See `forward-paragraph' for more information."
 
 (defun mark-paragraph (&optional arg allow-extend)
   "Put point at beginning of this paragraph, mark at end.
-The paragraph marked is the one that contains point or follows point.
+The paragraph marked is the one that contains point or follows
+point.
 
-With argument ARG, puts mark at end of a following paragraph, so that
-the number of paragraphs marked equals ARG.
+With argument ARG, puts mark at the end of this or a following
+paragraph, so that the number of paragraphs marked equals ARG.
 
-If ARG is negative, point is put at end of this paragraph, mark is put
-at beginning of this or a previous paragraph.
+If ARG is negative, point is put at the end of this paragraph,
+mark is put at the beginning of this or a previous paragraph.
 
 Interactively (or if ALLOW-EXTEND is non-nil), if this command is
-repeated or (in Transient Mark mode) if the mark is active,
-it marks the next ARG paragraphs after the ones already marked."
-  (interactive "p\np")
-  (unless arg (setq arg 1))
-  (when (zerop arg)
-    (error "Cannot mark zero paragraphs"))
-  (cond ((and allow-extend
-	      (or (and (eq last-command this-command) (mark t))
-		  (and transient-mark-mode mark-active)))
-	 (set-mark
-	  (save-excursion
-	    (goto-char (mark))
-	    (forward-paragraph arg)
-	    (point))))
-	(t
-	 (forward-paragraph arg)
-	 (push-mark nil t t)
-	 (backward-paragraph arg))))
+repeated or (in Transient Mark mode) if the mark is active, it
+marks the next ARG paragraphs after the region already marked.
+This also means when activating the mark immediately before using
+this command, the current paragraph is only marked from point."
+  (interactive "P\np")
+  (let ((numeric-arg (prefix-numeric-value arg)))
+    (cond ((zerop numeric-arg))
+	  ((and allow-extend
+		(or (and (eq last-command this-command) mark-active)
+		    (region-active-p)))
+	   (if arg
+	       (setq arg numeric-arg)
+	     (if (< (mark) (point))
+		 (setq arg -1)
+	       (setq arg 1)))
+	   (set-mark
+	    (save-excursion
+	      (goto-char (mark))
+	      (forward-paragraph arg)
+	      (point))))
+	  ;; don't activate the mark when at eob
+	  ((and (eobp) (> numeric-arg 0)))
+	  (t
+	   (unless (save-excursion
+		     (forward-line 0)
+		     (looking-at  paragraph-start))
+	     (backward-paragraph (signum numeric-arg)))
+	   (push-mark
+	    (save-excursion
+	      (forward-paragraph numeric-arg)
+	      (point)) t t)))))
 
 (defun kill-paragraph (arg)
   "Kill forward to end of paragraph.

-- 
Best wishes
H. Dieter Wilhelm
Darmstadt, Germany