- (beginning-of-line)
- (narrow-to-region (point) to)
-
- (if (not justify) ; filling disabled: just check indentation
- (progn
- (goto-char from)
- (while (not (eobp))
- (if (and (not (eolp))
- (< (current-indentation) (current-left-margin)))
- (indent-to-left-margin))
- (forward-line 1)))
-
- (if use-hard-newlines
- (remove-text-properties from (point-max) '(hard nil)))
- ;; Make sure first line is indented (at least) to left margin...
- (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)
-
- ;; 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))
-
- ;; This is the actual filling loop.
- (let ((prefixcol 0) linebeg)
- (while (not (eobp))
- (setq linebeg (point))
- (move-to-column (1+ (current-fill-column)))
- (if (eobp)
- (or nosqueeze (delete-horizontal-space))
- ;; Move back to the point where we can break the line
- ;; at. We break the line between word or after/before
- ;; the character which has character category `|'. We
- ;; 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 (or (and sentence-end-double-space
- (> (point) (+ linebeg 2))
- (eq (preceding-char) ?\ )
- (not (eq (following-char) ?\ ))
- (eq (char-after (- (point) 2)) ?\.)
- (progn (forward-char -2) t))
- (and fill-nobreak-predicate
- (funcall fill-nobreak-predicate)
- (skip-chars-backward " \t")))
- (if (re-search-backward " \\|\\c|.\\|.\\c|" linebeg 0)
- (forward-char 1)))
- ;; 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,
- ;; keep at least one word or a character which has
- ;; category `|'anyway .
- ;; This handles ALL BUT the first line of the paragraph.
- (if (if (zerop prefixcol)
- (save-excursion
- (skip-chars-backward " \t" linebeg)
- (bolp))
- (>= prefixcol (current-column)))
- ;; Ok, skip at least one word or one \c| character.
- ;; Meanwhile, don't stop at a period followed by one space.
- (let ((first t))
- (move-to-column prefixcol)
- (while (and (not (eobp))
- (or first
- (and (not (bobp))
- sentence-end-double-space
- (save-excursion
- (forward-char -1)
- (and (looking-at "\\. ")
- (not (looking-at "\\. ")))))
- (and fill-nobreak-predicate
- (funcall fill-nobreak-predicate))))
- ;; Find a breakable point while ignoring the
- ;; following spaces.
- (skip-chars-forward " \t")
- (if (looking-at "\\c|")
- (forward-char 1)
- (let ((pos (save-excursion
- (skip-chars-forward "^ \n\t")
- (point))))
- (if (re-search-forward "\\c|" pos t)
- (forward-char -1)
- (goto-char pos))))
- (setq first nil)))
- ;; Normally, move back over the single space between
- ;; the words.
- (if (= (preceding-char) ?\ ) (forward-char -1))
-
- (if enable-multibyte-characters
- ;; If we are going to break the line after or
- ;; before a non-ascii character, we may have to
- ;; run a special function for the charset of the
- ;; character to find the correct break point.
- (if (not (and (eq (charset-after (1- (point))) 'ascii)
- (eq (charset-after (point)) 'ascii)))
- ;; Make sure we take SOMETHING after the
- ;; fill prefix if any.
- (fill-find-break-point
- (save-excursion
- (goto-char linebeg)
- (move-to-column prefixcol)
- (point))))))
-
- ;; If the left margin and fill prefix by themselves
- ;; pass the fill-column, keep at least one word.
- ;; This handles the first line of the paragraph.
- (if (and (zerop prefixcol)
- (let ((fill-point (point)) nchars)
- (save-excursion
- (move-to-left-margin)
- (setq nchars (- fill-point (point)))
- (or (< nchars 0)
- (and fill-prefix
- (< nchars (length fill-prefix))
- (string= (buffer-substring (point)
- fill-point)
- (substring fill-prefix
- 0 nchars)))))))
- ;; Ok, skip at least one word. But
- ;; don't stop at a period followed by just one space.
- (let ((first t))
- (while (and (not (eobp))
- (or first
- (and (not (bobp))
- sentence-end-double-space
- (save-excursion
- (forward-char -1)
- (and (looking-at "\\. ")
- (not (looking-at "\\. ")))))
- (and fill-nobreak-predicate
- (funcall fill-nobreak-predicate))))
- ;; Find a breakable point while ignoring the
- ;; following spaces.
- (skip-chars-forward " \t")
- (if (looking-at "\\c|")
- (forward-char 1)
- (let ((pos (save-excursion
- (skip-chars-forward "^ \n\t")
- (point))))
- (if (re-search-forward "\\c|" pos t)
- (forward-char -1)
- (goto-char pos))))
- (setq first nil))))
- ;; Check again to see if we got to the end of the paragraph.
- (if (save-excursion (skip-chars-forward " \t") (eobp))
- (or nosqueeze (delete-horizontal-space))
- ;; Replace whitespace here with one newline, then
- ;; indent to left margin.
- (skip-chars-backward " \t")
- (if (and (= (following-char) ?\ )
- (or (aref (char-category-set (preceding-char)) ?|)
- (looking-at "[ \t]+\\c|")))
- ;; We need one space at end of line so that
- ;; further filling won't delete it. NOTE: We
- ;; intentionally leave this one space to
- ;; distingush the case that user wants to put
- ;; space between \c| characters.
- (forward-char 1))
- (insert ?\n)
- ;; Give newline the properties of the space(s) it replaces
- (set-text-properties (1- (point)) (point)
- (text-properties-at (point)))
- (if (or fill-prefix
- (not fill-indent-according-to-mode)
- (memq indent-line-function
- ;; Brain dead "indenting" functions.
- '(indent-relative-maybe indent-relative)))
- (indent-to-left-margin)
- (indent-according-to-mode))
- ;; Insert the fill prefix after indentation.
- ;; Set prefixcol so whitespace in the prefix won't get lost.
- (and fill-prefix (not (equal fill-prefix ""))
- (progn
- (insert-and-inherit fill-prefix)
- (setq prefixcol (current-column))))))
- ;; Justify the line just ended, if desired.
- (if justify
- (if (save-excursion (skip-chars-forward " \t") (eobp))
- (progn
- (delete-horizontal-space)
- (justify-current-line justify t t))
- (forward-line -1)
- (justify-current-line justify nil t)
- (forward-line 1))))))
- ;; Leave point after final newline.
- (goto-char (point-max)))
- (unless (eobp)
- (forward-char 1))