/[emacs]/emacs/lisp/textmodes/fill.el
ViewVC logotype

Diff of /emacs/lisp/textmodes/fill.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.139 by monnier, Wed Apr 10 18:19:44 2002 UTC revision 1.140 by monnier, Wed Apr 10 21:21:12 2002 UTC
# Line 1  Line 1 
1  ;;; fill.el --- fill commands for Emacs  ;;; fill.el --- fill commands for Emacs
2    
3  ;; Copyright (C) 1985, 86, 92, 94, 95, 96, 97, 1999 Free Software Foundation, Inc.  ;; Copyright (C) 1985,86,92,94,95,96,97,1999,2001,2002
4    ;;               Free Software Foundation, Inc.
5    
6  ;; Maintainer: FSF  ;; Maintainer: FSF
7  ;; Keywords: wp  ;; Keywords: wp
# Line 75  reinserts the fill prefix in each result Line 76  reinserts the fill prefix in each result
76    :group 'fill)    :group 'fill)
77    
78  (defcustom adaptive-fill-regexp  (defcustom adaptive-fill-regexp
79    (purecopy "[ \t]*\\([-|#;>*]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*")    ;; Added `!' for doxygen comments starting with `//!' or `/*!'.
80      ;; Added `%' for TeX comments.
81      (purecopy "[ \t]*\\([-!|#%;>*]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*")
82    "*Regexp to match text at start of line that constitutes indentation.    "*Regexp to match text at start of line that constitutes indentation.
83  If Adaptive Fill mode is enabled, a prefix matching this pattern  If Adaptive Fill mode is enabled, a prefix matching this pattern
84  on the first and second lines of a paragraph is used as the  on the first and second lines of a paragraph is used as the
# Line 234  act as a paragraph-separator." Line 237  act as a paragraph-separator."
237              (unless first-line-prefix (setq first-line-prefix ""))              (unless first-line-prefix (setq first-line-prefix ""))
238    
239              (if ;; If the non-whitespace chars match the first line,              (if ;; If the non-whitespace chars match the first line,
240                  ;; just use it (this subsumes the 2 previous checks).                  ;; just use it (this subsumes the 2 checks used previously).
241                  ;; Used when first line is `/* ...' and second-line is                  ;; Used when first line is `/* ...' and second-line is
242                  ;; ` * ...'.                  ;; ` * ...'.
243                  (string-match                  (string-match
# Line 317  Can be customized with the variable `fil Line 320  Can be customized with the variable `fil
320       ;; The reason is that if a period ends up at the end of a       ;; The reason is that if a period ends up at the end of a
321       ;; line, further fills will assume it ends a sentence.       ;; line, further fills will assume it ends a sentence.
322       ;; If we now know it does not end a sentence, avoid putting       ;; If we now know it does not end a sentence, avoid putting
323       ;; it at the end of the line.       ;; it at the end of the line.
324       (and sentence-end-double-space       (and sentence-end-double-space
325            (save-excursion            (save-excursion
326              (skip-chars-backward ". ")              (skip-chars-backward ". ")
# Line 368  If the charset has no such property, do Line 371  If the charset has no such property, do
371    "Delete the fill prefix from every line except the first.    "Delete the fill prefix from every line except the first.
372  The first line may not even have a fill prefix.  The first line may not even have a fill prefix.
373  Point is moved to just past the fill prefix on the first line."  Point is moved to just past the fill prefix on the first line."
374    (goto-char from)    (let ((fpre (if (and prefix (not (string-match "\\`[ \t]*\\'" prefix)))
375    (let ((fpre (and prefix (not (equal prefix ""))                    (concat "[ \t]*\\("
376                     (concat "[ \t]*"                            (replace-regexp-in-string
377                             (replace-regexp-in-string                             "[ \t]+" "[ \t]*"
378                              "[ \t]+" "[ \t]*"                             (regexp-quote prefix))
379                              (regexp-quote prefix))                            "\\)?[ \t]*")
380                             "[ \t]*"))))                  "[ \t]*")))
381      (when fpre      (goto-char from)
382        (if (>= (+ (current-left-margin) (length prefix))      (if (>= (+ (current-left-margin) (length prefix))
383                (current-fill-column))              (current-fill-column))
384            (error "fill-prefix too long for specified width"))          (error "fill-prefix too long for specified width"))
385        (forward-line 1)      (forward-line 1)
386        (while (< (point) to)      (while (< (point) to)
         (if (looking-at fpre)  
             (delete-region (point) (match-end 0)))  
         (forward-line 1))  
       (goto-char from)  
387        (if (looking-at fpre)        (if (looking-at fpre)
388            (goto-char (match-end 0)))            (delete-region (point) (match-end 0)))
389        (setq from (point))))        (forward-line 1))
390    ;; Remove indentation from lines other than the first.      (goto-char from)
391    (beginning-of-line 2)      (if (looking-at fpre)
392    (indent-region (point) to 0)          (goto-char (match-end 0)))
393    (goto-char from))      (setq from (point))))
394    
395  (defun fill-delete-newlines (from to justify nosqueeze squeeze-after)  (defun fill-delete-newlines (from to justify nosqueeze squeeze-after)
396    (goto-char from)    (goto-char from)
397    ;; Make sure sentences ending at end of line get an extra space.    ;; Make sure sentences ending at end of line get an extra space.
398    ;; loses on split abbrevs ("Mr.\nSmith")    ;; loses on split abbrevs ("Mr.\nSmith")
399    (let ((eol-double-space-re (if colon-double-space    (let ((eol-double-space-re
400                                   "[.?!:][])}\"']*$"           (cond
401                                 "[.?!][])}\"']*$")))            ((not colon-double-space) (concat sentence-end "$"))
402              ;; Try to add the : inside the `sentence-end' regexp.
403              ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end)
404               (concat (replace-match ".:" nil nil sentence-end 1) "$"))
405              ;; Can't find the right spot to insert the colon.
406              (t "[.?!:][])}\"']*$"))))
407      (while (re-search-forward eol-double-space-re to t)      (while (re-search-forward eol-double-space-re to t)
408        (or (>= (point) to) (insert-and-inherit ?\ ))))        (or (>= (point) to) (memq (char-before) '(?\t ?\ ))
409              (insert-and-inherit ?\ ))))
410    
411    (goto-char from)    (goto-char from)
412    (if enable-multibyte-characters    (if enable-multibyte-characters
# Line 437  Point is moved to just past the fill pre Line 442  Point is moved to just past the fill pre
442      (insert-and-inherit " "))      (insert-and-inherit " "))
443    (goto-char from))    (goto-char from))
444    
445    (defun fill-move-to-break-point (linebeg)
446      "Move to the position where the line should be broken.
447    The break position will normally be after LINEBEG and before point."
448      ;; If the fill column is before linebeg, we have an insanely
449      ;; wide prefix and might as well ignore it.
450      (if (> linebeg (point)) (setq linebeg (line-beginning-position)))
451      ;; Move back to the point where we can break the line
452      ;; at.  We break the line between word or after/before
453      ;; the character which has character category `|'.  We
454      ;; search space, \c| followed by a character, or \c|
455      ;; following a character.  If not found, place
456      ;; the point at linebeg.
457      (while
458          (when (re-search-backward "[ \t]\\|\\c|.\\|.\\c|" linebeg 0)
459            ;; In case of space, we place the point at next to
460            ;; the point where the break occurs actually,
461            ;; because we don't want to change the following
462            ;; logic of original Emacs.  In case of \c|, the
463            ;; point is at the place where the break occurs.
464            (forward-char 1)
465            (when (fill-nobreak-p) (skip-chars-backward " \t" linebeg))))
466      ;; If the left margin and fill prefix by themselves
467      ;; pass the fill-column. or if they are zero
468      ;; but we have no room for even one word,
469      ;; keep at least one word or a character which has
470      ;; category `|' anyway.
471      (if (>= linebeg (point))
472          ;; Ok, skip at least one word or one \c| character.
473          ;; Meanwhile, don't stop at a period followed by one space.
474          (let ((to (line-end-position))
475                (fill-nobreak-predicate nil) ;to break sooner.
476                (first t))
477            (goto-char linebeg)
478            (while (and (< (point) to) (or first (fill-nobreak-p)))
479              ;; Find a breakable point while ignoring the
480              ;; following spaces.
481              (skip-chars-forward " \t")
482              (if (looking-at "\\c|")
483                  (forward-char 1)
484                (let ((pos (save-excursion
485                             (skip-chars-forward "^ \n\t")
486                             (point))))
487                  (if (re-search-forward "\\c|" pos t)
488                      (forward-char -1)
489                    (goto-char pos))))
490              (setq first nil)))
491        ;; Normally, move back over the single space between
492        ;; the words.
493        (skip-chars-backward " \t")
494    
495        (if enable-multibyte-characters
496            ;; If we are going to break the line after or
497            ;; before a non-ascii character, we may have to
498            ;; run a special function for the charset of the
499            ;; character to find the correct break point.
500            (if (not (and (eq (charset-after (1- (point))) 'ascii)
501                          (eq (charset-after (point)) 'ascii)))
502                ;; Make sure we take SOMETHING after the fill prefix if any.
503                (fill-find-break-point linebeg)))))
504    
505    (defun fill-newline ()
506      ;; Replace whitespace here with one newline, then
507      ;; indent to left margin.
508      (skip-chars-backward " \t")
509      (if (and (= (following-char) ?\ )
510               (or (aref (char-category-set (preceding-char)) ?|)
511                   (looking-at "[ \t]+\\c|")))
512          ;; We need one space at end of line so that
513          ;; further filling won't delete it.  NOTE: We
514          ;; intentionally leave this one space to
515          ;; distingush the case that user wants to put
516          ;; space between \c| characters.
517          (forward-char 1))
518      (insert ?\n)
519      ;; Give newline the properties of the space(s) it replaces
520      (set-text-properties (1- (point)) (point)
521                           (text-properties-at (point)))
522      (if (or fill-prefix
523              (not fill-indent-according-to-mode))
524          (indent-to-left-margin)
525        (indent-according-to-mode))
526      ;; Insert the fill prefix after indentation.
527      ;; Set prefixcol so whitespace in the prefix won't get lost.
528      (and fill-prefix (not (equal fill-prefix ""))
529           (insert-and-inherit fill-prefix)))
530    
531  (defun fill-region-as-paragraph (from to &optional justify  (defun fill-region-as-paragraph (from to &optional justify
532                                        nosqueeze squeeze-after)                                        nosqueeze squeeze-after)
533    "Fill the region as one paragraph.    "Fill the region as one paragraph.
# Line 498  space does not end a sentence, so don't Line 589  space does not end a sentence, so don't
589      (goto-char from-plus-indent))      (goto-char from-plus-indent))
590    
591    (if (not (> to (point)))    (if (not (> to (point)))
592        nil ; There is no paragraph, only whitespace: exit now.        nil ;; There is no paragraph, only whitespace: exit now.
593    
594      (or justify (setq justify (current-justification)))      (or justify (setq justify (current-justification)))
595    
     ;; Never indent-according-to-mode with brain dead "indenting" functions.  
     (when (and fill-indent-according-to-mode  
                (memq indent-line-function  
                    '(indent-relative-maybe indent-relative  
                        indent-to-left-margin)))  
       (set (make-local-variable 'fill-indent-according-to-mode) nil))  
   
596      ;; Don't let Adaptive Fill mode alter the fill prefix permanently.      ;; Don't let Adaptive Fill mode alter the fill prefix permanently.
597      (let ((fill-prefix fill-prefix))      (let ((fill-prefix fill-prefix))
598        ;; Figure out how this paragraph is indented, if desired.        ;; Figure out how this paragraph is indented, if desired.
# Line 526  space does not end a sentence, so don't Line 610  space does not end a sentence, so don't
610          (beginning-of-line)          (beginning-of-line)
611          (narrow-to-region (point) to)          (narrow-to-region (point) to)
612    
613          (if (not justify)           ; filling disabled: just check indentation          (if (not justify)         ; filling disabled: just check indentation
614              (progn              (progn
615                (goto-char from)                (goto-char from)
616                (while (< (point) to)                (while (< (point) to)
# Line 551  space does not end a sentence, so don't Line 635  space does not end a sentence, so don't
635            (fill-delete-newlines from to justify nosqueeze squeeze-after)            (fill-delete-newlines from to justify nosqueeze squeeze-after)
636    
637            ;; This is the actual filling loop.            ;; This is the actual filling loop.
638            (let ((prefixcol 0) linebeg)            (goto-char from)
639              (while (not (eobp))            (let (linebeg)
640                (while (< (point) to)
641                (setq linebeg (point))                (setq linebeg (point))
642                (move-to-column (1+ (current-fill-column)))                (move-to-column (1+ (current-fill-column)))
643                (if (eobp)                (if (>= (point) to)
644                    (or nosqueeze (delete-horizontal-space))                    (or nosqueeze (delete-horizontal-space))
645                  ;; Move back to the point where we can break the line                  ;; Find the position where we'll break the line.
646                  ;; at.  We break the line between word or after/before                  (fill-move-to-break-point linebeg)
647                  ;; the character which has character category `|'.  We  
                 ;; search space, \c| followed by a character, or \c|  
                 ;; following a character.  If not found, place  
                 ;; the point at linebeg.  
                 (while  
                     (when (re-search-backward "[ \t]\\|\\c|.\\|.\\c|" linebeg 0)  
                       ;; In case of space, we place the point at next to  
                       ;; the point where the break occurs actually,  
                       ;; because we don't want to change the following  
                       ;; logic of original Emacs.  In case of \c|, the  
                       ;; point is at the place where the break occurs.  
                       (forward-char 1)  
                       (when (fill-nobreak-p) (skip-chars-backward " \t"))))  
                 ;; If the left margin and fill prefix by themselves  
                 ;; pass the fill-column. or if they are zero  
                 ;; but we have no room for even one word,  
                 ;; keep at least one word or a character which has  
                 ;; category `|'anyway .  
                 ;; This handles ALL BUT the first line of the paragraph.  
                 (if (if (zerop prefixcol)  
                         (save-excursion  
                           (skip-chars-backward " \t" linebeg)  
                           (bolp))  
                       (>= prefixcol (current-column)))  
                     ;; Ok, skip at least one word or one \c| character.  
                     ;; Meanwhile, don't stop at a period followed by one space.  
                     (let ((fill-nobreak-predicate nil) ;to break sooner.  
                           (first t))  
                       (move-to-column prefixcol)  
                       (while (and (not (eobp)) (or first (fill-nobreak-p)))  
                         ;; Find a breakable point while ignoring the  
                         ;; following spaces.  
                         (skip-chars-forward " \t")  
                         (if (looking-at "\\c|")  
                             (forward-char 1)  
                           (let ((pos (save-excursion  
                                        (skip-chars-forward "^ \n\t")  
                                        (point))))  
                             (if (re-search-forward "\\c|" pos t)  
                                 (forward-char -1)  
                               (goto-char pos))))  
                         (setq first nil)))  
                   ;; Normally, move back over the single space between  
                   ;; the words.  
                   (skip-chars-backward " \t")  
   
                   (if enable-multibyte-characters  
                       ;; If we are going to break the line after or  
                       ;; before a non-ascii character, we may have to  
                       ;; run a special function for the charset of the  
                       ;; character to find the correct break point.  
                       (if (not (and (eq (charset-after (1- (point))) 'ascii)  
                                     (eq (charset-after (point)) 'ascii)))  
                           ;; Make sure we take SOMETHING after the  
                           ;; fill prefix if any.  
                           (fill-find-break-point  
                            (save-excursion  
                              (goto-char linebeg)  
                              (move-to-column prefixcol)  
                              (point))))))  
   
                 ;; If the left margin and fill prefix by themselves  
                 ;; pass the fill-column, keep at least one word.  
                 ;; This handles the first line of the paragraph.  
                 (if (and (zerop prefixcol)  
                          (let ((fill-point (point)) nchars)  
                            (save-excursion  
                              (move-to-left-margin)  
                              (setq nchars (- fill-point (point)))  
                              (or (< nchars 0)  
                                  (and fill-prefix  
                                       (< nchars (length fill-prefix))  
                                       (string= (buffer-substring (point)  
                                                                  fill-point)  
                                                (substring fill-prefix  
                                                           0 nchars)))))))  
                     ;; Ok, skip at least one word.  But  
                     ;; don't stop at a period followed by just one space.  
                     (let ((fill-nobreak-predicate nil) ;to break sooner.  
                           (first t))  
                       (while (and (not (eobp)) (or first (fill-nobreak-p)))  
                         ;; Find a breakable point while ignoring the  
                         ;; following spaces.  
                         (skip-chars-forward " \t")  
                         (if (looking-at "\\c|")  
                             (forward-char 1)  
                           (let ((pos (save-excursion  
                                        (skip-chars-forward "^ \n\t")  
                                        (point))))  
                             (if (re-search-forward "\\c|" pos t)  
                                 (forward-char -1)  
                               (goto-char pos))))  
                         (setq first nil))))  
648                  ;; Check again to see if we got to the end of the paragraph.                  ;; Check again to see if we got to the end of the paragraph.
649                  (if (save-excursion (skip-chars-forward " \t") (eobp))                  (if (save-excursion (skip-chars-forward " \t") (>= (point) to))
650                      (or nosqueeze (delete-horizontal-space))                      (or nosqueeze (delete-horizontal-space))
651                    ;; Replace whitespace here with one newline, then                    (fill-newline)))
                   ;; indent to left margin.  
                   (skip-chars-backward " \t")  
                   (if (and (= (following-char) ?\ )  
                            (or (aref (char-category-set (preceding-char)) ?|)  
                                (looking-at "[ \t]+\\c|")))  
                       ;; We need one space at end of line so that  
                       ;; further filling won't delete it.  NOTE: We  
                       ;; intentionally leave this one space to  
                       ;; distingush the case that user wants to put  
                       ;; space between \c| characters.  
                       (forward-char 1))  
                   (insert ?\n)  
                   ;; Give newline the properties of the space(s) it replaces  
                   (set-text-properties (1- (point)) (point)  
                                        (text-properties-at (point)))  
                   (if (or fill-prefix  
                           (not fill-indent-according-to-mode))  
                       (indent-to-left-margin)  
                     (indent-according-to-mode))  
                   ;; Insert the fill prefix after indentation.  
                   ;; Set prefixcol so whitespace in the prefix won't get lost.  
                   (and fill-prefix (not (equal fill-prefix ""))  
                        (progn  
                          (insert-and-inherit fill-prefix)  
                          (setq prefixcol (current-column))))))  
652                ;; Justify the line just ended, if desired.                ;; Justify the line just ended, if desired.
653                (if justify                (if justify
654                  (if (save-excursion (skip-chars-forward " \t") (eobp))                  (if (save-excursion (skip-chars-forward " \t") (eobp))
# Line 691  space does not end a sentence, so don't Line 659  space does not end a sentence, so don't
659                      (justify-current-line justify nil t)                      (justify-current-line justify nil t)
660                      (forward-line 1))))))                      (forward-line 1))))))
661          ;; Leave point after final newline.          ;; Leave point after final newline.
662          (goto-char (point-max)))          (goto-char to))
663        (unless (eobp)        (unless (eobp)
664          (forward-char 1))          (forward-char 1))
665        ;; Return the fill-prefix we used        ;; Return the fill-prefix we used

Legend:
Removed from v.1.139  
changed lines
  Added in v.1.140

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26