changeset 2376:f7a3795bd1c5

(fill-paragraph, justify-current-line) Now uses the skip-syntax- forward and backward characters and char-syntax to be smart about filling syntaxes other than text. This change was inspired by Richard Caley's fill-para package from LCD, but the implementation is original.
author Eric S. Raymond <esr@snark.thyrsus.com>
date Sat, 27 Mar 1993 01:58:16 +0000
parents 94e135f2d64d
children 9721e0530cd9
files lisp/textmodes/fill.el
diffstat 1 files changed, 39 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/textmodes/fill.el	Fri Mar 26 07:28:20 1993 +0000
+++ b/lisp/textmodes/fill.el	Sat Mar 27 01:58:16 1993 +0000
@@ -66,7 +66,7 @@
   (if (and buffer-undo-list (not (eq buffer-undo-list t)))
       (setq buffer-undo-list (cons (point) buffer-undo-list)))
   ;; Don't let Adaptive Fill mode alter the fill prefix permanently.
-  (let ((fill-prefix fill-prefix))
+  (let ((fill-prefix fill-prefix) spc)
     ;; Figure out how this paragraph is indented, if desired.
     (if (and adaptive-fill-mode
 	     (or (null fill-prefix) (string= fill-prefix "")))
@@ -114,34 +114,48 @@
       ;; from is now before the text to fill,
       ;; but after any fill prefix on the first line.
 
+      ;; spc (our filler character) is normally SPC;
+      ;; if SPC does not have syntax class whitespace, find a filler that does.
+      (if (= (char-syntax ?\ ) ?\ )
+	  (setq spc ?\ )
+	(setq spc 0)
+	(while (not (= (char-syntax spc) ?\ ))
+	  (setq spc (1+ spc))))
+
       ;; Make sure sentences ending at end of line get an extra space.
-      ;; loses on split abbrevs ("Mr.\nSmith")
+      ;; loses on split abbrevs ("Mr.\nSmith").  This is fairly specific
+      ;; to text mode.
       (goto-char from)
       (while (re-search-forward "[.?!][])}\"']*$" nil t)
-	(insert ? ))
+	(insert spc))
 
       ;; Then change all newlines to spaces.
-      (subst-char-in-region from (point-max) ?\n ?\ )
+      (subst-char-in-region from to ?\n spc)
 
-      ;; Flush excess spaces, except in the paragraph indentation.
+      ;; Go to beginning of paragraph (after indent)
       (goto-char from)
-      (skip-chars-forward " \t")
-      ;; nuke tabs while we're at it; they get screwed up in a fill
-      ;; this is quick, but loses when a sole tab follows the end of a sentence.
-      ;; actually, it is difficult to tell that from "Mr.\tSmith".
-      ;; blame the typist.
-      (subst-char-in-region (point) (point-max) ?\t ?\ )
-      (while (re-search-forward "   *" nil t)
+      (skip-syntax-forward " ")
+
+      ;; If tabs have whitespace class, nuke them; they get screwed up
+      ;; in a fill.  This is quick, but loses when a sole tab follows
+      ;; the end of a sentence.  actually, it is difficult to tell
+      ;; that from "Mr.\tSmith".  Blame the typist.
+      (if (= (char-syntax ?\t) ?\ )
+	  (subst-char-in-region (point) to ?\t spc))
+
+      ;; Flush excess whitespace, except in the paragraph indentation.
+      (while (re-search-forward "\\s-\\s-\\s-*" nil t)
 	(delete-region
 	 (+ (match-beginning 0)
 	    (if (save-excursion
-		  (skip-chars-backward " ]})\"'")
+		  (skip-syntax-backward " ).")
 		  (memq (preceding-char) '(?. ?? ?!)))
 		2 1))
 	 (match-end 0)))
       (goto-char (point-max))
       (delete-horizontal-space)
-      (insert "  ")
+      (insert spc)
+      (insert spc)
       (goto-char (point-min))
 
       ;; This is the actual filling loop.
@@ -152,7 +166,7 @@
 	  (if (eobp)
 	      nil
 	    ;; Move back to start of word.
-	    (skip-chars-backward "^ \n" linebeg)
+	    (skip-syntax-backward "^ " linebeg)
 	    ;; 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,
@@ -160,16 +174,16 @@
 	    ;; If we now know it does not end a sentence,
 	    ;; avoid putting it at the end of the line.
 	    (while (and (> (point) (+ linebeg 2))
-			(eq (preceding-char) ?\ )
+			(eq (char-syntax (preceding-char)) ?\ )
 			(eq (char-after (- (point) 2)) ?\.))
 	      (forward-char -2)
-	      (skip-chars-backward "^ \n" linebeg))
+	      (skip-syntax-backward "^ " linebeg))
 	    (if (if (zerop prefixcol) (bolp) (>= prefixcol (current-column)))
 		;; Keep at least one word even if fill prefix exceeds margin.
 		;; This handles all but the first line of the paragraph.
 		(progn
-		  (skip-chars-forward " ")
-		  (skip-chars-forward "^ \n"))
+		  (skip-syntax-forward " ")
+		  (skip-syntax-forward "^ "))
 	      ;; Normally, move back over the single space between the words.
 	      (forward-char -1)))
 	    (if (and fill-prefix (zerop prefixcol)
@@ -179,12 +193,12 @@
 		;; Keep at least one word even if fill prefix exceeds margin.
 		;; This handles the first line of the paragraph.
 		(progn
-		  (skip-chars-forward " ")
-		  (skip-chars-forward "^ \n")))
+		  (skip-syntax-forward " ")
+		  (skip-syntax-forward "^ ")))
 	  ;; Replace all whitespace here with one newline.
 	  ;; Insert before deleting, so we don't forget which side of
 	  ;; the whitespace point or markers used to be on.
-	  (skip-chars-backward " ")
+	  (skip-syntax-backward " ")
 	  (insert ?\n)
 	  (delete-horizontal-space)
 	  ;; Insert the fill prefix at start of each line.
@@ -236,17 +250,17 @@
     (let (ncols beg indent)
       (beginning-of-line)
       (forward-char (length fill-prefix))
-      (skip-chars-forward " \t")
+      (skip-syntax-forward " " (save-excursion (end-of-line) (point)))
       (setq indent (current-column))
       (setq beg (point))
       (end-of-line)
       (narrow-to-region beg (point))
       (goto-char beg)
-      (while (re-search-forward "   *" nil t)
+      (while (re-search-forward "\\s-\\s-\\s-*" nil t)
 	(delete-region
 	 (+ (match-beginning 0)
 	    (if (save-excursion
-		 (skip-chars-backward " ])\"'")
+		 (skip-syntax-backward " ).")
 		 (memq (preceding-char) '(?. ?? ?!)))
 		2 1))
 	 (match-end 0)))