+(defun fortran-fill-paragraph (&optional justify)
+ "Fill surrounding comment block as paragraphs, else fill statement.
+
+Intended as the value of `fill-paragraph-function'."
+ (interactive "P")
+ (save-excursion
+ (beginning-of-line)
+ (if (not (looking-at "[Cc*]"))
+ (fortran-fill-statement)
+ ;; We're in a comment block. Find the start and end of a
+ ;; paragraph, delimited either by non-comment lines or empty
+ ;; comments. (Get positions as markers, since the
+ ;; `indent-region' below can shift the block's end).
+ (let* ((non-empty-comment (concat "\\(" comment-line-start-skip
+ "\\)" "[^ \t\n]"))
+ (start (save-excursion
+ ;; Find (start of) first line.
+ (while (and (zerop (forward-line -1))
+ (looking-at non-empty-comment)))
+ (or (looking-at non-empty-comment)
+ (forward-line)) ; overshot
+ (point-marker)))
+ (end (save-excursion
+ ;; Find start of first line past region to fill.
+ (while (progn (forward-line)
+ (looking-at non-empty-comment)))
+ (point-marker))))
+ ;; Indent the block, find the string comprising the effective
+ ;; comment start skip and use that as a fill-prefix for
+ ;; filling the region.
+ (indent-region start end nil)
+ (let ((paragraph-ignore-fill-prefix nil)
+ (fill-prefix (progn (beginning-of-line)
+ (looking-at comment-line-start-skip)
+ (match-string 0))))
+ (let (fill-paragraph-function)
+ (fill-region start end justify))) ; with normal `fill-paragraph'
+ (set-marker start nil)
+ (set-marker end nil))))
+ t)
+
+(defun fortran-fill-statement ()
+ "Fill a fortran statement up to `fill-column'."
+ (interactive)
+ (let ((auto-fill-function #'fortran-do-auto-fill))
+ (if (not (save-excursion
+ (beginning-of-line)
+ (or (looking-at "[ \t]*$")
+ (looking-at comment-line-start-skip)
+ (and comment-start-skip
+ (looking-at (concat "[ \t]*" comment-start-skip))))))
+ (save-excursion
+ ;; Find beginning of statement.
+ (fortran-next-statement)
+ (fortran-previous-statement)
+ ;; Re-indent initially.
+ (fortran-indent-line)
+ ;; Replace newline plus continuation field plus indentation with
+ ;; single space.
+ (while (progn
+ (forward-line)
+ (fortran-remove-continuation)))
+ (fortran-previous-statement)))
+ (fortran-indent-line)))
+