Function: idlwave-fill-paragraph

idlwave-fill-paragraph is an interactive and byte-compiled function defined in idlwave.el.gz.

Signature

(idlwave-fill-paragraph &optional NOHANG)

Documentation

Fill paragraphs in comments.

A paragraph is made up of all contiguous lines having the same comment leader (the leading whitespace before the comment delimiter and the comment delimiter). In addition, paragraphs are separated by blank line comments. The indentation is given by the hanging indent of the first line, otherwise by the minimum indentation of the lines after the first line. The indentation of the first line does not change. Does not effect code lines. Does not fill comments on the same line with code. The hanging indent is given by the end of the first match matching idlwave-hang-indent-regexp on the paragraph's first line. If the optional argument NOHANG is non-nil then the hanging indent is ignored.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/obsolete/idlwave.el.gz
(defun idlwave-fill-paragraph (&optional nohang)
  "Fill paragraphs in comments.
A paragraph is made up of all contiguous lines having the same comment
leader (the leading whitespace before the comment delimiter and the
comment delimiter).  In addition, paragraphs are separated by blank
line comments.  The indentation is given by the hanging indent of the
first line, otherwise by the minimum indentation of the lines after
the first line.  The indentation of the first line does not change.
Does not effect code lines.  Does not fill comments on the same line
with code.  The hanging indent is given by the end of the first match
matching `idlwave-hang-indent-regexp' on the paragraph's first line.
If the optional argument NOHANG is non-nil then the hanging indent is
ignored."
  (interactive "P")
  ;; check if this is a line comment
  (if (save-excursion
        (beginning-of-line)
        (skip-chars-forward " \t")
        (looking-at comment-start))
      (let
          ((indent 999)
           pre here diff fill-prefix-reg bcl first-indent
           hang start end)
        ;; Change tabs to spaces in the surrounding paragraph.
        ;; The surrounding paragraph will be the largest containing block of
        ;; contiguous line comments. Thus, we may be changing tabs in
        ;; a much larger area than is needed, but this is the easiest
        ;; brute force way to do it.
        ;;
        ;; This has the undesirable side effect of replacing the tabs
        ;; permanently without the user's request or knowledge.
        (save-excursion
          (backward-paragraph)
          (setq start (point)))
        (save-excursion
          (forward-paragraph)
          (setq end (point)))
        (untabify start end)
        ;;
        (setq here (point))
        (beginning-of-line)
        (setq bcl (point))
        (re-search-forward (concat "^[ \t]*" comment-start "+")
                           (line-end-position) t)
        ;; Get the comment leader on the line and its length
        (setq pre (current-column))
        ;; the comment leader is the indentation plus exactly the
        ;; number of consecutive ";".
        (setq fill-prefix-reg
              (concat
               (setq fill-prefix
                     (regexp-quote (buffer-substring (line-beginning-position)
                                                     (point))))
               "[^;]"))

        ;; Mark the beginning and end of the paragraph
        (goto-char bcl)
        (while (and (looking-at fill-prefix-reg)
                    (not (looking-at paragraph-separate))
                    (not (bobp)))
          (forward-line -1))
        ;; Move to first line of paragraph
        (if (/= (point) bcl)
            (forward-line 1))
        (setq start (point))
        (goto-char bcl)
        (while (and (looking-at fill-prefix-reg)
                    (not (looking-at paragraph-separate))
                    (not (eobp)))
          (forward-line 1))
        (beginning-of-line)
        (if (or (not (looking-at fill-prefix-reg))
                (looking-at paragraph-separate))
            (forward-line -1))
        (end-of-line)
        ;; if at end of buffer add a newline (need this because
        ;; fill-region needs END to be at the beginning of line after
        ;; the paragraph or it will add a line).
        (if (eobp)
            (progn (insert ?\n) (backward-char 1)))
        ;; Set END to the beginning of line after the paragraph
        ;; END is calculated as distance from end of buffer
        (setq end (- (point-max) (point) 1))
        ;;
        ;; Calculate the indentation for the paragraph.
        ;;
        ;; In the following while statements, after one iteration
        ;; point will be at the beginning of a line in which case
        ;; the while will not be executed for the
        ;; first paragraph line and thus will not affect the
        ;; indentation.
        ;;
        ;; First check to see if indentation is based on hanging indent.
        (if (and (not nohang) idlwave-hanging-indent
                 (setq hang
                       (save-excursion
                         (goto-char start)
                         (idlwave-calc-hanging-indent))))
            ;; Adjust lines of paragraph by inserting spaces so that
            ;; each line's indent is at least as great as the hanging
            ;; indent. This is needed for fill-paragraph to work with
            ;; a fill-prefix.
            (progn
              (setq indent hang)
              (beginning-of-line)
              (while (> (point) start)
                (re-search-forward comment-start-skip (line-end-position) t)
                (if (> (setq diff (- indent (current-column))) 0)
                    (progn
                      (if (>= here (point))
                          ;; adjust the original location for the
                          ;; inserted text.
                          (setq here (+ here diff)))
                      (insert (make-string diff ?\ ))))
                (forward-line -1))
              )

          ;; No hang. Instead find minimum indentation of paragraph
          ;; after first line.
          ;; For the following while statement, since START is at the
          ;; beginning of line and END is at the end of line
          ;; point is greater than START at least once (which would
          ;; be the case for a single line paragraph).
          (while (> (point) start)
            (beginning-of-line)
            (setq indent
                  (min indent
                       (progn
                         (re-search-forward comment-start-skip (line-end-position) t)
                         (current-column))))
            (forward-line -1)))
        (setq fill-prefix (concat fill-prefix
                                  (make-string (- indent pre)
                                               ?\ )))
        ;; first-line indent
        (setq first-indent
              (max
               (progn
                 (re-search-forward comment-start-skip (line-end-position) t)
                 (current-column))
               indent))

        ;; try to keep point at its original place
        (goto-char here)

        ;; In place of the more modern fill-region-as-paragraph, a hack
        ;; to keep whitespace untouched on the first line within the
        ;; indent length and to preserve any indent on the first line
        ;; (first indent).
        (save-excursion
          (setq diff
                (buffer-substring start (+ start first-indent -1)))
          (subst-char-in-region start (+ start first-indent -1) ?\  ?~ nil)
          (fill-region-as-paragraph
           start
           (- (point-max) end)
           (current-justification)
           nil)
          (delete-region start (+ start first-indent -1))
          (goto-char start)
          (insert diff))
        ;; When we want the point at the beginning of the comment
        ;; body fill-region will put it at the beginning of the line.
        (if (bolp) (skip-chars-forward (concat " \t" comment-start)))
        (setq fill-prefix nil))))