(defvar refill-ignorable-overlay nil
"Portion of the most recently filled paragraph not needing filling.
This is used to optimize refilling.")
(make-variable-buffer-local 'refill-ignorable-overlay)
(defun refill-adjust-ignorable-overlay (overlay afterp beg end &optional len)
"Adjust OVERLAY to not include the about-to-be-modified region."
(when (not afterp)
(save-excursion
(goto-char beg)
(forward-line -1)
(if (<= (point) (overlay-start overlay))
(move-overlay overlay 1 1)
(move-overlay overlay (overlay-start overlay) (point))))))
(defun refill-fill-paragraph-at (pos &optional arg)
"Like `fill-paragraph' at POS, but don't delete whitespace at paragraph end."
(let (fill-pfx)
(save-excursion
(goto-char pos)
(forward-paragraph)
(skip-syntax-backward "-")
(let ((end (point))
(beg (progn (backward-paragraph) (point)))
(obeg (overlay-start refill-ignorable-overlay))
(oend (overlay-end refill-ignorable-overlay)))
(goto-char pos)
(if (and (>= beg obeg) (< beg oend))
(let ( (fill-prefix
(if (and adaptive-fill-mode
(or (null fill-prefix) (string= fill-prefix "")))
(fill-context-prefix beg end)
fill-prefix))
(adaptive-fill-mode nil))
(save-restriction
(if use-hard-newlines
(fill-region oend end arg)
(fill-region-as-paragraph oend end arg)))
(setq fill-pfx fill-prefix)
(move-overlay refill-ignorable-overlay obeg (point)))
(setq fill-pfx
(save-restriction
(if use-hard-newlines
(fill-region beg end arg)
(fill-region-as-paragraph beg end arg))))
(move-overlay refill-ignorable-overlay beg (point)))))
(skip-line-prefix fill-pfx)))
(defun refill-fill-paragraph (arg)
"Like `fill-paragraph' but don't delete whitespace at paragraph end."
(refill-fill-paragraph-at (point) arg))
(defvar refill-doit nil
"Non-nil means that `refill-post-command-function' does its processing.
Set by `refill-after-change-function' in `after-change-functions' and
unset by `refill-post-command-function' in `post-command-hook', and
sometimes `refill-pre-command-function' in `pre-command-hook'. This
ensures refilling is only done once per command that causes a change,
regardless of the number of after-change calls from commands doing
complex processing.")
(make-variable-buffer-local 'refill-doit)
(defun refill-after-change-function (beg end len)
"Function for `after-change-functions' which just sets `refill-doit'."
(unless undo-in-progress
(setq refill-doit end)))
(defun refill-post-command-function ()
"Post-command function to do refilling (conditionally)."
(when refill-doit (if (eq this-command 'self-insert-command)
(when (aref auto-fill-chars (char-before))
(refill-fill-paragraph-at refill-doit)
(setq refill-doit nil))
(cond
((or (eq this-command 'quoted-insert)
(eq this-command 'fill-paragraph)
(eq this-command 'fill-region))
nil)
((or (eq this-command 'newline)
(eq this-command 'newline-and-indent)
(eq this-command 'open-line))
(save-excursion
(beginning-of-line) (skip-chars-backward "\n")
(save-restriction
(narrow-to-region (point-min) (point))
(refill-fill-paragraph-at refill-doit)))
(widen)
(save-excursion
(skip-chars-forward "\n")
(save-restriction
(narrow-to-region (line-beginning-position) (point-max))
(refill-fill-paragraph-at refill-doit))))
(t
(refill-fill-paragraph-at refill-doit)))
(setq refill-doit nil))))
(defun refill-pre-command-function ()
"Pre-command function to do refilling (conditionally)."
(when (and refill-doit (not (eq this-command 'self-insert-command)))
(refill-fill-paragraph-at refill-doit)
(setq refill-doit nil)))
(defvar refill-late-fill-paragraph-function nil)
(define-minor-mode refill-mode
"Toggle Refill minor mode.
With prefix arg, turn Refill mode on iff arg is positive.
When Refill mode is on, the current paragraph will be formatted when
changes are made within it. Self-inserting characters only cause
refilling if they would cause auto-filling."
nil " Refill" nil
(make-local-variable 'fill-paragraph-function)
(if refill-mode
(progn
(add-hook 'after-change-functions 'refill-after-change-function nil t)
(add-hook 'post-command-hook 'refill-post-command-function nil t)
(add-hook 'pre-command-hook 'refill-pre-command-function nil t)
(set (make-local-variable 'refill-late-fill-paragraph-function)
fill-paragraph-function)
(set (make-local-variable 'fill-paragraph-function)
'refill-fill-paragraph)
(setq refill-ignorable-overlay (make-overlay 1 1 nil nil t))
(overlay-put refill-ignorable-overlay 'modification-hooks
'(refill-adjust-ignorable-overlay))
(overlay-put refill-ignorable-overlay 'insert-behind-hooks
'(refill-adjust-ignorable-overlay))
(auto-fill-mode 0))
(remove-hook 'after-change-functions 'refill-after-change-function t)
(remove-hook 'post-command-hook 'refill-post-command-function t)
(delete-overlay refill-ignorable-overlay)
(setq fill-paragraph-function refill-late-fill-paragraph-function)))
(provide 'refill)