;;; fill.el --- fill commands for Emacs -*- coding: iso-2022-7bit -*-
;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1999, 2001, 2002,
-;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;; 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: wp
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
(defvar fill-paragraph-function nil
"Mode-specific function to fill a paragraph, or nil if there is none.
-If the function returns nil, then `fill-paragraph' does its normal work.")
+If the function returns nil, then `fill-paragraph' does its normal work.
+A value of t means explicitly \"do nothing special\".")
(defvar fill-paragraph-handle-comment t
"Non-nil means paragraph filling will try to pay attention to comments.")
(defcustom adaptive-fill-regexp
;; Added `!' for doxygen comments starting with `//!' or `/*!'.
;; Added `%' for TeX comments.
- (purecopy "[ \t]*\\([-!|#%;>*\e,A7\e$,1s"s#sC\e$,2"F\e(B]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*")
+ ;; RMS: deleted the code to match `1.' and `(1)'.
+ "[ \t]*\\([-!|#%;>*\e,A7\e$,1s"s#sC\e$,2"F\e(B]+[ \t]*\\)*"
"*Regexp to match text at start of line that constitutes indentation.
If Adaptive Fill mode is enabled, a prefix matching this pattern
on the first and second lines of a paragraph is used as the
:group 'fill)
(defcustom adaptive-fill-function nil
- "*Function to call to choose a fill prefix for a paragraph, or nil.
-nil means the function has not determined the fill prefix."
+ "Function to call to choose a fill prefix for a paragraph, or nil.
+A nil value means the function has not determined the fill prefix."
:type '(choice (const nil) function)
:group 'fill)
and `sentence-end-without-period').
Remove indentation from each line."
(interactive "*r")
+ ;; Ideally, we'd want to scan the text from the end, so that changes to
+ ;; text don't affect the boundary, but the regexp we match against does
+ ;; not match as eagerly when matching backward, so we instead use
+ ;; a marker.
+ (unless (markerp end) (setq end (copy-marker end t)))
(let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\| +")))
(save-excursion
(goto-char beg)
(defun fill-single-word-nobreak-p ()
"Don't break a line after the first or before the last word of a sentence."
- (or (looking-at (concat "[ \t]*\\sw+" "\\(?:" (sentence-end) "\\)"))
+ ;; Actually, allow breaking before the last word of a sentence, so long as
+ ;; it's not the last word of the paragraph.
+ (or (looking-at (concat "[ \t]*\\sw+" "\\(?:" (sentence-end) "\\)[ \t]*$"))
(save-excursion
(skip-chars-backward " \t")
(and (/= (skip-syntax-backward "w") 0)
Can be customized with the variables `fill-nobreak-predicate'
and `fill-nobreak-invisible'."
(or
- (and fill-nobreak-invisible (line-move-invisible-p (point)))
+ (and fill-nobreak-invisible (invisible-p (point)))
(unless (bolp)
(or
;; Don't break after a period followed by just one space.
This function is called when we are going to break the current line
after or before a non-ASCII character. If the charset of the
character has the property `fill-find-break-point-function', this
-function calls the property value as a function with one arg LINEBEG.
+function calls the property value as a function with one arg LIMIT.
If the charset has no such property, do nothing."
(let* ((ch (following-char))
(charset (char-charset ch))
;; Ok, skip at least one word or one \c| character.
;; Meanwhile, don't stop at a period followed by one space.
(let ((to (line-end-position))
- (fill-nobreak-predicate nil) ;to break sooner.
(first t))
(goto-char linebeg)
(while (and (< (point) to) (or first (fill-nobreak-p)))
(let ((from-plus-indent (point))
(oneleft nil))
+ (beginning-of-line)
;; We used to round up to whole line, but that prevents us from
- ;; correctly handling filling of mixed code-and-comment where we
- ;; do want to fill the comment but not the code.
- ;; (beginning-of-line) (setq from (point))
+ ;; correctly handling filling of mixed code-and-comment where we do want
+ ;; to fill the comment but not the code. So only use (point) if it's
+ ;; further than `from', which means that `from' is followed by some
+ ;; number of empty lines.
+ (setq from (max (point) from))
;; Delete all but one soft newline at end of region.
;; And leave TO before that one.
(looking-at (regexp-quote prefix))))
(goto-char (match-end 0))))
-(defun fill-paragraph (arg)
- "Fill paragraph at or after point. Prefix ARG means justify as well.
+(defun fill-minibuffer-function (arg)
+ "Fill a paragraph in the minibuffer, ignoring the prompt."
+ (save-restriction
+ (narrow-to-region (minibuffer-prompt-end) (point-max))
+ (fill-paragraph arg)))
+
+(defun fill-paragraph (&optional justify region)
+ "Fill paragraph at or after point.
+
+If JUSTIFY is non-nil (interactively, with prefix argument), justify as well.
If `sentence-end-double-space' is non-nil, then period followed by one
space does not end a sentence, so don't break a line there.
the variable `fill-column' controls the width for filling.
If `fill-paragraph-function' is non-nil, we call it (passing our
argument to it), and if it returns non-nil, we simply return its value.
-If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling."
+If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling.
+
+Interactively (when `region' is non-nil) in Transient Mark mode when
+the mark is active, call `fill-region' to fill each of the paragraphs
+in the active region."
(interactive (progn
(barf-if-buffer-read-only)
- (list (if current-prefix-arg 'full))))
- ;; First try fill-paragraph-function.
- (or (and fill-paragraph-function
- (let ((function fill-paragraph-function)
- ;; If fill-paragraph-function is set, it probably takes care
- ;; of comments and stuff. If not, it will have to set
- ;; fill-paragraph-handle-comment back to t explicitly or
- ;; return nil.
- (fill-paragraph-handle-comment nil)
- fill-paragraph-function)
- (funcall function arg)))
- ;; Then try our syntax-aware filling code.
- (and fill-paragraph-handle-comment
- ;; Our code only handles \n-terminated comments right now.
- comment-start (equal comment-end "")
- (let ((fill-paragraph-handle-comment nil))
- (fill-comment-paragraph arg)))
- ;; If it all fails, default to the good ol' text paragraph filling.
- (let ((before (point))
- (paragraph-start paragraph-start)
- ;; Fill prefix used for filling the paragraph.
- fill-pfx)
- ;; Try to prevent code sections and comment sections from being
- ;; filled together.
- (when (and fill-paragraph-handle-comment comment-start-skip)
- (setq paragraph-start
- (concat paragraph-start "\\|[ \t]*\\(?:"
- comment-start-skip "\\)")))
- (save-excursion
- ;; To make sure the return value of forward-paragraph is meaningful,
- ;; we have to start from the beginning of line, otherwise skipping
- ;; past the last few chars of a paragraph-separator would count as
- ;; a paragraph (and not skipping any chars at EOB would not count
- ;; as a paragraph even if it is).
- (move-to-left-margin)
- (if (not (zerop (forward-paragraph)))
- ;; There's no paragraph at or after point: give up.
- (setq fill-pfx "")
- (let ((end (point))
- (beg (progn (backward-paragraph) (point))))
- (goto-char before)
- (setq fill-pfx
- (if use-hard-newlines
- ;; Can't use fill-region-as-paragraph, since this
- ;; paragraph may still contain hard newlines. See
- ;; fill-region.
- (fill-region beg end arg)
- (fill-region-as-paragraph beg end arg))))))
- fill-pfx)))
+ (list (if current-prefix-arg 'full) t)))
+ (or
+ ;; 1. Fill the region if it is active when called interactively.
+ (and region transient-mark-mode mark-active
+ (not (eq (region-beginning) (region-end)))
+ (or (fill-region (region-beginning) (region-end) justify) t))
+ ;; 2. Try fill-paragraph-function.
+ (and (not (eq fill-paragraph-function t))
+ (or fill-paragraph-function
+ (and (minibufferp (current-buffer))
+ (= 1 (point-min))))
+ (let ((function (or fill-paragraph-function
+ ;; In the minibuffer, don't count the width
+ ;; of the prompt.
+ 'fill-minibuffer-function))
+ ;; If fill-paragraph-function is set, it probably takes care
+ ;; of comments and stuff. If not, it will have to set
+ ;; fill-paragraph-handle-comment back to t explicitly or
+ ;; return nil.
+ (fill-paragraph-handle-comment nil)
+ (fill-paragraph-function t))
+ (funcall function justify)))
+ ;; 3. Try our syntax-aware filling code.
+ (and fill-paragraph-handle-comment
+ ;; Our code only handles \n-terminated comments right now.
+ comment-start (equal comment-end "")
+ (let ((fill-paragraph-handle-comment nil))
+ (fill-comment-paragraph justify)))
+ ;; 4. If it all fails, default to the good ol' text paragraph filling.
+ (let ((before (point))
+ (paragraph-start paragraph-start)
+ ;; Fill prefix used for filling the paragraph.
+ fill-pfx)
+ ;; Try to prevent code sections and comment sections from being
+ ;; filled together.
+ (when (and fill-paragraph-handle-comment comment-start-skip)
+ (setq paragraph-start
+ (concat paragraph-start "\\|[ \t]*\\(?:"
+ comment-start-skip "\\)")))
+ (save-excursion
+ ;; To make sure the return value of forward-paragraph is meaningful,
+ ;; we have to start from the beginning of line, otherwise skipping
+ ;; past the last few chars of a paragraph-separator would count as
+ ;; a paragraph (and not skipping any chars at EOB would not count
+ ;; as a paragraph even if it is).
+ (move-to-left-margin)
+ (if (not (zerop (forward-paragraph)))
+ ;; There's no paragraph at or after point: give up.
+ (setq fill-pfx "")
+ (let ((end (point))
+ (beg (progn (backward-paragraph) (point))))
+ (goto-char before)
+ (setq fill-pfx
+ (if use-hard-newlines
+ ;; Can't use fill-region-as-paragraph, since this
+ ;; paragraph may still contain hard newlines. See
+ ;; fill-region.
+ (fill-region beg end justify)
+ (fill-region-as-paragraph beg end justify))))))
+ fill-pfx)))
+
+(declare-function comment-search-forward "newcomment" (limit &optional noerror))
+(declare-function comment-string-strip "newcomment" (str beforep afterp))
+
(defun fill-comment-paragraph (&optional justify)
"Fill current comment.
(commark
(comment-string-strip (buffer-substring comstart comin) nil t))
(comment-re
- (if (string-match comment-start-skip (concat commark "a"))
- (concat "[ \t]*" (regexp-quote commark)
- ;; Make sure we only match comments that use
- ;; the exact same comment marker.
- "[^" (substring commark -1) "]")
- ;; If the commark needs to be followed by some special
- ;; set of characters (like @c in TeXinfo), we can't
- ;; rely just on `commark'.
- (concat "[ \t]*\\(?:" comment-start-skip "\\)")))
- (comment-fill-prefix ; Compute a fill prefix.
+ ;; A regexp more specialized than comment-start-skip, that only
+ ;; matches the current commark rather than any valid commark.
+ ;;
+ ;; The specialized regexp only works for "normal" comment
+ ;; syntax, not for Texinfo's "@c" (which can't be immediately
+ ;; followed by word-chars) or Fortran's "C" (which needs to be
+ ;; at bol), so check that comment-start-skip indeed allows the
+ ;; commark to appear in the middle of the line and followed by
+ ;; word chars. The choice of "\0" and "a" is mostly arbitrary.
+ (if (string-match comment-start-skip (concat "\0" commark "a"))
+ (concat "[ \t]*" (regexp-quote commark)
+ ;; Make sure we only match comments that
+ ;; use the exact same comment marker.
+ "[^" (substring commark -1) "]")
+ (concat "[ \t]*\\(?:" comment-start-skip "\\)")))
+ (comment-fill-prefix ; Compute a fill prefix.
(save-excursion
(goto-char comstart)
(if has-code-and-comment
Noninteractively, the third argument JUSTIFY specifies which
kind of justification to do: `full', `left', `right', `center',
-or `none' (equivalent to nil). t means handle each paragraph
-as specified by its text properties.
+or `none' (equivalent to nil). A value of t means handle each
+paragraph as specified by its text properties.
-The fourth arg NOSQUEEZE non-nil means to leave
-whitespace other than line breaks untouched, and fifth arg TO-EOP
-non-nil means to keep filling to the end of the paragraph (or next
-hard newline, if variable `use-hard-newlines' is on).
+The fourth arg NOSQUEEZE non-nil means to leave whitespace other
+than line breaks untouched, and fifth arg TO-EOP non-nil means
+to keep filling to the end of the paragraph (or next hard newline,
+if variable `use-hard-newlines' is on).
Return the fill-prefix used for filling the last paragraph.
When calling from a program, pass the range to fill
as the first two arguments.
-Optional third and fourth arguments JUSTIFY and MAIL-FLAG:
-JUSTIFY to justify paragraphs (prefix arg),
+Optional third and fourth arguments JUSTIFY and CITATION-REGEXP:
+JUSTIFY to justify paragraphs (prefix arg).
When filling a mail message, pass a regexp for CITATION-REGEXP
which will match the prefix of a line which is a citation marker
plus whitespace, but no other kind of prefix.
(fill-region-as-paragraph start (point) justify)
(if (and (bolp) (not had-newline))
(delete-char -1))))))))
+
(defun fill-individual-paragraphs-prefix (citation-regexp)
(let* ((adaptive-fill-first-line-regexp ".*")
(just-one-line-prefix