"*Non-nil means put two spaces after a colon when filling.")
(defvar fill-paragraph-function nil
- "Mode-specific function to fill a paragraph.")
+ "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.")
(defun set-fill-prefix ()
"Set the fill prefix to the current line up to point.
(re-search-forward "[.?!][])}\"']*$" end t))
(insert-and-inherit ? ))))
-(defun fill-context-prefix (from to)
+(defun fill-context-prefix (from to &optional first-line-regexp)
"Compute a fill prefix from the text between FROM and TO.
-This uses the variables `adapive-fill-prefix' and `adaptive-fill-function'."
+This uses the variables `adaptive-fill-prefix' and `adaptive-fill-function'.
+If FIRST-LINE-REGEXP is non-nil, then when taking a prefix from the
+first line, insist it must match FIRST-LINE-REGEXP."
(save-excursion
(goto-char from)
(if (eolp) (forward-line 1))
;; Move to the second line unless there is just one.
- (let ((firstline (point)))
+ (let ((firstline (point))
+ ;; Non-nil if we are on the second line.
+ at-second
+ result)
(forward-line 1)
(if (>= (point) to)
- (goto-char firstline)))
- (move-to-left-margin)
- (let ((start (point))
- (eol (save-excursion (end-of-line) (point))))
- (if (not (looking-at paragraph-start))
- (cond ((looking-at adaptive-fill-regexp)
- (buffer-substring-no-properties start (match-end 0)))
- (t (funcall adaptive-fill-function)))))))
+ (goto-char firstline)
+ (setq at-second t))
+ (move-to-left-margin)
+ (let ((start (point))
+ (eol (save-excursion (end-of-line) (point))))
+ (setq result
+ (if (not (looking-at paragraph-start))
+ (cond ((and adaptive-fill-regexp (looking-at adaptive-fill-regexp))
+ (buffer-substring-no-properties start (match-end 0)))
+ (adaptive-fill-function (funcall adaptive-fill-function)))))
+ (and result
+ (or at-second
+ (null first-line-regexp)
+ (string-match first-line-regexp result))
+ result)))))
(defun fill-region-as-paragraph (from to &optional justify nosqueeze)
"Fill the region as one paragraph.
-Removes any paragraph breaks in the region and extra newlines at the end,
+It removes any paragraph breaks in the region and extra newlines at the end,
indents and fills lines between the margins given by the
`current-left-margin' and `current-fill-column' functions.
+It leaves point at the beginning of the line following the paragraph.
Normally performs justification according to the `current-justification'
function, but with a prefix arg, does full justification instead.
(if (and buffer-undo-list (not (eq buffer-undo-list t)))
(setq buffer-undo-list (cons (point) buffer-undo-list)))
- ;; Make sure "to" is the endpoint. Make sure that we end up there.
+ ;; Make sure "to" is the endpoint.
(goto-char (min from to))
(setq to (max from to))
- (setq from (point))
+ ;; Ignore blank lines at beginning of region.
+ (skip-chars-forward " \t\n")
- ;; Delete all but one soft newline at end of region.
- (goto-char to)
- (let ((oneleft nil))
+ (let ((from-plus-indent (point))
+ (oneleft nil))
+
+ (beginning-of-line)
+ (setq from (point))
+
+ ;; Delete all but one soft newline at end of region.
+ (goto-char to)
(while (and (> (point) from) (eq ?\n (char-after (1- (point)))))
(if (and oneleft
(not (and use-hard-newlines
(delete-backward-char 1)
(backward-char 1)
(setq oneleft t)))
- ;; If there was no newline, create one.
- (if (and (not oneleft) (> (point) from))
- (save-excursion (newline))))
- (setq to (point))
+ (setq to (point))
- ;; Ignore blank lines at beginning of region.
- (goto-char from)
- (skip-chars-forward " \t\n")
- (beginning-of-line)
- (setq from (point))
-
- (if (>= from to)
- nil ; There is no paragraph at all.
+ ;; If there was no newline, and there is text in the paragraph, then
+ ;; create a newline.
+ (if (and (not oneleft) (> to from-plus-indent))
+ (newline))
+ (goto-char from-plus-indent))
+
+ (if (not (> to (point)))
+ nil ; There is no paragraph, only whitespace: exit now.
(or justify (setq justify (current-justification)))
(eq (char-after (- (point) 2)) ?\.))
(forward-char -2)
(skip-chars-backward "^ \n" linebeg)))
+ ;; If the left margin and fill prefix by themselves
+ ;; pass the fill-column, keep at least one word.
+ ;; This handles ALL BUT the first line of the paragraph.
(if (if (zerop prefixcol)
(save-excursion
- (skip-chars-backward " " linebeg)
+ (skip-chars-backward " \t" linebeg)
(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.
+ ;; Ok, skip at least one word.
;; Meanwhile, don't stop at a period followed by one space.
(let ((first t))
(move-to-column prefixcol)
(save-excursion (forward-char -1)
(and (looking-at "\\. ")
(not (looking-at "\\. ")))))))
- (skip-chars-forward " ")
- (skip-chars-forward "^ \n")
+ (skip-chars-forward " \t")
+ (skip-chars-forward "^ \n\t")
(setq first nil)))
;; Normally, move back over the single space between the words.
(forward-char -1))
- (if (and fill-prefix (zerop prefixcol)
- (< (- (point) (point-min)) (length fill-prefix))
- (string= (buffer-substring (point-min) (point))
- (substring fill-prefix 0 (- (point) (point-min)))))
- ;; Keep at least one word even if fill prefix exceeds margin.
- ;; This handles the first line of the paragraph.
- ;; Don't stop at a period followed by just one space.
+ ;; 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
(save-excursion (forward-char -1)
(and (looking-at "\\. ")
(not (looking-at "\\. ")))))))
- (skip-chars-forward " ")
- (skip-chars-forward "^ \n")
+ (skip-chars-forward " \t")
+ (skip-chars-forward "^ \t\n")
(setq first nil))))
;; Replace whitespace here with one newline, then indent to left
;; margin.
- (skip-chars-backward " ")
+ (skip-chars-backward " \t")
(insert ?\n)
;; Give newline the properties of the space(s) it replaces
(set-text-properties (1- (point)) (point)
(defun unjustify-current-line ()
"Remove justification whitespace from current line.
If the line is centered or right-justified, this function removes any
-indentation past the left margin. If the line is full-jusitified, it removes
+indentation past the left margin. If the line is full-justified, it removes
extra spaces between words. It does nothing in other justification modes."
(let ((justify (current-justification)))
(cond ((eq 'left justify) nil)
(defun unjustify-region (&optional begin end)
"Remove justification whitespace from region.
For centered or right-justified regions, this function removes any indentation
-past the left margin from each line. For full-jusitified lines, it removes
+past the left margin from each line. For full-justified lines, it removes
extra spaces between words. It does nothing in other justification modes.
Arguments BEGIN and END are optional; default is the whole buffer."
(save-excursion