Hello,

`canonically-space-region' doesn't stop at the end of the region.
That's because it limits its searches at `end', while the actual region
keeps getting smaller.

For example:
a                                     b
c   d
Mark the first line, call `canonically-space-region' and observe that
the spaces in the second line disappear as well.

`fill-delete-newlines' has the same problem because it calls
`canonically-space-region' and because it uses the `to' variable
afterwards.

A proposed patch is attached.


regards,
Nikolaj Schumacher

diff -du /Users/nik/.emacs.d/backup/\!Applications\!Emacs.app\!Contents\!Resources\!share\!emacs\!22.1.50\!lisp\!textmodes\!fill.el.\~1\~ /Applications/Emacs.app/Contents/Resources/share/emacs/22.1.50/lisp/textmodes/fill.el
--- lisp/textmodes/fill.el	2007-04-27 15:28:14.000000000 +0200
+++ lisp/textmodes/fill.el	2007-05-24 14:28:23.000000000 +0200
@@ -159,7 +159,8 @@
 and `sentence-end-without-period').
 Remove indentation from each line."
   (interactive "*r")
-  (let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\|  +")))
+  (let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\|  +"))
+	delete-begin delete-end)
     (save-excursion
       (goto-char beg)
       ;; Nuke tabs; they get screwed up in a fill.
@@ -169,35 +170,41 @@
       (subst-char-in-region beg end ?\t ?\s)
       (while (and (< (point) end)
 		  (re-search-forward end-spc-re end t))
-	(delete-region
-	 (cond
-	  ;; `sentence-end' matched and did not match all spaces.
-	  ;; I.e. it only matched the number of spaces it needs: drop the rest.
-	  ((and (match-end 1) (> (match-end 0) (match-end 1)))  (match-end 1))
-	  ;; `sentence-end' matched but with nothing left.  Either that means
-	  ;; nothing should be removed, or it means it's the "old-style"
-	  ;; sentence-end which matches all it can.  Keep only 2 spaces.
-	  ;; We probably don't even need to check `sentence-end-double-space'.
-	  ((match-end 1)
-	   (min (match-end 0)
-		(+ (if sentence-end-double-space 2 1)
-		   (save-excursion (goto-char (match-end 0))
-				   (skip-chars-backward " ")
-				   (point)))))
-	  (t ;; It's not an end of sentence.
-	   (+ (match-beginning 0)
-	      ;; Determine number of spaces to leave:
-	      (save-excursion
-		(skip-chars-backward " ]})\"'")
-		(cond ((and sentence-end-double-space
-			    (or (memq (preceding-char) '(?. ?? ?!))
-				(and sentence-end-without-period
-				     (= (char-syntax (preceding-char)) ?w)))) 2)
-		      ((and colon-double-space
-			    (= (preceding-char) ?:))  2)
-		      ((char-equal (preceding-char) ?\n)  0)
-		      (t 1))))))
-	 (match-end 0))))))
+	(setq delete-begin
+	      (cond
+	       ;; `sentence-end' matched and did not match all spaces.  I.e. it
+	       ;; only matched the number of spaces it needs: drop the rest.
+	       ((and (match-end 1) (> (match-end 0) (match-end 1)))
+		(match-end 1))
+	       ;; `sentence-end' matched but with nothing left.  Either that
+	       ;; means nothing should be removed, or it means it's the
+	       ;; "old-style" sentence-end which matches all it can.  Keep only
+	       ;; 2 spaces.  We probably don't even need to check
+	       ;; `sentence-end-double-space'.
+	       ((match-end 1)
+		(min (match-end 0)
+		     (+ (if sentence-end-double-space 2 1)
+			(save-excursion (goto-char (match-end 0))
+					(skip-chars-backward " ")
+					(point)))))
+	       (t ;; It's not an end of sentence.
+		(+ (match-beginning 0)
+		   ;; Determine number of spaces to leave:
+		   (save-excursion
+		     (skip-chars-backward " ]})\"'")
+		     (cond ((and sentence-end-double-space
+				 (or (memq (preceding-char) '(?. ?? ?!))
+				     (and sentence-end-without-period
+					  (= (char-syntax (preceding-char)) ?w)))) 2)
+			   ((and colon-double-space
+				 (= (preceding-char) ?:))  2)
+			   ((char-equal (preceding-char) ?\n)  0)
+			   (t 1))))))
+	      delete-end (match-end 0))
+	(delete-region delete-begin delete-end)
+	;; Move end position to accommodate for deleted text.
+	(setq end (- end (- delete-end delete-begin)))
+	))))
 
 (defun fill-common-string-prefix (s1 s2)
   "Return the longest common prefix of strings S1 and S2, or nil if none."
@@ -482,10 +489,12 @@
   (subst-char-in-region from to ?\n ?\s)
   (if (and nosqueeze (not (eq justify 'full)))
       nil
-    (canonically-space-region (or squeeze-after (point)) to)
-    ;; Remove trailing whitespace.
+    ;; Remove trailing whitespace, so canonically-space-region doesn't leave
+    ;; them at the end.  Do this first, since `to' will be invalid after.
     ;; Maybe canonically-space-region should do that.
-    (goto-char to) (delete-char (- (skip-chars-backward " \t"))))
+    (let ((beg (point)))
+      (goto-char to) (delete-char (- (skip-chars-backward " \t")))
+      (canonically-space-region (or squeeze-after beg) (point))))
   (goto-char from))
 
 (defun fill-move-to-break-point (linebeg)

Diff finished.  Thu May 24 14:40:37 2007
_______________________________________________
emacs-pretest-bug mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug

Reply via email to