]> git.eshelyaron.com Git - emacs.git/commitdiff
(fill-paragraph-handle-comment): New var.
authorStefan Monnier <monnier@iro.umontreal.ca>
Sun, 3 Nov 2002 03:41:11 +0000 (03:41 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sun, 3 Nov 2002 03:41:11 +0000 (03:41 +0000)
(fill-comment-paragraph): New fun (generalizes of lisp-fill-paragraph).
(fill-paragraph): Use them.

lisp/textmodes/fill.el

index 44f01898c3c3516d28988c1d97c65de4f462ddc4..a14ce886de560dad439b5852649a6e6d5023978e 100644 (file)
@@ -48,6 +48,9 @@ A value of nil means that any change in indentation starts a new 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.")
 
+(defvar fill-paragraph-handle-comment t
+  "If non-nil, paragraph filling will try to pay attention to comments.")
+
 (defvar enable-kinsoku t
   "*Non-nil means enable \"kinsoku\" processing on filling paragraph.
 Kinsoku processing is designed to prevent certain characters from being
@@ -689,10 +692,23 @@ If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling."
   (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full))))
+  ;; First try fill-paragraph-function.
   (or (and fill-paragraph-function
           (let ((function fill-paragraph-function)
+                ;; If fill-paragraph-function is set, it probably takes care
+                ;; of comments and stuff.  If not, it will have to set
+                ;; fill-paragraph-handle-comment back to t explicitly or
+                ;; return nil.
+                (fill-paragraph-handle-comment nil)
                 fill-paragraph-function)
             (funcall function arg)))
+      ;; Then try our syntax-aware filling code.
+      (and fill-paragraph-handle-comment
+          ;; Our code only handle \n-terminated comments right now.
+          comment-start comment-start-skip (equal comment-end "")
+          (let ((fill-paragraph-handle-comment nil))
+            (fill-comment-paragraph arg)))
+      ;; If it all fails, default to the good ol' text paragraph filling.
       (let ((before (point))
            ;; Fill prefix used for filling the paragraph.
            fill-pfx)
@@ -722,6 +738,90 @@ If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling."
        (skip-line-prefix fill-pfx)
        fill-pfx)))
 
+(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."
+  (let ((comment-re (concat "[ \t]*" comment-start-skip))
+       has-comment        ; Non-nil if the current line contains a comment.
+       has-code-and-comment    ; Non-nil if it contains code and a comment.
+       comment-fill-prefix)   ; If has-comment, the appropriate fill-prefix.
+
+    ;; Figure out what kind of comment we are looking at.
+    (save-excursion
+      (beginning-of-line)
+      (cond
+
+       ;; A line with nothing but a comment on it?
+       ((looking-at comment-re)
+       (setq has-comment t
+             comment-fill-prefix (match-string 0)))
+
+       ;; A line with some code, followed by a comment?  Remember that the
+       ;; semi which starts the comment shouldn't be part of a string or
+       ;; character.
+       ((let ((state (syntax-ppss (line-end-position))))
+         (when (nth 4 state)
+           (goto-char (nth 8 state))
+           (save-restriction
+             ;; comment-start-skip sometimes tries to count \ quoting from ^.
+             (narrow-to-region (point) (point-max))
+             (looking-at comment-start-skip))))
+       (setq has-comment t has-code-and-comment t)
+       (setq comment-fill-prefix
+             (concat (make-string (/ (current-column) tab-width) ?\t)
+                     (make-string (% (current-column) tab-width) ?\ )
+                     (match-string 0))))))
+
+    (if (not has-comment)
+       ;; Return nil, so the normal filling will take place.
+       nil
+
+      ;; Narrow to include only the comment, and then fill the region.
+      (save-excursion
+       (save-restriction
+         (beginning-of-line)
+         (narrow-to-region
+          ;; Find the first line we should include in the region to fill.
+          (save-excursion
+            (while (and (zerop (forward-line -1))
+                        (looking-at comment-re)))
+            ;; We may have gone too far.  Go forward again.
+            (or (looking-at (concat ".*" comment-start-skip))
+                (forward-line 1))
+            (point))
+          ;; Find the beginning of the first line past the region to fill.
+          (save-excursion
+            (while (progn (forward-line 1)
+                          (looking-at comment-re)))
+            (point)))
+
+         ;; Lines with only semicolons on them can be paragraph boundaries.
+         (let* ((paragraph-separate
+                 (concat paragraph-start "\\|" comment-re "$"))
+                (paragraph-ignore-fill-prefix nil)
+                (fill-prefix comment-fill-prefix)
+                (after-line (if has-code-and-comment
+                                (line-beginning-position 2)))
+                (end (progn
+                       (forward-paragraph)
+                       (or (bolp) (newline 1))
+                       (point)))
+                ;; If this comment starts on a line with code,
+                ;; include that like in the filling.
+                (beg (progn (backward-paragraph)
+                            (if (eq (point) after-line)
+                                (forward-line -1))
+                            (point))))
+           (fill-region-as-paragraph beg end
+                                     justify nil
+                                     (save-excursion
+                                       (goto-char beg)
+                                       (if (looking-at fill-prefix)
+                                           nil
+                                         (re-search-forward comment-start-skip))))
+           t))))))
+
 (defun fill-region (from to &optional justify nosqueeze to-eop)
   "Fill each of the paragraphs in the region.
 A prefix arg means justify as well.