changeset 41303:ada5571dc737

(fill-delete-prefix, fill-delete-newlines): New functions, extracted from fill-region-as-paragraph. (fill-region-as-paragraph): Use them. Use an end marker instead of eob. Ignore whitespace-only fill-prefixes when indenting according to mode. Simply the loop that searches for spaces backwards.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 19 Nov 2001 23:51:03 +0000
parents 65b9b5655f50
children eecd5a100096
files lisp/textmodes/fill.el
diffstat 1 files changed, 112 insertions(+), 106 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/textmodes/fill.el	Mon Nov 19 23:45:15 2001 +0000
+++ b/lisp/textmodes/fill.el	Mon Nov 19 23:51:03 2001 +0000
@@ -151,7 +151,7 @@
     ;; Blame the typist.
     (subst-char-in-region beg end ?\t ?\ )
     (while (and (< (point) end)
-		(re-search-forward "   *" end t))
+		(re-search-forward "  +" end t))
       (delete-region
        (+ (match-beginning 0)
 	  ;; Determine number of spaces to leave:
@@ -173,11 +173,11 @@
                                    "[.?!:][])}\"']*$"
                                  "[.?!][])}\"']*$")))
       (while (and (< (point) end)
-                (re-search-forward eol-double-space-re end t))
-      ;; We insert before markers in case a caller such as
-      ;; do-auto-fill has done a save-excursion with point at the end
-      ;; of the line and wants it to stay at the end of the line.
-      (insert-before-markers-and-inherit ? )))))
+		  (re-search-forward eol-double-space-re end t))
+	;; We insert before markers in case a caller such as
+	;; do-auto-fill has done a save-excursion with point at the end
+	;; of the line and wants it to stay at the end of the line.
+	(insert-before-markers-and-inherit ? )))))
 
 (defun fill-common-string-prefix (s1 s2)
   "Return the longest common prefix of strings S1 and S2, or nil if none."
@@ -251,9 +251,9 @@
 				  second-line-prefix))))
 		second-line-prefix
 
-		 ;; Use the longest common substring of both prefixes,
-		 ;; if there is one.
-		 (fill-common-string-prefix first-line-prefix
+	      ;; Use the longest common substring of both prefixes,
+	      ;; if there is one.
+	      (fill-common-string-prefix first-line-prefix
 					 second-line-prefix))))
 	;; If we get a fill prefix from a one-line paragraph,
 	;; maybe change it to whitespace,
@@ -321,7 +321,7 @@
      ;; The reason is that if a period ends up at the end of a
      ;; line, further fills will assume it ends a sentence.
      ;; If we now know it does not end a sentence, avoid putting
-     ;; it at the end of the line.
+     ;; it at the end of the line. 
      (and sentence-end-double-space
 	  (save-excursion
 	    (skip-chars-backward ". ")
@@ -340,10 +340,10 @@
 ;; Put `fill-find-break-point-function' property to charsets which
 ;; require special functions to find line breaking point.
 (dolist (pair '((katakana-jisx0201 . kinsoku)
-	       (chinese-gb2312 . kinsoku)
-	       (japanese-jisx0208 . kinsoku)
-	       (japanese-jisx0212 . kinsoku)
-	       (chinese-big5-1 . kinsoku)
+		(chinese-gb2312 . kinsoku)
+		(japanese-jisx0208 . kinsoku)
+		(japanese-jisx0212 . kinsoku)
+		(chinese-big5-1 . kinsoku)
 		(chinese-big5-2 . kinsoku)))
   (put-charset-property (car pair) 'fill-find-break-point-function (cdr pair)))
 
@@ -368,6 +368,79 @@
     (if (and func (fboundp func))
 	(funcall func limit))))
 
+(defun fill-delete-prefix (from to prefix)
+  "Delete the fill prefix from every line except the first.
+The first line may not even have a fill prefix.
+Point is moved to just past the fill prefix on the first line."
+  (goto-char from)
+  (let ((fpre (and prefix (not (equal prefix ""))
+		   (concat "[ \t]*"
+			   (replace-regexp-in-string
+			    "[ \t]+" "[ \t]*"
+			    (regexp-quote prefix))
+			   "[ \t]*"))))
+    (when fpre
+      (if (>= (+ (current-left-margin) (length prefix))
+	      (current-fill-column))
+	  (error "fill-prefix too long for specified width"))
+      (forward-line 1)
+      (while (< (point) to)
+	(if (looking-at fpre)
+	    (delete-region (point) (match-end 0)))
+	(forward-line 1))
+      (goto-char from)
+      (if (looking-at fpre)
+	  (goto-char (match-end 0)))
+      (setq from (point))))
+  ;; Remove indentation from lines other than the first.
+  (beginning-of-line 2)
+  (indent-region (point) to 0)
+  (goto-char from))
+
+(defun fill-delete-newlines (from to justify nosqueeze squeeze-after)
+  (goto-char from)
+  ;; Make sure sentences ending at end of line get an extra space.
+  ;; loses on split abbrevs ("Mr.\nSmith")
+  (let ((eol-double-space-re (if colon-double-space
+				 "[.?!:][])}\"']*$"
+			       "[.?!][])}\"']*$")))
+    (while (re-search-forward eol-double-space-re to t)
+      (or (>= (point) to) (insert-and-inherit ?\ ))))
+
+  (goto-char from)
+  (if enable-multibyte-characters
+      ;; Delete unnecessay newlines surrounded by words.  The
+      ;; character category `|' means that we can break a line
+      ;; at the character.  And, charset property
+      ;; `nospace-between-words' tells how to concatenate
+      ;; words.  If the value is non-nil, never put spaces
+      ;; between words, thus delete a newline between them.
+      ;; If the value is nil, delete a newline only when a
+      ;; character preceding a newline has text property
+      ;; `nospace-between-words'.
+      (while (search-forward "\n" to t)
+	(let ((prev (char-before (match-beginning 0)))
+	      (next (following-char)))
+	  (if (and (or (aref (char-category-set next) ?|)
+		       (aref (char-category-set prev) ?|))
+		   (or (get-charset-property (char-charset prev)
+					     'nospace-between-words)
+		       (get-text-property (1- (match-beginning 0))
+					  'nospace-between-words)))
+	      (delete-char -1)))))
+
+  (goto-char from)
+  (skip-chars-forward " \t")
+  ;; Then change all newlines to spaces.
+  (subst-char-in-region from to ?\n ?\ )
+  (if (and nosqueeze (not (eq justify 'full)))
+      nil
+    (canonically-space-region (or squeeze-after (point)) to)
+    (goto-char to)
+    (delete-horizontal-space)
+    (insert-and-inherit " "))
+  (goto-char from))
+
 (defun fill-region-as-paragraph (from to &optional justify
 				      nosqueeze squeeze-after)
   "Fill the region as one paragraph.
@@ -421,7 +494,7 @@
 	  (delete-backward-char 1)
 	(backward-char 1)
 	(setq oneleft t)))
-    (setq to (point))
+    (setq to (copy-marker (point) t))
     ;; ;; If there was no newline, and there is text in the paragraph, then
     ;; ;; create a newline.
     ;; (if (and (not oneleft) (> to from-plus-indent))
@@ -436,16 +509,21 @@
     ;; Never indent-according-to-mode with brain dead "indenting" functions.
     (when (and fill-indent-according-to-mode
 	       (memq indent-line-function
-		     '(indent-relative-maybe indent-relative
+		   '(indent-relative-maybe indent-relative
 		       indent-to-left-margin)))
       (set (make-local-variable 'fill-indent-according-to-mode) nil))
 
     ;; Don't let Adaptive Fill mode alter the fill prefix permanently.
     (let ((fill-prefix fill-prefix))
       ;; Figure out how this paragraph is indented, if desired.
-      (if (and adaptive-fill-mode
-	       (or (null fill-prefix) (string= fill-prefix "")))
-	  (setq fill-prefix (fill-context-prefix from to)))
+      (when (and adaptive-fill-mode
+		 (or (null fill-prefix) (string= fill-prefix "")))
+	(setq fill-prefix (fill-context-prefix from to))
+	;; Ignore a white-space only fill-prefix
+	;; if we indent-according-to-mode.
+	(when (and fill-prefix fill-indent-according-to-mode
+		   (string-match "\\`[ \t]*\\'" fill-prefix))
+	  (setq fill-prefix nil)))
 
       (save-restriction
 	(goto-char from)
@@ -455,7 +533,7 @@
 	(if (not justify)	    ; filling disabled: just check indentation
 	    (progn
 	      (goto-char from)
-	      (while (not (eobp))
+	      (while (< (point) to)
 		(if (and (not (eolp))
 			 (< (current-indentation) (current-left-margin)))
 		    (indent-to-left-margin))
@@ -467,77 +545,14 @@
 	  (if (or (memq justify '(right center))
 		  (< (current-indentation) (current-left-margin)))
 	      (indent-to-left-margin))
-	  ;; Delete the fill prefix from every line except the first.
-	  ;; The first line may not even have a fill prefix.
-	  (goto-char from)
-	  (let ((fpre (and fill-prefix (not (equal fill-prefix ""))
-			   (concat "[ \t]*"
-				   (regexp-quote fill-prefix)
-				   "[ \t]*"))))
-	    (and fpre
-		 (progn
-		   (if (>= (+ (current-left-margin) (length fill-prefix))
-			   (current-fill-column))
-		       (error "fill-prefix too long for specified width"))
-		   (goto-char from)
-		   (forward-line 1)
-		   (while (not (eobp))
-		     (if (looking-at fpre)
-			 (delete-region (point) (match-end 0)))
-		     (forward-line 1))
-		   (goto-char from)
-		   (if (looking-at fpre)
-		       (goto-char (match-end 0)))
-		   (setq from (point)))))
-	  ;; Remove indentation from lines other than the first.
-	  (beginning-of-line 2)
-	  (indent-region (point) (point-max) 0)
-	  (goto-char from)
-
+	  ;; Delete the fill-prefix from every line.
+	  (fill-delete-prefix from to fill-prefix)
+	  (setq from (point))
+	  
 	  ;; FROM, and point, are now before the text to fill,
 	  ;; but after any fill prefix on the first line.
 
-	  ;; Make sure sentences ending at end of line get an extra space.
-	  ;; loses on split abbrevs ("Mr.\nSmith")
-          (let ((eol-double-space-re (if colon-double-space
-                                         "[.?!:][])}\"']*$"
-                                       "[.?!][])}\"']*$")))
-            (while (re-search-forward eol-double-space-re nil t)
-              (or (eobp) (insert-and-inherit ?\ ))))
-
-	  (goto-char from)	  
-	  (if enable-multibyte-characters
-	      ;; Delete unnecessay newlines surrounded by words.  The
-	      ;; character category `|' means that we can break a line
-	      ;; at the character.  And, charset property
-	      ;; `nospace-between-words' tells how to concatenate
-	      ;; words.  If the value is non-nil, never put spaces
-	      ;; between words, thus delete a newline between them.
-	      ;; If the value is nil, delete a newline only when a
-	      ;; character preceding a newline has text property
-	      ;; `nospace-between-words'.
-	      (while (search-forward "\n" nil t)
-		(let ((prev (char-before (match-beginning 0)))
-		      (next (following-char)))
-		  (if (and (or (aref (char-category-set next) ?|)
-			       (aref (char-category-set prev) ?|))
-			   (or (get-charset-property (char-charset prev)
-						     'nospace-between-words)
-			       (get-text-property (1- (match-beginning 0))
-						  'nospace-between-words)))
-		      (delete-char -1)))))
-
-	  (goto-char from)
-	  (skip-chars-forward " \t")
-	  ;; Then change all newlines to spaces.
-	  (subst-char-in-region from (point-max) ?\n ?\ )
-	  (if (and nosqueeze (not (eq justify 'full)))
-	      nil
-	    (canonically-space-region (or squeeze-after (point)) (point-max))
-	    (goto-char (point-max))
-	    (delete-horizontal-space)
-	    (insert-and-inherit " "))
-	  (goto-char (point-min))
+	  (fill-delete-newlines from to justify nosqueeze squeeze-after)
 
 	  ;; This is the actual filling loop.
 	  (let ((prefixcol 0) linebeg)
@@ -552,24 +567,15 @@
 		;; search space, \c| followed by a character, or \c|
 		;; following a character.  If not found, place
 		;; the point at linebeg.
-		(if (re-search-backward " \\|\\c|.\\|.\\c|" linebeg 0)
-		    ;; In case of space, we place the point at next to
-		    ;; the point where the break occurs acutually,
-		    ;; because we don't want to change the following
-		    ;; logic of original Emacs.  In case of \c|, the
-		    ;; point is at the place where the break occurs.
-		    (forward-char 1))
-		;; Don't break after a period followed by just one space.
-		;; Move back to the previous place to break.
-		;; The reason is that if a period ends up at the end of a line,
-		;; further fills will assume it ends a sentence.
-		;; If we now know it does not end a sentence,
-		;; avoid putting it at the end of the line.
-		(while (and (> (point) linebeg)
-			    (fill-nobreak-p)
-			    (skip-chars-backward " \t"))
-		  (if (re-search-backward " \\|\\c|.\\|.\\c|" linebeg 0)
-		      (forward-char 1)))
+		(while
+		    (when (re-search-backward "[ \t]\\|\\c|.\\|.\\c|" linebeg 0)
+		      ;; In case of space, we place the point at next to
+		      ;; the point where the break occurs actually,
+		      ;; because we don't want to change the following
+		      ;; logic of original Emacs.  In case of \c|, the
+		      ;; point is at the place where the break occurs.
+		      (forward-char 1)
+		      (when (fill-nobreak-p) (skip-chars-backward " \t"))))
 		;; If the left margin and fill prefix by themselves
 		;; pass the fill-column. or if they are zero
 		;; but we have no room for even one word,