+(defun fill-comment-paragraph (&optional justify)
+ "Fill current comment.
+If we're not in a comment, just return nil so that the caller
+can take care of filling. JUSTIFY is used as in `fill-paragraph'."
+ (comment-normalize-vars)
+ (let (has-code-and-comment ; Non-nil if it contains code and a comment.
+ comin comstart)
+ ;; Figure out what kind of comment we are looking at.
+ (save-excursion
+ (beginning-of-line)
+ (when (setq comstart (comment-search-forward (line-end-position) t))
+ (setq comin (point))
+ (goto-char comstart) (skip-chars-backward " \t")
+ (setq has-code-and-comment (not (bolp)))))
+
+ (if (not comstart)
+ ;; Return nil, so the normal filling will take place.
+ nil
+
+ ;; Narrow to include only the comment, and then fill the region.
+ (let* ((fill-prefix fill-prefix)
+ (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.
+ (save-excursion
+ (goto-char comstart)
+ (if has-code-and-comment
+ (concat
+ (if (not indent-tabs-mode)
+ (make-string (current-column) ?\s)
+ (concat
+ (make-string (/ (current-column) tab-width) ?\t)
+ (make-string (% (current-column) tab-width) ?\s)))
+ (buffer-substring (point) comin))
+ (buffer-substring (line-beginning-position) comin))))
+ beg end)
+ (save-excursion
+ (save-restriction
+ (beginning-of-line)
+ (narrow-to-region
+ ;; Find the first line we should include in the region to fill.
+ (if has-code-and-comment
+ (line-beginning-position)
+ (save-excursion
+ (while (and (zerop (forward-line -1))
+ (looking-at comment-re)))
+ ;; We may have gone too far. Go forward again.
+ (line-beginning-position
+ (if (progn
+ (goto-char
+ (or (comment-search-forward (line-end-position) t)
+ (point)))
+ (looking-at comment-re))
+ 1 2))))
+ ;; Find the beginning of the first line past the region to fill.
+ (save-excursion
+ (while (progn (forward-line 1)
+ (looking-at comment-re)))
+ (point)))
+ ;; Obey paragraph starters and boundaries within comments.
+ (let* ((paragraph-separate
+ ;; Use the default values since they correspond to
+ ;; the values to use for plain text.
+ (concat paragraph-separate "\\|[ \t]*\\(?:"
+ comment-start-skip "\\)\\(?:"
+ (default-value 'paragraph-separate) "\\)"))
+ (paragraph-start
+ (concat paragraph-start "\\|[ \t]*\\(?:"
+ comment-start-skip "\\)\\(?:"
+ (default-value 'paragraph-start) "\\)"))
+ ;; We used to reply on fill-prefix to break paragraph at
+ ;; comment-starter changes, but it did not work for the
+ ;; first line (mixed comment&code).
+ ;; We now use comment-re instead to "manually" make sure
+ ;; we treat comment-marker changes as paragraph boundaries.
+ ;; (paragraph-ignore-fill-prefix nil)
+ ;; (fill-prefix comment-fill-prefix)
+ (after-line (if has-code-and-comment
+ (line-beginning-position 2))))
+ (setq end (progn (forward-paragraph) (point)))
+ ;; If this comment starts on a line with code,
+ ;; include that line in the filling.
+ (setq beg (progn (backward-paragraph)
+ (if (eq (point) after-line)
+ (forward-line -1))
+ (point)))))
+
+ ;; Find the fill-prefix to use.
+ (cond
+ (fill-prefix) ; Use the user-provided fill prefix.
+ ((and adaptive-fill-mode ; Try adaptive fill mode.
+ (setq fill-prefix (fill-context-prefix beg end))
+ (string-match comment-start-skip fill-prefix)))
+ (t
+ (setq fill-prefix comment-fill-prefix)))
+
+ ;; Don't fill with narrowing.
+ (or
+ (fill-region-as-paragraph
+ beg end justify nil
+ ;; Don't canonicalize spaces within the code just before
+ ;; the comment.
+ (save-excursion
+ (goto-char beg)
+ (if (looking-at fill-prefix)
+ nil
+ (re-search-forward comment-start-skip))))
+ ;; Make sure we don't return nil.
+ t))))))
+